diff --git a/custom_components/myenergi/const.py b/custom_components/myenergi/const.py index a57e08e..297be6c 100644 --- a/custom_components/myenergi/const.py +++ b/custom_components/myenergi/const.py @@ -3,7 +3,7 @@ NAME = "myenergi" DOMAIN = "myenergi" DOMAIN_DATA = f"{DOMAIN}_data" -VERSION = "0.0.23" +VERSION = "0.0.24" ATTRIBUTION = "Data provided by myenergi" ISSUE_URL = "https://github.com/CJNE/ha-myenergi/issues" diff --git a/custom_components/myenergi/manifest.json b/custom_components/myenergi/manifest.json index 5f3936f..796d802 100644 --- a/custom_components/myenergi/manifest.json +++ b/custom_components/myenergi/manifest.json @@ -7,6 +7,6 @@ "documentation": "https://github.com/cjne/ha-myenergi", "iot_class": "cloud_polling", "issue_tracker": "https://github.com/cjne/ha-myenergi/issues", - "requirements": ["pymyenergi==0.0.27"], - "version": "0.0.23" + "requirements": ["pymyenergi==0.0.29"], + "version": "0.0.24" } diff --git a/custom_components/myenergi/number.py b/custom_components/myenergi/number.py index 6856111..a91cff0 100644 --- a/custom_components/myenergi/number.py +++ b/custom_components/myenergi/number.py @@ -22,6 +22,8 @@ async def async_setup_entry(hass, entry, async_add_devices): elif device.kind == "eddi": devices.append(HeaterPriorityNumber(coordinator, device, entry)) devices.append(DevicePriorityNumber(coordinator, device, entry)) + elif device.kind == "libbi": + devices.append(DevicePriorityNumber(coordinator, device, entry)) async_add_devices(devices) diff --git a/custom_components/myenergi/select.py b/custom_components/myenergi/select.py index 7fb9741..3d5ad2c 100644 --- a/custom_components/myenergi/select.py +++ b/custom_components/myenergi/select.py @@ -4,6 +4,10 @@ from homeassistant.helpers import entity_platform from pymyenergi.eddi import EDDI_MODES from pymyenergi.zappi import CHARGE_MODES +from pymyenergi.libbi import LIBBI_MODES +from pymyenergi.libbi import LIBBI_MODE_NAMES +from pymyenergi.libbi import MODE_STOPPED +from pymyenergi.libbi import MODE_NORMAL from .const import DOMAIN from .entity import MyenergiEntity @@ -60,6 +64,8 @@ async def async_setup_entry(hass, entry, async_add_devices): "start_eddi_boost", ) devices.append(EddiOperatingModeSelect(coordinator, device, entry)) + elif device.kind == "libbi": + devices.append(LibbiOperatingModeSelect(coordinator, device, entry)) async_add_devices(devices) @@ -132,3 +138,38 @@ async def async_select_option(self, option: str) -> None: @property def options(self): return CHARGE_MODES[1:] + + +class LibbiOperatingModeSelect(MyenergiEntity, SelectEntity): + """myenergi Sensor class.""" + + def __init__(self, coordinator, device, config_entry): + super().__init__(coordinator, device, config_entry) + + @property + def unique_id(self): + """Return a unique ID to use for this entity.""" + return ( + f"{self.config_entry.entry_id}-{self.device.serial_number}-operating_mode" + ) + + @property + def name(self): + """Return the name of the sensor.""" + return f"myenergi {self.device.name} Operating Mode" + + @property + def current_option(self): + """Return the state of the sensor.""" + if self.device.local_mode == LIBBI_MODE_NAMES[MODE_STOPPED]: + return LIBBI_MODES[MODE_STOPPED] + return LIBBI_MODES[MODE_NORMAL] + + async def async_select_option(self, option: str) -> None: + """Change the selected option.""" + await self.device.set_operating_mode(option) + self.async_schedule_update_ha_state() + + @property + def options(self): + return LIBBI_MODES diff --git a/custom_components/myenergi/sensor.py b/custom_components/myenergi/sensor.py index 18766d2..dc5c909 100644 --- a/custom_components/myenergi/sensor.py +++ b/custom_components/myenergi/sensor.py @@ -8,6 +8,7 @@ from homeassistant.const import DEVICE_CLASS_POWER from homeassistant.const import DEVICE_CLASS_TEMPERATURE from homeassistant.const import DEVICE_CLASS_VOLTAGE +from homeassistant.const import DEVICE_CLASS_BATTERY from homeassistant.const import ELECTRIC_POTENTIAL_VOLT from homeassistant.const import ENERGY_KILO_WATT_HOUR from homeassistant.const import FREQUENCY_HERTZ @@ -20,6 +21,7 @@ from pymyenergi import EDDI from pymyenergi import HARVI from pymyenergi import ZAPPI +from pymyenergi import LIBBI from .const import DOMAIN from .entity import MyenergiEntity @@ -29,6 +31,8 @@ ICON_VOLT = "mdi:lightning-bolt" ICON_FREQ = "mdi:sine-wave" +ICON_POWER = "mdi:flash" +ICON_HOME_BATTERY = "mdi:home-battery" def create_meta( @@ -486,6 +490,177 @@ async def async_setup_entry(hass, entry, async_add_devices): ), ) ) + elif device.kind == LIBBI: + sensors.append( + MyenergiSensor( + coordinator, + device, + entry, + create_meta( + f"SoC", + "state_of_charge", + DEVICE_CLASS_BATTERY, + PERCENTAGE, + ), + ) + ) + sensors.append( + MyenergiSensor( + coordinator, + device, + entry, + create_meta( + f"Voltage", + "supply_voltage", + DEVICE_CLASS_VOLTAGE, + ELECTRIC_POTENTIAL_VOLT, + ENTITY_CATEGORY_DIAGNOSTIC, + ICON_VOLT, + STATE_CLASS_MEASUREMENT, + ), + ) + ) + sensors.append( + MyenergiSensor( + coordinator, + device, + entry, + create_meta( + f"Frequency", + "supply_frequency", + None, + FREQUENCY_HERTZ, + ENTITY_CATEGORY_DIAGNOSTIC, + ICON_FREQ, + STATE_CLASS_MEASUREMENT, + ), + ) + ) + sensors.append( + MyenergiSensor( + coordinator, + device, + entry, + create_meta( + f"Inverter size", + "inverter_size", + None, + ENERGY_KILO_WATT_HOUR, + ENTITY_CATEGORY_DIAGNOSTIC, + ICON_POWER, + ), + ) + ) + sensors.append( + MyenergiSensor( + coordinator, + device, + entry, + create_meta( + f"Battery size", + "battery_size", + None, + ENERGY_KILO_WATT_HOUR, + ENTITY_CATEGORY_DIAGNOSTIC, + ICON_POWER, + ) + ) + ) + sensors.append( + MyenergiSensor( + coordinator, + device, + entry, + create_meta( + f"Status", + "status", + None, + None, + None, + ICON_HOME_BATTERY, + ) + ) + ) + sensors.append( + MyenergiSensor( + coordinator, + device, + entry, + create_meta( + f"Grid import today", + "grid_import", + DEVICE_CLASS_ENERGY, + ENERGY_KILO_WATT_HOUR, + None, + None, + STATE_CLASS_TOTAL_INCREASING, + ) + ) + ) + sensors.append( + MyenergiSensor( + coordinator, + device, + entry, + create_meta( + f"Grid export today", + "grid_export", + DEVICE_CLASS_ENERGY, + ENERGY_KILO_WATT_HOUR, + None, + None, + STATE_CLASS_TOTAL_INCREASING, + ) + ) + ) + sensors.append( + MyenergiSensor( + coordinator, + device, + entry, + create_meta( + f"Battery charge today", + "battery_charge", + DEVICE_CLASS_ENERGY, + ENERGY_KILO_WATT_HOUR, + None, + None, + STATE_CLASS_TOTAL_INCREASING, + ) + ) + ) + sensors.append( + MyenergiSensor( + coordinator, + device, + entry, + create_meta( + f"Battery discharge today", + "battery_discharge", + DEVICE_CLASS_ENERGY, + ENERGY_KILO_WATT_HOUR, + None, + None, + STATE_CLASS_TOTAL_INCREASING, + ) + ) + ) + sensors.append( + MyenergiSensor( + coordinator, + device, + entry, + create_meta( + f"Solar generation today", + "generated", + DEVICE_CLASS_ENERGY, + ENERGY_KILO_WATT_HOUR, + None, + None, + STATE_CLASS_TOTAL_INCREASING, + ) + ) + ) async_add_devices(sensors) @@ -498,7 +673,7 @@ def __init__(self, coordinator, config_entry, meta): @property def unique_id(self): """Return a unique ID to use for this entity.""" - return f"{self.config_entry.entry_id}-{self.coordinator.client.serial_number}-{self.meta['prop_name']}" + return f"{self.config_entry.entry_id}-hub-{self.coordinator.client.serial_number}-{self.meta['prop_name']}" @property def name(self):