Skip to content

Commit

Permalink
Merge pull request #34 from mattjgalloway/pv_divert_updates
Browse files Browse the repository at this point in the history
PV diverter updates
  • Loading branch information
tomasmcguinness authored Mar 5, 2024
2 parents 6b1efd1 + ca87803 commit f15552a
Show file tree
Hide file tree
Showing 6 changed files with 250 additions and 85 deletions.
25 changes: 21 additions & 4 deletions custom_components/mixergy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .const import ATTR_CHARGE, SERVICE_SET_CHARGE, ATTR_TEMPERATURE, SERVICE_SET_TARGET_TEMPERATURE
from datetime import timedelta
import logging
import asyncio
import voluptuous as vol
Expand All @@ -11,13 +12,18 @@
from .tank import Tank
from typing import Any, Final, final
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator

CHARGE_SERVICE_SCHEMA: Final = make_entity_service_schema(
{vol.Optional("target_percentage"): cv.positive_int}
)

DOMAIN = "mixergy"
PLATFORMS = ["sensor"]
PLATFORMS = [
"sensor",
"switch",
"number",
]
_LOGGER = logging.getLogger(__name__)

async def async_setup(hass: HomeAssistant, config):
Expand All @@ -38,7 +44,18 @@ async def async_setup_entry(hass: HomeAssistant, entry:ConfigEntry) -> bool:

tank = Tank(hass, entry.data[CONF_USERNAME],entry.data[CONF_PASSWORD],entry.data["serial_number"])

hass.data[DOMAIN][entry.entry_id] = tank
async def async_update_data():
_LOGGER.info("Fetching data from Mixergy...")
await tank.fetch_data()

# Create a coordinator to fetch data from the Mixergy API.
coordinator = DataUpdateCoordinator(hass, _LOGGER, name="Mixergy", update_method = async_update_data, update_interval = timedelta(seconds=30))
await coordinator.async_config_entry_first_refresh()

hass.data[DOMAIN][entry.entry_id] = {
"tank": tank,
"coordinator": coordinator,
}

_register_services(hass)

Expand Down Expand Up @@ -73,7 +90,7 @@ async def mixergy_set_charge(call):

tasks = [
tank.set_target_charge(charge)
for tank in hass.data[DOMAIN].values()
for tank in [d["tank"] for d in hass.data[DOMAIN].values()]
if isinstance(tank, Tank)
]

Expand All @@ -89,7 +106,7 @@ async def mixergy_set_target_temperature(call):

tasks = [
tank.set_target_temperature(temperature)
for tank in hass.data[DOMAIN].values()
for tank in [d["tank"] for d in hass.data[DOMAIN].values()]
if isinstance(tank, Tank)
]

Expand Down
32 changes: 32 additions & 0 deletions custom_components/mixergy/mixergy_entity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from .const import DOMAIN
from .tank import Tank
from homeassistant.helpers.update_coordinator import CoordinatorEntity

class MixergyEntityBase(CoordinatorEntity):

should_poll = True

def __init__(self, coordinator, tank:Tank):
super().__init__(coordinator)
self._tank = tank

@property
def device_info(self):
return {
"identifiers": {(DOMAIN, self._tank.serial_number)},
"manufacturer": "Mixergy Ltd",
"name": "Mixergy Tank",
"suggested_area": "garage",
"model": self._tank.modelCode,
"sw_version": self._tank.firmwareVersion
}

@property
def available(self) -> bool:
return self._tank.online

async def async_added_to_hass(self):
self._tank.register_callback(self.async_write_ha_state)

async def async_will_remove_from_hass(self):
self._tank.remove_callback(self.async_write_ha_state)
57 changes: 57 additions & 0 deletions custom_components/mixergy/number.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import logging
from homeassistant.components.number import NumberEntity
from .const import DOMAIN
from .tank import Tank
from .mixergy_entity import MixergyEntityBase

_LOGGER = logging.getLogger(__name__)

async def async_setup_entry(hass, config_entry, async_add_entities):
_LOGGER.info("Setting up entry based on user config")

entry = hass.data[DOMAIN][config_entry.entry_id]
tank = entry["tank"]
coordinator = entry["coordinator"]

new_entities = []

new_entities.append(PVChargeLimitSensor(coordinator, tank))

async_add_entities(new_entities)

class NumberEntityBase(MixergyEntityBase, NumberEntity):

def __init__(self, coordinator, tank:Tank):
super().__init__(coordinator, tank)

class PVChargeLimitSensor(NumberEntityBase):

native_max_value = 100
native_min_value = 0
native_step = 10

def __init__(self, coordinator, tank:Tank):
super().__init__( coordinator, tank)

@property
def unique_id(self):
return f"mixergy_{self._tank.tank_id}_pv_charge_limit"

@property
def state(self):
return self._tank.pv_charge_limit

@property
def available(self):
return super().available and self._tank.has_pv_diverter

async def async_set_native_value(self, value: float):
await self._tank.set_pv_charge_limit(int(value))

@property
def icon(self):
return "mdi:lightning-bolt"

@property
def name(self):
return f"PV Charge Limit"
90 changes: 15 additions & 75 deletions custom_components/mixergy/sensor.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,21 @@
import logging
from datetime import timedelta
from homeassistant.const import UnitOfPower, UnitOfTemperature, PERCENTAGE, STATE_OFF
from homeassistant.components.sensor import SensorEntity
from homeassistant.components.sensor import SensorDeviceClass
from homeassistant.components.sensor import SensorDeviceClass, SensorEntity
from homeassistant.components.integration.sensor import IntegrationSensor
from homeassistant.components.binary_sensor import BinarySensorDeviceClass
from homeassistant.components.binary_sensor import BinarySensorEntity
from homeassistant.components.binary_sensor import BinarySensorDeviceClass, BinarySensorEntity
from .const import DOMAIN
from .tank import Tank
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
DataUpdateCoordinator,
)
from .mixergy_entity import MixergyEntityBase

