examples/daemon: re-organize sample handler split commands to show one weave feature at a time: - hello: command handling with args and results - ping: device state - countdown: long running command w/ progress Bug: 24992153 Change-Id: Ib901239170287225c239c224c4fc9aa0b4112856 Reviewed-on: https://weave-review.googlesource.com/1347 Reviewed-by: Johan Euphrosine <proppy@google.com>
diff --git a/libweave/examples/daemon/greeter_handler.h b/libweave/examples/daemon/greeter_handler.h deleted file mode 100644 index 7f71a06..0000000 --- a/libweave/examples/daemon/greeter_handler.h +++ /dev/null
@@ -1,111 +0,0 @@ -// 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 <weave/device.h> -#include <weave/provider/task_runner.h> - -#include <base/bind.h> -#include <base/memory/weak_ptr.h> - -namespace weave { -namespace examples { -namespace daemon { - -class GreeterHandler { - public: - GreeterHandler(provider::TaskRunner* task_runner) - : task_runner_{task_runner} {} - void Register(Device* device) { - device_ = device; - - device->AddStateDefinitionsFromJson(R"({ - "_greeter": {"_greetings_counter":"integer"} - })"); - - device->SetStatePropertiesFromJson(R"({ - "_greeter": {"_greetings_counter": 0} - })", - nullptr); - - device->AddCommandDefinitionsFromJson(R"({ - "_greeter": { - "_greet": { - "minimalRole": "user", - "parameters": { - "_name": "string", - "_count": {"minimum": 1, "maximum": 100} - }, - "progress": { "_todo": "integer"}, - "results": { "_greeting": "string" } - } - } - })"); - device->AddCommandHandler("_greeter._greet", - base::Bind(&GreeterHandler::OnGreetCommand, - weak_ptr_factory_.GetWeakPtr())); - } - - private: - void DoGreet(const std::weak_ptr<Command>& command, int todo) { - auto cmd = command.lock(); - if (!cmd) - return; - - std::string name; - if (!cmd->GetParameters()->GetString("_name", &name)) { - ErrorPtr error; - Error::AddTo(&error, FROM_HERE, "example", - "invalid_parameter_value", "Name is missing"); - cmd->Abort(error.get(), nullptr); - return; - } - - if (todo-- > 0) { - LOG(INFO) << "Hello " << name; - - base::DictionaryValue progress; - progress.SetInteger("_todo", todo); - cmd->SetProgress(progress, nullptr); - - base::DictionaryValue state; - state.SetInteger("_greeter._greetings_counter", ++counter_); - device_->SetStateProperties(state, nullptr); - } - - if (todo > 0) { - task_runner_->PostDelayedTask( - FROM_HERE, base::Bind(&GreeterHandler::DoGreet, - weak_ptr_factory_.GetWeakPtr(), command, todo), - base::TimeDelta::FromSeconds(1)); - return; - } - - base::DictionaryValue result; - result.SetString("_greeting", "Hello " + name); - cmd->Complete(result, nullptr); - LOG(INFO) << cmd->GetName() << " command finished: " << result; - LOG(INFO) << "New state: " << *device_->GetState(); - } - - void OnGreetCommand(const std::weak_ptr<Command>& command) { - auto cmd = command.lock(); - if (!cmd) - return; - LOG(INFO) << "received command: " << cmd->GetName(); - - int todo = 1; - cmd->GetParameters()->GetInteger("_count", &todo); - DoGreet(command, todo); - } - - Device* device_{nullptr}; - provider::TaskRunner* task_runner_{nullptr}; - - int counter_{0}; - base::WeakPtrFactory<GreeterHandler> weak_ptr_factory_{this}; -}; - -} // namespace daemon -} // namespace examples -} // namespace weave
diff --git a/libweave/examples/daemon/ledflasher_handler.h b/libweave/examples/daemon/ledflasher_handler.h index fba5197..812a3d4 100644 --- a/libweave/examples/daemon/ledflasher_handler.h +++ b/libweave/examples/daemon/ledflasher_handler.h
@@ -18,6 +18,8 @@ const size_t kLedCount = 3; } // namespace +// LedFlasherHandler is a complete command handler example that shows +// how to handle commands that modify device state. class LedFlasherHandler { public: LedFlasherHandler() {} @@ -84,7 +86,7 @@ } ErrorPtr error; Error::AddTo(&error, FROM_HERE, "example", "invalid_parameter_value", - "Invalid parameters"); + "Invalid parameters"); cmd->Abort(error.get(), nullptr); } @@ -105,7 +107,7 @@ } ErrorPtr error; Error::AddTo(&error, FROM_HERE, "example", "invalid_parameter_value", - "Invalid parameters"); + "Invalid parameters"); cmd->Abort(error.get(), nullptr); }
diff --git a/libweave/examples/daemon/main.cc b/libweave/examples/daemon/main.cc index 2c3841a..d49576a 100644 --- a/libweave/examples/daemon/main.cc +++ b/libweave/examples/daemon/main.cc
@@ -7,6 +7,9 @@ #include <base/bind.h> +#include "examples/daemon/ledflasher_handler.h" +#include "examples/daemon/sample_handler.h" + #include "examples/provider/avahi_client.h" #include "examples/provider/bluez_client.h" #include "examples/provider/curl_http_client.h" @@ -16,9 +19,6 @@ #include "examples/provider/file_config_store.h" #include "examples/provider/wifi_manager.h" -#include "examples/daemon/greeter_handler.h" -#include "examples/daemon/ledflasher_handler.h" - namespace { // Supported LED count on this device @@ -108,9 +108,9 @@ base::Bind(&OnRegisterDeviceDone, device.get())); } - weave::examples::daemon::GreeterHandler greeter{&task_runner}; + weave::examples::daemon::SampleHandler sample{&task_runner}; weave::examples::daemon::LedFlasherHandler ledFlasher; - greeter.Register(device.get()); + sample.Register(device.get()); ledFlasher.Register(device.get()); task_runner.Run();
diff --git a/libweave/examples/daemon/sample_handler.h b/libweave/examples/daemon/sample_handler.h new file mode 100644 index 0000000..eca3452 --- /dev/null +++ b/libweave/examples/daemon/sample_handler.h
@@ -0,0 +1,160 @@ +// 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 <weave/device.h> +#include <weave/provider/task_runner.h> + +#include <base/bind.h> +#include <base/memory/weak_ptr.h> + +namespace weave { +namespace examples { +namespace daemon { + +// 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(provider::TaskRunner* task_runner) + : task_runner_{task_runner} {} + void Register(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<Command>& command) { + auto cmd = command.lock(); + if (!cmd) + return; + LOG(INFO) << "received command: " << cmd->GetName(); + + std::string name; + if (!cmd->GetParameters()->GetString("_name", &name)) { + ErrorPtr error; + 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<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<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<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; + } + + Device* device_{nullptr}; + provider::TaskRunner* task_runner_{nullptr}; + + int ping_count_{0}; + base::WeakPtrFactory<SampleHandler> weak_ptr_factory_{this}; +}; + +} // namespace daemon +} // namespace examples +} // namespace weave