diff options
Diffstat (limited to 'examples')
-rw-r--r-- | examples/daemon/oven/oven.cc | 290 | ||||
-rw-r--r-- | examples/daemon/speaker/speaker.cc | 178 | ||||
-rw-r--r-- | examples/examples.mk | 12 | ||||
-rw-r--r-- | examples/provider/avahi_client.cc | 1 | ||||
-rw-r--r-- | examples/provider/avahi_client.h | 1 | ||||
-rw-r--r-- | examples/provider/event_network.h | 2 | ||||
-rw-r--r-- | examples/provider/event_task_runner.h | 1 |
7 files changed, 478 insertions, 7 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; +} diff --git a/examples/daemon/speaker/speaker.cc b/examples/daemon/speaker/speaker.cc new file mode 100644 index 0000000..56da840 --- /dev/null +++ b/examples/daemon/speaker/speaker.cc @@ -0,0 +1,178 @@ +// 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 <base/bind.h> +#include <base/memory/weak_ptr.h> + +namespace { + +const char kTraits[] = R"({ + "onOff": { + "commands": { + "setConfig": { + "minimalRole": "user", + "parameters": { + "state": { + "type": "string", + "enum": [ "on", "off" ] + } + } + } + }, + "state": { + "state": { + "type": "string", + "enum": [ "on", "off" ], + "isRequired": true + } + } + }, + "volume": { + "commands": { + "setConfig": { + "minimalRole": "user", + "parameters": { + "volume": { + "type": "integer", + "minimum": 0, + "maximum": 100 + }, + "isMuted": { "type": "boolean" } + } + } + }, + "state": { + "isMuted": { + "type": "boolean", + "isRequired": true + }, + "volume": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "isRequired": true + } + } + } +})"; + +const char kComponent[] = "speaker"; + +} // anonymous namespace + +// SpeakerHandler is a command handler example that shows +// how to handle commands for a Weave speaker. +class SpeakerHandler { + public: + SpeakerHandler() = default; + void Register(weave::Device* device) { + device_ = device; + + device->AddTraitDefinitionsFromJson(kTraits); + CHECK(device->AddComponent(kComponent, {"onOff", "volume"}, nullptr)); + UpdateSpeakerState(); + + device->AddCommandHandler(kComponent, "onOff.setConfig", + base::Bind(&SpeakerHandler::OnOnOffSetConfig, + weak_ptr_factory_.GetWeakPtr())); + device->AddCommandHandler(kComponent, "volume.setConfig", + base::Bind(&SpeakerHandler::OnVolumeSetConfig, + weak_ptr_factory_.GetWeakPtr())); + } + + private: + void OnVolumeSetConfig(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(); + // Handle volume parameter + int32_t volume_value = 0; + if (params.GetInteger("volume", &volume_value)) { + // Display this command in terminal. + LOG(INFO) << cmd->GetName() << " volume: " << volume_value; + + if (volume_value_ != volume_value) { + volume_value_ = volume_value; + UpdateSpeakerState(); + } + cmd->Complete({}, nullptr); + return; + } + + // Handle isMuted parameter + bool isMuted_status = false; + if (params.GetBoolean("isMuted", &isMuted_status)) { + // Display this command in terminal. + LOG(INFO) << cmd->GetName() << " is " + << (isMuted_status ? "muted" : "not muted"); + + if (isMuted_status_ != isMuted_status) { + isMuted_status_ = isMuted_status; + + LOG(INFO) << "Speaker is now: " + << (isMuted_status ? "muted" : "not muted"); + UpdateSpeakerState(); + } + } + + cmd->Complete({}, nullptr); + } + + void OnOnOffSetConfig(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 requested_state; + if (params.GetString("state", &requested_state)) { + LOG(INFO) << cmd->GetName() << " state: " << requested_state; + + bool new_speaker_status = requested_state == "on"; + if (new_speaker_status != speaker_status_) { + speaker_status_ = new_speaker_status; + + LOG(INFO) << "Speaker is now: " << (speaker_status_ ? "ON" : "OFF"); + UpdateSpeakerState(); + } + } + cmd->Complete({}, nullptr); + } + + void UpdateSpeakerState() { + base::DictionaryValue state; + state.SetString("onOff.state", speaker_status_ ? "on" : "off"); + state.SetBoolean("volume.isMuted", isMuted_status_); + state.SetInteger("volume.volume", volume_value_); + device_->SetStateProperties(kComponent, state, nullptr); + } + + weave::Device* device_{nullptr}; + + // Simulate the state of the speaker. + bool speaker_status_; + bool isMuted_status_; + int32_t volume_value_; + base::WeakPtrFactory<SpeakerHandler> 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}; + SpeakerHandler speaker; + speaker.Register(daemon.GetDevice()); + daemon.Run(); + return 0; +} diff --git a/examples/examples.mk b/examples/examples.mk index cb64e2b..555322c 100644 --- a/examples/examples.mk +++ b/examples/examples.mk @@ -21,7 +21,9 @@ EXAMPLES_DAEMON_SRC_FILES := \ examples/daemon/ledflasher/ledflasher.cc \ examples/daemon/light/light.cc \ examples/daemon/lock/lock.cc \ - examples/daemon/sample/sample.cc + examples/daemon/oven/oven.cc \ + examples/daemon/sample/sample.cc \ + examples/daemon/speaker/speaker.cc examples_daemon_obj_files := $(EXAMPLES_DAEMON_SRC_FILES:%.cc=out/$(BUILD_MODE)/%.o) @@ -60,10 +62,16 @@ out/$(BUILD_MODE)/weave_daemon_light : out/$(BUILD_MODE)/examples/daemon/light/l out/$(BUILD_MODE)/weave_daemon_lock : out/$(BUILD_MODE)/examples/daemon/lock/lock.o $(example_daemon_deps) $(CXX) -o $@ $^ $(CFLAGS) $(example_daemon_common_flags) +out/$(BUILD_MODE)/weave_daemon_oven : out/$(BUILD_MODE)/examples/daemon/oven/oven.o $(example_daemon_deps) + $(CXX) -o $@ $^ $(CFLAGS) $(example_daemon_common_flags) + out/$(BUILD_MODE)/weave_daemon_sample : out/$(BUILD_MODE)/examples/daemon/sample/sample.o $(example_daemon_deps) $(CXX) -o $@ $^ $(CFLAGS) $(example_daemon_common_flags) -all-examples : out/$(BUILD_MODE)/weave_daemon_ledflasher out/$(BUILD_MODE)/weave_daemon_light out/$(BUILD_MODE)/weave_daemon_lock out/$(BUILD_MODE)/weave_daemon_sample +out/$(BUILD_MODE)/weave_daemon_speaker : out/$(BUILD_MODE)/examples/daemon/speaker/speaker.o $(example_daemon_deps) + $(CXX) -o $@ $^ $(CFLAGS) $(example_daemon_common_flags) + +all-examples : out/$(BUILD_MODE)/weave_daemon_ledflasher out/$(BUILD_MODE)/weave_daemon_light out/$(BUILD_MODE)/weave_daemon_lock out/$(BUILD_MODE)/weave_daemon_oven out/$(BUILD_MODE)/weave_daemon_sample out/$(BUILD_MODE)/weave_daemon_speaker .PHONY : all-examples diff --git a/examples/provider/avahi_client.cc b/examples/provider/avahi_client.cc index 36109c4..ddd4630 100644 --- a/examples/provider/avahi_client.cc +++ b/examples/provider/avahi_client.cc @@ -5,7 +5,6 @@ #include "examples/provider/avahi_client.h" #include <cstdlib> -#include <memory> #include <vector> #include <avahi-common/error.h> diff --git a/examples/provider/avahi_client.h b/examples/provider/avahi_client.h index f9ba01c..7d9b932 100644 --- a/examples/provider/avahi_client.h +++ b/examples/provider/avahi_client.h @@ -6,7 +6,6 @@ #define LIBWEAVE_EXAMPLES_PROVIDER_AVAHI_CLIENT_H_ #include <map> -#include <memory> #include <string> #include <avahi-client/client.h> diff --git a/examples/provider/event_network.h b/examples/provider/event_network.h index 6a5617f..3aeac24 100644 --- a/examples/provider/event_network.h +++ b/examples/provider/event_network.h @@ -5,8 +5,6 @@ #ifndef LIBWEAVE_EXAMPLES_UBUNTU_EVENT_NETWORK_H_ #define LIBWEAVE_EXAMPLES_UBUNTU_EVENT_NETWORK_H_ -#include <vector> - #include <weave/provider/network.h> #include <base/memory/weak_ptr.h> diff --git a/examples/provider/event_task_runner.h b/examples/provider/event_task_runner.h index a788950..97f9db9 100644 --- a/examples/provider/event_task_runner.h +++ b/examples/provider/event_task_runner.h @@ -6,7 +6,6 @@ #define LIBWEAVE_EXAMPLES_PROVIDER_EVENT_TASK_RUNNER_H_ #include <queue> -#include <map> #include <utility> #include <vector> |