adjusting enabled sensors and sensor types

This commit is contained in:
Constantin Pascal
2025-12-30 09:18:52 +02:00
parent 8d982dd988
commit 1d0cc328c0
4 changed files with 97 additions and 13 deletions
+93 -10
View File
@@ -9,7 +9,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity
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
@@ -22,24 +22,27 @@ async def async_setup_entry(
coordinator = entry.runtime_data
# 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
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:
return
current_slaves = {
entities = []
# Add coil binary sensors for slaves with coil data
current_slaves_coils = {
slave_id
for slave_id, slave_data in coordinator.data.items()
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:
entities = []
for slave_id in new_slaves:
if new_slaves_coils:
for slave_id in new_slaves_coils:
# Create 40 binary sensors (coil1-40) for each slave
for coil_idx in range(COIL_COUNT):
entities.append(
@@ -47,8 +50,26 @@ async def async_setup_entry(
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)
added_slaves.update(new_slaves)
# Subscribe to coordinator updates
entry.async_on_unload(
@@ -116,4 +137,66 @@ class ModbusRTUMonitorCoilSensor(
@property
def extra_state_attributes(self) -> dict[str, int]:
"""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}
+1 -1
View File
@@ -31,7 +31,7 @@ REGISTER_NAMES: dict[int, str] = {
156: "Day of week",
157: "Current temperature",
179: "Outside temperature",
211: "Heating status",
211: "Zone pump",
# Add more registers as discovered
# Example:
# 165: "Register name",
+2 -2
View File
@@ -226,8 +226,8 @@ class ModbusRTUMonitorHub:
self._writer.close()
await self._writer.wait_closed()
# Wait before reconnecting
await asyncio.sleep(5)
# Wait before reconnecting (30 seconds to prevent DDOS during server outages)
await asyncio.sleep(30)
# Attempt reconnection
try:
+1
View File
@@ -16,6 +16,7 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import ModbusRTUMonitorConfigEntry
from .const import (
DOMAIN,
HEATING_STATUS_REGISTER,
MANUFACTURER,
MODEL,
REGISTER_MONITOR_COUNT,