Dedicated hardware poller + read-only consumers #4
@@ -80,7 +80,10 @@ class MqttPublisher:
|
|||||||
self.discovery_prefix = os.environ.get("MQTT_DISCOVERY_PREFIX", "homeassistant")
|
self.discovery_prefix = os.environ.get("MQTT_DISCOVERY_PREFIX", "homeassistant")
|
||||||
self.base_topic = os.environ.get("MQTT_BASE_TOPIC", "jbod-monitor")
|
self.base_topic = os.environ.get("MQTT_BASE_TOPIC", "jbod-monitor")
|
||||||
self.interval = int(os.environ.get("MQTT_PUBLISH_INTERVAL", "60"))
|
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"
|
self.availability_topic = f"{self.base_topic}/{self.node}/status"
|
||||||
# unique_ids for which we've already published discovery this connection.
|
# unique_ids for which we've already published discovery this connection.
|
||||||
@@ -127,6 +130,16 @@ class MqttPublisher:
|
|||||||
logger.warning("MQTT disconnected: %s", reason_code)
|
logger.warning("MQTT disconnected: %s", reason_code)
|
||||||
|
|
||||||
# discovery / state ------------------------------------------------------
|
# 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:
|
def _device_block(self, enc: dict) -> dict:
|
||||||
enc_id = enc["id"]
|
enc_id = enc["id"]
|
||||||
vendor = enc.get("vendor", "").strip()
|
vendor = enc.get("vendor", "").strip()
|
||||||
@@ -137,9 +150,29 @@ class MqttPublisher:
|
|||||||
"name": f"JBOD {name} ({enc_id})",
|
"name": f"JBOD {name} ({enc_id})",
|
||||||
"manufacturer": vendor or None,
|
"manufacturer": vendor or None,
|
||||||
"model": model 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:
|
def _publish_discovery(self, enc: dict) -> None:
|
||||||
enc_id = enc["id"]
|
enc_id = enc["id"]
|
||||||
enc_slug = _slug(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)
|
self._client.publish(state_topic, json.dumps(payload), qos=0, retain=True)
|
||||||
|
|
||||||
def publish_snapshot(self, snapshot: dict) -> None:
|
def publish_snapshot(self, snapshot: dict) -> None:
|
||||||
|
self._publish_hub() # name the parent device before nesting enclosures
|
||||||
for enc in snapshot.get("enclosures", []):
|
for enc in snapshot.get("enclosures", []):
|
||||||
self._publish_discovery(enc)
|
self._publish_discovery(enc)
|
||||||
self._publish_state(enc)
|
self._publish_state(enc)
|
||||||
|
|||||||
Reference in New Issue
Block a user