Home IO Control
ESPHome add-on for IO-Homecontrol devices
Loading...
Searching...
No Matches
oneway_key_adoption.h
Go to the documentation of this file.
1#pragma once
2
3/// @file oneway_key_adoption.h
4/// @brief Opt-in, receive-only adoption of a 1W installation's controller key.
5/// @ingroup hioc_hub
6///
7/// See oneway_key_adoption.cpp for the security framing. This header carries only the collaborator
8/// class; IOHomeControlComponent owns one instance (hub_core.h) and forwards the three public
9/// entry points to it.
10
11#include "hub_hooks.h"
12#include "proto_codecs.h"
13#include "proto_device_model.h"
14#include "proto_frame.h"
15
16#include <cstdint>
17
18namespace esphome {
19namespace home_io_control {
20
21/// @brief Opt-in, receive-only listener that adopts an overheard 1W controller key.
22///
23/// Receive-only: nothing here transmits. While armed, an overheard CMD_ONEWAY_ADD_CONTROLLER
24/// broadcast is decrypted and reported once, after which the listener disarms itself — one
25/// adoption per arm. Constructed once by IOHomeControlComponent; non-copyable because it is wired
26/// with an injected scheduling callback.
27/// @ingroup hioc_hub
29 public:
30 /// @param schedule_auto_off Named-timeout scheduler for the 10-minute arm window (see NamedTimeoutFn).
31 explicit OnewayKeyAdoption(NamedTimeoutFn schedule_auto_off) : schedule_auto_off_(std::move(schedule_auto_off)) {}
32
33 /// Non-copyable — holds an injected callback and is owned by the hub.
36
37 /// @brief Arm or disarm the 1W controller-key adoption listener.
38 ///
39 /// Arming resets any class observed in an earlier window and schedules a 10-minute auto-off.
40 /// Disarming — manual, on successful adoption, or on auto-off — is immediate. See the class doc
41 /// comment; this is the body that was IOHomeControlComponent::set_oneway_key_adoption_armed().
42 /// @param armed Desired state.
43 void set_armed(bool armed);
44
45 /// @brief Whether the listener is currently armed.
46 [[nodiscard]] bool armed() const { return this->armed_; }
47
48 /// Register a callback invoked whenever the armed state changes (manual toggle, successful
49 /// adoption, or auto-off), so the switch entity stays in sync when the listener disarms itself.
50 /// @param cb Callable receiving the new armed state.
51 void set_armed_callback(std::function<void(bool)> cb) { this->armed_callback_ = std::move(cb); }
52
53 /// Remember the most recent 1W target device class observed from `info.src`, for the adoption
54 /// report's `io_device_type` prefill. No-op unless armed and `info.target_type` is a real class.
55 /// @param info Already-decoded 1W frame info (see decode_1w_frame()).
56 void record_observed_class(const OneWayFrameInfo &info);
57
58 /// Decode an inbound CMD_ONEWAY_ADD_CONTROLLER (0x30) while armed, report the result, and
59 /// disarm. Returns nothing and never consumes the frame — the caller still runs it through the
60 /// normal 1W logging path.
61 /// @param frame Parsed inbound 1W frame.
62 void try_adopt(const IoFrame &frame);
63
64 /// Most recent 1W target device class observed while armed. Single-slot — this is a one-gesture
65 /// flow, not a per-node registry — and reset on every arm so a stale observation from an earlier
66 /// window never leaks into the next one. Feeds the `io_device_type` prefill in the report.
72 /// @return The most recent observed class (see ObservedClass).
73 [[nodiscard]] const ObservedClass &last_observed_class() const { return this->observed_class_; }
74
75 private:
76 NamedTimeoutFn schedule_auto_off_;
77 bool armed_{false};
78 std::function<void(bool)> armed_callback_;
79 ObservedClass observed_class_{};
80};
81
82} // namespace home_io_control
83} // namespace esphome
OnewayKeyAdoption(NamedTimeoutFn schedule_auto_off)
void try_adopt(const IoFrame &frame)
Decode an inbound CMD_ONEWAY_ADD_CONTROLLER (0x30) while armed, report the result,...
bool armed() const
Whether the listener is currently armed.
void set_armed_callback(std::function< void(bool)> cb)
Register a callback invoked whenever the armed state changes (manual toggle, successful adoption,...
const ObservedClass & last_observed_class() const
OnewayKeyAdoption & operator=(const OnewayKeyAdoption &)=delete
OnewayKeyAdoption(const OnewayKeyAdoption &)=delete
Non-copyable — holds an injected callback and is owned by the hub.
void set_armed(bool armed)
Arm or disarm the 1W controller-key adoption listener.
void record_observed_class(const OneWayFrameInfo &info)
Remember the most recent 1W target device class observed from info.src, for the adoption report's io_...
Injected-capability callback aliases shared by the hub's collaborator objects.
static constexpr uint8_t NODE_ID_SIZE
Device/node addresses are 3 bytes (e.g., "123ABC").
Definition proto_sizes.h:20
DeviceType
Device type identifiers reported by IO‑Homecontrol products.
@ UNKNOWN
Unknown/unspecified device.
std::function< void(const char *name, uint32_t delay_ms, std::function< void()> callback)> NamedTimeoutFn
Schedules a named, replace-on-same-name timeout on the hub's ESPHome scheduler.
Definition hub_hooks.h:27
Device-name, address-classification and 1W-frame codecs.
IO-Homecontrol device-type model, capabilities and runtime device state.
IO-Homecontrol 2W frame container: control bytes, IoFrame and (de)serialization.
Parsed IO‑Homecontrol frame (CTRL0/1 + addresses + command + data).
Definition proto_frame.h:88
Decoded representation of a 1W remote frame.
Most recent 1W target device class observed while armed.