Home IO Control
ESPHome add-on for IO-Homecontrol devices
Loading...
Searching...
No Matches
platform_companion_sensors.cpp
Go to the documentation of this file.
1/// @file platform_companion_sensors.cpp
2/// @brief The auto-generated per-device diagnostic companion sensors.
3/// @ingroup hioc_platforms
4
6
7#include "entity_helpers.h"
8#include "proto_constants.h"
9#include "esphome/core/hal.h"
10#include "esphome/core/log.h"
11
12namespace esphome {
13namespace home_io_control {
14
15// Each dump_config() keeps its own log tag as a `static` function-local constant: the ESPHome
16// LOG_SENSOR / LOG_TEXT_SENSOR macros expand to a bare `TAG` identifier, so one shared file-scope
17// constant could not carry a different value per sensor. Values are unchanged from the former per-sensor
18// files. (`static` so the name resolves as a StaticConstant, i.e. UPPER_CASE, under clang-tidy's
19// identifier-naming check rather than as a lower_case local.)
20
21namespace {
22
23constexpr float MS_PER_SECOND = 1000.0F;
24// How often the Last Contact heartbeat re-publishes the age while the device stays quiet.
25// Frame-driven updates alone would freeze the entity's value at whatever it was the moment
26// traffic stopped; without this it can't count up in Home Assistant between frames.
27constexpr uint32_t HEARTBEAT_INTERVAL_MS = 60000;
28
29} // namespace
30
32 this->register_companion_binding_([this](const IoDevice &dev) {
33 if (const int16_t ema_dbm = device_rssi_ema_dbm(dev); ema_dbm != RSSI_UNKNOWN_DBM)
34 this->publish_state(ema_dbm);
35 });
36}
37
39 static const char *const TAG = "home_io_control.rssi";
40 LOG_SENSOR("", "IO-Homecontrol RSSI", this);
41 ESP_LOGCONFIG(TAG, " Device ID: %s", this->device_id_.c_str());
42}
43
45 this->register_companion_binding_([this](const IoDevice &dev) { this->publish_age_(dev); });
46
47 this->set_interval("heartbeat", HEARTBEAT_INTERVAL_MS, [this]() {
48 if (this->parent_ == nullptr)
49 return;
50 if (const auto *dev = this->parent_->get_device(this->device_id_); dev != nullptr)
51 this->publish_age_(*dev);
52 });
53}
54
56 if (dev.last_seen_ms != 0)
57 this->publish_state(static_cast<float>(millis() - dev.last_seen_ms) / MS_PER_SECOND);
58}
59
61 static const char *const TAG = "home_io_control.last_contact";
62 LOG_SENSOR("", "IO-Homecontrol Last Contact", this);
63 ESP_LOGCONFIG(TAG, " Device ID: %s", this->device_id_.c_str());
64}
65
68 [this](const IoDevice &dev) { this->publish_state(static_cast<float>(this->counter_value(dev))); });
69}
70
72 static const char *const TAG = "home_io_control.exchange_failures";
73 LOG_SENSOR("", "IO-Homecontrol Exchange Failures", this);
74 ESP_LOGCONFIG(TAG, " Device ID: %s", this->device_id_.c_str());
75}
76
78 static const char *const TAG = "home_io_control.unconfirmed_exchanges";
79 LOG_SENSOR("", "IO-Homecontrol Unconfirmed Exchanges", this);
80 ESP_LOGCONFIG(TAG, " Device ID: %s", this->device_id_.c_str());
81}
82
84 if (this->parent_ == nullptr)
85 return;
86
87 this->register_companion_binding_([this](const IoDevice &dev) { this->publish_state(dev.name); });
88
89 this->set_timeout("init_name", INITIAL_STATUS_REQUEST_DELAY_MS,
90 [this]() { this->parent_->queue_request_device_name(this->device_id_); });
91}
92
94 static const char *const TAG = "home_io_control.device_name";
95 LOG_TEXT_SENSOR("", "IO-Homecontrol Device Name", this);
96 ESP_LOGCONFIG(TAG, " Device ID: %s", this->device_id_.c_str());
97}
98
100 this->register_companion_binding_([this](const IoDevice &dev) {
101 // Empty string when no result is recorded; otherwise the symbolic result name.
102 this->publish_state(dev.last_result_code == 0 ? "" : command_result_name(dev.last_result_code));
103 });
104}
105
107 static const char *const TAG = "home_io_control.active_issue";
108 LOG_TEXT_SENSOR("", "IO-Homecontrol Active Issue", this);
109 ESP_LOGCONFIG(TAG, " Device ID: %s", this->device_id_.c_str());
110}
111
113 // No parent_ == nullptr guard needed here (unlike IOHomeDeviceNameTextSensor, which dereferences
114 // parent_ a second time outside the binding, in a set_timeout lambda): register_companion_binding_()
115 // already no-ops on a null parent before this lambda is ever invoked, so parent_ is guaranteed
116 // non-null every time it runs.
118 [this](const IoDevice &dev) { this->publish_state(this->parent_->describe_last_commander(dev)); });
119}
120
122 static const char *const TAG = "home_io_control.last_commanded_by";
123 LOG_TEXT_SENSOR("", "IO-Homecontrol Last Commanded By", this);
124 ESP_LOGCONFIG(TAG, " Device ID: %s", this->device_id_.c_str());
125}
126
129 [this](const IoDevice &dev) { this->publish_state(detail::describe_last_command_source(dev)); });
130}
131
133 static const char *const TAG = "home_io_control.last_command_source";
134 LOG_TEXT_SENSOR("", "IO-Homecontrol Last Command Source", this);
135 ESP_LOGCONFIG(TAG, " Device ID: %s", this->device_id_.c_str());
136}
137
138} // namespace home_io_control
139} // namespace esphome
void register_companion_binding_(const std::function< void(const IoDevice &)> &publish)
Shared setup() body: subscribe to this device's updates and publish the initial state.
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.
std::string describe_last_commander(const IoDevice &dev) const
Render a device's "last commanded by" string, resolving this hub's own node ID.
virtual IoDevice * get_device(const std::string &device_id)
Retrieve a device by ID; returns nullptr if not found.
Definition hub_core.cpp:334
virtual void queue_request_device_name(const std::string &device_id)
Queue an async device-name request; returns immediately, executed in loop().
void setup() final
Register the device-update subscription and publish the initial cached count.
virtual uint16_t counter_value(const IoDevice &dev) const =0
Return the counter this sensor publishes.
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.
void dump_config() override
Dump sensor configuration to the log.
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.
void setup() override
Register the device-update subscription, start the heartbeat, and publish the initial cached state.
void setup() override
Register the device-update subscription and publish the initial cached state.
void dump_config() override
Dump sensor configuration to the log.
void dump_config() override
Dump sensor configuration to the log.
Conversions and renderers shared by the hub and its Home Assistant entities.
std::string describe_last_command_source(const IoDevice &dev)
Render the "Last Command Source" sensor string.
const char * command_result_name(uint8_t result)
Return a stable symbolic name for a CMD_ERROR_RESP result code.
int16_t device_rssi_ema_dbm(const IoDevice &dev)
A device's smoothed RSSI in whole dBm.
The auto-generated per-device diagnostic companion sensors.
IO-Homecontrol command IDs, result codes and protocol enumerations.
Runtime state of a paired IO‑Homecontrol device.
uint8_t last_result_code
Last CMD_ERROR_RESP result byte (0 = none recorded).
char name[DEVICE_NAME_BUFFER_SIZE]
Cached UTF-8 device name decoded from Latin-1 wire payloads.
uint32_t last_seen_ms
millis() of the last frame received from this device (any command), 0 = never.