Drops the CONF_GREETING option, the first-contact greeting logic and its
RuntimeData state, and all related strings/translations/README text. Any
greeting value left in an existing entry's options is simply ignored.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- messages_sent now increments when a message is queued (async_send_message),
not only when a delivery proof returns. LXMessage's delivery callback only
fires on a returned proof (LXMessage.py ~566), which many peers/methods never
send, so the "Messages sent" sensor was stuck at 0 for messages that were
actually delivered. The delivery callback now only emits the event.
- Implement the previously-inert "greeting" option: send it automatically the
first time each sender contacts HA (tracked per sender in RuntimeData).
- Clarify the notify entity (rename to "Send message" / "Отправить сообщение")
and document greeting + notify in strings/translations/README.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- entity.py: decorate the dispatcher target _handle_update with @callback so it
runs on the event loop. Without it, async_dispatcher_send offloaded the plain
sync callback to an executor thread, and async_write_ha_state raised
"calls async_write_ha_state from a thread other than the event loop".
- config_flow.py: replace the free-text Assist agent field with
ConversationAgentSelector (a proper agent dropdown), and use LanguageSelector
for the language field.
- README: clarify that the built-in Assist agent only handles device commands;
an LLM conversation agent is required for free-form chat.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
v1.0.2 only neutralised signal.signal around RNS.Reticulum(), but
LXMF.LXMRouter.__init__ also calls signal.signal(SIGINT/SIGTERM) (LXMRouter.py
308-309), so init still crashed with "signal only works in main thread of the
main interpreter" when the router was constructed in the executor thread.
Wrap the entire _start init (both constructors) with signal.signal neutralised
instead of just the RNS constructor. Confirmed via upstream source that the
only relevant signal registration sites are RNS/Reticulum.py:366-367 and
LXMF/LXMRouter.py:308-309, both module-attribute calls, so the module-level
patch intercepts both.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Root cause of setup failure: Reticulum.__init__ calls signal.signal() with no
main-thread guard, but we (correctly) initialise off the event loop in an
executor thread, where signal.signal() raises ValueError. It failed after
setting the __instance singleton, which both broke setup and caused the
"Attempt to reinitialise Reticulum" error on every retry.
- Temporarily neutralise signal.signal during RNS init so init completes in the
executor, and so RNS does not hijack HA's SIGINT/SIGTERM (needed for clean
shutdown under Kubernetes).
- Unregister RNS's and LXMF's atexit exit handlers, which otherwise persist
state with blocking file I/O on the event-loop thread and detach HA's
stdout/stderr at interpreter exit (the loop-blocking warnings seen in logs).
- Persist RNS/LXMF state ourselves off-loop on the homeassistant_stop event.
Documents the remaining non-daemon RNS worker threads as a known shutdown note.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
RNS.Reticulum.__init__ sets its internal singleton before it can fail partway
through init, which left our module-level _RNS_INSTANCE cache out of sync (None)
while RNS believed it was already running. Every setup retry then hit RNS's
reinit guard and raised "Attempt to reinitialise Reticulum, when it was already
running".
Use RNS.Reticulum.get_instance() as the source of truth and adopt an existing
instance instead of re-creating it (with an OSError fallback that also adopts).
Also cache and reuse the LXMF router, delivery destination, identity and
announce handler across reloads so a reload never spawns a duplicate router or
stacks announce handlers.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Custom integration connecting Home Assistant to a Reticulum network over a
TCPClientInterface and exchanging LXMF messages, with an Assist conversation
bridge, notify entity, sensors (incl. interface telemetry), buttons, services,
bus events and device triggers.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>