Home | History | Annotate | Download | only in speaker
      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 namespace {
     13 
     14 const char kTraits[] = R"({
     15   "onOff": {
     16     "commands": {
     17       "setConfig": {
     18         "minimalRole": "user",
     19         "parameters": {
     20           "state": {
     21             "type": "string",
     22             "enum": [ "on", "standby" ]
     23           }
     24         }
     25       }
     26     },
     27     "state": {
     28       "state": {
     29         "type": "string",
     30         "enum": [ "on", "standby" ],
     31         "isRequired": true
     32       }
     33     }
     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": {
     50       "isMuted": {
     51         "type": "boolean",
     52         "isRequired": true
     53       },
     54       "volume": {
     55         "type": "integer",
     56         "minimum": 0,
     57         "maximum": 100,
     58         "isRequired": true
     59       }
     60     }
     61   }
     62 })";
     63 
     64 const char kComponent[] = "speaker";
     65 
     66 }  // anonymous namespace
     67 
     68 // SpeakerHandler is a command handler example that shows
     69 // how to handle commands for a Weave speaker.
     70 class SpeakerHandler {
     71  public:
     72   SpeakerHandler() = default;
     73   void Register(weave::Device* device) {
     74     device_ = device;
     75 
     76     device->AddTraitDefinitionsFromJson(kTraits);
     77     CHECK(device->AddComponent(kComponent, {"onOff", "volume"}, nullptr));
     78     UpdateSpeakerState();
     79 
     80     device->AddCommandHandler(kComponent, "onOff.setConfig",
     81                               base::Bind(&SpeakerHandler::OnOnOffSetConfig,
     82                                          weak_ptr_factory_.GetWeakPtr()));
     83     device->AddCommandHandler(kComponent, "volume.setConfig",
     84                               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 
     95     const auto& params = cmd->GetParameters();
     96     // Handle volume parameter
     97     int32_t volume_value = 0;
     98     if (params.GetInteger("volume", &volume_value)) {
     99       // 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;
    112     if (params.GetBoolean("isMuted", &isMuted_status)) {
    113       // Display this command in terminal.
    114       LOG(INFO) << cmd->GetName() << " is "
    115                 << (isMuted_status ? "muted" : "not muted");
    116 
    117       if (isMuted_status_ != isMuted_status) {
    118         isMuted_status_ = isMuted_status;
    119 
    120         LOG(INFO) << "Speaker is now: "
    121                   << (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();
    134     const auto& params = cmd->GetParameters();
    135     std::string requested_state;
    136     if (params.GetString("state", &requested_state)) {
    137       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;
    152     state.SetString("onOff.state", speaker_status_ ? "on" : "standby");
    153     state.SetBoolean("volume.isMuted", isMuted_status_);
    154     state.SetInteger("volume.volume", volume_value_);
    155     device_->SetStateProperties(kComponent, state, nullptr);
    156   }
    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 
    167 int 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 }
    179