diff options
author | Luis Hector Chavez <lhchavez@google.com> | 2016-05-31 23:41:41 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2016-05-31 23:41:41 +0000 |
commit | d77dfa0b5a854a80a586b89f13f602ee5a523d06 (patch) | |
tree | dd9041de1b74c6133fb3a07fcaa321de989b9668 /examples/daemon/oven/oven.cc | |
parent | f91e999fb2dc8a70365471277e846e7b8e7b3284 (diff) | |
parent | abfe7a063bbaebdca8703d27137c8c9aed826dac (diff) | |
download | libweave-d77dfa0b5a854a80a586b89f13f602ee5a523d06.tar.gz |
Revert "Merge remote-tracking branch \'weave/master\' into \'weave/aosp-master\'"
am: abfe7a063b
* commit 'abfe7a063bbaebdca8703d27137c8c9aed826dac':
Revert "Merge remote-tracking branch 'weave/master' into 'weave/aosp-master'"
Change-Id: Id85d181a0a73598c6c4a3f397bd8085dd2c398e5
Diffstat (limited to 'examples/daemon/oven/oven.cc')
-rw-r--r-- | examples/daemon/oven/oven.cc | 290 |
1 files changed, 290 insertions, 0 deletions
diff --git a/examples/daemon/oven/oven.cc b/examples/daemon/oven/oven.cc new file mode 100644 index 0000000..f92c838 --- /dev/null +++ b/examples/daemon/oven/oven.cc @@ -0,0 +1,290 @@ +// Copyright 2015 The Weave Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "examples/daemon/common/daemon.h" + +#include <weave/device.h> +#include <weave/provider/task_runner.h> + +#include <base/bind.h> +#include <base/memory/weak_ptr.h> + +namespace { +// Time for sensor temperature to match setting temperature +const double kWarmUpTime = 60.0; +// Oven max temp +const double kMaxTemp = 300.0; +// Oven min temp +const double kMinTemp = 20.0; + +const char kTraits[] = R"({ + "temperatureSetting": { + "commands": { + "setConfig": { + "minimalRole": "user", + "parameters": { + "units": { + "type": "string" + }, + "tempSetting": { + "type": "number" + } + }, + "errors": ["tempOutOfRange", "unsupportedUnits"] + } + }, + "state": { + "supportedUnits": { + "type": "array", + "items": { + "type": "string", + "enum": [ "celsius", "fahrenheit", "kelvin" ] + }, + "minItems": 1, + "uniqueItems": true, + "isRequired": true + }, + "units": { + "type": "string", + "enum": [ "celsius", "fahrenheit", "kelvin" ], + "isRequired": true + }, + "tempSetting": { + "type": "number", + "isRequired": true + }, + "maxTempSetting": { + "type": "number", + "isRequired": true + }, + "minTempSetting": { + "type": "number", + "isRequired": true + } + } + }, + "temperatureSensor": { + "commands": { + "setConfig": { + "minimalRole": "user", + "parameters": { + "units": { + "type": "string" + } + }, + "errors": ["unsupportedUnits"] + } + }, + "state": { + "supportedUnits": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "celsius", + "fahrenheit", + "kelvin" + ] + }, + "minItems": 1, + "uniqueItems": true, + "isRequired": true + }, + "units": { + "type": "string", + "enum": [ "celsius", "fahrenheit", "kelvin" ], + "isRequired": true + }, + "value": { + "type": "number", + "isRequired": true + } + } + }, + "brightness": { + "commands": { + "setConfig": { + "minimalRole": "user", + "parameters": { + "brightness": { + "type": "integer", + "minimum": 0, + "maximum": 100 + } + } + } + }, + "state": { + "brightness": { + "type": "integer", + "isRequired": true, + "minimum": 0, + "maximum": 100 + } + } + } +})"; + +const char kComponent[] = "oven"; +} // anonymous namespace + +// OvenHandler is a virtual oven example +// It implements the following commands from traits: +// - temperatureSetting: sets the temperature for the oven +// - brightness: sets the brightness of the oven light +// It exposes the following states from traits: +// - temperatureSetting: temperature setting for the oven +// - temperatureSensor: current oven temperature +// - brightness: current oven brightness +class OvenHandler { + public: + OvenHandler(weave::provider::TaskRunner* task_runner) + : task_runner_{task_runner} {} + + void Register(weave::Device* device) { + device_ = device; + + device->AddTraitDefinitionsFromJson(kTraits); + CHECK(device->AddComponent( + kComponent, {"temperatureSetting", "temperatureSensor", "brightness"}, + nullptr)); + + UpdateOvenState(); + + device->AddCommandHandler(kComponent, "temperatureSetting.setConfig", + base::Bind(&OvenHandler::OnSetTempCommand, + weak_ptr_factory_.GetWeakPtr())); + + device->AddCommandHandler(kComponent, "brightness.setConfig", + base::Bind(&OvenHandler::OnSetBrightnessCommand, + weak_ptr_factory_.GetWeakPtr())); + } + + private: + void OnSetTempCommand(const std::weak_ptr<weave::Command>& command) { + auto cmd = command.lock(); + if (!cmd) + return; + LOG(INFO) << "received command: " << cmd->GetName(); + + const auto& params = cmd->GetParameters(); + std::string units; + double temp; + + if (params.GetString("units", &units) && + params.GetDouble("tempSetting", &temp)) { + units_ = units; + target_temperature_ = temp; + + UpdateOvenState(); + + cmd->Complete({}, nullptr); + LOG(INFO) << cmd->GetName() << " updated oven, matching temp"; + + if (target_temperature_ != current_temperature_ && !is_match_ticking_) { + double tickIncrement = + ((target_temperature_ - current_temperature_) / kWarmUpTime); + DoTick(tickIncrement); + } + return; + } + + weave::ErrorPtr error; + weave::Error::AddTo(&error, FROM_HERE, "invalid_parameter_value", + "Invalid parameters"); + cmd->Abort(error.get(), nullptr); + } + + void OnSetBrightnessCommand(const std::weak_ptr<weave::Command>& command) { + auto cmd = command.lock(); + if (!cmd) + return; + LOG(INFO) << "received command: " << cmd->GetName(); + + const auto& params = cmd->GetParameters(); + + int brightness; + if (params.GetInteger("brightness", &brightness)) { + brightness_ = brightness; + + UpdateOvenState(); + + cmd->Complete({}, nullptr); + return; + } + + weave::ErrorPtr error; + weave::Error::AddTo(&error, FROM_HERE, "invalid_parameter_value", + "Invalid parameters"); + cmd->Abort(error.get(), nullptr); + } + + void UpdateOvenState() { + base::DictionaryValue state; + base::ListValue supportedUnits; + supportedUnits.AppendStrings({"celsius"}); + + state.SetString("temperatureSensor.units", units_); + state.SetDouble("temperatureSensor.value", current_temperature_); + state.Set("temperatureSensor.supportedUnits", + supportedUnits.CreateDeepCopy()); + + state.SetString("temperatureSetting.units", units_); + state.SetDouble("temperatureSetting.tempSetting", target_temperature_); + state.Set("temperatureSetting.supportedUnits", + supportedUnits.CreateDeepCopy()); + state.SetDouble("temperatureSetting.maxTempSetting", kMaxTemp); + state.SetDouble("temperatureSetting.minTempSetting", kMinTemp); + + state.SetInteger("brightness.brightness", brightness_); + + device_->SetStateProperties(kComponent, state, nullptr); + } + + void DoTick(double tickIncrement) { + LOG(INFO) << "Oven matching temp tick"; + + if (std::fabs(target_temperature_ - current_temperature_) >= + tickIncrement) { + is_match_ticking_ = true; + current_temperature_ += tickIncrement; + UpdateOvenState(); + task_runner_->PostDelayedTask( + FROM_HERE, base::Bind(&OvenHandler::DoTick, + weak_ptr_factory_.GetWeakPtr(), tickIncrement), + base::TimeDelta::FromSeconds(1)); + return; + } + + is_match_ticking_ = false; + current_temperature_ = target_temperature_; + UpdateOvenState(); + + LOG(INFO) << "Oven temp matched"; + } + + weave::Device* device_{nullptr}; + weave::provider::TaskRunner* task_runner_{nullptr}; + + std::string units_ = "celsius"; + double target_temperature_ = 0.0; + double current_temperature_ = 0.0; + int brightness_ = 0; + bool is_match_ticking_ = false; + + base::WeakPtrFactory<OvenHandler> weak_ptr_factory_{this}; +}; + +int main(int argc, char** argv) { + Daemon::Options opts; + if (!opts.Parse(argc, argv)) { + Daemon::Options::ShowUsage(argv[0]); + return 1; + } + Daemon daemon{opts}; + OvenHandler handler{daemon.GetTaskRunner()}; + handler.Register(daemon.GetDevice()); + daemon.Run(); + return 0; +} |