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
13 namespace weave {
14 namespace lockstate {
15 enum class LockState { kUnlocked, kLocked, kPartiallyLocked };
16
17 const weave::EnumToStringMap<LockState>::Map kLockMapMethod[] = {
18 {LockState::kLocked, "locked"},
19 {LockState::kUnlocked, "unlocked"},
20 {LockState::kPartiallyLocked, "partiallyLocked"}};
21 } // namespace lockstate
22
23 template <>
EnumToStringMap()24 EnumToStringMap<lockstate::LockState>::EnumToStringMap()
25 : EnumToStringMap(lockstate::kLockMapMethod) {}
26 } // namespace weave
27
28 namespace {
29
30 const 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
58 const char kDefaultState[] = R"({
59 "lock":{"isLockingSupported": true}
60 })";
61
62 const 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.
68 class LockHandler {
69 public:
70 LockHandler() = default;
Register(weave::Device * device)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:
OnLockSetConfig(const std::weak_ptr<weave::Command> & command)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
UpdateLockState()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
main(int argc,char ** argv)135 int 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