22constexpr size_t HEX_BYTE_STR_SIZE = 8;
24constexpr size_t HEX_ADDR_STR_SIZE = 16;
26constexpr size_t BANDWIDTH_STR_SIZE = 16;
29constexpr float BW_KHZ_58_6 = 58.6F;
30constexpr float BW_KHZ_78_2 = 78.2F;
31constexpr float BW_KHZ_117_3 = 117.3F;
32constexpr float BW_KHZ_156_2 = 156.2F;
33constexpr float BW_KHZ_187_2 = 187.2F;
36constexpr float BW_KHZ_20_8 = 20.8F;
37constexpr float BW_KHZ_41_7 = 41.7F;
38constexpr float BW_KHZ_62_5 = 62.5F;
39constexpr float BW_KHZ_83_3 = 83.3F;
40constexpr float BW_KHZ_125_0 = 125.0F;
43constexpr float BW_KHZ_39_0 = 39.0F;
44constexpr float BW_KHZ_46_9 = 46.9F;
65 char buf[BANDWIDTH_STR_SIZE];
67 return std::string(buf);
71 std::string normalized = value;
73 normalized.erase(std::remove_if(normalized.begin(), normalized.end(), ::isspace), normalized.end());
74 for (
char &c : normalized)
75 c =
static_cast<char>(std::tolower(
static_cast<unsigned char>(c)));
76 if (normalized.size() > 3 && normalized.ends_with(
"khz"))
77 normalized.resize(normalized.size() - 3);
79 if (normalized ==
"58.6" || normalized ==
"58")
81 if (normalized ==
"78.2" || normalized ==
"78")
83 if (normalized ==
"117.3" || normalized ==
"117")
85 if (normalized ==
"156.2" || normalized ==
"156")
87 if (normalized ==
"187.2" || normalized ==
"187")
109 char buf[BANDWIDTH_STR_SIZE];
111 return std::string(buf);
115 std::string normalized = value;
117 normalized.erase(std::remove_if(normalized.begin(), normalized.end(), ::isspace), normalized.end());
118 for (
char &c : normalized)
119 c =
static_cast<char>(std::tolower(
static_cast<unsigned char>(c)));
120 if (normalized.size() > 3 && normalized.ends_with(
"khz"))
121 normalized.resize(normalized.size() - 3);
123 if (normalized ==
"20.8" || normalized ==
"20")
125 if (normalized ==
"41.7" || normalized ==
"41")
127 if (normalized ==
"62.5" || normalized ==
"62")
129 if (normalized ==
"83.3" || normalized ==
"83")
131 if (normalized ==
"125.0" || normalized ==
"125")
157 char buf[BANDWIDTH_STR_SIZE];
159 return std::string(buf);
163 std::string normalized = value;
165 normalized.erase(std::remove_if(normalized.begin(), normalized.end(), ::isspace), normalized.end());
166 for (
char &c : normalized)
167 c =
static_cast<char>(std::tolower(
static_cast<unsigned char>(c)));
168 if (normalized.size() > 3 && normalized.ends_with(
"khz"))
169 normalized.resize(normalized.size() - 3);
171 if (normalized ==
"39.0" || normalized ==
"39")
173 if (normalized ==
"46.9" || normalized ==
"46")
175 if (normalized ==
"58.6" || normalized ==
"58")
177 if (normalized ==
"78.2" || normalized ==
"78")
179 if (normalized ==
"117.3" || normalized ==
"117")
181 if (normalized ==
"156.2" || normalized ==
"156")
183 if (normalized ==
"187.2" || normalized ==
"187")
189 std::string normalized = value;
190 for (
char &c : normalized)
191 c =
static_cast<char>(std::tolower(
static_cast<unsigned char>(c)));
192 if (normalized ==
"0x28" || normalized ==
"discover")
194 if (normalized ==
"0x2a" || normalized ==
"discover_spe")
196 if (normalized ==
"0x2e" || normalized ==
"discover_alt")
202 char buf[HEX_BYTE_STR_SIZE];
203 snprintf(buf,
sizeof(buf),
"0x%02X",
static_cast<uint8_t
>(cmd));
204 return std::string(buf);
209 for (
size_t i = 0; i < commands.size(); ++i) {
223 if (!destination_auto)
239 if (destination_auto)
241 char buf[HEX_ADDR_STR_SIZE];
242 snprintf(buf,
sizeof(buf),
"0x%02X%02X%02X", destination[0], destination[1], destination[2]);
243 return std::string(buf);
247 if (!payload_enabled)
249 char buf[HEX_BYTE_STR_SIZE];
250 snprintf(buf,
sizeof(buf),
"0x%02X", payload);
251 return std::string(buf);
255 return "Tuning updated via HA: " + name +
"=" + value;
299 result +=
" pairing_discovery_payload=" +
317 return "Tuning: defaults active";
318 return "Tuning overrides active:" + result;
std::string discovery_commands_to_csv(const std::vector< DiscoveryCommand > &commands)
Format the ordered discovery command list as a UI/preset option string.
static constexpr uint8_t CMD_DISCOVER_REQ
Broadcast discovery request.
static constexpr uint8_t NODE_ID_SIZE
Device/node addresses are 3 bytes (e.g., "123ABC").
std::optional< LR1121RxBandwidth > lr1121_bandwidth_from_string(const std::string &value)
Convert a YAML LR1121 bandwidth string to the enum value.
SX1262RxBandwidth
Valid SX1262 RX bandwidth options (kHz register values).
@ BW_58_6_KHZ
58.6 kHz — narrowest; SX1276-equivalent width, marginal on the default TX→RX turnaround.
@ BW_78_2_KHZ
78.2 kHz — narrow.
@ BW_156_2_KHZ
156.2 kHz — wider tolerance for LO offset.
@ BW_117_3_KHZ
117.3 kHz — default.
@ BW_187_2_KHZ
187.2 kHz — widest selectable option.
std::string discovery_payload_to_string(bool payload_enabled, uint8_t payload)
Format a payload option for YAML/logs.
std::optional< DiscoveryCommand > discovery_command_from_string(const std::string &value)
Parse a discovery command string (e.g., "0x28") into the enum.
static constexpr uint8_t CMD_DISCOVER_ALT_REQ
Alternate discovery.
LR1121RxBandwidth
Valid LR1121 RX bandwidth options (register values).
@ BW_39_0_KHZ
39.0 kHz — narrowest; close to SX1276's validated 41.7 kHz default.
@ BW_46_9_KHZ
46.9 kHz — narrow.
@ BW_156_2_KHZ
156.2 kHz — wider tolerance for LO offset.
@ BW_117_3_KHZ
117.3 kHz — default.
@ BW_187_2_KHZ
187.2 kHz — widest selectable option.
std::string lr1121_bandwidth_to_string(LR1121RxBandwidth bw)
Format an LR1121 bandwidth enum as its YAML/UI option string (bare kHz number).
std::string tuning_config_snapshot(const TuningConfig &cfg)
Format the current tuning configuration as a one-line YAML-compatible snapshot.
std::optional< SX1262RxBandwidth > sx1262_bandwidth_from_string(const std::string &value)
Convert a YAML bandwidth string to the enum value.
std::string sx1276_bandwidth_to_string(SX1276RxBandwidth bw)
Format an SX1276 bandwidth enum as its YAML/UI option string (bare kHz number).
float lr1121_bandwidth_to_khz(LR1121RxBandwidth bw)
Convert an LR1121 bandwidth enum to the numeric kHz value used in YAML/logs.
std::string discovery_commands_to_string(const std::vector< DiscoveryCommand > &commands)
Format the ordered discovery command list for logs.
std::string tuning_config_full_snapshot(const TuningConfig &cfg)
Format the current tuning configuration as a full one-line snapshot.
float sx1262_bandwidth_to_khz(SX1262RxBandwidth bw)
Convert a bandwidth enum to the numeric kHz value used in YAML/logs.
static constexpr uint8_t CMD_DISCOVER_SPE_REQ
Broadcast roll-call answered by every device that already holds this controller's system key,...
std::string sx1262_bandwidth_to_string(SX1262RxBandwidth bw)
Format a bandwidth enum as its YAML/UI option string (bare kHz number, e.g.
std::string tuning_update_log_line(const std::string &name, const std::string &value)
Format a single tuning update for the log.
DiscoveryCommand
Discovery request command codes.
@ DISCOVER_SPE
SPE roll-call request (self-authenticating; see CMD_DISCOVER_SPE_REQ).
@ DISCOVER
Standard broadcast discovery request (to 0x00003B).
@ DISCOVER_ALT
Alternate broadcast discovery (to 0x00003F), with optional payload byte.
float sx1276_bandwidth_to_khz(SX1276RxBandwidth bw)
Convert an SX1276 bandwidth enum to the numeric kHz value used in YAML/logs.
static constexpr uint8_t BROADCAST_DISCOVER[NODE_ID_SIZE]
Broadcast address for device discovery (0x00003B).
static constexpr uint8_t BROADCAST_DISCOVER_ALT[NODE_ID_SIZE]
Alternate discovery / 1W broadcast address (0x00003F).
std::string discovery_command_to_string(DiscoveryCommand cmd)
Format a discovery command enum for YAML/logs.
SX1276RxBandwidth
Valid SX1276 RX bandwidth options (RegRxBw register bytes).
@ BW_41_7_KHZ
41.7 kHz — default (validated against real devices).
@ BW_125_0_KHZ
125.0 kHz — widest selectable option.
@ BW_20_8_KHZ
20.8 kHz — narrowest; maximal noise rejection, least LO-offset tolerance.
std::optional< SX1276RxBandwidth > sx1276_bandwidth_from_string(const std::string &value)
Convert a YAML SX1276 bandwidth string to the enum value.
const uint8_t * resolve_discovery_destination(uint8_t command, bool destination_auto, const uint8_t destination[NODE_ID_SIZE])
Resolve the destination address for a discovery command.
std::string discovery_destination_to_string(bool destination_auto, const uint8_t destination[NODE_ID_SIZE])
Format a destination option for YAML/logs.
IO-Homecontrol command IDs, result codes and protocol enumerations.
All runtime tunable parameters for pairing and radio diagnostics.
uint16_t pairing_discovery_initial_dwell_ms
Initial dwell on CH2 before discovery hopping begins.
bool pairing_discovery_destination_auto
When true, map commands to conventional addresses.
SX1276RxBandwidth sx1276_rx_bandwidth
SX1276 RX bandwidth selector.
int16_t lbt_rssi_threshold_dbm
LBT channel-free threshold (dBm).
SX1262RxBandwidth sx1262_rx_bandwidth
SX1262 RX bandwidth selector.
std::vector< uint8_t > pairing_discovery_destination
Destination when auto=false.
std::vector< DiscoveryCommand > pairing_discovery_commands
Ordered discovery commands.
uint16_t lr1121_discovery_hop_slice_ms
Per-channel dwell while LR1121 discovery hops.
uint16_t sx1276_response_preamble
SX1276 response preamble in bytes.
uint16_t sx1262_post_tx_settle_us
Delay after SX1262 TX before RX (µs).
uint8_t pairing_key_exchange_retries
Retries for the authenticated key exchange phase.
bool pairing_discovery_low_power
Set LOW_POWER flag in discovery frames.
uint16_t sx1276_discovery_hop_slice_ms
Per-channel dwell while SX1276 discovery hops.
uint16_t sx1262_response_preamble
SX1262 response preamble in bytes.
uint16_t pairing_discovery_wait_ms
Total wait window after sending discovery commands.
bool pairing_discovery_payload_enabled
Whether the optional payload is enabled.
LR1121RxBandwidth lr1121_rx_bandwidth
LR1121 RX bandwidth selector.
uint16_t lr1121_post_tx_settle_us
Delay after LR1121 TX before RX (µs).
uint8_t lbt_max_retries
LBT retries before forced TX.
uint16_t sx1262_discovery_hop_slice_ms
Per-channel dwell while SX1262 discovery hops.
uint16_t lr1121_response_preamble
LR1121 response preamble in bytes.
uint8_t pairing_discovery_payload
Optional payload byte (used for 0x2E).
Runtime tuning configuration for pairing and radio diagnostics.