1aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying// Copyright 2015 The Weave Authors. All rights reserved. 2aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying// Use of this source code is governed by a BSD-style license that can be 3aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying// found in the LICENSE file. 4aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 5aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying#include "examples/daemon/common/daemon.h" 6aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 7aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying#include <weave/device.h> 8aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying#include <weave/provider/task_runner.h> 9aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 10aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying#include <base/bind.h> 11aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying#include <base/memory/weak_ptr.h> 12aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 13aef87f5214d4e8b5924281d82dae2c8156f4203apeng yingnamespace { 14aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying// Time for sensor temperature to match setting temperature 15aef87f5214d4e8b5924281d82dae2c8156f4203apeng yingconst double kWarmUpTime = 60.0; 16aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying// Oven max temp 17aef87f5214d4e8b5924281d82dae2c8156f4203apeng yingconst double kMaxTemp = 300.0; 18aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying// Oven min temp 19aef87f5214d4e8b5924281d82dae2c8156f4203apeng yingconst double kMinTemp = 20.0; 20aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 21aef87f5214d4e8b5924281d82dae2c8156f4203apeng yingconst char kTraits[] = R"({ 22aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "temperatureSetting": { 23aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "commands": { 24aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "setConfig": { 25aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "minimalRole": "user", 26aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "parameters": { 27aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "units": { 28aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "type": "string" 29aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying }, 30aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "tempSetting": { 31aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "type": "number" 32aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying } 338d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko }, 348d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "errors": ["tempOutOfRange", "unsupportedUnits"] 35aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying } 36aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying }, 37aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "state": { 38aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "supportedUnits": { 39aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "type": "array", 40aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "items": { 41aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "type": "string", 428d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "enum": [ "celsius", "fahrenheit", "kelvin" ] 438d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko }, 448d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "minItems": 1, 458d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "uniqueItems": true, 468d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "isRequired": true 47aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying }, 48aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "units": { 498d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "type": "string", 508d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "enum": [ "celsius", "fahrenheit", "kelvin" ], 518d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "isRequired": true 52aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying }, 53aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "tempSetting": { 548d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "type": "number", 558d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "isRequired": true 56aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying }, 57aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "maxTempSetting": { 588d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "type": "number", 598d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "isRequired": true 60aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying }, 61aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "minTempSetting": { 628d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "type": "number", 638d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "isRequired": true 64aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying } 65aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying } 66aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying }, 67aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "temperatureSensor": { 688d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "commands": { 698d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "setConfig": { 708d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "minimalRole": "user", 718d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "parameters": { 728d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "units": { 738d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "type": "string" 748d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko } 758d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko }, 768d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "errors": ["unsupportedUnits"] 778d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko } 788d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko }, 79aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "state": { 80aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "supportedUnits": { 81aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "type": "array", 82aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "items": { 83aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "type": "string", 84aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "enum": [ 85aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "celsius", 86aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "fahrenheit", 87aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "kelvin" 88aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying ] 898d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko }, 908d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "minItems": 1, 918d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "uniqueItems": true, 928d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "isRequired": true 93aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying }, 94aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "units": { 958d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "type": "string", 968d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "enum": [ "celsius", "fahrenheit", "kelvin" ], 978d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "isRequired": true 98aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying }, 99aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "value": { 1008d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "type": "number", 1018d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "isRequired": true 102aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying } 103aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying } 104aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying }, 105aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "brightness": { 106aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "commands": { 107aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "setConfig": { 108aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "minimalRole": "user", 109aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "parameters": { 110aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "brightness": { 111aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "type": "integer", 112aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "minimum": 0, 113aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "maximum": 100 114aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying } 115aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying } 116aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying } 117aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying }, 118aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "state": { 119aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "brightness": { 1208d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "type": "integer", 1218d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "isRequired": true, 1228d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "minimum": 0, 1238d0cfefae24985025a934ea5461a51472c59cfc0Alex Vakulenko "maximum": 100 124aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying } 125aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying } 126aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying } 127aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying})"; 128aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 129aef87f5214d4e8b5924281d82dae2c8156f4203apeng yingconst char kComponent[] = "oven"; 130aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying} // anonymous namespace 131aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 132aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying// OvenHandler is a virtual oven example 133aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying// It implements the following commands from traits: 134aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying// - temperatureSetting: sets the temperature for the oven 135aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying// - brightness: sets the brightness of the oven light 136aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying// It exposes the following states from traits: 137aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying// - temperatureSetting: temperature setting for the oven 138aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying// - temperatureSensor: current oven temperature 139aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying// - brightness: current oven brightness 140aef87f5214d4e8b5924281d82dae2c8156f4203apeng yingclass OvenHandler { 141aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying public: 142aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying OvenHandler(weave::provider::TaskRunner* task_runner) 143aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying : task_runner_{task_runner} {} 144aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 145aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying void Register(weave::Device* device) { 146aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying device_ = device; 147aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 148aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying device->AddTraitDefinitionsFromJson(kTraits); 149aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying CHECK(device->AddComponent( 150aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying kComponent, {"temperatureSetting", "temperatureSensor", "brightness"}, 151aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying nullptr)); 152aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 153aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying UpdateOvenState(); 154aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 155aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying device->AddCommandHandler(kComponent, "temperatureSetting.setConfig", 156aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying base::Bind(&OvenHandler::OnSetTempCommand, 157aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying weak_ptr_factory_.GetWeakPtr())); 158aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 159aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying device->AddCommandHandler(kComponent, "brightness.setConfig", 160aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying base::Bind(&OvenHandler::OnSetBrightnessCommand, 161aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying weak_ptr_factory_.GetWeakPtr())); 162aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying } 163aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 16434668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka private: 165aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying void OnSetTempCommand(const std::weak_ptr<weave::Command>& command) { 166aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying auto cmd = command.lock(); 167aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying if (!cmd) 168aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying return; 169aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying LOG(INFO) << "received command: " << cmd->GetName(); 170aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 171aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying const auto& params = cmd->GetParameters(); 172aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying std::string units; 173aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying double temp; 174aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 175aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying if (params.GetString("units", &units) && 176aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying params.GetDouble("tempSetting", &temp)) { 177aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying units_ = units; 178aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying target_temperature_ = temp; 179aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 180aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying UpdateOvenState(); 181aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 182aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying cmd->Complete({}, nullptr); 183aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying LOG(INFO) << cmd->GetName() << " updated oven, matching temp"; 184aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 185aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying if (target_temperature_ != current_temperature_ && !is_match_ticking_) { 18634668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka double tickIncrement = 18734668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka ((target_temperature_ - current_temperature_) / kWarmUpTime); 188aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying DoTick(tickIncrement); 189aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying } 190aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying return; 191aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying } 192aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 193aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying weave::ErrorPtr error; 19448a8669ddc2e8d785aad9ad18a5abbf8f1224fdeVitaly Buka weave::Error::AddTo(&error, FROM_HERE, "invalid_parameter_value", 195aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "Invalid parameters"); 196aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying cmd->Abort(error.get(), nullptr); 197aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying } 198aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 199aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying void OnSetBrightnessCommand(const std::weak_ptr<weave::Command>& command) { 200aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying auto cmd = command.lock(); 201aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying if (!cmd) 202aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying return; 203aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying LOG(INFO) << "received command: " << cmd->GetName(); 204aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 205aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying const auto& params = cmd->GetParameters(); 206aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 207aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying int brightness; 208aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying if (params.GetInteger("brightness", &brightness)) { 209aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying brightness_ = brightness; 210aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 211aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying UpdateOvenState(); 212aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 213aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying cmd->Complete({}, nullptr); 214aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying return; 215aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying } 216aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 217aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying weave::ErrorPtr error; 21848a8669ddc2e8d785aad9ad18a5abbf8f1224fdeVitaly Buka weave::Error::AddTo(&error, FROM_HERE, "invalid_parameter_value", 219aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying "Invalid parameters"); 220aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying cmd->Abort(error.get(), nullptr); 221aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying } 222aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 223aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying void UpdateOvenState() { 224aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying base::DictionaryValue state; 225aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying base::ListValue supportedUnits; 226aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying supportedUnits.AppendStrings({"celsius"}); 227aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 228aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying state.SetString("temperatureSensor.units", units_); 229aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying state.SetDouble("temperatureSensor.value", current_temperature_); 230aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying state.Set("temperatureSensor.supportedUnits", supportedUnits.DeepCopy()); 231aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 232aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying state.SetString("temperatureSetting.units", units_); 233aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying state.SetDouble("temperatureSetting.tempSetting", target_temperature_); 234aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying state.Set("temperatureSetting.supportedUnits", supportedUnits.DeepCopy()); 235aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying state.SetDouble("temperatureSetting.maxTempSetting", kMaxTemp); 236aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying state.SetDouble("temperatureSetting.minTempSetting", kMinTemp); 237aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 238aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying state.SetInteger("brightness.brightness", brightness_); 239aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 240aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying device_->SetStateProperties(kComponent, state, nullptr); 241aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying } 242aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 243aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying void DoTick(double tickIncrement) { 244aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying LOG(INFO) << "Oven matching temp tick"; 245aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 246aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying if (std::fabs(target_temperature_ - current_temperature_) >= 247aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying tickIncrement) { 248aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying is_match_ticking_ = true; 249aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying current_temperature_ += tickIncrement; 250aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying UpdateOvenState(); 251aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying task_runner_->PostDelayedTask( 252aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying FROM_HERE, base::Bind(&OvenHandler::DoTick, 253aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying weak_ptr_factory_.GetWeakPtr(), tickIncrement), 254aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying base::TimeDelta::FromSeconds(1)); 255aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying return; 256aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying } 257aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 258aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying is_match_ticking_ = false; 259aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying current_temperature_ = target_temperature_; 260aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying UpdateOvenState(); 261aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 262aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying LOG(INFO) << "Oven temp matched"; 263aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying } 264aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 265aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying weave::Device* device_{nullptr}; 266aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying weave::provider::TaskRunner* task_runner_{nullptr}; 267aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 268aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying std::string units_ = "celsius"; 269aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying double target_temperature_ = 0.0; 270aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying double current_temperature_ = 0.0; 271aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying int brightness_ = 0; 272aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying bool is_match_ticking_ = false; 273aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 274aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying base::WeakPtrFactory<OvenHandler> weak_ptr_factory_{this}; 275aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying}; 276aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying 277aef87f5214d4e8b5924281d82dae2c8156f4203apeng yingint main(int argc, char** argv) { 278aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying Daemon::Options opts; 279aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying if (!opts.Parse(argc, argv)) { 280aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying Daemon::Options::ShowUsage(argv[0]); 281aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying return 1; 282aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying } 283aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying Daemon daemon{opts}; 284aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying OvenHandler handler{daemon.GetTaskRunner()}; 285aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying handler.Register(daemon.GetDevice()); 286aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying daemon.Run(); 287aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying return 0; 288aef87f5214d4e8b5924281d82dae2c8156f4203apeng ying} 289