Skip to content

Commit

Permalink
Added hot water switch, active alarm sensor
Browse files Browse the repository at this point in the history
  • Loading branch information
klejejs committed Jan 13, 2022
1 parent dd01ce4 commit ca9c2f5
Show file tree
Hide file tree
Showing 10 changed files with 267 additions and 71 deletions.
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,17 @@ _Component to integrate with [Thermia Heat Pump](https://github.com/klejejs/ha-t
Platform | Description
-- | --
`water_heater` | Thermia Heat Pump integration
`sensor` | Thermia Outside Temperature sensor
`sensor` | Thermia Outside Temperature sensor (if available)
`switch` | Thermia Heat Pump Hot Water Switch (if available)

## Confirmed heat pumps that API supports:
## Confirmed Thermia profiles that API supports:
* Thermia Diplomat / Diplomat Duo
* Thermia iTec


## Confirmed Thermia models that API supports:
* Danfoss DHP-AQ 9

## Setup

To set up Thermia Heat Pump Integration, go to Settings -> Integrations -> Add Integration and search for Thermia Heat Pump.
Expand Down
2 changes: 1 addition & 1 deletion custom_components/thermia/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

from .const import CONF_PASSWORD, CONF_USERNAME, DOMAIN

PLATFORMS: list[str] = ["sensor", "water_heater"]
PLATFORMS: list[str] = ["sensor", "switch", "water_heater"]


_LOGGER = logging.getLogger(__name__)
Expand Down
2 changes: 1 addition & 1 deletion custom_components/thermia/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"@klejejs"
],
"requirements": [
"ThermiaOnlineAPI==2.3"
"ThermiaOnlineAPI==2.5"
],
"version": "1.0",
"iot_class": "cloud_polling",
Expand Down
79 changes: 12 additions & 67 deletions custom_components/thermia/sensor.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
"""Thermia outdoor temperature sensor integration."""
"""Thermia sensor integration."""

from __future__ import annotations

from homeassistant.components.sensor import SensorEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import TEMP_CELSIUS
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity

from .sensors.active_alarms_sensor import ThermiaActiveAlarmsSensor
from .sensors.outdoor_temperature_sensor import ThermiaOutdoorTemperatureSensor

from .const import DOMAIN

