Skip to content

Commit

Permalink
Fix/add ability to operate two or more instances of the integration
Browse files Browse the repository at this point in the history
  • Loading branch information
ylabonte committed Feb 11, 2024
1 parent 877deea commit 6afb0c7
Show file tree
Hide file tree
Showing 11 changed files with 305 additions and 120 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@

<!---->

## Changelog

### Version 1.2.0 (2024-02-12)
WARNING: This update will create new entities. I could not find a way to remove the old entities programatically, so I apologize, but you will have to remove the obsolete entities manually (you can easily filter for them and remove all at once).

* Require Home Assistant Core 2024.2.1 or newer.
* Fix configuration/setup bug (issue #28).
* Fix multi instance support.

## Support for this integration

If you have trouble with this integration and want to get support, you can open an [issue on github][issues], so others
Expand Down
180 changes: 140 additions & 40 deletions custom_components/proconip_pool_controller/binary_sensor.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,65 @@
"""Binary sensor platform for ProCon.IP Pool Controller."""

from __future__ import annotations

from homeassistant.core import HomeAssistant
from homeassistant.config_entries import ConfigEntry
from homeassistant.components.binary_sensor import BinarySensorEntity
from homeassistant.helpers.entity_platform import AddEntitiesCallback


from .const import DOMAIN
from .coordinator import ProconipPoolControllerDataUpdateCoordinator
from .entity import ProconipPoolControllerEntity


async def async_setup_entry(hass, entry, async_add_devices):
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_devices: AddEntitiesCallback
) -> None:
"""Set up the binary_sensor platform."""
coordinator = hass.data[DOMAIN][entry.entry_id]

async_add_devices(
[
ProconipChlorineDosageEnabledBinarySensor(coordinator),
ProconipElectrolysisEnabledBinarySensor(coordinator),
ProconipPhMinusDosageEnabledBinarySensor(coordinator),
ProconipPhPlusDosageEnabledBinarySensor(coordinator),
ProconipTcpIpBoostEnabledBinarySensor(coordinator),
ProconipSdCardEnabledBinarySensor(coordinator),
ProconipDmxEnabledBinarySensor(coordinator),
ProconipAvatarEnabledBinarySensor(coordinator),
ProconipRelayExtensionEnabledBinarySensor(coordinator),
ProconipHighBusLoadEnabledBinarySensor(coordinator),
ProconipFlowSensorEnabledBinarySensor(coordinator),
ProconipRepeatedMailEnabledBinarySensor(coordinator),
ProconipDmxExtensionEnabledBinarySensor(coordinator),
ProconipChlorineDosageEnabledBinarySensor(
coordinator=coordinator, instance_id=entry.entry_id
),
ProconipElectrolysisEnabledBinarySensor(
coordinator=coordinator, instance_id=entry.entry_id
),
ProconipPhMinusDosageEnabledBinarySensor(
coordinator=coordinator, instance_id=entry.entry_id
),
ProconipPhPlusDosageEnabledBinarySensor(
coordinator=coordinator, instance_id=entry.entry_id
),
ProconipTcpIpBoostEnabledBinarySensor(
coordinator=coordinator, instance_id=entry.entry_id
),
ProconipSdCardEnabledBinarySensor(
coordinator=coordinator, instance_id=entry.entry_id
),
ProconipDmxEnabledBinarySensor(
coordinator=coordinator, instance_id=entry.entry_id
),
ProconipAvatarEnabledBinarySensor(
coordinator=coordinator, instance_id=entry.entry_id
),
ProconipRelayExtensionEnabledBinarySensor(
coordinator=coordinator, instance_id=entry.entry_id
),
ProconipHighBusLoadEnabledBinarySensor(
coordinator=coordinator, instance_id=entry.entry_id
),
ProconipFlowSensorEnabledBinarySensor(
coordinator=coordinator, instance_id=entry.entry_id
),
ProconipRepeatedMailEnabledBinarySensor(
coordinator=coordinator, instance_id=entry.entry_id
),
ProconipDmxExtensionEnabledBinarySensor(
coordinator=coordinator, instance_id=entry.entry_id
),
]
)

