// 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 #include #include 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& 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& 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 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; }