Count sent messages at send time; implement first-contact greeting
- 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>
This commit is contained in:
@@ -80,6 +80,8 @@ class RuntimeData:
|
||||
# Maps a peer address -> the HA conversation_id we opened for it, so
|
||||
# each remote user keeps its own Assist conversation context.
|
||||
self.conversation_ids: dict[str, str] = {}
|
||||
# Senders we've already greeted this session (first-contact greeting).
|
||||
self.greeted: set[str] = set()
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
@@ -236,6 +238,12 @@ def _make_incoming_handler(
|
||||
_LOGGER.debug("Ignoring message from non-allowed sender %s", source)
|
||||
return
|
||||
|
||||
# First-contact greeting: send the configured greeting once per sender.
|
||||
greeting = (options.get(CONF_GREETING) or "").strip()
|
||||
if greeting and source not in runtime.greeted:
|
||||
runtime.greeted.add(source)
|
||||
await _reply(runtime.manager, source, greeting, "Home Assistant")
|
||||
|
||||
if not options.get(CONF_ENABLE_ASSIST, True):
|
||||
return
|
||||
|
||||
|
||||
@@ -12,5 +12,5 @@
|
||||
"loggers": ["RNS", "LXMF"],
|
||||
"requirements": ["rns>=0.9.0", "lxmf>=0.6.0"],
|
||||
"single_config_entry": true,
|
||||
"version": "1.0.5"
|
||||
"version": "1.0.6"
|
||||
}
|
||||
|
||||
@@ -362,9 +362,15 @@ class ReticulumManager:
|
||||
) -> str:
|
||||
"""Send an LXMF message. Returns the message hash (hex)."""
|
||||
dest_hash = self._normalise_hash(destination)
|
||||
return await self.hass.async_add_executor_job(
|
||||
message_hash = await self.hass.async_add_executor_job(
|
||||
self._send, dest_hash, content, title, method, fields
|
||||
)
|
||||
# Count at send time. The delivery callback only fires on a returned
|
||||
# proof, which many peers/methods never send, so counting there would
|
||||
# leave this stuck at 0 even for messages that were delivered fine.
|
||||
self.state.messages_sent += 1
|
||||
self._push_state()
|
||||
return message_hash
|
||||
|
||||
def _send(
|
||||
self,
|
||||
@@ -535,10 +541,10 @@ class ReticulumManager:
|
||||
|
||||
@callback
|
||||
def _on_outbound_delivered(self, message: Any) -> None:
|
||||
# messages_sent is counted at send time (see async_send_message); this
|
||||
# callback only confirms delivery, so it just emits the event.
|
||||
import RNS # noqa: PLC0415
|
||||
|
||||
self.state.messages_sent += 1
|
||||
self._push_state()
|
||||
_fire_event(
|
||||
self.hass,
|
||||
"delivered",
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
"allow_all_senders": "Reply to any sender",
|
||||
"allowed_identities": "Allowed sender addresses",
|
||||
"default_recipient": "Default recipient address (for the notify entity)",
|
||||
"greeting": "Greeting message",
|
||||
"greeting": "First-contact greeting message",
|
||||
"delivery_method": "Default delivery method",
|
||||
"announce_interval": "Announce interval",
|
||||
"propagation_node": "Propagation node address",
|
||||
@@ -48,6 +48,7 @@
|
||||
"enable_assist": "When enabled, incoming LXMF messages are answered by the Assist conversation agent and the reply is sent back over Reticulum.",
|
||||
"allowed_identities": "One address per line (or comma separated). Only used when 'Reply to any sender' is off.",
|
||||
"default_recipient": "16-byte hex LXMF address that the notify.reticulum entity sends to.",
|
||||
"greeting": "Sent automatically the first time each sender messages Home Assistant (once per sender per restart). Leave blank to disable.",
|
||||
"announce_interval": "How often (seconds) to announce our address. 0 disables periodic announces.",
|
||||
"propagation_node": "Optional LXMF propagation node for store-and-forward delivery.",
|
||||
"sync_interval": "How often (seconds) to pull queued messages from the propagation node. 0 disables."
|
||||
@@ -79,7 +80,7 @@
|
||||
"sync": { "name": "Sync propagation node" }
|
||||
},
|
||||
"notify": {
|
||||
"message": { "name": "Message" }
|
||||
"message": { "name": "Send message" }
|
||||
}
|
||||
},
|
||||
"selector": {
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
"allow_all_senders": "Reply to any sender",
|
||||
"allowed_identities": "Allowed sender addresses",
|
||||
"default_recipient": "Default recipient address (for the notify entity)",
|
||||
"greeting": "Greeting message",
|
||||
"greeting": "First-contact greeting message",
|
||||
"delivery_method": "Default delivery method",
|
||||
"announce_interval": "Announce interval",
|
||||
"propagation_node": "Propagation node address",
|
||||
@@ -48,6 +48,7 @@
|
||||
"enable_assist": "When enabled, incoming LXMF messages are answered by the Assist conversation agent and the reply is sent back over Reticulum.",
|
||||
"allowed_identities": "One address per line (or comma separated). Only used when 'Reply to any sender' is off.",
|
||||
"default_recipient": "16-byte hex LXMF address that the notify.reticulum entity sends to.",
|
||||
"greeting": "Sent automatically the first time each sender messages Home Assistant (once per sender per restart). Leave blank to disable.",
|
||||
"announce_interval": "How often (seconds) to announce our address. 0 disables periodic announces.",
|
||||
"propagation_node": "Optional LXMF propagation node for store-and-forward delivery.",
|
||||
"sync_interval": "How often (seconds) to pull queued messages from the propagation node. 0 disables."
|
||||
@@ -79,7 +80,7 @@
|
||||
"sync": { "name": "Sync propagation node" }
|
||||
},
|
||||
"notify": {
|
||||
"message": { "name": "Message" }
|
||||
"message": { "name": "Send message" }
|
||||
}
|
||||
},
|
||||
"selector": {
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
"allow_all_senders": "Отвечать любому отправителю",
|
||||
"allowed_identities": "Разрешённые адреса отправителей",
|
||||
"default_recipient": "Адрес получателя по умолчанию (для сущности notify)",
|
||||
"greeting": "Приветственное сообщение",
|
||||
"greeting": "Приветствие при первом обращении",
|
||||
"delivery_method": "Способ доставки по умолчанию",
|
||||
"announce_interval": "Интервал анонсов",
|
||||
"propagation_node": "Адрес узла ретрансляции (propagation node)",
|
||||
@@ -48,6 +48,7 @@
|
||||
"enable_assist": "Если включено, входящие сообщения LXMF обрабатываются агентом Assist, а ответ отправляется обратно через Reticulum.",
|
||||
"allowed_identities": "По одному адресу в строке (или через запятую). Используется только если «Отвечать любому отправителю» выключено.",
|
||||
"default_recipient": "16-байтовый hex-адрес LXMF, на который отправляет сущность notify.reticulum.",
|
||||
"greeting": "Отправляется автоматически при первом сообщении от каждого отправителя (один раз на отправителя до перезапуска). Оставьте пустым, чтобы отключить.",
|
||||
"announce_interval": "Как часто (в секундах) анонсировать наш адрес. 0 отключает периодические анонсы.",
|
||||
"propagation_node": "Необязательный узел ретрансляции LXMF для доставки по принципу store-and-forward.",
|
||||
"sync_interval": "Как часто (в секундах) забирать сообщения из очереди узла ретрансляции. 0 отключает."
|
||||
@@ -79,7 +80,7 @@
|
||||
"sync": { "name": "Синхронизировать узел ретрансляции" }
|
||||
},
|
||||
"notify": {
|
||||
"message": { "name": "Сообщение" }
|
||||
"message": { "name": "Отправить сообщение" }
|
||||
}
|
||||
},
|
||||
"selector": {
|
||||
|
||||
Reference in New Issue
Block a user