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#include <weave/enum_to_string.h> 9 10#include <base/bind.h> 11#include <base/memory/weak_ptr.h> 12 13namespace weave { 14namespace lockstate { 15enum class LockState { kUnlocked, kLocked, kPartiallyLocked }; 16 17const weave::EnumToStringMap<LockState>::Map kLockMapMethod[] = { 18 {LockState::kLocked, "locked"}, 19 {LockState::kUnlocked, "unlocked"}, 20 {LockState::kPartiallyLocked, "partiallyLocked"}}; 21} // namespace lockstate 22 23template <> 24EnumToStringMap<lockstate::LockState>::EnumToStringMap() 25 : EnumToStringMap(lockstate::kLockMapMethod) {} 26} // namespace weave 27 28namespace { 29 30const char kTraits[] = R"({ 31 "lock": { 32 "commands": { 33 "setConfig": { 34 "minimalRole": "user", 35 "parameters": { 36 "lockedState": { 37 "type": "string", 38 "enum": [ "locked", "unlocked" ] 39 } 40 }, 41 "errors": ["batteryTooLow", "jammed", "lockingNotSupported"] 42 } 43 }, 44 "state": { 45 "lockedState": { 46 "type": "string", 47 "enum": [ "locked", "unlocked", "partiallyLocked" ], 48 "isRequired": true 49 }, 50 "isLockingSupported": { 51 "type": "boolean", 52 "isRequired": true 53 } 54 } 55 } 56})"; 57 58const char kDefaultState[] = R"({ 59 "lock":{"isLockingSupported": true} 60})"; 61 62const char kComponent[] = "lock"; 63 64} // anonymous namespace 65 66// LockHandler is a command handler example that shows 67// how to handle commands for a Weave lock. 68class LockHandler { 69 public: 70 LockHandler() = default; 71 void Register(weave::Device* device) { 72 device_ = device; 73 74 device->AddTraitDefinitionsFromJson(kTraits); 75 CHECK(device->AddComponent(kComponent, {"lock"}, nullptr)); 76 CHECK( 77 device->SetStatePropertiesFromJson(kComponent, kDefaultState, nullptr)); 78 UpdateLockState(); 79 80 device->AddCommandHandler(kComponent, "lock.setConfig", 81 base::Bind(&LockHandler::OnLockSetConfig, 82 weak_ptr_factory_.GetWeakPtr())); 83 } 84 85 private: 86 void OnLockSetConfig(const std::weak_ptr<weave::Command>& command) { 87 auto cmd = command.lock(); 88 if (!cmd) 89 return; 90 LOG(INFO) << "received command: " << cmd->GetName(); 91 const auto& params = cmd->GetParameters(); 92 std::string requested_state; 93 if (params.GetString("lockedState", &requested_state)) { 94 LOG(INFO) << cmd->GetName() << " state: " << requested_state; 95 96 weave::lockstate::LockState new_lock_status; 97 98 if (!weave::StringToEnum(requested_state, &new_lock_status)) { 99 // Invalid lock state was specified. 100 weave::ErrorPtr error; 101 weave::Error::AddTo(&error, FROM_HERE, "invalid_parameter_value", 102 "Invalid parameters"); 103 cmd->Abort(error.get(), nullptr); 104 return; 105 } 106 107 if (new_lock_status != lock_state_) { 108 lock_state_ = new_lock_status; 109 110 LOG(INFO) << "Lock is now: " << requested_state; 111 UpdateLockState(); 112 } 113 cmd->Complete({}, nullptr); 114 return; 115 } 116 weave::ErrorPtr error; 117 weave::Error::AddTo(&error, FROM_HERE, "invalid_parameter_value", 118 "Invalid parameters"); 119 cmd->Abort(error.get(), nullptr); 120 } 121 122 void UpdateLockState() { 123 std::string updated_state = weave::EnumToString(lock_state_); 124 device_->SetStateProperty(kComponent, "lock.lockedState", 125 base::StringValue{updated_state}, nullptr); 126 } 127 128 weave::Device* device_{nullptr}; 129 130 // Simulate the state of the light. 131 weave::lockstate::LockState lock_state_{weave::lockstate::LockState::kLocked}; 132 base::WeakPtrFactory<LockHandler> weak_ptr_factory_{this}; 133}; 134 135int main(int argc, char** argv) { 136 Daemon::Options opts; 137 opts.model_id_ = "AOAAA"; 138 if (!opts.Parse(argc, argv)) { 139 Daemon::Options::ShowUsage(argv[0]); 140 return 1; 141 } 142 Daemon daemon{opts}; 143 LockHandler handler; 144 handler.Register(daemon.GetDevice()); 145 daemon.Run(); 146 return 0; 147} 148