Skip to content
Open
7 changes: 4 additions & 3 deletions custom_components/aquanta/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from datetime import timedelta
import async_timeout

from aquanta import Aquanta
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import (
Expand All @@ -21,10 +22,10 @@ class AquantaCoordinator(DataUpdateCoordinator):

config_entry: ConfigEntry

def __init__(self, hass: HomeAssistant, aquanta, account_id) -> None:
def __init__(self, hass: HomeAssistant, aquanta: Aquanta, account_id: str) -> None:
"""Initialize the coordinator."""
self.aquanta = aquanta
self.account_id = account_id
self.aquanta: Aquanta = aquanta
self.account_id: str = account_id
super().__init__(
hass=hass,
logger=LOGGER,
Expand Down
17 changes: 16 additions & 1 deletion custom_components/aquanta/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
SensorEntityDescription,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import UnitOfTemperature, PERCENTAGE
from homeassistant.const import UnitOfTemperature, PERCENTAGE, EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback

Expand Down Expand Up @@ -87,6 +87,21 @@
"timer",
],
},
{
"desc": SensorEntityDescription(
key="efficiency_level",
name="Efficiency level",
entity_category=EntityCategory.DIAGNOSTIC,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=PERCENTAGE,
),
"native_value": lambda entity: (
entity.coordinator.data["devices"][entity.aquanta_id]["advanced"]["efficiencySelection"]
* 100
),
"suggested_precision": 0,
"options": None,
},
)


Expand Down
79 changes: 51 additions & 28 deletions custom_components/aquanta/water_heater.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
from __future__ import annotations

from homeassistant.components.water_heater import (
STATE_ECO,
STATE_PERFORMANCE,
STATE_OFF,
WaterHeaterEntity,
WaterHeaterEntityFeature,
)
Expand All @@ -17,6 +14,12 @@
from .entity import AquantaEntity
from .const import DOMAIN, LOGGER

STATE_INTELLIGENCE = "Aquanta Intelligence"
STATE_SETPOINT = "Setpoint"
STATE_TIME_OF_USE = "Time of Use"
STATE_TIMER = "Manual Timer"
# Away is a special state in homeassistant


async def async_setup_entry(
hass: HomeAssistant,
Expand All @@ -35,14 +38,26 @@ async def async_setup_entry(

async_add_entities(entities)


class AquantaWaterHeater(AquantaEntity, WaterHeaterEntity):
"""Representation of an Aquanta water heater controller."""

_attr_has_entity_name = True
# TODO: Enable setting operation mode from homeassistant
_attr_supported_features = WaterHeaterEntityFeature.AWAY_MODE
_attr_temperature_unit = UnitOfTemperature.CELSIUS
_attr_operation_list = [STATE_ECO, STATE_PERFORMANCE, STATE_OFF]
_attr_operation_list: list[str] = [
STATE_INTELLIGENCE,
STATE_SETPOINT,
STATE_TIME_OF_USE,
STATE_TIMER,
]
_attr_name = "Water heater"
# The settable temp range (in celsius) according to Aquanta App
_attr_max_temp: float = 110.0
_attr_min_temp: float = 10.0
_attr_target_temperature_high: None = None
_attr_target_temperature_low: None = None

def __init__(self, coordinator, aquanta_id) -> None:
"""Initialize the water heater."""
Expand All @@ -52,41 +67,49 @@ def __init__(self, coordinator, aquanta_id) -> None:
LOGGER.debug("Created water heater with unique ID %s", self._attr_unique_id)

@property
def current_temperature(self):
def current_temperature(self) -> float | None:
"""Return the current temperature."""
return self.coordinator.data["devices"][self.aquanta_id]["water"]["temperature"]

@property
def current_operation(self):
def current_operation(self) -> str:
"""Return current operation ie. eco, performance, off."""
operation = STATE_OFF

if (
self.coordinator.data["devices"][self.aquanta_id]["info"]["currentMode"][
"type"
]
!= "off"
):
found = False

mode_type = self.coordinator.data["devices"][self.aquanta_id]["info"][
"currentMode"
]["type"]
# Since and boost/away modes are special temporary states which preempt
# other operations states, we need to sometimes look at the records
record_types = [
record["type"]
for record in self.coordinator.data["devices"][self.aquanta_id]["info"][
"records"
]:
if record["type"] == "boost" and record["state"] == "ongoing":
operation = STATE_PERFORMANCE
found = True
elif record["type"] == "away" and record["state"] == "ongoing":
operation = STATE_OFF
found = True
break

if not found:
operation = STATE_ECO
]
]
LOGGER.debug(
"Aquanta API reports current mode: %s with records of type: %s.",
mode_type,
record_types,
)

operation: str = STATE_SETPOINT

if mode_type == "off":
# Turning Aquanta "off" actually reverts to the non-smart
# controller; it doesn't actually disable the water heater. "Away"
# is the closest state to "off" that Aquanta can provide.
operation = STATE_SETPOINT
elif "intel" in record_types:
operation = STATE_INTELLIGENCE
elif "timer" in record_types:
operation = STATE_TIMER
elif "tou" in record_types:
operation = STATE_TIME_OF_USE

LOGGER.debug("The resolved operation mode is %s.", operation)
return operation

@property
def target_temperature(self):
def target_temperature(self) -> float | None:
"""Return the temperature we try to reach."""
if self.coordinator.data["devices"][self.aquanta_id]["advanced"][
"thermostatEnabled"
Expand Down