Expand All @@ -17,7 +17,7 @@ async def async_setup_entry(
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the Thermia outdoor temperature sensor."""
"""Set up the Thermia sensors."""

coordinator = hass.data[DOMAIN][config_entry.entry_id]

Expand All @@ -28,66 +28,11 @@ async def async_setup_entry(
and heat_pump.outdoor_temperature
]

async_add_entities(hass_thermia_outdoor_temperature_sensors)


class ThermiaOutdoorTemperatureSensor(CoordinatorEntity, SensorEntity):
"""Representation of an Thermia outdoor temperature sensor."""

def __init__(self, coordinator, idx):
super().__init__(coordinator)
self.idx = idx

@property
def available(self):
"""Return True if entity is available."""
return self.coordinator.data.heat_pumps[self.idx].is_online

@property
def name(self):
"""Return the name of the sensor."""
return f"{self.coordinator.data.heat_pumps[self.idx].name} Outdoor Temperature"

@property
def unique_id(self):
"""Return the unique ID of the sensor."""
return f"{self.coordinator.data.heat_pumps[self.idx].name}_outdoor_temperature"

@property
def icon(self):
"""Return the icon of the sensor."""
return "mdi:thermometer"

@property
def device_info(self):
"""Return device information."""
return {
"identifiers": {(DOMAIN, self.coordinator.data.heat_pumps[self.idx].id)},
"name": self.coordinator.data.heat_pumps[self.idx].name,
"manufacturer": "Thermia",
"model": self.coordinator.data.heat_pumps[self.idx].model,
}

@property
def device_class(self):
"""Return the device class."""
return "temperature"

@property
def state_class(self):
"""Return the state class."""
return "measurement"

@property
def native_value(self):
"""Return the temperature of the sensor."""
return self.coordinator.data.heat_pumps[self.idx].outdoor_temperature

@property
def native_unit_of_measurement(self):
"""Return the unit of measurement of the sensor."""
return TEMP_CELSIUS
hass_thermia_active_alarms_sensors = [
ThermiaActiveAlarmsSensor(coordinator, idx)
for idx, _ in enumerate(coordinator.data.heat_pumps)
]

async def async_update(self):
"""Update the sensor."""
await self.coordinator.async_request_refresh()
async_add_entities(
[*hass_thermia_outdoor_temperature_sensors, *hass_thermia_active_alarms_sensors]
)
1 change: 1 addition & 0 deletions custom_components/thermia/sensors/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Thermia Heat Pump Sensors."""
60 changes: 60 additions & 0 deletions custom_components/thermia/sensors/active_alarms_sensor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"""Thermia active alarms sensor integration."""

from __future__ import annotations

from homeassistant.components.sensor import SensorEntity
from homeassistant.helpers.update_coordinator import CoordinatorEntity

from ..const import DOMAIN


class ThermiaActiveAlarmsSensor(CoordinatorEntity, SensorEntity):
"""Representation of an Thermia active alarms sensor."""

def __init__(self, coordinator, idx):
super().__init__(coordinator)
self.idx = idx

@property
def available(self):
"""Return True if entity is available."""
return self.coordinator.data.heat_pumps[self.idx].is_online

@property
def name(self):
"""Return the name of the sensor."""
return f"{self.coordinator.data.heat_pumps[self.idx].name} Active Alarms"

@property
def unique_id(self):
"""Return the unique ID of the sensor."""
return f"{self.coordinator.data.heat_pumps[self.idx].name}_active_alarms"

@property
def icon(self):
"""Return the icon of the sensor."""
return "mdi:bell-alert"

@property
def device_info(self):
"""Return device information."""
return {
"identifiers": {(DOMAIN, self.coordinator.data.heat_pumps[self.idx].id)},
"name": self.coordinator.data.heat_pumps[self.idx].name,
"manufacturer": "Thermia",
"model": self.coordinator.data.heat_pumps[self.idx].model,
}

@property
def state_class(self):
"""Return the state class."""
return "total"

@property
def native_value(self):
"""Return active alarms count of the sensor."""
return self.coordinator.data.heat_pumps[self.idx].active_alarm_count

async def async_update(self):
"""Update the sensor."""
await self.coordinator.async_request_refresh()
71 changes: 71 additions & 0 deletions custom_components/thermia/sensors/outdoor_temperature_sensor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
"""Thermia outdoor temperature sensor integration."""

from __future__ import annotations

from homeassistant.components.sensor import SensorEntity
from homeassistant.const import TEMP_CELSIUS
from homeassistant.helpers.update_coordinator import CoordinatorEntity

from ..const import DOMAIN


class ThermiaOutdoorTemperatureSensor(CoordinatorEntity, SensorEntity):
"""Representation of an Thermia outdoor temperature sensor."""

def __init__(self, coordinator, idx):
super().__init__(coordinator)
self.idx = idx

@property
def available(self):
"""Return True if entity is available."""
return self.coordinator.data.heat_pumps[self.idx].is_online

@property
def name(self):
"""Return the name of the sensor."""
return f"{self.coordinator.data.heat_pumps[self.idx].name} Outdoor Temperature"

@property
def unique_id(self):
"""Return the unique ID of the sensor."""
return f"{self.coordinator.data.heat_pumps[self.idx].name}_outdoor_temperature"

@property
def icon(self):
"""Return the icon of the sensor."""
return "mdi:thermometer"

@property
def device_info(self):
"""Return device information."""
return {
"identifiers": {(DOMAIN, self.coordinator.data.heat_pumps[self.idx].id)},
"name": self.coordinator.data.heat_pumps[self.idx].name,
"manufacturer": "Thermia",
"model": self.coordinator.data.heat_pumps[self.idx].model,
}

@property
def device_class(self):
"""Return the device class."""
return "temperature"

@property
def state_class(self):
"""Return the state class."""
return "measurement"

@property
def native_value(self):
"""Return the temperature of the sensor."""
return self.coordinator.data.heat_pumps[self.idx].outdoor_temperature

@property
def native_unit_of_measurement(self):
"""Return the unit of measurement of the sensor."""
return TEMP_CELSIUS

async def async_update(self):
"""Update the sensor."""
await self.coordinator.async_request_refresh()
30 changes: 30 additions & 0 deletions custom_components/thermia/switch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""Thermia switch integration."""

from __future__ import annotations

from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from .switches.hot_water_switch import ThermiaHotWaterSwitch

from .const import DOMAIN


async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the Thermia switches."""

coordinator = hass.data[DOMAIN][config_entry.entry_id]

hass_thermia_hot_water_switches = [
ThermiaHotWaterSwitch(coordinator, idx)
for idx, heat_pump in enumerate(coordinator.data.heat_pumps)
if heat_pump.is_hot_water_switch_available
and heat_pump.hot_water_switch_state is not None
]

async_add_entities(hass_thermia_hot_water_switches)
1 change: 1 addition & 0 deletions custom_components/thermia/switches/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Thermia Heat Pump Switches."""
83 changes: 83 additions & 0 deletions custom_components/thermia/switches/hot_water_switch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
"""Thermia hot water switch integration."""

from __future__ import annotations

from homeassistant.components.switch import SwitchEntity
from homeassistant.helpers.update_coordinator import CoordinatorEntity

from ..const import DOMAIN


class ThermiaHotWaterSwitch(CoordinatorEntity, SwitchEntity):
"""Representation of an Thermia hot water switch."""

def __init__(self, coordinator, idx):
super().__init__(coordinator)
self.idx = idx

@property
def available(self):
"""Return True if entity is available."""
return self.coordinator.data.heat_pumps[self.idx].is_online

@property
def name(self):
"""Return the name of the switch."""
return f"{self.coordinator.data.heat_pumps[self.idx].name} Hot Water"

@property
def unique_id(self):
"""Return the unique ID of the switch."""
return f"{self.coordinator.data.heat_pumps[self.idx].name}_hot_water"

@property
def icon(self):
"""Return the icon of the switch."""
return "mdi:water-boiler"

@property
def device_info(self):
"""Return device information."""
return {
"identifiers": {(DOMAIN, self.coordinator.data.heat_pumps[self.idx].id)},
"name": self.coordinator.data.heat_pumps[self.idx].name,
"manufacturer": "Thermia",
"model": self.coordinator.data.heat_pumps[self.idx].model,
}

@property
def device_class(self):
"""Return the device class of the switch."""
return "switch"

@property
def is_on(self):
"""Return true if switch is on."""
return self.coordinator.data.heat_pumps[self.idx].hot_water_switch_state == 1

async def async_turn_on(self, **kwargs):
"""Turn on the switch."""
await self.hass.async_add_executor_job(
lambda: self.coordinator.data.heat_pumps[
self.idx
].set_hot_water_switch_state(1)
)

async def async_turn_off(self, **kwargs):
"""Turn off the switch."""
await self.hass.async_add_executor_job(
lambda: self.coordinator.data.heat_pumps[
self.idx
].set_hot_water_switch_state(0)
)

async def async_toggle(self, **kwargs):
"""Toggle the switch."""
if self.is_on:
await self.async_turn_off()
else:
await self.async_turn_on()

async def async_update(self):
"""Update the switch."""
await self.coordinator.async_request_refresh()

0 comments on commit ca9c2f5

Please sign in to comment.