aboutsummaryrefslogtreecommitdiff
path: root/examples/daemon/sample/sample.cc
diff options
context:
space:
mode:
Diffstat (limited to 'examples/daemon/sample/sample.cc')
-rw-r--r--examples/daemon/sample/sample.cc167
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;
+}