Dedicated hardware poller + read-only consumers #4
@@ -80,7 +80,10 @@ class MqttPublisher:
|
||||
self.discovery_prefix = os.environ.get("MQTT_DISCOVERY_PREFIX", "homeassistant")
|
||||
self.base_topic = os.environ.get("MQTT_BASE_TOPIC", "jbod-monitor")
|
||||
self.interval = int(os.environ.get("MQTT_PUBLISH_INTERVAL", "60"))
|
||||
self.node = _slug(get_node_id())
|
||||
self.node_raw = get_node_id()
|
||||
self.node = _slug(self.node_raw)
|
||||
# Parent "hub" device that the per-enclosure devices nest under.
|
||||
self.hub_id = f"{self.node}_jbod_monitor"
|
||||
|
||||
self.availability_topic = f"{self.base_topic}/{self.node}/status"
|
||||
# unique_ids for which we've already published discovery this connection.
|
||||
@@ -127,6 +130,16 @@ class MqttPublisher:
|
||||
logger.warning("MQTT disconnected: %s", reason_code)
|
||||
|
||||
# discovery / state ------------------------------------------------------
|
||||
def _hub_device_block(self) -> dict:
|
||||
"""The parent device the enclosures nest under (named, so HA doesn't
|
||||
show an 'Unnamed Device')."""
|
||||
return {
|
||||
"identifiers": [self.hub_id],
|
||||
"name": f"JBOD Monitor ({self.node_raw})",
|
||||
"manufacturer": "jbod-monitor",
|
||||
"model": "SES/SMART poller",
|
||||
}
|
||||
|
||||
def _device_block(self, enc: dict) -> dict:
|
||||
enc_id = enc["id"]
|
||||
vendor = enc.get("vendor", "").strip()
|
||||
@@ -137,9 +150,29 @@ class MqttPublisher:
|
||||
"name": f"JBOD {name} ({enc_id})",
|
||||
"manufacturer": vendor or None,
|
||||
"model": model or None,
|
||||
"via_device": f"{self.node}_jbod_monitor",
|
||||
"via_device": self.hub_id,
|
||||
}
|
||||
|
||||
def _publish_hub(self) -> None:
|
||||
"""Announce the hub device via a connectivity binary_sensor, so the
|
||||
parent device is named and shows monitor online/offline status."""
|
||||
uid = f"{self.hub_id}_status"
|
||||
if uid in self._discovered:
|
||||
return
|
||||
payload = {
|
||||
"name": "Status",
|
||||
"unique_id": uid,
|
||||
"device_class": "connectivity",
|
||||
"state_topic": self.availability_topic,
|
||||
"payload_on": "online",
|
||||
"payload_off": "offline",
|
||||
"entity_category": "diagnostic",
|
||||
"device": self._hub_device_block(),
|
||||
}
|
||||
topic = f"{self.discovery_prefix}/binary_sensor/{self.hub_id}/status/config"
|
||||
self._client.publish(topic, json.dumps(payload), qos=1, retain=True)
|
||||
self._discovered.add(uid)
|
||||
|
||||
def _publish_discovery(self, enc: dict) -> None:
|
||||
enc_id = enc["id"]
|
||||
enc_slug = _slug(enc_id)
|
||||
@@ -204,6 +237,7 @@ class MqttPublisher:
|
||||
self._client.publish(state_topic, json.dumps(payload), qos=0, retain=True)
|
||||
|
||||
def publish_snapshot(self, snapshot: dict) -> None:
|
||||
self._publish_hub() # name the parent device before nesting enclosures
|
||||
for enc in snapshot.get("enclosures", []):
|
||||
self._publish_discovery(enc)
|
||||
self._publish_state(enc)
|
||||
|
||||
Reference in New Issue
Block a user