diff options
Diffstat (limited to 'examples/daemon/sample/sample.cc')
-rw-r--r-- | examples/daemon/sample/sample.cc | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/examples/daemon/sample/sample.cc b/examples/daemon/sample/sample.cc new file mode 100644 index 0000000..905a977 --- /dev/null +++ b/examples/daemon/sample/sample.cc @@ -0,0 +1,167 @@ +// Copyright 2015 The Weave Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "examples/daemon/common/daemon.h" + +#include <weave/device.h> +#include <weave/provider/task_runner.h> + +#include <base/bind.h> +#include <base/memory/weak_ptr.h> + +// SampleHandler is a command handler example. +// It implements the following commands: +// - _hello: handle a command with an argument and set its results. +// - _ping: update device state. +// - _countdown: handle long running command and report progress. +class SampleHandler { + public: + SampleHandler(weave::provider::TaskRunner* task_runner) + : task_runner_{task_runner} {} + void Register(weave::Device* device) { + device_ = device; + + device->AddCommandDefinitionsFromJson(R"({ + "_sample": { + "_hello": { + "minimalRole": "user", + "parameters": { + "_name": "string" + }, + "results": { "_reply": "string" } + }, + "_ping": { + "minimalRole": "user", + "results": {} + }, + "_countdown": { + "minimalRole": "user", + "parameters": { + "_seconds": {"minimum": 1, "maximum": 25} + }, + "progress": { "_seconds_left": "integer"}, + "results": {} + } + } + })"); + + device->AddStateDefinitionsFromJson(R"({ + "_sample": {"_ping_count":"integer"} + })"); + + device->SetStatePropertiesFromJson(R"({ + "_sample": {"_ping_count": 0} + })", + nullptr); + + device->AddCommandHandler("_sample._hello", + base::Bind(&SampleHandler::OnHelloCommand, + weak_ptr_factory_.GetWeakPtr())); + device->AddCommandHandler("_sample._ping", + base::Bind(&SampleHandler::OnPingCommand, + weak_ptr_factory_.GetWeakPtr())); + device->AddCommandHandler("_sample._countdown", + base::Bind(&SampleHandler::OnCountdownCommand, + weak_ptr_factory_.GetWeakPtr())); + } + + private: + void OnHelloCommand(const std::weak_ptr<weave::Command>& command) { + auto cmd = command.lock(); + if (!cmd) + return; + LOG(INFO) << "received command: " << cmd->GetName(); + + std::string name; + if (!cmd->GetParameters()->GetString("_name", &name)) { + weave::ErrorPtr error; + weave::Error::AddTo(&error, FROM_HERE, "example", + "invalid_parameter_value", "Name is missing"); + cmd->Abort(error.get(), nullptr); + return; + } + + base::DictionaryValue result; + result.SetString("_reply", "Hello " + name); + cmd->Complete(result, nullptr); + LOG(INFO) << cmd->GetName() << " command finished: " << result; + } + + void OnPingCommand(const std::weak_ptr<weave::Command>& command) { + auto cmd = command.lock(); + if (!cmd) + return; + LOG(INFO) << "received command: " << cmd->GetName(); + + base::DictionaryValue state; + state.SetInteger("_sample._ping_count", ++ping_count_); + device_->SetStateProperties(state, nullptr); + LOG(INFO) << "New state: " << *device_->GetState(); + + base::DictionaryValue result; + cmd->Complete(result, nullptr); + + LOG(INFO) << cmd->GetName() << " command finished: " << result; + } + + void OnCountdownCommand(const std::weak_ptr<weave::Command>& command) { + auto cmd = command.lock(); + if (!cmd) + return; + LOG(INFO) << "received command: " << cmd->GetName(); + + int seconds; + if (!cmd->GetParameters()->GetInteger("_seconds", &seconds)) + seconds = 10; + + LOG(INFO) << "starting countdown"; + DoTick(cmd, seconds); + } + + void DoTick(const std::weak_ptr<weave::Command>& command, int seconds) { + auto cmd = command.lock(); + if (!cmd) + return; + + if (seconds > 0) { + std::string todo; + cmd->GetParameters()->GetString("_todo", &todo); + LOG(INFO) << "countdown tick: " << seconds << " seconds left"; + + base::DictionaryValue progress; + progress.SetInteger("_seconds_left", seconds); + cmd->SetProgress(progress, nullptr); + task_runner_->PostDelayedTask( + FROM_HERE, + base::Bind(&SampleHandler::DoTick, weak_ptr_factory_.GetWeakPtr(), + command, --seconds), + base::TimeDelta::FromSeconds(1)); + return; + } + + base::DictionaryValue result; + cmd->Complete(result, nullptr); + LOG(INFO) << "countdown finished"; + LOG(INFO) << cmd->GetName() << " command finished: " << result; + } + + weave::Device* device_{nullptr}; + weave::provider::TaskRunner* task_runner_{nullptr}; + + int ping_count_{0}; + base::WeakPtrFactory<SampleHandler> weak_ptr_factory_{this}; +}; + +int main(int argc, char** argv) { + Daemon::Options opts; + if (!opts.Parse(argc, argv)) { + Daemon::Options::ShowUsage(argv[0]); + return 1; + } + Daemon daemon{opts}; + SampleHandler handler{daemon.GetTaskRunner()}; + handler.Register(daemon.GetDevice()); + daemon.Run(); + return 0; +} |