mqtt: push Klipper status updates after subscription

This resolves an issue where MQTT clients miss the first status
update after a Klipper restart.

Signed-off-by:  Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
Eric Callahan 2025-02-07 06:15:26 -05:00
parent b8388db18d
commit fb6e416e1c
No known key found for this signature in database
GPG Key ID: 5A1EB336DFB4C71B
2 changed files with 14 additions and 6 deletions

View File

@ -266,12 +266,15 @@ class KlippyAPI(APITransport):
objects: Mapping[str, Optional[List[str]]],
transport: APITransport,
default: Union[Sentinel, _T] = Sentinel.MISSING,
full_response: bool = False
) -> Union[_T, Dict[str, Any]]:
params = {"objects": dict(objects)}
result = await self._send_klippy_request(
SUBSCRIPTION_ENDPOINT, params, default, transport
)
if isinstance(result, dict) and "status" in result:
if full_response:
return result
return result["status"]
if default is not Sentinel.MISSING:
return default

View File

@ -453,9 +453,13 @@ class MQTTClient(APITransport):
async def _handle_klippy_started(self, state: KlippyState) -> None:
if self.status_objs:
kapi: KlippyAPI = self.server.lookup_component("klippy_apis")
await kapi.subscribe_from_transport(
self.status_objs, self, default=None,
result = await kapi.subscribe_from_transport(
self.status_objs, self, default=None, full_response=True
)
if result is not None:
status: Dict[str, Any] = result["status"]
eventtime: float = result["eventtime"]
self.send_status(status, eventtime)
if self.status_update_timer is not None:
self.status_update_timer.start(delay=self.status_interval)
@ -496,7 +500,7 @@ class MQTTClient(APITransport):
{'server': 'online'}, retain=True)
subs = [(k, v[0]) for k, v in self.subscribed_topics.items()]
if subs:
res, msg_id = client.subscribe(subs)
_, msg_id = client.subscribe(subs)
if msg_id is not None:
sub_fut: asyncio.Future = self.eventloop.create_future()
topics = list(self.subscribed_topics.keys())
@ -618,7 +622,7 @@ class MQTTClient(APITransport):
need_sub = qos != prev_qos
self.subscribed_topics[topic] = (qos, sub_handles)
if self.is_connected() and need_sub:
res, msg_id = self.client.subscribe(topic, qos)
_, msg_id = self.client.subscribe(topic, qos)
if msg_id is not None:
sub_fut: asyncio.Future = self.eventloop.create_future()
sub_fut.add_done_callback(
@ -636,7 +640,7 @@ class MQTTClient(APITransport):
pass
if not sub_hdls:
del self.subscribed_topics[topic]
res, msg_id = self.client.unsubscribe(topic)
_, msg_id = self.client.unsubscribe(topic)
if msg_id is not None:
unsub_fut: asyncio.Future = self.eventloop.create_future()
unsub_fut.add_done_callback(
@ -814,7 +818,8 @@ class MQTTClient(APITransport):
payload = {'eventtime': eventtime, 'value': objval[statekey]}
self.publish_topic(
f"{self.klipper_state_prefix}/{objkey}/{statekey}",
payload, retain=True)
payload, retain=True
)
else:
payload = {'eventtime': eventtime, 'status': status}
self.publish_topic(self.klipper_status_topic, payload)