Expand All @@ -36,10 +71,15 @@ class ProconipChlorineDosageEnabledBinarySensor(

_attr_name = "Chlorine Dosage enabled"
_attr_icon = "mdi:check-circle"
_attr_unique_id = "is_chlorine_dosage_enabled"

def __init__(
self, coordinator: ProconipPoolControllerDataUpdateCoordinator, instance_id: str
) -> None:
super().__init__(coordinator=coordinator)
self._attr_unique_id = f"is_chlorine_dosage_enabled_{instance_id}"

@property
def is_on(self):
def is_on(self) -> bool:
"""Return true if the binary_sensor is on."""
return self.coordinator.data.is_chlorine_dosage_enabled()

Expand All @@ -51,10 +91,15 @@ class ProconipElectrolysisEnabledBinarySensor(

_attr_name = "Electrolysis enabled"
_attr_icon = "mdi:check-circle"
_attr_unique_id = "is_electrolysis_enabled"

def __init__(
self, coordinator: ProconipPoolControllerDataUpdateCoordinator, instance_id: str
) -> None:
super().__init__(coordinator=coordinator)
self._attr_unique_id = f"is_electrolysis_enabled_{instance_id}"

@property
def is_on(self):
def is_on(self) -> bool:
"""Return true if the binary_sensor is on."""
return self.coordinator.data.is_electrolysis_enabled()

Expand All @@ -66,10 +111,15 @@ class ProconipPhMinusDosageEnabledBinarySensor(

_attr_name = "pH Minus Dosage enabled"
_attr_icon = "mdi:check-circle"
_attr_unique_id = "is_ph_minus_dosage_enabled"

def __init__(
self, coordinator: ProconipPoolControllerDataUpdateCoordinator, instance_id: str
) -> None:
super().__init__(coordinator=coordinator)
self._attr_unique_id = f"is_ph_minus_dosage_enabled_{instance_id}"

@property
def is_on(self):
def is_on(self) -> bool:
"""Return true if the binary_sensor is on."""
return self.coordinator.data.is_ph_minus_dosage_enabled()

Expand All @@ -81,10 +131,15 @@ class ProconipPhPlusDosageEnabledBinarySensor(

_attr_name = "pH Plus Dosage enabled"
_attr_icon = "mdi:check-circle"
_attr_unique_id = "is_ph_plus_dosage_enabled"

def __init__(
self, coordinator: ProconipPoolControllerDataUpdateCoordinator, instance_id: str
) -> None:
super().__init__(coordinator=coordinator)
self._attr_unique_id = f"is_ph_plus_dosage_enabled_{instance_id}"

@property
def is_on(self):
def is_on(self) -> bool:
"""Return true if the binary_sensor is on."""
return self.coordinator.data.is_ph_plus_dosage_enabled()

Expand All @@ -96,10 +151,15 @@ class ProconipTcpIpBoostEnabledBinarySensor(

_attr_name = "TCP/IP Boost enabled"
_attr_icon = "mdi:check-circle"
_attr_unique_id = "is_tcpip_boost_enabled"

def __init__(
self, coordinator: ProconipPoolControllerDataUpdateCoordinator, instance_id: str
) -> None:
super().__init__(coordinator=coordinator)
self._attr_unique_id = f"is_tcpip_boost_enabled_{instance_id}"

@property
def is_on(self):
def is_on(self) -> bool:
"""Return true if the binary_sensor is on."""
return self.coordinator.data.is_tcpip_boost_enabled()

Expand All @@ -111,10 +171,15 @@ class ProconipSdCardEnabledBinarySensor(

_attr_name = "SD Card enabled"
_attr_icon = "mdi:check-circle"
_attr_unique_id = "is_sd_card_enabled"

def __init__(
self, coordinator: ProconipPoolControllerDataUpdateCoordinator, instance_id: str
) -> None:
super().__init__(coordinator=coordinator)
self._attr_unique_id = f"is_sd_card_enabled_{instance_id}"

@property
def is_on(self):
def is_on(self) -> bool:
"""Return true if the binary_sensor is on."""
return self.coordinator.data.is_sd_card_enabled()

Expand All @@ -124,10 +189,15 @@ class ProconipDmxEnabledBinarySensor(ProconipPoolControllerEntity, BinarySensorE

_attr_name = "DMX enabled"
_attr_icon = "mdi:check-circle"
_attr_unique_id = "is_dmx_enabled"

def __init__(
self, coordinator: ProconipPoolControllerDataUpdateCoordinator, instance_id: str
) -> None:
super().__init__(coordinator=coordinator)
self._attr_unique_id = f"is_dmx_enabled_{instance_id}"

@property
def is_on(self):
def is_on(self) -> bool:
"""Return true if the binary_sensor is on."""
return self.coordinator.data.is_dmx_enabled()

Expand All @@ -139,10 +209,15 @@ class ProconipAvatarEnabledBinarySensor(

_attr_name = "Avatar enabled"
_attr_icon = "mdi:check-circle"
_attr_unique_id = "is_avatar_enabled"

def __init__(
self, coordinator: ProconipPoolControllerDataUpdateCoordinator, instance_id: str
) -> None:
super().__init__(coordinator=coordinator)
self._attr_unique_id = f"is_avatar_enabled_{instance_id}"

@property
def is_on(self):
def is_on(self) -> bool:
"""Return true if the binary_sensor is on."""
return self.coordinator.data.is_avatar_enabled()

Expand All @@ -154,10 +229,15 @@ class ProconipRelayExtensionEnabledBinarySensor(

_attr_name = "Relay Extension enabled"
_attr_icon = "mdi:check-circle"
_attr_unique_id = "is_relay_extension_enabled"

def __init__(
self, coordinator: ProconipPoolControllerDataUpdateCoordinator, instance_id: str
) -> None:
super().__init__(coordinator=coordinator)
self._attr_unique_id = f"is_relay_extension_enabled_{instance_id}"

@property
def is_on(self):
def is_on(self) -> bool:
"""Return true if the binary_sensor is on."""
return self.coordinator.data.is_relay_extension_enabled()

Expand All @@ -169,10 +249,15 @@ class ProconipHighBusLoadEnabledBinarySensor(

_attr_name = "High Bus Load enabled"
_attr_icon = "mdi:check-circle"
_attr_unique_id = "is_high_bus_load_enabled"

def __init__(
self, coordinator: ProconipPoolControllerDataUpdateCoordinator, instance_id: str
) -> None:
super().__init__(coordinator=coordinator)
self._attr_unique_id = f"is_high_bus_load_enabled_{instance_id}"

@property
def is_on(self):
def is_on(self) -> bool:
"""Return true if the binary_sensor is on."""
return self.coordinator.data.is_high_bus_load_enabled()

Expand All @@ -184,10 +269,15 @@ class ProconipFlowSensorEnabledBinarySensor(

_attr_name = "Flow Sensor enabled"
_attr_icon = "mdi:check-circle"
_attr_unique_id = "is_flow_sensor_enabled"

def __init__(
self, coordinator: ProconipPoolControllerDataUpdateCoordinator, instance_id: str
) -> None:
super().__init__(coordinator=coordinator)
self._attr_unique_id = f"is_flow_sensor_enabled_{instance_id}"

@property
def is_on(self):
def is_on(self) -> bool:
"""Return true if the binary_sensor is on."""
return self.coordinator.data.is_flow_sensor_enabled()

Expand All @@ -199,10 +289,15 @@ class ProconipRepeatedMailEnabledBinarySensor(

_attr_name = "Repeated Mails enabled"
_attr_icon = "mdi:check-circle"
_attr_unique_id = "is_repeated_mails_enabled"

def __init__(
self, coordinator: ProconipPoolControllerDataUpdateCoordinator, instance_id: str
) -> None:
super().__init__(coordinator=coordinator)
self._attr_unique_id = f"is_repeated_mails_enabled_{instance_id}"

@property
def is_on(self):
def is_on(self) -> bool:
"""Return true if the binary_sensor is on."""
return self.coordinator.data.is_repeated_mails_enabled()

Expand All @@ -214,9 +309,14 @@ class ProconipDmxExtensionEnabledBinarySensor(

_attr_name = "DMX Extension enabled"
_attr_icon = "mdi:check-circle"
_attr_unique_id = "is_dmx_extension_enabled"

def __init__(
self, coordinator: ProconipPoolControllerDataUpdateCoordinator, instance_id: str
) -> None:
super().__init__(coordinator=coordinator)
self._attr_unique_id = f"is_dmx_extension_enabled_{instance_id}"

@property
def is_on(self):
def is_on(self) -> bool:
"""Return true if the binary_sensor is on."""
return self.coordinator.data.is_dmx_extension_enabled()
3 changes: 2 additions & 1 deletion custom_components/proconip_pool_controller/const.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
"""Constants for proconip."""

from logging import Logger, getLogger

LOGGER: Logger = getLogger(__package__)

NAME = "ProCon.IP Pool Controller"
DOMAIN = "proconip_pool_controller"
VERSION = "1.1.0"
VERSION = "1.2.0"
ATTRIBUTION = (
"Data provided by your Pool Digital ProCon.IP (https://www.pooldigital.de)"
)
3 changes: 2 additions & 1 deletion custom_components/proconip_pool_controller/coordinator.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""DataUpdateCoordinator for ProCon.IP Pool Controller."""

from __future__ import annotations

from datetime import timedelta
Expand Down Expand Up @@ -51,7 +52,7 @@ def __init__(

async def proconip_update_method(self) -> GetStateData:
"""Update data via library."""
data: GetStateData = None
data: GetStateData | None = None
try:
data = await self.client.async_get_data()
except BadCredentialsException as exception:
Expand Down
1 change: 1 addition & 0 deletions custom_components/proconip_pool_controller/entity.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""BlueprintEntity class."""

from __future__ import annotations

from homeassistant.helpers.entity import DeviceInfo
Expand Down
6 changes: 3 additions & 3 deletions custom_components/proconip_pool_controller/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"iot_class": "local_polling",
"issue_tracker": "https://github.com/ylabonte/proconip-hass/issues",
"requirements": [
"proconip==1.3.0"
"proconip>=1.3.0"
],
"version": "1.1.0"
}
"version": "1.2.0"
}
Loading

0 comments on commit 6afb0c7

Please sign in to comment.