adjusting enabled sensors and sensor types
This commit is contained in:
+93
-10
@@ -9,7 +9,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
|
||||||
from . import ModbusRTUMonitorConfigEntry
|
from . import ModbusRTUMonitorConfigEntry
|
||||||
from .const import COIL_COUNT, DOMAIN, MANUFACTURER, MODEL
|
from .const import COIL_COUNT, DOMAIN, HEATING_STATUS_REGISTER, MANUFACTURER, MODEL
|
||||||
from .coordinator import ModbusRTUMonitorCoordinator
|
from .coordinator import ModbusRTUMonitorCoordinator
|
||||||
|
|
||||||
|
|
||||||
@@ -22,24 +22,27 @@ async def async_setup_entry(
|
|||||||
coordinator = entry.runtime_data
|
coordinator = entry.runtime_data
|
||||||
|
|
||||||
# Track which slaves have binary sensor entities
|
# Track which slaves have binary sensor entities
|
||||||
added_slaves: set[int] = set()
|
added_slaves_coils: set[int] = set()
|
||||||
|
added_slaves_zone_pump: set[int] = set()
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def _async_add_binary_sensor_entities() -> None:
|
def _async_add_binary_sensor_entities() -> None:
|
||||||
"""Add binary sensor entities for newly discovered slaves with coil data."""
|
"""Add binary sensor entities for newly discovered slaves."""
|
||||||
if coordinator.data is None:
|
if coordinator.data is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
current_slaves = {
|
entities = []
|
||||||
|
|
||||||
|
# Add coil binary sensors for slaves with coil data
|
||||||
|
current_slaves_coils = {
|
||||||
slave_id
|
slave_id
|
||||||
for slave_id, slave_data in coordinator.data.items()
|
for slave_id, slave_data in coordinator.data.items()
|
||||||
if slave_data.coils is not None
|
if slave_data.coils is not None
|
||||||
}
|
}
|
||||||
new_slaves = current_slaves - added_slaves
|
new_slaves_coils = current_slaves_coils - added_slaves_coils
|
||||||
|
|
||||||
if new_slaves:
|
if new_slaves_coils:
|
||||||
entities = []
|
for slave_id in new_slaves_coils:
|
||||||
for slave_id in new_slaves:
|
|
||||||
# Create 40 binary sensors (coil1-40) for each slave
|
# Create 40 binary sensors (coil1-40) for each slave
|
||||||
for coil_idx in range(COIL_COUNT):
|
for coil_idx in range(COIL_COUNT):
|
||||||
entities.append(
|
entities.append(
|
||||||
@@ -47,8 +50,26 @@ async def async_setup_entry(
|
|||||||
coordinator, slave_id, coil_idx + 1
|
coordinator, slave_id, coil_idx + 1
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
added_slaves_coils.update(new_slaves_coils)
|
||||||
|
|
||||||
|
# Add zone pump binary sensor for slaves with register data
|
||||||
|
current_slaves_zone_pump = {
|
||||||
|
slave_id
|
||||||
|
for slave_id, slave_data in coordinator.data.items()
|
||||||
|
if slave_data.registers is not None
|
||||||
|
and HEATING_STATUS_REGISTER in slave_data.registers
|
||||||
|
}
|
||||||
|
new_slaves_zone_pump = current_slaves_zone_pump - added_slaves_zone_pump
|
||||||
|
|
||||||
|
if new_slaves_zone_pump:
|
||||||
|
for slave_id in new_slaves_zone_pump:
|
||||||
|
entities.append(
|
||||||
|
ModbusRTUMonitorZonePumpSensor(coordinator, slave_id)
|
||||||
|
)
|
||||||
|
added_slaves_zone_pump.update(new_slaves_zone_pump)
|
||||||
|
|
||||||
|
if entities:
|
||||||
async_add_entities(entities)
|
async_add_entities(entities)
|
||||||
added_slaves.update(new_slaves)
|
|
||||||
|
|
||||||
# Subscribe to coordinator updates
|
# Subscribe to coordinator updates
|
||||||
entry.async_on_unload(
|
entry.async_on_unload(
|
||||||
@@ -116,4 +137,66 @@ class ModbusRTUMonitorCoilSensor(
|
|||||||
@property
|
@property
|
||||||
def extra_state_attributes(self) -> dict[str, int]:
|
def extra_state_attributes(self) -> dict[str, int]:
|
||||||
"""Return additional state attributes."""
|
"""Return additional state attributes."""
|
||||||
return {"coil_number": self._coil_number}
|
return {"coil_number": self._coil_number}
|
||||||
|
|
||||||
|
|
||||||
|
class ModbusRTUMonitorZonePumpSensor(
|
||||||
|
CoordinatorEntity[ModbusRTUMonitorCoordinator], BinarySensorEntity
|
||||||
|
):
|
||||||
|
"""Binary sensor entity for zone pump status."""
|
||||||
|
|
||||||
|
_attr_has_entity_name = True
|
||||||
|
_attr_name = "Zone pump" # User-friendly name
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
coordinator: ModbusRTUMonitorCoordinator,
|
||||||
|
slave_id: int,
|
||||||
|
) -> None:
|
||||||
|
"""Initialize zone pump binary sensor."""
|
||||||
|
super().__init__(coordinator)
|
||||||
|
|
||||||
|
self._slave_id = slave_id
|
||||||
|
|
||||||
|
self._attr_unique_id = (
|
||||||
|
f"{coordinator.config_entry.entry_id}_{slave_id}_zone_pump"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Device info (groups with climate and humidity sensor)
|
||||||
|
self._attr_device_info = DeviceInfo(
|
||||||
|
identifiers={(DOMAIN, f"{coordinator.config_entry.entry_id}_{slave_id}")},
|
||||||
|
name=f"Modbus Slave {slave_id}",
|
||||||
|
manufacturer=MANUFACTURER,
|
||||||
|
model=MODEL,
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def available(self) -> bool:
|
||||||
|
"""Return if entity is available."""
|
||||||
|
if self._slave_id not in self.coordinator.data:
|
||||||
|
return False
|
||||||
|
slave_data = self.coordinator.data[self._slave_id]
|
||||||
|
if not slave_data.available or slave_data.registers is None:
|
||||||
|
return False
|
||||||
|
return HEATING_STATUS_REGISTER in slave_data.registers
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_on(self) -> bool | None:
|
||||||
|
"""Return true if the zone pump is on (register value = 1)."""
|
||||||
|
if self._slave_id not in self.coordinator.data:
|
||||||
|
return None
|
||||||
|
slave_data = self.coordinator.data[self._slave_id]
|
||||||
|
if slave_data.registers is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
zone_pump_value = slave_data.registers.get(HEATING_STATUS_REGISTER)
|
||||||
|
if zone_pump_value is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# ON if register value is 1, OFF otherwise
|
||||||
|
return zone_pump_value == 1
|
||||||
|
|
||||||
|
@property
|
||||||
|
def extra_state_attributes(self) -> dict[str, int]:
|
||||||
|
"""Return additional state attributes."""
|
||||||
|
return {"register_address": HEATING_STATUS_REGISTER}
|
||||||
@@ -31,7 +31,7 @@ REGISTER_NAMES: dict[int, str] = {
|
|||||||
156: "Day of week",
|
156: "Day of week",
|
||||||
157: "Current temperature",
|
157: "Current temperature",
|
||||||
179: "Outside temperature",
|
179: "Outside temperature",
|
||||||
211: "Heating status",
|
211: "Zone pump",
|
||||||
# Add more registers as discovered
|
# Add more registers as discovered
|
||||||
# Example:
|
# Example:
|
||||||
# 165: "Register name",
|
# 165: "Register name",
|
||||||
|
|||||||
@@ -226,8 +226,8 @@ class ModbusRTUMonitorHub:
|
|||||||
self._writer.close()
|
self._writer.close()
|
||||||
await self._writer.wait_closed()
|
await self._writer.wait_closed()
|
||||||
|
|
||||||
# Wait before reconnecting
|
# Wait before reconnecting (30 seconds to prevent DDOS during server outages)
|
||||||
await asyncio.sleep(5)
|
await asyncio.sleep(30)
|
||||||
|
|
||||||
# Attempt reconnection
|
# Attempt reconnection
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
|||||||
from . import ModbusRTUMonitorConfigEntry
|
from . import ModbusRTUMonitorConfigEntry
|
||||||
from .const import (
|
from .const import (
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
|
HEATING_STATUS_REGISTER,
|
||||||
MANUFACTURER,
|
MANUFACTURER,
|
||||||
MODEL,
|
MODEL,
|
||||||
REGISTER_MONITOR_COUNT,
|
REGISTER_MONITOR_COUNT,
|
||||||
|
|||||||
Reference in New Issue
Block a user