_LOGGER = logging.getLogger(__name__)

async def async_setup_entry(hass, config_entry, async_add_entities):
_LOGGER.info("Setting up entry based on user config")

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

async def async_update_data():
_LOGGER.info("Fetching data from Mixergy...")
await tank.fetch_data()

# Create a coordinator to fetch data from the Mixergy API.
coordinator = DataUpdateCoordinator(hass, _LOGGER, name="sensor", update_method = async_update_data, update_interval = timedelta(seconds=30))

await coordinator.async_config_entry_first_refresh()
entry = hass.data[DOMAIN][config_entry.entry_id]
tank = entry["tank"]
coordinator = entry["coordinator"]

new_entities = []

Expand All @@ -48,66 +36,18 @@ async def async_update_data():
new_entities.append(PVEnergySensor(tank))
new_entities.append(ClampPowerSensor(coordinator, tank))
new_entities.append(IsChargingSensor(coordinator, tank))

async_add_entities(new_entities)

class SensorBase(CoordinatorEntity,SensorEntity):
async_add_entities(new_entities)

should_poll = True
class SensorBase(MixergyEntityBase, SensorEntity):

def __init__(self, coordinator, tank:Tank):
super().__init__(coordinator)
self._tank = tank

@property
def device_info(self):
return {
"identifiers": {(DOMAIN, self._tank.serial_number)},
"manufacturer":"Mixergy Ltd",
"name":"Mixergy Tank",
"suggested_area":"garage",
"model":self._tank.modelCode,
"sw_version":self._tank.firmwareVersion
}

@property
def available(self) -> bool:
return self._tank.online

async def async_added_to_hass(self):
self._tank.register_callback(self.async_write_ha_state)

async def async_will_remove_from_hass(self):
self._tank.remove_callback(self.async_write_ha_state)

class BinarySensorBase(CoordinatorEntity,BinarySensorEntity):
super().__init__(coordinator, tank)

should_poll = True
class BinarySensorBase(MixergyEntityBase, BinarySensorEntity):

def __init__(self, coordinator, tank:Tank):
super().__init__(coordinator)
self._tank = tank

@property
def device_info(self):
return {
"identifiers": {(DOMAIN, self._tank.serial_number)},
"manufacturer":"Mixergy Ltd",
"name":"Mixergy Tank",
"suggested_area":"garage",
"model":self._tank.modelCode,
"sw_version":self._tank.firmwareVersion
}

@property
def available(self) -> bool:
return self._tank.online

async def async_added_to_hass(self):
self._tank.register_callback(self.async_write_ha_state)

async def async_will_remove_from_hass(self):
self._tank.remove_callback(self.async_write_ha_state)
super().__init__(coordinator, tank)

class ChargeSensor(SensorBase):

Expand All @@ -133,7 +73,7 @@ def icon(self):
@property
def name(self):
return f"Current Charge"

class TargetChargeSensor(SensorBase):

def __init__(self, coordinator, tank:Tank):
Expand Down Expand Up @@ -205,7 +145,7 @@ def unit_of_measurement(self):
@property
def name(self):
return f"Coldest Water Temperature"

class TargetTemperatureSensor(SensorBase):

device_class = SensorDeviceClass.TEMPERATURE
Expand Down Expand Up @@ -335,7 +275,7 @@ def icon(self):
@property
def name(self):
return f"Low Hot Water"

class IsChargingSensor(BinarySensorBase):

def __init__(self, coordinator, tank:Tank):
Expand Down Expand Up @@ -461,7 +401,7 @@ def state(self):

@property
def unit_of_measurement(self):
return POWER_WATT
return UnitOfPower.WATT

@property
def name(self):
Expand Down
54 changes: 54 additions & 0 deletions custom_components/mixergy/switch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import logging
from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity
from .const import DOMAIN
from .tank import Tank
from .mixergy_entity import MixergyEntityBase

_LOGGER = logging.getLogger(__name__)

async def async_setup_entry(hass, config_entry, async_add_entities):
_LOGGER.info("Setting up entry based on user config")

entry = hass.data[DOMAIN][config_entry.entry_id]
tank = entry["tank"]
coordinator = entry["coordinator"]

new_entities = []

new_entities.append(PVDivertSwitch(coordinator, tank))

async_add_entities(new_entities)

class SwitchEntityBase(MixergyEntityBase, SwitchEntity):

device_class = SwitchDeviceClass.SWITCH

def __init__(self, coordinator, tank:Tank):
super().__init__(coordinator, tank)

class PVDivertSwitch(SwitchEntityBase):

def __init__(self, coordinator, tank:Tank):
super().__init__(coordinator, tank)

@property
def unique_id(self):
return f"mixergy_{self._tank.tank_id}_pv_divert_enabled"

@property
def name(self):
return f"PV Divert Enabled"

@property
def available(self):
return super().available and self._tank.has_pv_diverter

@property
def is_on(self):
return self._tank.divert_exported_enabled

async def async_turn_on(self, **kwargs):
await self._tank.set_divert_exported_enabled(True)

async def async_turn_off(self, **kwargs):
await self._tank.set_divert_exported_enabled(False)
Loading

0 comments on commit f15552a

Please sign in to comment.