Cleaner discovery topics, ability to specify own node_id
This commit is contained in:
@@ -9,6 +9,7 @@ mqtt:
|
||||
monitor:
|
||||
interval: 15 # seconds between stat publishes
|
||||
device_name: "" # display name in HA; defaults to hostname
|
||||
node_id: "" # MQTT topic slug and unique_id prefix; defaults to hostname if empty
|
||||
|
||||
sensors:
|
||||
cpu: true
|
||||
|
||||
+20
-8
@@ -62,6 +62,7 @@ def load_config(path: Path = CONFIG_PATH) -> dict:
|
||||
mn = cfg["monitor"]
|
||||
mn.setdefault("interval", 30)
|
||||
mn.setdefault("device_name", "")
|
||||
mn.setdefault("node_id", "")
|
||||
|
||||
s = cfg["sensors"]
|
||||
s.setdefault("cpu", True)
|
||||
@@ -711,14 +712,14 @@ class DiscoveryPublisher:
|
||||
def __init__(
|
||||
self,
|
||||
client: mqtt.Client,
|
||||
hostname: str,
|
||||
node_id: str,
|
||||
device_name: str,
|
||||
state_topic: str,
|
||||
availability_topic: str,
|
||||
discovery_prefix: str = "homeassistant",
|
||||
):
|
||||
self._client = client
|
||||
self._hostname = hostname
|
||||
self._node_id = node_id
|
||||
self._device_name = device_name
|
||||
self._state_topic = state_topic
|
||||
self._availability_topic = availability_topic
|
||||
@@ -726,7 +727,7 @@ def __init__(
|
||||
|
||||
def _device_block(self) -> dict:
|
||||
return {
|
||||
"identifiers": [f"{self._hostname}_monitor"],
|
||||
"identifiers": [f"{self._node_id}_monitor"],
|
||||
"name": self._device_name,
|
||||
"manufacturer": "monitor.py",
|
||||
"model": "Linux System Monitor",
|
||||
@@ -740,7 +741,7 @@ def publish_all(self, sensor_defs: list[dict]) -> None:
|
||||
|
||||
def _publish_one(self, defn: dict) -> None:
|
||||
key = defn["key"]
|
||||
unique_id = f"{self._hostname}_{key}"
|
||||
unique_id = f"{self._node_id}_{key}"
|
||||
object_id = unique_id
|
||||
|
||||
payload: dict[str, Any] = {
|
||||
@@ -762,7 +763,7 @@ def _publish_one(self, defn: dict) -> None:
|
||||
payload["icon"] = defn["icon"]
|
||||
|
||||
discovery_topic = (
|
||||
f"{self._discovery_prefix}/sensor/{object_id}/config"
|
||||
f"{self._discovery_prefix}/sensor/{self._node_id}/{object_id}/config"
|
||||
)
|
||||
self._client.publish(
|
||||
discovery_topic,
|
||||
@@ -836,22 +837,24 @@ def __init__(self, cfg: dict):
|
||||
self._cfg = cfg
|
||||
self._hostname = socket.gethostname()
|
||||
self._device_name = cfg["monitor"].get("device_name") or self._hostname
|
||||
raw_node_id = cfg["monitor"].get("node_id", "").strip()
|
||||
self._node_id = self._make_node_id(raw_node_id or self._hostname)
|
||||
self._interval = max(5, int(cfg["monitor"].get("interval", 30)))
|
||||
|
||||
prefix = cfg["mqtt"]["topic_prefix"]
|
||||
self._state_topic, self._avail_topic = make_topics(prefix, self._hostname)
|
||||
self._state_topic, self._avail_topic = make_topics(prefix, self._node_id)
|
||||
|
||||
self._collectors = self._build_collectors()
|
||||
self._sensor_defs = all_sensor_defs(self._collectors, self._hostname)
|
||||
|
||||
self._client = build_client(cfg, self._hostname)
|
||||
self._client = build_client(cfg, self._node_id)
|
||||
self._client.on_connect = self._on_connect
|
||||
self._client.on_disconnect = self._on_disconnect
|
||||
self._client.on_message = self._on_message
|
||||
|
||||
self._discovery = DiscoveryPublisher(
|
||||
self._client,
|
||||
self._hostname,
|
||||
self._node_id,
|
||||
self._device_name,
|
||||
self._state_topic,
|
||||
self._avail_topic,
|
||||
@@ -862,6 +865,15 @@ def __init__(self, cfg: dict):
|
||||
# Warm up cpu_percent (first call always returns 0.0)
|
||||
psutil.cpu_percent(interval=None)
|
||||
|
||||
@staticmethod
|
||||
def _make_node_id(name: str) -> str:
|
||||
"""Sanitize a string for use in MQTT topics and HA unique_ids."""
|
||||
safe = "".join(c if c.isalnum() or c in "-_" else "-" for c in name.lower())
|
||||
# Collapse consecutive hyphens and strip leading/trailing separators
|
||||
while "--" in safe:
|
||||
safe = safe.replace("--", "-")
|
||||
return safe.strip("-_") or "monitor"
|
||||
|
||||
def _build_collectors(self) -> list:
|
||||
s = self._cfg["sensors"]
|
||||
collectors = []
|
||||
|
||||
Reference in New Issue
Block a user