Pre-release of the internal architecture refactor. External contract (events, services, entity ids, attributes, default polling timing) is unchanged and now pinned by fixtures. Install from the beta branch / this pre-release only if you want to help test.
Requirements
- Home Assistant 2025.6.0 or newer (the code already needed APIs newer than the advertised 2023.8)
- meshcore 2.3.11 or newer
Behavior changes
- Radio session is owned by the integration:
auto_reconnect=False, our own jittered reconnect,connectedflips on real link loss instead of ~100s later, and every subscription survives a reconnect. The "goes deaf after a reconnect until reload" failure is gone. (#354) - All radio commands go through one gate. Remote requests match their own reply on node prefix + tag, so concurrent commands no longer steal each other's responses. (#354)
- Private key and channel secrets are redacted on the HA bus and raw-mode MQTT by default.
expose_secrets(Global Settings) restores the old payloads. (#356) - Config edits apply in place. Only connection identity and the
cli_console_enabled/self_diagnostics_enabledtoggles reload the entry. Adding, removing or editing a tracked repeater/client, changing intervals, brokers, discovery settings and the firmware refresh button no longer restart the radio session. (#355) execute_commandrefusesrequest_factory_reset,confirm_factory_reset,import_private_key,send_raw_packet,send_raw_dataand_-prefixed names.add_selected_contact/remove_selected_contactare admin services. (#356)select.meshcore_contactdefaults to "Select a contact..." instead of the first contact, so a renamed or removed target cannot silently redirect a message. (#357)- Outgoing channel
meshcore_messagefires immediately (repeater_count: 0,collecting: true); the repeater count now arrives onmeshcore_delivery_update, terminal one hasprogressive: false. DMs get an immediatemeshcore_message_sentplus a terminalmeshcore_delivery_update; the post-ACKmeshcore_message_sentstill fires as before. (#356)
Features
traffic_policyoption (Global Settings):legacy(default) keeps today's polling/retry numbers exactly;governedis a flat per-radio budget split into flood / direct / message lanes with deferral instead of failure, persisted across restarts, rates exposed on the rate-limiter sensor and in the log. (#354)- Every
meshcore_*event carriesentry_idanddevice_id. Newmeshcore_message_send_failedevent. Unknown-sender DMs are published withsender_name: nullinstead of dropped. (#356) messages_intervalis editable in Global Settings. Entries get aunique_id; adding the same radio twice is refused. (#355)- Telemetry entities for LPP types that never created any: accelerometer, colour, gyrometer (per axis), barometer, altitude, frequency, percentage, load, concentration, distance, energy, direction, time, switch. (#357)
- The six radio-identity sensors (tx power, lat/lon, frequency, bandwidth, SF) populate at startup. (#357)
- Architecture diagram as code in
docs/architecture/(squinch). (#354)
Fixes
- Reconnect no longer orphans subscriptions; failed connects no longer leak the transport; disconnect is bounded; unload cancels in-flight node tasks. (#354)
- Login races
LOGIN_SUCCESSvsLOGIN_FAILED; wrong password fails fast. Neighbour paging is bounded. (#354) send_messagewithout a recipient raises a clear error instead ofKeyError.traceaccepts 6-char prefixes.cleanup_unavailable_contactsonly removes contact diagnostic sensors of the targeted entry. Unnamed channels render as their index. (#356)- Adverts no longer write the whole discovered-contacts store per packet or reschedule the tick; discovered FIFO loads once; contact sync has a failure backoff. (#357)
- MQTT uploader no longer blocks entry setup; map uploader stops re-exporting the private key on every advert. (#357)
- Push-path telemetry frames are attributed to the right node. (#357)
Notes
- Validation: 365 unit tests and 228 real Home Assistant integration tests. Live on a TCP companion with six tracked repeaters: forced link drops, entry reloads, every global setting and tracked-node edit through the options flow, channel sends, redaction and refusals.
- Entries migrate from v3 to v4 on load (settings copied into options, prefixes normalised, firmware version moved to the device registry). Downgrading keeps working because the data copies are retained.