Home IO Control
ESPHome add-on for IO-Homecontrol devices
Loading...
Searching...
No Matches
platform_companion_sensors.h
Go to the documentation of this file.
1#pragma once
2
3/// @file platform_companion_sensors.h
4/// @brief The seven auto-generated per-device diagnostic companion sensors.
5/// @ingroup hioc_platforms
6///
7/// Every device-bound platform (cover, light, switch, lock) gets the same seven read-only
8/// companions generated alongside it by platform_common.py: smoothed RSSI, seconds since last
9/// contact, cumulative exchange-failure count, the stored device name, the currently outstanding
10/// CMD_ERROR_RESP reason, and the last-command record's commander/originator. They share the
11/// DeviceBoundCompanion binding (observe-only: no add_device(), no polling) and an all-but-
12/// identical setup()/dump_config() skeleton, so they live together here rather than in seven
13/// near-duplicate file pairs.
14
15#include "esphome/components/sensor/sensor.h"
16#include "esphome/components/text_sensor/text_sensor.h"
17#include "esphome/core/component.h"
19
20namespace esphome {
21namespace home_io_control {
22
23/// @brief Diagnostic sensor that publishes a device's smoothed (EMA) RSSI in dBm.
24///
25/// Publishes nothing until the first RX from this device seeds the EMA (see
26/// detail::update_link_health() in hub_internal.h) — Home Assistant shows the entity as
27/// unavailable until then, rather than a misleading 0 dBm.
28/// @ingroup hioc_platforms
29class IOHomeRssiSensor : public sensor::Sensor, public Component, public DeviceBoundCompanion {
30 public:
31 /// @brief Register the device-update subscription and publish the initial cached state.
32 void setup() override;
33
34 /// @brief Dump sensor configuration to the log.
35 void dump_config() override;
36
37 /// @brief Get setup priority so the parent hub is available first.
38 /// @return setup_priority::DATA.
39 [[nodiscard]] float get_setup_priority() const override { return setup_priority::DATA; }
40};
41
42/// @brief Diagnostic sensor that publishes seconds elapsed since the last frame received from a
43/// device (see detail::update_link_health() in hub_internal.h).
44///
45/// This is an age, not a timestamp: it resets to ~0 on every frame from the device — including
46/// replies to the hub's own status polls and commands, not just traffic the device sends
47/// unprompted — and counts up from there. A periodic heartbeat (see HEARTBEAT_INTERVAL_MS in the
48/// .cpp) re-publishes it even when the device stays quiet, so the value keeps advancing in Home
49/// Assistant instead of freezing at whatever it was at the last frame. Publishes nothing until
50/// the first frame is seen.
51/// @ingroup hioc_platforms
52class IOHomeLastContactSensor : public sensor::Sensor, public Component, public DeviceBoundCompanion {
53 public:
54 /// @brief Register the device-update subscription, start the heartbeat, and publish the
55 /// initial cached state.
56 void setup() override;
57
58 /// @brief Dump sensor configuration to the log.
59 void dump_config() override;
60
61 /// @brief Get setup priority so the parent hub is available first.
62 /// @return setup_priority::DATA.
63 [[nodiscard]] float get_setup_priority() const override { return setup_priority::DATA; }
64
65 protected:
66 /// @brief Compute and publish seconds since `dev.last_seen_ms`; no-op before the first frame.
67 /// @param dev Device to read `last_seen_ms` from.
68 void publish_age_(const IoDevice &dev);
69};
70
71/// @brief Diagnostic sensor that publishes a device's cumulative count of outbound exchanges
72/// that timed out (no valid response) — see detail::record_exchange_timeout() in
73/// hub_internal.h.
74///
75/// Unlike the RSSI and Last Contact sensors, zero is a meaningful value here (no failures yet),
76/// so this publishes on setup unconditionally.
77/// @ingroup hioc_platforms
78class IOHomeExchangeFailuresSensor : public sensor::Sensor, public Component, public DeviceBoundCompanion {
79 public:
80 /// @brief Register the device-update subscription and publish the initial cached state.
81 void setup() override;
82
83 /// @brief Dump sensor configuration to the log.
84 void dump_config() override;
85
86 /// @brief Get setup priority so the parent hub is available first.
87 /// @return setup_priority::DATA.
88 [[nodiscard]] float get_setup_priority() const override { return setup_priority::DATA; }
89};
90
91/// @brief Diagnostic text sensor that publishes the cached device name.
92///
93/// Beyond the shared companion behavior it also queues one boot-time GET_NAME request so the
94/// cache gets populated without waiting for unrelated traffic.
95/// @ingroup hioc_platforms
96class IOHomeDeviceNameTextSensor : public text_sensor::TextSensor, public Component, public DeviceBoundCompanion {
97 public:
98 /// @brief Register the device-update subscription and schedule an initial name fetch.
99 void setup() override;
100
101 /// @brief Dump text-sensor configuration to the log.
102 void dump_config() override;
103
104 /// @brief Get setup priority so the parent hub is available first.
105 /// @return setup_priority::DATA.
106 [[nodiscard]] float get_setup_priority() const override { return setup_priority::DATA; }
107};
108
109/// @brief Diagnostic text sensor that publishes the symbolic name of a device's most recent
110/// CMD_ERROR_RESP result code (e.g. "LIMITATION_BY_RAIN"), letting a "nothing happened" command
111/// self-explain instead of only showing up in the log. Shared by every device-bound platform
112/// (cover, light, switch, lock) via platform_common.py's companion-sensor codegen.
113///
114/// Not a per-operation outcome — it does not get set on every command, only on an explicit
115/// CMD_ERROR_RESP. Publishes an empty string until the first one is seen, and again after any
116/// subsequent successful status/command reply clears it (see detail::clear_command_result()), so
117/// a non-empty value always means "this is still going on" rather than "this is what happened
118/// last."
119/// @ingroup hioc_platforms
120class IOHomeActiveIssueTextSensor : public text_sensor::TextSensor, public Component, public DeviceBoundCompanion {
121 public:
122 /// @brief Register the device-update subscription and publish the initial cached state.
123 void setup() override;
124
125 /// @brief Dump text-sensor configuration to the log.
126 void dump_config() override;
127
128 /// @brief Get setup priority so the parent hub is available first.
129 /// @return setup_priority::DATA.
130 [[nodiscard]] float get_setup_priority() const override { return setup_priority::DATA; }
131};
132
133/// @brief Diagnostic text sensor naming the controller that last commanded this device.
134///
135/// Read from bytes the device already includes in every status reply — no extra radio traffic and
136/// no probe. Last-writer-wins and inherently stale: it only changes when something actually
137/// commands the device, and a foreign controller's node ID has no name unless the user recognises
138/// it. Publishes an empty string until the first status reply carrying the record arrives.
139/// @ingroup hioc_platforms
140class IOHomeLastCommandedByTextSensor : public text_sensor::TextSensor, public Component, public DeviceBoundCompanion {
141 public:
142 void setup() override;
143 void dump_config() override;
144 [[nodiscard]] float get_setup_priority() const override { return setup_priority::DATA; }
145};
146
147/// @brief Diagnostic text sensor naming what kind of source issued that last command.
148///
149/// The device's own Command Originator byte, rendered "name(0xXX)". Field-validated as a clean
150/// remote-vs-motor-button split on roller shutters only; other device classes may report values
151/// with no ORIGINATOR_* name, which surface as "unknown(0xXX)" rather than being dropped.
152/// @ingroup hioc_platforms
153class IOHomeLastCommandSourceTextSensor : public text_sensor::TextSensor,
154 public Component,
155 public DeviceBoundCompanion {
156 public:
157 void setup() override;
158 void dump_config() override;
159 [[nodiscard]] float get_setup_priority() const override { return setup_priority::DATA; }
160};
161
162} // namespace home_io_control
163} // namespace esphome
Mixin holding the parent + device-id binding shared by per-device entities that are not full entity p...
Diagnostic text sensor that publishes the symbolic name of a device's most recent CMD_ERROR_RESP resu...
void setup() override
Register the device-update subscription and publish the initial cached state.
void dump_config() override
Dump text-sensor configuration to the log.
float get_setup_priority() const override
Get setup priority so the parent hub is available first.
Diagnostic text sensor that publishes the cached device name.
void setup() override
Register the device-update subscription and schedule an initial name fetch.
void dump_config() override
Dump text-sensor configuration to the log.
float get_setup_priority() const override
Get setup priority so the parent hub is available first.
Diagnostic sensor that publishes a device's cumulative count of outbound exchanges that timed out (no...
float get_setup_priority() const override
Get setup priority so the parent hub is available first.
void setup() override
Register the device-update subscription and publish the initial cached state.
void dump_config() override
Dump sensor configuration to the log.
Diagnostic text sensor naming what kind of source issued that last command.
Diagnostic text sensor naming the controller that last commanded this device.
Diagnostic sensor that publishes seconds elapsed since the last frame received from a device (see det...
void dump_config() override
Dump sensor configuration to the log.
void publish_age_(const IoDevice &dev)
Compute and publish seconds since dev.last_seen_ms; no-op before the first frame.
float get_setup_priority() const override
Get setup priority so the parent hub is available first.
void setup() override
Register the device-update subscription, start the heartbeat, and publish the initial cached state.
Diagnostic sensor that publishes a device's smoothed (EMA) RSSI in dBm.
float get_setup_priority() const override
Get setup priority so the parent hub is available first.
void setup() override
Register the device-update subscription and publish the initial cached state.
void dump_config() override
Dump sensor configuration to the log.
Shared device-binding mixins for IO-Homecontrol entity platforms.
Runtime state of a paired IO‑Homecontrol device.