Home IO Control
ESPHome add-on for IO-Homecontrol devices
Toggle main menu visibility
Loading...
Searching...
No Matches
entity_helpers.h
Go to the documentation of this file.
1
#pragma once
2
3
/// @file entity_helpers.h
4
/// @brief Conversions and renderers shared by the hub and its Home Assistant entities.
5
/// @ingroup hioc_hub
6
///
7
/// Carries no dependency on the hub itself, so an entity can include this header instead of the
8
/// hub's private helpers (make include-graph enforces that split).
9
10
#include "
log_helpers.h
"
11
#include "
proto_constants.h
"
12
#include "
proto_device_model.h
"
13
#include "
proto_frame.h
"
14
#include "
proto_sizes.h
"
15
16
#include <cmath>
17
#include <cstdint>
18
#include <cstring>
19
#include <string>
20
21
namespace
esphome
{
22
namespace
home_io_control
{
23
namespace
detail
{
24
25
// ============================================================================
26
// Shared constants
27
// ============================================================================
28
29
inline
constexpr
float
BINARY_ENTITY_ON_POSITION_THRESHOLD
=
30
50.0F;
///< Shared 0-100 cutoff: values below this mean binary "on".
31
32
// ============================================================================
33
// Percent conversion helpers
34
// ============================================================================
35
36
/// @brief Convert a 0.0-1.0 HA fraction (position, tilt, or brightness) to a 0-100 IO percent.
37
///
38
/// Rounds rather than truncates: HA quantizes call values to 0-255 before they ever reach us, so
39
/// its "50%" is 128/255=0.50196, not exactly 0.5 — a truncating cast compounds that quantization
40
/// into a consistent ~1% bias, caught on real hardware in both platform_cover.cpp (position and
41
/// tilt) and platform_light.cpp (brightness). Callers apply their own invert/complement logic
42
/// (e.g. `1.0F - fraction`) before calling this; it only owns the rounding.
43
/// @param fraction Value in [0.0, 1.0].
44
/// @return Rounded 0-100 percent.
45
inline
uint8_t
round_percent
(
float
fraction) {
return
static_cast<
uint8_t
>
(std::lround(fraction * 100.0F)); }
46
47
// ============================================================================
48
// Last-command record rendering
49
// ============================================================================
50
51
/// @brief Render a Command Originator byte as "name(0xXX)", e.g. "user_remote(0x01)".
52
///
53
/// The one rendering every originator display shares (the "Last Command Source" sensor and the 0x71
54
/// status-update log line), so a byte with no ORIGINATOR_* case reads "unknown(0x0A)" everywhere
55
/// rather than being silently dropped or mislabelled.
56
/// @param originator Command Originator byte (ORIGINATOR_*).
57
/// @return "name(0xXX)".
58
inline
std::string
format_originator
(uint8_t originator) {
59
return
format_name_and_hex
(
originator_name
(originator), originator);
60
}
61
62
/// @brief Render the "Last Commanded By" sensor string.
63
///
64
/// Always leads with the raw node ID — that is the diagnostic value, and the only thing a user can
65
/// match against a remote they own. The qualifier is additive, never a substitute: a device naming
66
/// its own ID is NOT reliably "the button on the motor" (the one non-shutter this project has data
67
/// on, a mains gate, names its own ID with an undefined originator), so the cause belongs to the
68
/// separate originator sensor, not to this one's wording.
69
/// @param dev Device record to read.
70
/// @param hub_node_id This hub's own 3-byte node ID.
71
/// @return e.g. "3B74DC", "C0FFEE (this hub)", "2FE2D2 (this device)"; empty before the first record.
72
inline
std::string
describe_last_commander
(
const
IoDevice
&dev,
const
uint8_t *hub_node_id) {
73
if
(!dev.
has_last_command
)
74
return
{};
75
std::string out =
node_id_to_string
(dev.
last_commander
);
76
if
(memcmp(dev.
last_commander
, hub_node_id, NODE_ID_SIZE) == 0) {
77
out +=
" (this hub)"
;
78
}
else
if
(memcmp(dev.
last_commander
, dev.
node_id
, NODE_ID_SIZE) == 0) {
79
out +=
" (this device)"
;
80
}
81
return
out;
82
}
83
84
/// @brief Render the "Last Command Source" sensor string.
85
///
86
/// Rendered by format_originator(), so an undecoded byte keeps its raw hex. The decode is
87
/// field-validated for roller shutters (a clean 0x00/0x01 split, remote vs. motor
88
/// button); gates, lights and multi-channel units are not validated and are expected to surface
89
/// undecoded values here — which is the point of keeping the raw hex in the string.
90
/// @param dev Device record to read.
91
/// @return e.g. "user_remote(0x01)"; empty before the first record.
92
inline
std::string
describe_last_command_source
(
const
IoDevice
&dev) {
93
if
(!dev.
has_last_command
)
94
return
{};
95
return
format_originator
(dev.
last_command_originator
);
96
}
97
98
}
// namespace detail
99
}
// namespace home_io_control
100
}
// namespace esphome
log_helpers.h
Hub-layer log tag and log/format helpers shared by the hub and its collaborators.
esphome::home_io_control::detail
Definition
entity_helpers.h:23
esphome::home_io_control::detail::format_name_and_hex
std::string format_name_and_hex(const char *name, uint8_t value)
Format a name/value pair as "name(0xXX)", e.g. "execute(0x00)".
Definition
log_helpers.h:41
esphome::home_io_control::detail::BINARY_ENTITY_ON_POSITION_THRESHOLD
constexpr float BINARY_ENTITY_ON_POSITION_THRESHOLD
Shared 0-100 cutoff: values below this mean binary "on".
Definition
entity_helpers.h:29
esphome::home_io_control::detail::describe_last_command_source
std::string describe_last_command_source(const IoDevice &dev)
Render the "Last Command Source" sensor string.
Definition
entity_helpers.h:92
esphome::home_io_control::detail::round_percent
uint8_t round_percent(float fraction)
Convert a 0.0-1.0 HA fraction (position, tilt, or brightness) to a 0-100 IO percent.
Definition
entity_helpers.h:45
esphome::home_io_control::detail::describe_last_commander
std::string describe_last_commander(const IoDevice &dev, const uint8_t *hub_node_id)
Render the "Last Commanded By" sensor string.
Definition
entity_helpers.h:72
esphome::home_io_control::detail::format_originator
std::string format_originator(uint8_t originator)
Render a Command Originator byte as "name(0xXX)", e.g.
Definition
entity_helpers.h:58
esphome::home_io_control
Definition
device_registry.cpp:13
esphome::home_io_control::node_id_to_string
std::string node_id_to_string(const uint8_t id[NODE_ID_SIZE])
Format a 3‑byte node ID as a 6‑character uppercase hex string.
Definition
proto_frame.cpp:50
esphome::home_io_control::originator_name
const char * originator_name(uint8_t originator)
Get a human-readable name for a command originator byte.
Definition
proto_constants.cpp:174
esphome
Definition
device_registry.cpp:12
proto_constants.h
IO-Homecontrol command IDs, result codes and protocol enumerations.
proto_device_model.h
IO-Homecontrol device-type model, capabilities and runtime device state.
proto_frame.h
IO-Homecontrol 2W frame container: control bytes, IoFrame and (de)serialization.
proto_sizes.h
Fundamental IO-Homecontrol frame and crypto size constants.
esphome::home_io_control::IoDevice
Runtime state of a paired IO‑Homecontrol device.
Definition
proto_device_model.h:321
esphome::home_io_control::IoDevice::last_commander
uint8_t last_commander[NODE_ID_SIZE]
Node ID of the controller that last commanded this device, as reported verbatim by the device in its ...
Definition
proto_device_model.h:353
esphome::home_io_control::IoDevice::last_command_originator
uint8_t last_command_originator
That command's Command Originator byte (ORIGINATOR_* in proto_constants.h).
Definition
proto_device_model.h:357
esphome::home_io_control::IoDevice::node_id
uint8_t node_id[NODE_ID_SIZE]
Device's 3‑byte radio address.
Definition
proto_device_model.h:322
esphome::home_io_control::IoDevice::has_last_command
bool has_last_command
True once a status reply carried a well-formed last-command record.
Definition
proto_device_model.h:359
components
home_io_control
entity_helpers.h
Generated by
1.18.0