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 12 #include <bitset> 13 14 namespace { 15 // Supported LED count on this device 16 const size_t kLedCount = 3; 17 18 const char kTraits[] = R"({ 19 "_ledflasher": { 20 "commands": { 21 "set": { 22 "minimalRole": "user", 23 "parameters": { 24 "led": { 25 "type": "integer", 26 "minimum": 1, 27 "maximum": 3 28 }, 29 "on": { "type": "boolean" } 30 } 31 }, 32 "toggle": { 33 "minimalRole": "user", 34 "parameters": { 35 "led": { 36 "type": "integer", 37 "minimum": 1, 38 "maximum": 3 39 } 40 } 41 } 42 }, 43 "state": { 44 "leds": { 45 "type": "array", 46 "items": { "type": "boolean" } 47 } 48 } 49 } 50 })"; 51 52 const char kComponent[] = "ledflasher"; 53 54 } // namespace 55 56 // LedFlasherHandler is a complete command handler example that shows 57 // how to handle commands that modify device state. 58 class LedFlasherHandler { 59 public: 60 LedFlasherHandler() {} 61 void Register(weave::Device* device) { 62 device_ = device; 63 64 device->AddTraitDefinitionsFromJson(kTraits); 65 CHECK(device->AddComponent(kComponent, {"_ledflasher"}, nullptr)); 66 UpdateLedState(); 67 68 device->AddCommandHandler( 69 kComponent, "_ledflasher.toggle", 70 base::Bind(&LedFlasherHandler::OnFlasherToggleCommand, 71 weak_ptr_factory_.GetWeakPtr())); 72 device->AddCommandHandler( 73 kComponent, "_ledflasher.set", 74 base::Bind(&LedFlasherHandler::OnFlasherSetCommand, 75 weak_ptr_factory_.GetWeakPtr())); 76 } 77 78 private: 79 void OnFlasherSetCommand(const std::weak_ptr<weave::Command>& command) { 80 auto cmd = command.lock(); 81 if (!cmd) 82 return; 83 LOG(INFO) << "received command: " << cmd->GetName(); 84 int32_t led_index = 0; 85 const auto& params = cmd->GetParameters(); 86 bool cmd_value = false; 87 if (params.GetInteger("_led", &led_index) && 88 params.GetBoolean("_on", &cmd_value)) { 89 // Display this command in terminal 90 LOG(INFO) << cmd->GetName() << " _led: " << led_index 91 << ", _on: " << (cmd_value ? "true" : "false"); 92 93 led_index--; 94 int new_state = cmd_value ? 1 : 0; 95 int cur_state = led_status_[led_index]; 96 led_status_[led_index] = new_state; 97 98 if (cmd_value != cur_state) { 99 UpdateLedState(); 100 } 101 cmd->Complete({}, nullptr); 102 return; 103 } 104 weave::ErrorPtr error; 105 weave::Error::AddTo(&error, FROM_HERE, "invalid_parameter_value", 106 "Invalid parameters"); 107 cmd->Abort(error.get(), nullptr); 108 } 109 110 void OnFlasherToggleCommand(const std::weak_ptr<weave::Command>& command) { 111 auto cmd = command.lock(); 112 if (!cmd) 113 return; 114 LOG(INFO) << "received command: " << cmd->GetName(); 115 const auto& params = cmd->GetParameters(); 116 int32_t led_index = 0; 117 if (params.GetInteger("_led", &led_index)) { 118 LOG(INFO) << cmd->GetName() << " _led: " << led_index; 119 led_index--; 120 led_status_[led_index] = ~led_status_[led_index]; 121 122 UpdateLedState(); 123 cmd->Complete({}, nullptr); 124 return; 125 } 126 weave::ErrorPtr error; 127 weave::Error::AddTo(&error, FROM_HERE, "invalid_parameter_value", 128 "Invalid parameters"); 129 cmd->Abort(error.get(), nullptr); 130 } 131 132 void UpdateLedState() { 133 base::ListValue list; 134 for (uint32_t i = 0; i < led_status_.size(); i++) 135 list.AppendBoolean(led_status_[i] ? true : false); 136 137 device_->SetStateProperty(kComponent, "_ledflasher.leds", list, nullptr); 138 } 139 140 weave::Device* device_{nullptr}; 141 142 // Simulate LED status on this device so client app could explore 143 // Each bit represents one device, indexing from LSB 144 std::bitset<kLedCount> led_status_{0}; 145 base::WeakPtrFactory<LedFlasherHandler> weak_ptr_factory_{this}; 146 }; 147 148 int main(int argc, char** argv) { 149 Daemon::Options opts; 150 if (!opts.Parse(argc, argv)) { 151 Daemon::Options::ShowUsage(argv[0]); 152 return 1; 153 } 154 Daemon daemon{opts}; 155 LedFlasherHandler handler; 156 handler.Register(daemon.GetDevice()); 157 daemon.Run(); 158 return 0; 159 } 160