1// Copyright 2015 The Weave Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "examples/daemon/common/daemon.h" 6 7#include <weave/device.h> 8 9#include <base/bind.h> 10#include <base/memory/weak_ptr.h> 11 12namespace { 13 14const char kTraits[] = R"({ 15 "onOff": { 16 "commands": { 17 "setConfig": { 18 "minimalRole": "user", 19 "parameters": { 20 "state": { 21 "type": "string", 22 "enum": [ "on", "standby" ] 23 } 24 } 25 } 26 }, 27 "state": { 28 "state": { 29 "type": "string", 30 "enum": [ "on", "standby" ], 31 "isRequired": true 32 } 33 } 34 }, 35 "volume": { 36 "commands": { 37 "setConfig": { 38 "minimalRole": "user", 39 "parameters": { 40 "volume": { 41 "type": "integer", 42 "minimum": 0, 43 "maximum": 100 44 }, 45 "isMuted": { "type": "boolean" } 46 } 47 } 48 }, 49 "state": { 50 "isMuted": { 51 "type": "boolean", 52 "isRequired": true 53 }, 54 "volume": { 55 "type": "integer", 56 "minimum": 0, 57 "maximum": 100, 58 "isRequired": true 59 } 60 } 61 } 62})"; 63 64const char kComponent[] = "speaker"; 65 66} // anonymous namespace 67 68// SpeakerHandler is a command handler example that shows 69// how to handle commands for a Weave speaker. 70class SpeakerHandler { 71 public: 72 SpeakerHandler() = default; 73 void Register(weave::Device* device) { 74 device_ = device; 75 76 device->AddTraitDefinitionsFromJson(kTraits); 77 CHECK(device->AddComponent(kComponent, {"onOff", "volume"}, nullptr)); 78 UpdateSpeakerState(); 79 80 device->AddCommandHandler(kComponent, "onOff.setConfig", 81 base::Bind(&SpeakerHandler::OnOnOffSetConfig, 82 weak_ptr_factory_.GetWeakPtr())); 83 device->AddCommandHandler(kComponent, "volume.setConfig", 84 base::Bind(&SpeakerHandler::OnVolumeSetConfig, 85 weak_ptr_factory_.GetWeakPtr())); 86 } 87 88 private: 89 void OnVolumeSetConfig(const std::weak_ptr<weave::Command>& command) { 90 auto cmd = command.lock(); 91 if (!cmd) 92 return; 93 LOG(INFO) << "received command: " << cmd->GetName(); 94 95 const auto& params = cmd->GetParameters(); 96 // Handle volume parameter 97 int32_t volume_value = 0; 98 if (params.GetInteger("volume", &volume_value)) { 99 // Display this command in terminal. 100 LOG(INFO) << cmd->GetName() << " volume: " << volume_value; 101 102 if (volume_value_ != volume_value) { 103 volume_value_ = volume_value; 104 UpdateSpeakerState(); 105 } 106 cmd->Complete({}, nullptr); 107 return; 108 } 109 110 // Handle isMuted parameter 111 bool isMuted_status = false; 112 if (params.GetBoolean("isMuted", &isMuted_status)) { 113 // Display this command in terminal. 114 LOG(INFO) << cmd->GetName() << " is " 115 << (isMuted_status ? "muted" : "not muted"); 116 117 if (isMuted_status_ != isMuted_status) { 118 isMuted_status_ = isMuted_status; 119 120 LOG(INFO) << "Speaker is now: " 121 << (isMuted_status ? "muted" : "not muted"); 122 UpdateSpeakerState(); 123 } 124 } 125 126 cmd->Complete({}, nullptr); 127 } 128 129 void OnOnOffSetConfig(const std::weak_ptr<weave::Command>& command) { 130 auto cmd = command.lock(); 131 if (!cmd) 132 return; 133 LOG(INFO) << "received command: " << cmd->GetName(); 134 const auto& params = cmd->GetParameters(); 135 std::string requested_state; 136 if (params.GetString("state", &requested_state)) { 137 LOG(INFO) << cmd->GetName() << " state: " << requested_state; 138 139 bool new_speaker_status = requested_state == "on"; 140 if (new_speaker_status != speaker_status_) { 141 speaker_status_ = new_speaker_status; 142 143 LOG(INFO) << "Speaker is now: " << (speaker_status_ ? "ON" : "OFF"); 144 UpdateSpeakerState(); 145 } 146 } 147 cmd->Complete({}, nullptr); 148 } 149 150 void UpdateSpeakerState() { 151 base::DictionaryValue state; 152 state.SetString("onOff.state", speaker_status_ ? "on" : "standby"); 153 state.SetBoolean("volume.isMuted", isMuted_status_); 154 state.SetInteger("volume.volume", volume_value_); 155 device_->SetStateProperties(kComponent, state, nullptr); 156 } 157 158 weave::Device* device_{nullptr}; 159 160 // Simulate the state of the speaker. 161 bool speaker_status_; 162 bool isMuted_status_; 163 int32_t volume_value_; 164 base::WeakPtrFactory<SpeakerHandler> weak_ptr_factory_{this}; 165}; 166 167int main(int argc, char** argv) { 168 Daemon::Options opts; 169 if (!opts.Parse(argc, argv)) { 170 Daemon::Options::ShowUsage(argv[0]); 171 return 1; 172 } 173 Daemon daemon{opts}; 174 SpeakerHandler speaker; 175 speaker.Register(daemon.GetDevice()); 176 daemon.Run(); 177 return 0; 178} 179