diff --git a/libreset/src/shelly_reset.cpp b/libreset/src/shelly_reset.cpp index e7649a5e..a3afc7ec 100644 --- a/libreset/src/shelly_reset.cpp +++ b/libreset/src/shelly_reset.cpp @@ -226,7 +226,7 @@ void CheckRebootCounter() { ResetDevice(-1); return; } - SetRebootCounter((void *) (intptr_t) (reboot_counter + 1)); + SetRebootCounter((void *) (intptr_t)(reboot_counter + 1)); mgos_set_timer(10000, 0, SetRebootCounter, (void *) 0); } diff --git a/src/ShellyVintage/shelly_init.cpp b/src/ShellyVintage/shelly_init.cpp index 41a4fbd2..229399c6 100644 --- a/src/ShellyVintage/shelly_init.cpp +++ b/src/ShellyVintage/shelly_init.cpp @@ -53,5 +53,13 @@ void CreateComponents(std::vector> *comps, pri_acc->AddService(hap_light.get()); comps->push_back(std::move(hap_light)); + + SetIdentifyCB([](const HAPAccessoryIdentifyRequest *request UNUSED_ARG) { + if (!g_comps.empty()) { + g_comps[0]->Identify(); + } + return kHAPError_None; + }); } -} // namespace shelly \ No newline at end of file + +} // namespace shelly diff --git a/src/shelly_component.cpp b/src/shelly_component.cpp index d8b04332..8eaff252 100644 --- a/src/shelly_component.cpp +++ b/src/shelly_component.cpp @@ -29,6 +29,10 @@ int Component::id() const { return id_; } +void Component::Identify() { + LOG(LL_INFO, ("== Identify %d %d %s", id(), (int) type(), name().c_str())); +} + bool Component::IsIdle() { return true; } diff --git a/src/shelly_component.hpp b/src/shelly_component.hpp index 4f86b705..f69df0aa 100644 --- a/src/shelly_component.hpp +++ b/src/shelly_component.hpp @@ -62,6 +62,9 @@ class Component { bool *restart_required) = 0; // Set state from UI. virtual Status SetState(const std::string &state_json) = 0; + // Do something to identify this component to the user. + // Default is to print a log message, which is to say - not much. + virtual void Identify(); // Is there any activity going on? // If true is returned, it means it's ok to destroy the component. diff --git a/src/shelly_hap_light_bulb.cpp b/src/shelly_hap_light_bulb.cpp index 0be74235..a1a61bd8 100644 --- a/src/shelly_hap_light_bulb.cpp +++ b/src/shelly_hap_light_bulb.cpp @@ -397,6 +397,11 @@ Status LightBulb::SetState(const std::string &state_json) { return Status::OK(); } +void LightBulb::Identify() { + LOG(LL_INFO, ("=== IDENTIFY ===")); + // TODO: Set brightness to max and blink 5 times at 100 ms. +} + void LightBulb::ResetAutoOff() { auto_off_timer_.Reset(cfg_->auto_off_delay * 1000, 0); } diff --git a/src/shelly_hap_light_bulb.hpp b/src/shelly_hap_light_bulb.hpp index 05928142..bfcdf9a8 100644 --- a/src/shelly_hap_light_bulb.hpp +++ b/src/shelly_hap_light_bulb.hpp @@ -41,15 +41,16 @@ class LightBulb : public Component, public mgos::hap::Service { virtual ~LightBulb(); // Component interface impl. - Type type() const override; - std::string name() const override; - Status Init() override; + Type type() const final; + std::string name() const final; + Status Init() final; - StatusOr GetInfo() const override; - StatusOr GetInfoJSON() const override; + StatusOr GetInfo() const final; + StatusOr GetInfoJSON() const final; Status SetConfig(const std::string &config_json, - bool *restart_required) override; - Status SetState(const std::string &state_json) override; + bool *restart_required) final; + Status SetState(const std::string &state_json) final; + void Identify() final; protected: void InputEventHandler(Input::Event ev, bool state); diff --git a/src/shelly_rpc_service.cpp b/src/shelly_rpc_service.cpp index 62b0a3e8..6b8897d0 100644 --- a/src/shelly_rpc_service.cpp +++ b/src/shelly_rpc_service.cpp @@ -332,6 +332,29 @@ static void SetStateHandler(struct mg_rpc_request_info *ri, void *cb_arg, (void) fi; } +static void IdentifyHandler(struct mg_rpc_request_info *ri, + void *cb_arg UNUSED_ARG, + struct mg_rpc_frame_info *fi UNUSED_ARG, + struct mg_str args) { + int id = -1; + int type = -1; + + json_scanf(args.p, args.len, ri->args_fmt, &id, &type); + + Status st = Status::OK(); + bool found = false; + for (auto &c : g_comps) { + if (c->id() != id || (int) c->type() != type) continue; + c->Identify(); + found = true; + break; + } + if (!found) { + st = mgos::Errorf(STATUS_INVALID_ARGUMENT, "component not found"); + } + SendStatusResp(ri, st); +} + static void InjectInputEventHandler(struct mg_rpc_request_info *ri, void *cb_arg, struct mg_rpc_frame_info *fi, struct mg_str args) { @@ -556,6 +579,8 @@ bool RPCServiceInit(HAPAccessoryServerRef *server, SetConfigHandler, nullptr); mg_rpc_add_handler(c, "Shelly.SetState", "{id: %d, type: %d, state: %T}", SetStateHandler, nullptr); + mg_rpc_add_handler(c, "Shelly.Identify", "{id: %d, type: %d}", + IdentifyHandler, nullptr); mg_rpc_add_handler(c, "Shelly.InjectInputEvent", "{id: %d, event: %d}", InjectInputEventHandler, nullptr); mg_rpc_add_handler(c, "Shelly.Abort", "", AbortHandler, nullptr);