diff --git a/fs_src/index.html b/fs_src/index.html
index 92b33c81..f3992f6f 100644
--- a/fs_src/index.html
+++ b/fs_src/index.html
@@ -354,6 +354,7 @@
Input
+
@@ -403,6 +404,7 @@
Disabled Input
+
@@ -430,6 +432,7 @@
Sensor
+
diff --git a/fs_src/script.js b/fs_src/script.js
index 4bea6662..42e181f7 100644
--- a/fs_src/script.js
+++ b/fs_src/script.js
@@ -421,12 +421,15 @@ function findOrAddContainer(cd) {
case 7: // Motion Sensor.
case 8: // Occupancy Sensor.
case 9: // Contact Sensor.
+ case 10: // Doorbell
c = el("sensor_template").cloneNode(true);
c.id = elId;
el(c, "save_btn").onclick = function () {
mosSetConfig(c);
};
break;
+ default:
+ console.log(`Unhandled component type: ${cd.type}`);
}
if (c) {
c.style.display = "block";
@@ -566,6 +569,7 @@ function updateComponent(cd) {
case 7: // Motion Sensor
case 8: // Occupancy Sensor
case 9: // Contact Sensor
+ case 10: // Doorbell
var headText = `Input ${cd.id}`;
if (cd.name) headText += ` (${cd.name})`;
el(c, "head").innerText = headText;
@@ -582,6 +586,8 @@ function updateComponent(cd) {
}
el(c, "status").innerText = statusText;
break;
+ default:
+ console.log(`Unhandled component type: ${cd.type}`);
}
c.data = cd;
}
diff --git a/src/shelly_common.hpp b/src/shelly_common.hpp
index 7688e247..d38a7177 100644
--- a/src/shelly_common.hpp
+++ b/src/shelly_common.hpp
@@ -35,6 +35,7 @@
#define SHELLY_HAP_AID_BASE_OCCUPANCY_SENSOR 0x700
#define SHELLY_HAP_AID_BASE_CONTACT_SENSOR 0x800
#define SHELLY_HAP_AID_BASE_VALVE 0x900
+#define SHELLY_HAP_AID_BASE_DOORBELL 0xa00
#define SHELLY_HAP_IID_BASE_SWITCH 0x100
#define SHELLY_HAP_IID_STEP_SWITCH 4
@@ -54,6 +55,7 @@
#define SHELLY_HAP_IID_STEP_SENSOR 0x10
#define SHELLY_HAP_IID_BASE_VALVE 0xa00
#define SHELLY_HAP_IID_STEP_VALVE 0x10
+#define SHELLY_HAP_IID_BASE_DOORBELL 0xb00
namespace shelly {
diff --git a/src/shelly_component.hpp b/src/shelly_component.hpp
index f38c947e..4e7a97a8 100644
--- a/src/shelly_component.hpp
+++ b/src/shelly_component.hpp
@@ -34,6 +34,7 @@ class Component {
kMotionSensor = 7,
kOccupancySensor = 8,
kContactSensor = 9,
+ kDoorbell = 10,
kMax,
};
diff --git a/src/shelly_hap_doorbell.cpp b/src/shelly_hap_doorbell.cpp
new file mode 100644
index 00000000..c8b33860
--- /dev/null
+++ b/src/shelly_hap_doorbell.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) Shelly-HomeKit Contributors
+ * All rights reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "shelly_hap_doorbell.hpp"
+
+#include "HAPUUID.h"
+
+namespace shelly {
+namespace hap {
+
+const HAPUUID kHAPServiceType_Doorbell = HAPUUIDCreateAppleDefined(0x121);
+
+Doorbell::Doorbell(int id, Input *in, struct mgos_config_in_ssw *cfg)
+ : StatelessSwitchBase(id, in, cfg, SHELLY_HAP_IID_BASE_DOORBELL,
+ &kHAPServiceType_Doorbell, "service.doorbell") {
+}
+
+Doorbell::~Doorbell() {
+}
+
+Component::Type Doorbell::type() const {
+ return Type::kDoorbell;
+}
+
+} // namespace hap
+} // namespace shelly
\ No newline at end of file
diff --git a/src/shelly_hap_doorbell.hpp b/src/shelly_hap_doorbell.hpp
new file mode 100644
index 00000000..9b35a841
--- /dev/null
+++ b/src/shelly_hap_doorbell.hpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) Shelly-HomeKit Contributors
+ * All rights reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+#include "shelly_hap_stateless_switch_base.hpp"
+
+namespace shelly {
+namespace hap {
+
+class Doorbell : public StatelessSwitchBase {
+ public:
+ Doorbell(int id, Input *in, struct mgos_config_in_ssw *cfg);
+ virtual ~Doorbell();
+
+ // Component interface impl.
+ Type type() const override;
+};
+
+} // namespace hap
+} // namespace shelly
\ No newline at end of file
diff --git a/src/shelly_hap_input.cpp b/src/shelly_hap_input.cpp
index 24d41cbb..d59bb3cb 100644
--- a/src/shelly_hap_input.cpp
+++ b/src/shelly_hap_input.cpp
@@ -21,6 +21,7 @@
#include "mgos_hap.h"
#include "shelly_hap_contact_sensor.hpp"
+#include "shelly_hap_doorbell.hpp"
#include "shelly_hap_motion_sensor.hpp"
#include "shelly_hap_occupancy_sensor.hpp"
#include "shelly_hap_stateless_switch.hpp"
@@ -132,6 +133,13 @@ Status ShellyInput::Init() {
s_ = cs;
break;
}
+ case Type::kDoorbell: {
+ auto *db = new hap::Doorbell(id(), in_,
+ (struct mgos_config_in_ssw *) &cfg_->ssw);
+ c_.reset(db);
+ s_ = db;
+ break;
+ }
default: {
return mgos::Errorf(STATUS_INVALID_ARGUMENT, "Invalid type %d",
(int) initial_type_);
@@ -195,6 +203,8 @@ uint16_t ShellyInput::GetAIDBase() const {
return SHELLY_HAP_AID_BASE_OCCUPANCY_SENSOR;
case Type::kContactSensor:
return SHELLY_HAP_AID_BASE_CONTACT_SENSOR;
+ case Type::kDoorbell:
+ return SHELLY_HAP_AID_BASE_DOORBELL;
default:
return 0;
}
@@ -212,6 +222,7 @@ bool ShellyInput::IsValidType(int type) {
case (int) Type::kMotionSensor:
case (int) Type::kOccupancySensor:
case (int) Type::kContactSensor:
+ case (int) Type::kDoorbell:
return true;
}
return false;
diff --git a/src/shelly_hap_stateless_switch.cpp b/src/shelly_hap_stateless_switch.cpp
index 89e3f35f..7fc4debb 100644
--- a/src/shelly_hap_stateless_switch.cpp
+++ b/src/shelly_hap_stateless_switch.cpp
@@ -17,158 +17,23 @@
#include "shelly_hap_stateless_switch.hpp"
-#include "mgos.hpp"
-#include "mgos_hap.hpp"
-
namespace shelly {
namespace hap {
StatelessSwitch::StatelessSwitch(int id, Input *in,
struct mgos_config_in_ssw *cfg)
- : Component(id),
- Service(
- // IDs used to start at 0, preserve compat.
- (SHELLY_HAP_IID_BASE_STATELESS_SWITCH +
- (SHELLY_HAP_IID_STEP_STATELESS_SWITCH * (id - 1))),
+ : StatelessSwitchBase(
+ id, in, cfg, SHELLY_HAP_IID_BASE_STATELESS_SWITCH,
&kHAPServiceType_StatelessProgrammableSwitch,
- kHAPServiceDebugDescription_StatelessProgrammableSwitch),
- in_(in),
- cfg_(cfg) {
+ kHAPServiceDebugDescription_StatelessProgrammableSwitch) {
}
StatelessSwitch::~StatelessSwitch() {
- in_->RemoveHandler(handler_id_);
}
Component::Type StatelessSwitch::type() const {
return Type::kStatelessSwitch;
}
-std::string StatelessSwitch::name() const {
- return cfg_->name;
-}
-
-Status StatelessSwitch::Init() {
- if (in_ == nullptr) {
- return mgos::Errorf(STATUS_INVALID_ARGUMENT, "input is required");
- }
- uint16_t iid = svc_.iid + 1;
- // Name
- AddNameChar(iid++, cfg_->name);
- // Programmable Switch Event
- AddChar(new mgos::hap::UInt8Characteristic(
- iid++, &kHAPCharacteristicType_ProgrammableSwitchEvent, 0, 2, 1,
- [this](HAPAccessoryServerRef *, const HAPUInt8CharacteristicReadRequest *,
- uint8_t *value) {
- if (last_ev_ts_ == 0) return kHAPError_InvalidState;
- *value = last_ev_;
- return kHAPError_None;
- },
- true /* supports_notification */, nullptr /* write_handler */,
- kHAPCharacteristicDebugDescription_ProgrammableSwitchEvent));
-
- handler_id_ = in_->AddHandler(
- std::bind(&StatelessSwitch::InputEventHandler, this, _1, _2));
-
- return Status::OK();
-}
-
-StatusOr StatelessSwitch::GetInfo() const {
- double last_ev_age = -1;
- if (last_ev_ts_ > 0) {
- last_ev_age = mgos_uptime() - last_ev_ts_;
- }
- return mgos::SPrintf("st:%d m:%d lea: %.3f", in_->GetState(), cfg_->in_mode,
- last_ev_age);
-}
-
-StatusOr StatelessSwitch::GetInfoJSON() const {
- double last_ev_age = -1;
- if (last_ev_ts_ > 0) {
- last_ev_age = mgos_uptime() - last_ev_ts_;
- }
- return mgos::JSONPrintStringf(
- "{id: %d, type: %d, name: %Q, in_mode: %d, "
- "last_ev: %d, last_ev_age: %.3f}",
- id(), type(), (cfg_->name ? cfg_->name : ""), cfg_->in_mode, last_ev_,
- last_ev_age);
-}
-
-Status StatelessSwitch::SetConfig(const std::string &config_json,
- bool *restart_required) {
- char *name = nullptr;
- int in_mode = -1;
- json_scanf(config_json.c_str(), config_json.size(), "{name: %Q, in_mode: %d}",
- &name, &in_mode);
- mgos::ScopedCPtr name_owner(name);
- // Validation.
- if (name != nullptr && strlen(name) > 64) {
- return mgos::Errorf(STATUS_INVALID_ARGUMENT, "invalid %s",
- "name (too long, max 64)");
- }
- if (in_mode < 0 || in_mode > 2) {
- return mgos::Errorf(STATUS_INVALID_ARGUMENT, "invalid %s", "in_mode");
- }
- // Now copy over.
- if (name != nullptr && strcmp(name, cfg_->name) != 0) {
- mgos_conf_set_str(&cfg_->name, name);
- *restart_required = true;
- }
- cfg_->in_mode = in_mode;
- return Status::OK();
-}
-
-Status StatelessSwitch::SetState(const std::string &state_json) {
- (void) state_json;
- return Status::UNIMPLEMENTED();
-}
-
-void StatelessSwitch::InputEventHandler(Input::Event ev, bool state) {
- const auto in_mode = static_cast(cfg_->in_mode);
- switch (in_mode) {
- // In momentary input mode we translate input events to HAP events directly.
- case InMode::kMomentary:
- switch (ev) {
- case Input::Event::kSingle:
- RaiseEvent(
- kHAPCharacteristicValue_ProgrammableSwitchEvent_SinglePress);
- break;
- case Input::Event::kDouble:
- RaiseEvent(
- kHAPCharacteristicValue_ProgrammableSwitchEvent_DoublePress);
- break;
- case Input::Event::kLong:
- RaiseEvent(kHAPCharacteristicValue_ProgrammableSwitchEvent_LongPress);
- break;
- case Input::Event::kChange:
- case Input::Event::kReset:
- case Input::Event::kMax:
- // Ignore.
- break;
- }
- break;
- // In toggle switch input mode we translate changes to HAP events.
- case InMode::kToggleShort:
- case InMode::kToggleShortLong:
- if (ev != Input::Event::kChange) break;
- if (in_mode == InMode::kToggleShortLong && !state) {
- RaiseEvent(kHAPCharacteristicValue_ProgrammableSwitchEvent_DoublePress);
- } else {
- RaiseEvent(kHAPCharacteristicValue_ProgrammableSwitchEvent_SinglePress);
- }
- break;
- }
-}
-
-void StatelessSwitch::RaiseEvent(uint8_t ev) {
- last_ev_ = ev;
- last_ev_ts_ = mgos_uptime();
- LOG(LL_INFO, ("Input %d: HAP event (mode %d): %d", id(), cfg_->in_mode, ev));
- // May happen during init, we don't want to raise events until initialized.
- if (handler_id_ != Input::kInvalidHandlerID) {
- chars_[1]->RaiseEvent();
- }
-}
-
} // namespace hap
-} // namespace shelly
+} // namespace shelly
\ No newline at end of file
diff --git a/src/shelly_hap_stateless_switch.hpp b/src/shelly_hap_stateless_switch.hpp
index 657bc6e1..8d33f095 100644
--- a/src/shelly_hap_stateless_switch.hpp
+++ b/src/shelly_hap_stateless_switch.hpp
@@ -16,60 +16,19 @@
*/
#pragma once
-
-#include
-#include
-
-#include "mgos_hap.hpp"
-#include "mgos_sys_config.h"
-#include "mgos_timers.h"
-
-#include "shelly_common.hpp"
-#include "shelly_component.hpp"
-#include "shelly_input.hpp"
-#include "shelly_output.hpp"
-#include "shelly_pm.hpp"
+#include "shelly_hap_stateless_switch_base.hpp"
namespace shelly {
namespace hap {
-// Common base for Switch, Outlet and Lock services.
-class StatelessSwitch : public Component, public mgos::hap::Service {
+class StatelessSwitch : public StatelessSwitchBase {
public:
- enum class InMode {
- kMomentary = 0,
- kToggleShort = 1,
- kToggleShortLong = 2,
- };
-
StatelessSwitch(int id, Input *in, struct mgos_config_in_ssw *cfg);
virtual ~StatelessSwitch();
// Component interface impl.
- Status Init() override;
Type type() const override;
- std::string name() const override;
- StatusOr GetInfo() const override;
- StatusOr GetInfoJSON() const override;
- Status SetConfig(const std::string &config_json,
- bool *restart_required) override;
- Status SetState(const std::string &state_json) override;
-
- private:
- void InputEventHandler(Input::Event ev, bool state);
-
- void RaiseEvent(uint8_t ev);
-
- Input *const in_;
- struct mgos_config_in_ssw *cfg_;
-
- Input::HandlerID handler_id_ = Input::kInvalidHandlerID;
-
- uint8_t last_ev_ = 0;
- double last_ev_ts_ = 0;
-
- StatelessSwitch(const StatelessSwitch &other) = delete;
};
} // namespace hap
-} // namespace shelly
+} // namespace shelly
\ No newline at end of file
diff --git a/src/shelly_hap_stateless_switch_base.cpp b/src/shelly_hap_stateless_switch_base.cpp
new file mode 100644
index 00000000..12c44c9e
--- /dev/null
+++ b/src/shelly_hap_stateless_switch_base.cpp
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) Shelly-HomeKit Contributors
+ * All rights reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "shelly_hap_stateless_switch_base.hpp"
+
+#include "mgos.hpp"
+#include "mgos_hap.hpp"
+
+namespace shelly {
+namespace hap {
+
+StatelessSwitchBase::StatelessSwitchBase(int id, Input *in,
+ struct mgos_config_in_ssw *cfg,
+ uint16_t iid_base, const HAPUUID *type,
+ const char *debug_description)
+ : Component(id),
+ Service(
+ // IDs used to start at 0, preserve compat.
+ (iid_base + (SHELLY_HAP_IID_STEP_STATELESS_SWITCH * (id - 1))), type,
+ debug_description),
+ in_(in),
+ cfg_(cfg) {
+}
+
+StatelessSwitchBase::~StatelessSwitchBase() {
+ in_->RemoveHandler(handler_id_);
+}
+
+Component::Type StatelessSwitchBase::type() const {
+ return Type::kStatelessSwitch;
+}
+
+std::string StatelessSwitchBase::name() const {
+ return cfg_->name;
+}
+
+Status StatelessSwitchBase::Init() {
+ if (in_ == nullptr) {
+ return mgos::Errorf(STATUS_INVALID_ARGUMENT, "input is required");
+ }
+ uint16_t iid = svc_.iid + 1;
+ // Name
+ AddNameChar(iid++, cfg_->name);
+ // Programmable Switch Event
+ AddChar(new mgos::hap::UInt8Characteristic(
+ iid++, &kHAPCharacteristicType_ProgrammableSwitchEvent, 0, 2, 1,
+ [this](HAPAccessoryServerRef *, const HAPUInt8CharacteristicReadRequest *,
+ uint8_t *value) {
+ if (last_ev_ts_ == 0) return kHAPError_InvalidState;
+ *value = last_ev_;
+ return kHAPError_None;
+ },
+ true /* supports_notification */, nullptr /* write_handler */,
+ kHAPCharacteristicDebugDescription_ProgrammableSwitchEvent));
+
+ handler_id_ = in_->AddHandler(
+ std::bind(&StatelessSwitchBase::InputEventHandler, this, _1, _2));
+
+ return Status::OK();
+}
+
+StatusOr StatelessSwitchBase::GetInfo() const {
+ double last_ev_age = -1;
+ if (last_ev_ts_ > 0) {
+ last_ev_age = mgos_uptime() - last_ev_ts_;
+ }
+ return mgos::SPrintf("st:%d m:%d lea: %.3f", in_->GetState(), cfg_->in_mode,
+ last_ev_age);
+}
+
+StatusOr StatelessSwitchBase::GetInfoJSON() const {
+ double last_ev_age = -1;
+ if (last_ev_ts_ > 0) {
+ last_ev_age = mgos_uptime() - last_ev_ts_;
+ }
+ return mgos::JSONPrintStringf(
+ "{id: %d, type: %d, name: %Q, in_mode: %d, "
+ "last_ev: %d, last_ev_age: %.3f}",
+ id(), type(), (cfg_->name ? cfg_->name : ""), cfg_->in_mode, last_ev_,
+ last_ev_age);
+}
+
+Status StatelessSwitchBase::SetConfig(const std::string &config_json,
+ bool *restart_required) {
+ char *name = nullptr;
+ int in_mode = -1;
+ json_scanf(config_json.c_str(), config_json.size(), "{name: %Q, in_mode: %d}",
+ &name, &in_mode);
+ mgos::ScopedCPtr name_owner(name);
+ // Validation.
+ if (name != nullptr && strlen(name) > 64) {
+ return mgos::Errorf(STATUS_INVALID_ARGUMENT, "invalid %s",
+ "name (too long, max 64)");
+ }
+ if (in_mode < 0 || in_mode > 2) {
+ return mgos::Errorf(STATUS_INVALID_ARGUMENT, "invalid %s", "in_mode");
+ }
+ // Now copy over.
+ if (name != nullptr && strcmp(name, cfg_->name) != 0) {
+ mgos_conf_set_str(&cfg_->name, name);
+ *restart_required = true;
+ }
+ cfg_->in_mode = in_mode;
+ return Status::OK();
+}
+
+Status StatelessSwitchBase::SetState(const std::string &state_json) {
+ (void) state_json;
+ return Status::UNIMPLEMENTED();
+}
+
+void StatelessSwitchBase::InputEventHandler(Input::Event ev, bool state) {
+ const auto in_mode = static_cast(cfg_->in_mode);
+ switch (in_mode) {
+ // In momentary input mode we translate input events to HAP events directly.
+ case InMode::kMomentary:
+ switch (ev) {
+ case Input::Event::kSingle:
+ RaiseEvent(
+ kHAPCharacteristicValue_ProgrammableSwitchEvent_SinglePress);
+ break;
+ case Input::Event::kDouble:
+ RaiseEvent(
+ kHAPCharacteristicValue_ProgrammableSwitchEvent_DoublePress);
+ break;
+ case Input::Event::kLong:
+ RaiseEvent(kHAPCharacteristicValue_ProgrammableSwitchEvent_LongPress);
+ break;
+ case Input::Event::kChange:
+ case Input::Event::kReset:
+ case Input::Event::kMax:
+ // Ignore.
+ break;
+ }
+ break;
+ // In toggle switch input mode we translate changes to HAP events.
+ case InMode::kToggleShort:
+ case InMode::kToggleShortLong:
+ if (ev != Input::Event::kChange) break;
+ if (in_mode == InMode::kToggleShortLong && !state) {
+ RaiseEvent(kHAPCharacteristicValue_ProgrammableSwitchEvent_DoublePress);
+ } else {
+ RaiseEvent(kHAPCharacteristicValue_ProgrammableSwitchEvent_SinglePress);
+ }
+ break;
+ }
+}
+
+void StatelessSwitchBase::RaiseEvent(uint8_t ev) {
+ last_ev_ = ev;
+ last_ev_ts_ = mgos_uptime();
+ LOG(LL_INFO, ("Input %d: HAP event (mode %d): %d", id(), cfg_->in_mode, ev));
+ // May happen during init, we don't want to raise events until initialized.
+ if (handler_id_ != Input::kInvalidHandlerID) {
+ chars_[1]->RaiseEvent();
+ }
+}
+
+} // namespace hap
+} // namespace shelly
diff --git a/src/shelly_hap_stateless_switch_base.hpp b/src/shelly_hap_stateless_switch_base.hpp
new file mode 100644
index 00000000..1845233f
--- /dev/null
+++ b/src/shelly_hap_stateless_switch_base.hpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) Shelly-HomeKit Contributors
+ * All rights reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include
+#include
+
+#include "mgos_hap.hpp"
+#include "mgos_sys_config.h"
+#include "mgos_timers.h"
+
+#include "shelly_common.hpp"
+#include "shelly_component.hpp"
+#include "shelly_input.hpp"
+#include "shelly_output.hpp"
+#include "shelly_pm.hpp"
+
+namespace shelly {
+namespace hap {
+
+// Common base for Switch, Outlet and Lock services.
+class StatelessSwitchBase : public Component, public mgos::hap::Service {
+ public:
+ enum class InMode {
+ kMomentary = 0,
+ kToggleShort = 1,
+ kToggleShortLong = 2,
+ };
+
+ StatelessSwitchBase(int id, Input *in, struct mgos_config_in_ssw *cfg,
+ uint16_t iid_base, const HAPUUID *type,
+ const char *debug_description);
+ virtual ~StatelessSwitchBase();
+
+ // Component interface impl.
+ Status Init() override;
+ Type type() const override;
+ std::string name() const override;
+ StatusOr GetInfo() const override;
+ StatusOr GetInfoJSON() const override;
+ Status SetConfig(const std::string &config_json,
+ bool *restart_required) override;
+ Status SetState(const std::string &state_json) override;
+
+ private:
+ void InputEventHandler(Input::Event ev, bool state);
+
+ void RaiseEvent(uint8_t ev);
+
+ Input *const in_;
+ struct mgos_config_in_ssw *cfg_;
+
+ Input::HandlerID handler_id_ = Input::kInvalidHandlerID;
+
+ uint8_t last_ev_ = 0;
+ double last_ev_ts_ = 0;
+
+ StatelessSwitchBase(const StatelessSwitchBase &other) = delete;
+};
+
+} // namespace hap
+} // namespace shelly