Add uptime sensor and state topics for system and user clients

This commit is contained in:
Edgar P. Burkhart 2025-03-09 23:10:45 +01:00
parent e697a34fca
commit 2c35c39a1c
Signed by: edpibu
GPG key ID: 9833D3C5A25BD227
2 changed files with 28 additions and 0 deletions

View file

@ -66,5 +66,6 @@ def main() -> int:
log.info("Shutting down") log.info("Shutting down")
ha.timer.cancel()
ha.loop_stop() ha.loop_stop()
return 0 return 0

View file

@ -2,6 +2,7 @@ import io
import json import json
import logging import logging
import re import re
from datetime import datetime, timezone
from pathlib import Path from pathlib import Path
from subprocess import run from subprocess import run
from threading import Thread, Timer from threading import Thread, Timer
@ -150,6 +151,10 @@ class HassSystemClient(HassClient):
if code != 0: if code != 0:
log.error(f"Failed to execute command: {cmd}") log.error(f"Failed to execute command: {cmd}")
@property
def state_topic(self) -> str:
return f"{self.node_id}/system/state"
@property @property
def components(self) -> dict[str, dict[str, Any]]: def components(self) -> dict[str, dict[str, Any]]:
return { return {
@ -176,6 +181,14 @@ class HassSystemClient(HassClient):
"icon": "mdi:sleep", "icon": "mdi:sleep",
"payload_press": "SUSPEND", "payload_press": "SUSPEND",
}, },
"uptime": {
"unique_id": f"{self.node_id}_uptime",
"p": "sensor",
"name": "Uptime",
"icon": "mdi:clock",
"device_class": "timestamp",
"value_template": "{{ value_json.uptime|timestamp_utc }}",
},
} }
@property @property
@ -184,8 +197,18 @@ class HassSystemClient(HassClient):
"power": "POWER_OFF" "power": "POWER_OFF"
if Path("/run/systemd/shutdown/scheduled").exists() if Path("/run/systemd/shutdown/scheduled").exists()
else "POWER_ON", else "POWER_ON",
"uptime": self.uptime_value,
} }
@property
def uptime_value(self) -> float | None:
code, out = run_command(["uptime", "--since"])
if code != 0:
log.error("Failed to get uptime")
return None
return datetime.fromisoformat(out.strip()).astimezone(timezone.utc).timestamp()
class HassUserClient(HassClient): class HassUserClient(HassClient):
commands = { commands = {
@ -224,6 +247,10 @@ class HassUserClient(HassClient):
def availability_topic(self) -> str: def availability_topic(self) -> str:
return f"{self.node_id}/user/availability" return f"{self.node_id}/user/availability"
@property
def state_topic(self) -> str:
return f"{self.node_id}/user/state"
@property @property
def components(self) -> dict[str, dict[str, Any]]: def components(self) -> dict[str, dict[str, Any]]:
return { return {