Home | History | Annotate | Download | only in lock
      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 <>
     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;
     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 
    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