blob: 56da8409b2caf09a101672919fd85770c2350d54 [file] [log] [blame]
Luis Larcob51b4752015-11-04 19:05:37 -08001// 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
Alex Vakulenkod6db0492015-12-07 16:55:19 -080012namespace {
13
14const char kTraits[] = R"({
15 "onOff": {
16 "commands": {
17 "setConfig": {
18 "minimalRole": "user",
19 "parameters": {
20 "state": {
21 "type": "string",
Johan Euphrosinef7bfb6a2016-02-25 17:34:04 -080022 "enum": [ "on", "off" ]
Alex Vakulenkod6db0492015-12-07 16:55:19 -080023 }
24 }
25 }
26 },
27 "state": {
Alex Vakulenko8d0cfef2015-12-15 18:40:05 -080028 "state": {
29 "type": "string",
Johan Euphrosinef7bfb6a2016-02-25 17:34:04 -080030 "enum": [ "on", "off" ],
Alex Vakulenko8d0cfef2015-12-15 18:40:05 -080031 "isRequired": true
32 }
Alex Vakulenkod6db0492015-12-07 16:55:19 -080033 }
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": {
Alex Vakulenko8d0cfef2015-12-15 18:40:05 -080050 "isMuted": {
51 "type": "boolean",
52 "isRequired": true
53 },
54 "volume": {
55 "type": "integer",
56 "minimum": 0,
57 "maximum": 100,
58 "isRequired": true
59 }
Alex Vakulenkod6db0492015-12-07 16:55:19 -080060 }
61 }
62})";
63
64const char kComponent[] = "speaker";
65
66} // anonymous namespace
67
Luis Larcob51b4752015-11-04 19:05:37 -080068// 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
Alex Vakulenkod6db0492015-12-07 16:55:19 -080076 device->AddTraitDefinitionsFromJson(kTraits);
77 CHECK(device->AddComponent(kComponent, {"onOff", "volume"}, nullptr));
78 UpdateSpeakerState();
Luis Larcob51b4752015-11-04 19:05:37 -080079
Alex Vakulenkod6db0492015-12-07 16:55:19 -080080 device->AddCommandHandler(kComponent, "onOff.setConfig",
Luis Larcob51b4752015-11-04 19:05:37 -080081 base::Bind(&SpeakerHandler::OnOnOffSetConfig,
82 weak_ptr_factory_.GetWeakPtr()));
Alex Vakulenkod6db0492015-12-07 16:55:19 -080083 device->AddCommandHandler(kComponent, "volume.setConfig",
Luis Larcob51b4752015-11-04 19:05:37 -080084 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
Vitaly Bukac4305602015-11-24 23:33:09 -080095 const auto& params = cmd->GetParameters();
Luis Larcob51b4752015-11-04 19:05:37 -080096 // Handle volume parameter
97 int32_t volume_value = 0;
Vitaly Bukac4305602015-11-24 23:33:09 -080098 if (params.GetInteger("volume", &volume_value)) {
Luis Larcob51b4752015-11-04 19:05:37 -080099 // 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;
Vitaly Bukac4305602015-11-24 23:33:09 -0800112 if (params.GetBoolean("isMuted", &isMuted_status)) {
Luis Larcob51b4752015-11-04 19:05:37 -0800113 // Display this command in terminal.
Luis Larco5ca27be2015-11-11 09:55:40 -0800114 LOG(INFO) << cmd->GetName() << " is "
Luis Larcob51b4752015-11-04 19:05:37 -0800115 << (isMuted_status ? "muted" : "not muted");
116
117 if (isMuted_status_ != isMuted_status) {
118 isMuted_status_ = isMuted_status;
119
Luis Larco5ca27be2015-11-11 09:55:40 -0800120 LOG(INFO) << "Speaker is now: "
Luis Larcob51b4752015-11-04 19:05:37 -0800121 << (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();
Vitaly Bukac4305602015-11-24 23:33:09 -0800134 const auto& params = cmd->GetParameters();
Luis Larcob51b4752015-11-04 19:05:37 -0800135 std::string requested_state;
Vitaly Bukac4305602015-11-24 23:33:09 -0800136 if (params.GetString("state", &requested_state)) {
Luis Larcob51b4752015-11-04 19:05:37 -0800137 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;
Johan Euphrosinef7bfb6a2016-02-25 17:34:04 -0800152 state.SetString("onOff.state", speaker_status_ ? "on" : "off");
Luis Larcob51b4752015-11-04 19:05:37 -0800153 state.SetBoolean("volume.isMuted", isMuted_status_);
154 state.SetInteger("volume.volume", volume_value_);
Alex Vakulenkod6db0492015-12-07 16:55:19 -0800155 device_->SetStateProperties(kComponent, state, nullptr);
Luis Larcob51b4752015-11-04 19:05:37 -0800156 }
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}