From 1edb124b24ba420169f5bd66287abad19c88ea95 Mon Sep 17 00:00:00 2001 From: Olaf Strama Date: Mon, 21 Oct 2024 07:34:59 +0000 Subject: [PATCH 1/6] 1st version in DevContainer --- .../weishaupt_modbus/__init__.py | 4 +- .../weishaupt_modbus/config_flow.py | 5 +- custom_components/weishaupt_modbus/const.py | 16 +- .../weishaupt_modbus/entities.py | 86 +- custom_components/weishaupt_modbus/hpconst.py | 1081 ++++++++++++----- .../weishaupt_modbus/manifest.json | 4 +- 6 files changed, 861 insertions(+), 335 deletions(-) diff --git a/custom_components/weishaupt_modbus/__init__.py b/custom_components/weishaupt_modbus/__init__.py index 91f2242..46ea264 100644 --- a/custom_components/weishaupt_modbus/__init__.py +++ b/custom_components/weishaupt_modbus/__init__.py @@ -7,9 +7,10 @@ "number", "select", "sensor", -# "switch", + # "switch", ] + # Return boolean to indicate that initialization was successful. # return True async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: @@ -22,6 +23,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) return True + async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: # This is called when an entry/configured device is to be removed. The class # needs to unload itself, and remove callbacks. See the classes for further diff --git a/custom_components/weishaupt_modbus/config_flow.py b/custom_components/weishaupt_modbus/config_flow.py index eed0946..3866969 100644 --- a/custom_components/weishaupt_modbus/config_flow.py +++ b/custom_components/weishaupt_modbus/config_flow.py @@ -13,6 +13,7 @@ {vol.Required(CONF_HOST): str, vol.Optional(CONF_PORT, default="502"): cv.port} ) + async def validate_input(hass: HomeAssistant, data: dict) -> dict[str, Any]: # Validate the data can be used to set up a connection. @@ -65,13 +66,15 @@ async def async_step_user(self, user_input=None): except Exception: # noqa: BLE001 errors["base"] = "unknown" -# If there is no user input or there were errors, show the form again, including any errors that were found with the input. + # If there is no user input or there were errors, show the form again, including any errors that were found with the input. return self.async_show_form( step_id="user", data_schema=DATA_SCHEMA, errors=errors ) + class InvalidHost(exceptions.HomeAssistantError): """Error to indicate there is an invalid hostname.""" + class ConnectionFailed(exceptions.HomeAssistantError): """Error to indicate there is an invalid hostname.""" diff --git a/custom_components/weishaupt_modbus/const.py b/custom_components/weishaupt_modbus/const.py index 14eee76..c72ccb3 100644 --- a/custom_components/weishaupt_modbus/const.py +++ b/custom_components/weishaupt_modbus/const.py @@ -1,6 +1,14 @@ from dataclasses import dataclass from datetime import timedelta -from homeassistant.const import UnitOfEnergy, UnitOfTemperature, UnitOfTime, UnitOfVolumeFlowRate, UnitOfPower, PERCENTAGE +from homeassistant.const import ( + UnitOfEnergy, + UnitOfTemperature, + UnitOfTime, + UnitOfVolumeFlowRate, + UnitOfPower, + PERCENTAGE, +) + @dataclass(frozen=True) class MainConstants: @@ -10,8 +18,10 @@ class MainConstants: APPID = 100 KENNFELDFILE = "weishaupt_wbb_kennfeld.json" + CONST = MainConstants() + @dataclass(frozen=True) class FormatConstants: TEMPERATUR = UnitOfTemperature.CELSIUS @@ -25,8 +35,10 @@ class FormatConstants: TIME_MIN = UnitOfTime.MINUTES TIME_H = UnitOfTime.HOURS + FORMATS = FormatConstants() + @dataclass(frozen=True) class TypeConstants: SENSOR = "Sensor" @@ -35,5 +47,5 @@ class TypeConstants: NUMBER = "Number" NUMBER_RO = "Number_RO" -TYPES = TypeConstants() +TYPES = TypeConstants() diff --git a/custom_components/weishaupt_modbus/entities.py b/custom_components/weishaupt_modbus/entities.py index c6bc5fe..a240b42 100644 --- a/custom_components/weishaupt_modbus/entities.py +++ b/custom_components/weishaupt_modbus/entities.py @@ -1,6 +1,10 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_PORT -from homeassistant.components.sensor import SensorDeviceClass, SensorEntity, SensorStateClass +from homeassistant.components.sensor import ( + SensorDeviceClass, + SensorEntity, + SensorStateClass, +) from homeassistant.components.select import SelectEntity from homeassistant.components.number import NumberEntity from homeassistant.const import UnitOfEnergy, UnitOfTemperature @@ -11,14 +15,15 @@ from .hpconst import TEMPRANGE_STD, DEVICES from .kennfeld import PowerMap + def BuildEntityList(entries, config_entry, modbusitems, type): # this builds a list of entities that can be used as parameter by async_setup_entry() # type of list is defined by the ModbusItem's type flag - # so the app only holds one list of entities that is build from a list of ModbusItem + # so the app only holds one list of entities that is build from a list of ModbusItem # stored in hpconst.py so far, will be provided by an external file in future for index, item in enumerate(modbusitems): if item.type == type: - match type: + match type: # here the entities are created with the parameters provided by the ModbusItem object case TYPES.SENSOR | TYPES.NUMBER_RO: entries.append(MySensorEntity(config_entry, modbusitems[index])) @@ -31,7 +36,8 @@ def BuildEntityList(entries, config_entry, modbusitems, type): return entries -class MyEntity(): + +class MyEntity: # The base class for entities that hold general parameters _config_entry = None _modbus_item = None @@ -57,7 +63,7 @@ def __init__(self, config_entry, modbus_item) -> None: self._attr_state_class = SensorStateClass.MEASUREMENT if self._modbus_item._format == FORMATS.POWER: self._attr_state_class = SensorStateClass.MEASUREMENT - + if self._modbus_item.resultlist != None: self._attr_native_min_value = self._modbus_item.getNumberFromText("min") self._attr_native_max_value = self._modbus_item.getNumberFromText("max") @@ -65,7 +71,7 @@ def __init__(self, config_entry, modbus_item) -> None: self._divider = self._modbus_item.getNumberFromText("divider") self._attr_device_class = self._modbus_item.getTextFromNumber(-1) - def calcTemperature(self,val: float): + def calcTemperature(self, val: float): if val == None: return None if val == -32768: @@ -76,7 +82,7 @@ def calcTemperature(self,val: float): return None return val / self._divider - def calcPercentage(self,val: float): + def calcPercentage(self, val: float): if val == None: return None if val == 65535: @@ -103,7 +109,7 @@ def translateVal(self): return val / self._divider @translateVal.setter - def translateVal(self,value): + def translateVal(self, value): # translates and writes a value to the modbus mbo = ModbusObject(self._config_entry, self._modbus_item) if mbo == None: @@ -116,23 +122,24 @@ def translateVal(self,value): case _: val = value * self._divider mbo.value = val - + def my_device_info(self) -> DeviceInfo: - # helper to build the device info + # helper to build the device info return { - "identifiers": {(CONST.DOMAIN, self._dev_device)}, - "name": self._dev_device, - "sw_version": "Device_SW_Version", - "model": "Device_model", - "manufacturer": "Weishaupt", + "identifiers": {(CONST.DOMAIN, self._dev_device)}, + "name": self._dev_device, + "sw_version": "Device_SW_Version", + "model": "Device_model", + "manufacturer": "Weishaupt", } + class MySensorEntity(SensorEntity, MyEntity): - # class that represents a sensor entity derived from Sensorentity + # class that represents a sensor entity derived from Sensorentity # and decorated with general parameters from MyEntity _attr_native_unit_of_measurement = None - _attr_device_class = None - _attr_state_class = None + _attr_device_class = None + _attr_state_class = None def __init__(self, config_entry, modbus_item) -> None: MyEntity.__init__(self, config_entry, modbus_item) @@ -147,7 +154,7 @@ def device_info(self) -> DeviceInfo: class MyCalcSensorEntity(MySensorEntity): - # class that represents a sensor entity derived from Sensorentity + # class that represents a sensor entity derived from Sensorentity # and decorated with general parameters from MyEntity # calculates output from map my_map = PowerMap() @@ -162,20 +169,34 @@ async def async_update(self) -> None: def calcPower(self, val, x, y): if val == None: return val - return (val / 100) * self.my_map.map(x,y) + return (val / 100) * self.my_map.map(x, y) @property def translateVal(self): # reads an translates a value from the modbus mbo = ModbusObject(self._config_entry, self._modbus_item) val = self.calcPercentage(mbo.value) - - mb_x = ModbusItem(self._modbus_item.getNumberFromText("x"),"x",FORMATS.TEMPERATUR,TYPES.SENSOR_CALC,DEVICES.SYS, TEMPRANGE_STD) + + mb_x = ModbusItem( + self._modbus_item.getNumberFromText("x"), + "x", + FORMATS.TEMPERATUR, + TYPES.SENSOR_CALC, + DEVICES.SYS, + TEMPRANGE_STD, + ) mbo_x = ModbusObject(self._config_entry, mb_x) if mbo_x == None: return None val_x = self.calcTemperature(mbo_x.value) / 10 - mb_y = ModbusItem(self._modbus_item.getNumberFromText("y"),"y",FORMATS.TEMPERATUR,TYPES.SENSOR_CALC,DEVICES.WP, TEMPRANGE_STD) + mb_y = ModbusItem( + self._modbus_item.getNumberFromText("y"), + "y", + FORMATS.TEMPERATUR, + TYPES.SENSOR_CALC, + DEVICES.WP, + TEMPRANGE_STD, + ) mbo_y = ModbusObject(self._config_entry, mb_y) if mbo_x == None: return None @@ -183,7 +204,7 @@ def translateVal(self): match self._modbus_item.format: case FORMATS.POWER: - return self.calcPower(val,val_x,val_y) + return self.calcPower(val, val_x, val_y) case _: return val / self._divider @@ -193,15 +214,14 @@ def device_info(self) -> DeviceInfo: class MyNumberEntity(NumberEntity, MyEntity): - # class that represents a sensor entity derived from Sensorentity + # class that represents a sensor entity derived from Sensorentity # and decorated with general parameters from MyEntity _attr_native_unit_of_measurement = None - _attr_device_class = None - _attr_state_class = None + _attr_device_class = None + _attr_state_class = None _attr_native_min_value = 10 _attr_native_max_value = 60 - def __init__(self, config_entry, modbus_item) -> None: MyEntity.__init__(self, config_entry, modbus_item) @@ -212,7 +232,7 @@ def __init__(self, config_entry, modbus_item) -> None: async def async_set_native_value(self, value: float) -> None: self.translateVal = value - self._attr_native_value = self.translateVal + self._attr_native_value = self.translateVal self.async_write_ha_state() async def async_update(self) -> None: @@ -225,14 +245,16 @@ def device_info(self) -> DeviceInfo: class MySelectEntity(SelectEntity, MyEntity): - # class that represents a sensor entity derived from Sensorentity + # class that represents a sensor entity derived from Sensorentity # and decorated with general parameters from MyEntity options = [] _attr_current_option = "FEHLER" def __init__(self, config_entry, modbus_item) -> None: MyEntity.__init__(self, config_entry, modbus_item) - self.async_internal_will_remove_from_hass_port = self._config_entry.data[CONF_PORT] + self.async_internal_will_remove_from_hass_port = self._config_entry.data[ + CONF_PORT + ] # option list build from the status list of the ModbusItem self.options = [] for index, item in enumerate(self._modbus_item._resultlist): @@ -241,7 +263,7 @@ def __init__(self, config_entry, modbus_item) -> None: async def async_select_option(self, option: str) -> None: # the synching is done by the ModbusObject of the entity self.translateVal = option - self._attr_current_option = self.translateVal + self._attr_current_option = self.translateVal self.async_write_ha_state() async def async_update(self) -> None: diff --git a/custom_components/weishaupt_modbus/hpconst.py b/custom_components/weishaupt_modbus/hpconst.py index 3970158..8b8ec83 100644 --- a/custom_components/weishaupt_modbus/hpconst.py +++ b/custom_components/weishaupt_modbus/hpconst.py @@ -3,6 +3,7 @@ from .items import ModbusItem, StatusItem from homeassistant.components.sensor import SensorDeviceClass + @dataclass(frozen=True) class DeviceConstants: SYS = "System" @@ -12,6 +13,7 @@ class DeviceConstants: W2 = "2. Wärmeerzeuger" ST = "Statistik" + DEVICES = DeviceConstants() ############################################################################################################################## @@ -21,207 +23,207 @@ class DeviceConstants: ############################################################################################################################## SYS_FEHLER = [ - StatusItem(65535,"kein Fehler"), + StatusItem(65535, "kein Fehler"), ] SYS_WARNUNG = [ - StatusItem(65535,"keine Warnung"), - StatusItem(32,"Fehler Kältesatz (32)"), + StatusItem(65535, "keine Warnung"), + StatusItem(32, "Fehler Kältesatz (32)"), ] SYS_FEHLERFREI = [ - StatusItem(0,"Fehler aktiv"), - StatusItem(1,"Störungsfreier Betrieb"), + StatusItem(0, "Fehler aktiv"), + StatusItem(1, "Störungsfreier Betrieb"), ] SYS_BETRIEBSANZEIGE = [ - StatusItem(0,"undefiniert"), - StatusItem(1,"Relaistest"), - StatusItem(2,"Notaus"), - StatusItem(3,"Diagnose"), - StatusItem(4,"Handbetrieb"), - StatusItem(5,"Handbetrieb Heizen"), - StatusItem(6,"Handbetrieb Kühlen"), - StatusItem(7,"Manueller Abtaubetrieb"), - StatusItem(8,"Abtauen"), - StatusItem(9,"2. WEZ"), - StatusItem(10,"EVU_SPERRE"), - StatusItem(11,"SG Tarif"), - StatusItem(12,"SG Maximal"), - StatusItem(13,"Tarifladung"), - StatusItem(14,"Erhöhter Betrieb"), - StatusItem(15,"Standzeit"), - StatusItem(16,"Standby"), - StatusItem(17,"Spülen"), - StatusItem(18,"Frostschutz"), - StatusItem(19,"Heizbetrieb"), - StatusItem(20,"Warmwasserbetrieb"), - StatusItem(21,"Legionellenschutz"), - StatusItem(22,"Umschaltung HZ KU"), - StatusItem(23,"Kühlbetrieb"), - StatusItem(24,"Passive Kühlung"), - StatusItem(25,"Sommerbetrieb"), - StatusItem(26,"Schwimmbadbetrieb"), - StatusItem(27,"Urlaub"), - StatusItem(28,"Estrichprogramm"), - StatusItem(29,"Gesperrt"), - StatusItem(30,"Sperre AT"), - StatusItem(31,"Sperre Sommer"), - StatusItem(32,"Sperre Winter"), - StatusItem(33,"Einsatzgrenze"), - StatusItem(34,"HK Sperre"), - StatusItem(35,"Absenkbetrieb"), - StatusItem(43,"Ölrückführung"), + StatusItem(0, "undefiniert"), + StatusItem(1, "Relaistest"), + StatusItem(2, "Notaus"), + StatusItem(3, "Diagnose"), + StatusItem(4, "Handbetrieb"), + StatusItem(5, "Handbetrieb Heizen"), + StatusItem(6, "Handbetrieb Kühlen"), + StatusItem(7, "Manueller Abtaubetrieb"), + StatusItem(8, "Abtauen"), + StatusItem(9, "2. WEZ"), + StatusItem(10, "EVU_SPERRE"), + StatusItem(11, "SG Tarif"), + StatusItem(12, "SG Maximal"), + StatusItem(13, "Tarifladung"), + StatusItem(14, "Erhöhter Betrieb"), + StatusItem(15, "Standzeit"), + StatusItem(16, "Standby"), + StatusItem(17, "Spülen"), + StatusItem(18, "Frostschutz"), + StatusItem(19, "Heizbetrieb"), + StatusItem(20, "Warmwasserbetrieb"), + StatusItem(21, "Legionellenschutz"), + StatusItem(22, "Umschaltung HZ KU"), + StatusItem(23, "Kühlbetrieb"), + StatusItem(24, "Passive Kühlung"), + StatusItem(25, "Sommerbetrieb"), + StatusItem(26, "Schwimmbadbetrieb"), + StatusItem(27, "Urlaub"), + StatusItem(28, "Estrichprogramm"), + StatusItem(29, "Gesperrt"), + StatusItem(30, "Sperre AT"), + StatusItem(31, "Sperre Sommer"), + StatusItem(32, "Sperre Winter"), + StatusItem(33, "Einsatzgrenze"), + StatusItem(34, "HK Sperre"), + StatusItem(35, "Absenkbetrieb"), + StatusItem(43, "Ölrückführung"), ] SYS_BETRIEBSART = [ - StatusItem(0,"Automatik"), - StatusItem(1,"Heizen"), - StatusItem(2,"Kühlen"), - StatusItem(3,"Sommer"), - StatusItem(4,"Standby"), - StatusItem(5,"2.WEZ"), + StatusItem(0, "Automatik"), + StatusItem(1, "Heizen"), + StatusItem(2, "Kühlen"), + StatusItem(3, "Sommer"), + StatusItem(4, "Standby"), + StatusItem(5, "2.WEZ"), ] HP_BETRIEB = [ - StatusItem(0,"Undefiniert"), - StatusItem(1,"Relaistest"), - StatusItem(2,"Notaus"), - StatusItem(3,"Diagnose"), - StatusItem(4,"Handbetrieb"), - StatusItem(5,"Handbetrieb Heizen"), - StatusItem(6,"Handbetrieb Kühlen"), - StatusItem(7,"Manueller Abtaubetrieb"), - StatusItem(8,"Abtauen"), - StatusItem(9,"WEZ2"), - StatusItem(10,"EVU_SPERRE"), - StatusItem(11,"SG Tarif"), - StatusItem(12,"SG Maximal"), - StatusItem(13,"Tarifladung"), - StatusItem(14,"Erhöhter Betrieb"), - StatusItem(15,"Standzeit"), - StatusItem(16,"Standbybetrieb"), - StatusItem(17,"Spülbetrieb"), - StatusItem(18,"Frostschutz"), - StatusItem(19,"Heizbetrieb"), - StatusItem(20,"Warmwasserbetrieb"), - StatusItem(21,"Legionellenschutz"), - StatusItem(22,"Umschaltung HZ KU"), - StatusItem(23,"Kühlbetrieb"), - StatusItem(24,"Passive Kühlung"), - StatusItem(25,"Sommerbetrieb"), - StatusItem(26,"Schwimmbad"), - StatusItem(27,"Urlaub"), - StatusItem(28,"Estrich"), - StatusItem(29,"Gesperrt"), - StatusItem(30,"Sperre AT"), - StatusItem(31,"Sperre Sommer"), - StatusItem(32,"Sperre Winter"), - StatusItem(33,"Einsatzgrenze"), - StatusItem(34,"HK Sperre"), - StatusItem(35,"Absenk"), - StatusItem(43,"Ölrückführung"), + StatusItem(0, "Undefiniert"), + StatusItem(1, "Relaistest"), + StatusItem(2, "Notaus"), + StatusItem(3, "Diagnose"), + StatusItem(4, "Handbetrieb"), + StatusItem(5, "Handbetrieb Heizen"), + StatusItem(6, "Handbetrieb Kühlen"), + StatusItem(7, "Manueller Abtaubetrieb"), + StatusItem(8, "Abtauen"), + StatusItem(9, "WEZ2"), + StatusItem(10, "EVU_SPERRE"), + StatusItem(11, "SG Tarif"), + StatusItem(12, "SG Maximal"), + StatusItem(13, "Tarifladung"), + StatusItem(14, "Erhöhter Betrieb"), + StatusItem(15, "Standzeit"), + StatusItem(16, "Standbybetrieb"), + StatusItem(17, "Spülbetrieb"), + StatusItem(18, "Frostschutz"), + StatusItem(19, "Heizbetrieb"), + StatusItem(20, "Warmwasserbetrieb"), + StatusItem(21, "Legionellenschutz"), + StatusItem(22, "Umschaltung HZ KU"), + StatusItem(23, "Kühlbetrieb"), + StatusItem(24, "Passive Kühlung"), + StatusItem(25, "Sommerbetrieb"), + StatusItem(26, "Schwimmbad"), + StatusItem(27, "Urlaub"), + StatusItem(28, "Estrich"), + StatusItem(29, "Gesperrt"), + StatusItem(30, "Sperre AT"), + StatusItem(31, "Sperre Sommer"), + StatusItem(32, "Sperre Winter"), + StatusItem(33, "Einsatzgrenze"), + StatusItem(34, "HK Sperre"), + StatusItem(35, "Absenk"), + StatusItem(43, "Ölrückführung"), ] HP_STOERMELDUNG = [ - StatusItem(0,"Störung"), - StatusItem(1,"Störungsfrei"), + StatusItem(0, "Störung"), + StatusItem(1, "Störungsfrei"), ] HP_RUHEMODUS = [ - StatusItem(0,"aus"), - StatusItem(1,"80 %"), - StatusItem(2,"60 %"), - StatusItem(3,"40 %"), + StatusItem(0, "aus"), + StatusItem(1, "80 %"), + StatusItem(2, "60 %"), + StatusItem(3, "40 %"), ] HZ_KONFIGURATION = [ - StatusItem(0,"aus"), - StatusItem(1,"Pumpenkreis"), - StatusItem(2,"Mischkreis"), - StatusItem(3,"Sollwert (Pumpe M1)"), + StatusItem(0, "aus"), + StatusItem(1, "Pumpenkreis"), + StatusItem(2, "Mischkreis"), + StatusItem(3, "Sollwert (Pumpe M1)"), ] HZ_ANFORDERUNG = [ - StatusItem(0,"aus"), - StatusItem(1,"witterungsgeführt"), - StatusItem(2,"konstant"), + StatusItem(0, "aus"), + StatusItem(1, "witterungsgeführt"), + StatusItem(2, "konstant"), ] HZ_BETRIEBSART = [ - StatusItem(0,"Automatik"), - StatusItem(1,"Komfort"), - StatusItem(2,"Normal"), - StatusItem(3,"Absenkbetrieb"), - StatusItem(4,"Standby"), + StatusItem(0, "Automatik"), + StatusItem(1, "Komfort"), + StatusItem(2, "Normal"), + StatusItem(3, "Absenkbetrieb"), + StatusItem(4, "Standby"), ] HZ_PARTY_PAUSE = [ - StatusItem(1,"Pause 12.0h"), - StatusItem(2,"Pause 11.5h"), - StatusItem(3,"Pause 11.0h"), - StatusItem(4,"Pause 10.5h"), - StatusItem(5,"Pause 10.0h"), - StatusItem(6,"Pause 9.5h"), - StatusItem(7,"Pause 9.0h"), - StatusItem(8,"Pause 8.5h"), - StatusItem(9,"Pause 8.0h"), - StatusItem(10,"Pause 7.5h"), - StatusItem(11,"Pause 7.0h"), - StatusItem(12,"Pause 6.5h"), - StatusItem(13,"Pause 6.0h"), - StatusItem(14,"Pause 5.5h"), - StatusItem(15,"Pause 5.0h"), - StatusItem(16,"Pause 4.5h"), - StatusItem(17,"Pause 4.0h"), - StatusItem(18,"Pause 3.5h"), - StatusItem(19,"Pause 3.0h"), - StatusItem(20,"Pause 2.5h"), - StatusItem(21,"Pause 2.0h"), - StatusItem(22,"Pause 1.5h"), - StatusItem(23,"Pause 1.0h"), - StatusItem(24,"Pause 0.5h"), - StatusItem(25,"Automatik"), - StatusItem(26,"Party 0.5h"), - StatusItem(27,"Party 1.0h"), - StatusItem(28,"Party 1.5h"), - StatusItem(29,"Party 2.0h"), - StatusItem(30,"Party 2.5h"), - StatusItem(31,"Party 3.0h"), - StatusItem(32,"Party 3.5h"), - StatusItem(33,"Party 4.0h"), - StatusItem(34,"Party 4.5h"), - StatusItem(35,"Party 5.0h"), - StatusItem(36,"Party 5.5h"), - StatusItem(37,"Party 6.0h"), - StatusItem(38,"Party 6.5h"), - StatusItem(39,"Party 7.0h"), - StatusItem(40,"Party 7.5h"), - StatusItem(41,"Party 8.0h"), - StatusItem(42,"Party 8.5h"), - StatusItem(43,"Party 9.0h"), - StatusItem(44,"Party 9.5h"), - StatusItem(45,"Party 10.0h"), - StatusItem(46,"Party 10.5h"), - StatusItem(47,"Party 11.0h"), - StatusItem(48,"Party 11.5h"), - StatusItem(49,"Party 12.0h"), + StatusItem(1, "Pause 12.0h"), + StatusItem(2, "Pause 11.5h"), + StatusItem(3, "Pause 11.0h"), + StatusItem(4, "Pause 10.5h"), + StatusItem(5, "Pause 10.0h"), + StatusItem(6, "Pause 9.5h"), + StatusItem(7, "Pause 9.0h"), + StatusItem(8, "Pause 8.5h"), + StatusItem(9, "Pause 8.0h"), + StatusItem(10, "Pause 7.5h"), + StatusItem(11, "Pause 7.0h"), + StatusItem(12, "Pause 6.5h"), + StatusItem(13, "Pause 6.0h"), + StatusItem(14, "Pause 5.5h"), + StatusItem(15, "Pause 5.0h"), + StatusItem(16, "Pause 4.5h"), + StatusItem(17, "Pause 4.0h"), + StatusItem(18, "Pause 3.5h"), + StatusItem(19, "Pause 3.0h"), + StatusItem(20, "Pause 2.5h"), + StatusItem(21, "Pause 2.0h"), + StatusItem(22, "Pause 1.5h"), + StatusItem(23, "Pause 1.0h"), + StatusItem(24, "Pause 0.5h"), + StatusItem(25, "Automatik"), + StatusItem(26, "Party 0.5h"), + StatusItem(27, "Party 1.0h"), + StatusItem(28, "Party 1.5h"), + StatusItem(29, "Party 2.0h"), + StatusItem(30, "Party 2.5h"), + StatusItem(31, "Party 3.0h"), + StatusItem(32, "Party 3.5h"), + StatusItem(33, "Party 4.0h"), + StatusItem(34, "Party 4.5h"), + StatusItem(35, "Party 5.0h"), + StatusItem(36, "Party 5.5h"), + StatusItem(37, "Party 6.0h"), + StatusItem(38, "Party 6.5h"), + StatusItem(39, "Party 7.0h"), + StatusItem(40, "Party 7.5h"), + StatusItem(41, "Party 8.0h"), + StatusItem(42, "Party 8.5h"), + StatusItem(43, "Party 9.0h"), + StatusItem(44, "Party 9.5h"), + StatusItem(45, "Party 10.0h"), + StatusItem(46, "Party 10.5h"), + StatusItem(47, "Party 11.0h"), + StatusItem(48, "Party 11.5h"), + StatusItem(49, "Party 12.0h"), ] WW_KONFIGURATION = [ - StatusItem(0,"aus"), - StatusItem(1,"Umlenkventil"), - StatusItem(2,"Pumpe"), + StatusItem(0, "aus"), + StatusItem(1, "Umlenkventil"), + StatusItem(2, "Pumpe"), ] W2_STATUS = [ - StatusItem(0,"aus"), - StatusItem(1,"ein"), + StatusItem(0, "aus"), + StatusItem(1, "ein"), ] W2_KONFIG = [ - StatusItem(0,"0"), - StatusItem(1,"1"), + StatusItem(0, "0"), + StatusItem(1, "1"), ] ##################################################### @@ -229,84 +231,84 @@ class DeviceConstants: ##################################################### RANGE_PERCENTAGE = [ - StatusItem(0,"min"), - StatusItem(100,"max"), - StatusItem(1,"step"), - StatusItem(1,"divider"), + StatusItem(0, "min"), + StatusItem(100, "max"), + StatusItem(1, "step"), + StatusItem(1, "divider"), ] TEMPRANGE_ROOM = [ - StatusItem(16,"min"), - StatusItem(30,"max"), - StatusItem(0.5,"step"), - StatusItem(10,"divider"), - StatusItem(-1,SensorDeviceClass.TEMPERATURE), + StatusItem(16, "min"), + StatusItem(30, "max"), + StatusItem(0.5, "step"), + StatusItem(10, "divider"), + StatusItem(-1, SensorDeviceClass.TEMPERATURE), ] TEMPRANGE_WATER = [ - StatusItem(30,"min"), - StatusItem(60,"max"), - StatusItem(0.5,"step"), - StatusItem(10,"divider"), - StatusItem(-1,SensorDeviceClass.TEMPERATURE), + StatusItem(30, "min"), + StatusItem(60, "max"), + StatusItem(0.5, "step"), + StatusItem(10, "divider"), + StatusItem(-1, SensorDeviceClass.TEMPERATURE), ] TEMPRANGE_SGREADY = [ - StatusItem(0,"min"), - StatusItem(10,"max"), - StatusItem(0.5,"step"), - StatusItem(10,"divider"), - StatusItem(-1,SensorDeviceClass.TEMPERATURE), + StatusItem(0, "min"), + StatusItem(10, "max"), + StatusItem(0.5, "step"), + StatusItem(10, "divider"), + StatusItem(-1, SensorDeviceClass.TEMPERATURE), ] TEMPRANGE_BIVALENZ = [ - StatusItem(-20,"min"), - StatusItem(10,"max"), - StatusItem(0.5,"step"), - StatusItem(10,"divider"), - StatusItem(-1,SensorDeviceClass.TEMPERATURE), + StatusItem(-20, "min"), + StatusItem(10, "max"), + StatusItem(0.5, "step"), + StatusItem(10, "divider"), + StatusItem(-1, SensorDeviceClass.TEMPERATURE), ] TEMPRANGE_STD = [ - StatusItem(-60,"min"), - StatusItem(100,"max"), - StatusItem(0.5,"step"), - StatusItem(10,"divider"), - StatusItem(-1,SensorDeviceClass.TEMPERATURE), + StatusItem(-60, "min"), + StatusItem(100, "max"), + StatusItem(0.5, "step"), + StatusItem(10, "divider"), + StatusItem(-1, SensorDeviceClass.TEMPERATURE), ] RANGE_HZKENNLINIE = [ - StatusItem(0,"min"), - StatusItem(3,"max"), - StatusItem(0.05,"step"), - StatusItem(100,"divider"), + StatusItem(0, "min"), + StatusItem(3, "max"), + StatusItem(0.05, "step"), + StatusItem(100, "divider"), ] TIMERANGE_WWPUSH = [ - StatusItem(0,"min"), - StatusItem(240,"max"), - StatusItem(5,"step"), - StatusItem(1,"divider"), + StatusItem(0, "min"), + StatusItem(240, "max"), + StatusItem(5, "step"), + StatusItem(1, "divider"), ] RANGE_FLOWRATE = [ - StatusItem(0,"min"), - StatusItem(3,"max"), - StatusItem(0.1,"step"), - StatusItem(100,"divider"), + StatusItem(0, "min"), + StatusItem(3, "max"), + StatusItem(0.1, "step"), + StatusItem(100, "divider"), ] RANGE_ENERGY = [ - StatusItem(-1,SensorDeviceClass.ENERGY), - StatusItem(1,"divider"), + StatusItem(-1, SensorDeviceClass.ENERGY), + StatusItem(1, "divider"), ] RANGE_CALCPOWER = [ - StatusItem(-1,SensorDeviceClass.POWER), - StatusItem(1,"divider"), - StatusItem(30002,"x"), - StatusItem(33104,"y") + StatusItem(-1, SensorDeviceClass.POWER), + StatusItem(1, "divider"), + StatusItem(30002, "x"), + StatusItem(33104, "y"), ] ############################################################################################################################## @@ -315,95 +317,580 @@ class DeviceConstants: ############################################################################################################################## MODBUS_SYS_ITEMS = [ - ModbusItem(30001,"Aussentemperatur",FORMATS.TEMPERATUR,TYPES.SENSOR,DEVICES.SYS, TEMPRANGE_STD), - ModbusItem(30002,"Luftansaugtemperatur",FORMATS.TEMPERATUR,TYPES.SENSOR,DEVICES.SYS, TEMPRANGE_STD), - ModbusItem(30003,"Fehler",FORMATS.STATUS,TYPES.SENSOR,DEVICES.SYS, SYS_FEHLER), - ModbusItem(30004,"Warnung",FORMATS.STATUS,TYPES.SENSOR,DEVICES.SYS, SYS_WARNUNG), - ModbusItem(30005,"Fehlerfrei",FORMATS.STATUS,TYPES.SENSOR,DEVICES.SYS, SYS_FEHLERFREI), - ModbusItem(30006,"Betriebsanzeige",FORMATS.STATUS,TYPES.SENSOR,DEVICES.SYS, SYS_BETRIEBSANZEIGE), - ModbusItem(40001,"Systembetriebsart",FORMATS.STATUS,TYPES.SELECT,DEVICES.SYS, SYS_BETRIEBSART), - - ModbusItem(33101,"Betrieb",FORMATS.STATUS,TYPES.SENSOR,DEVICES.WP, HP_BETRIEB), - ModbusItem(33102,"Störmeldung",FORMATS.STATUS,TYPES.SENSOR,DEVICES.WP, HP_STOERMELDUNG), - ModbusItem(33103,"Leistungsanforderung",FORMATS.PERCENTAGE,TYPES.SENSOR,DEVICES.WP), - ModbusItem(33103,"Wärmeleistung",FORMATS.POWER,TYPES.SENSOR_CALC,DEVICES.WP,RANGE_CALCPOWER), - ModbusItem(33104,"Vorlauftemperatur",FORMATS.TEMPERATUR,TYPES.SENSOR,DEVICES.WP, TEMPRANGE_STD), - ModbusItem(33105,"Rücklauftemperatur",FORMATS.TEMPERATUR,TYPES.SENSOR,DEVICES.WP, TEMPRANGE_STD), - ModbusItem(43101,"Konfiguration ",FORMATS.NUMBER,TYPES.NUMBER_RO,DEVICES.WP), - ModbusItem(43102,"Ruhemodus",FORMATS.STATUS,TYPES.NUMBER_RO,DEVICES.WP,HP_RUHEMODUS), - ModbusItem(43103,"Pumpe Einschaltart",FORMATS.NUMBER,TYPES.NUMBER_RO,DEVICES.WP), - ModbusItem(43104,"Pumpe Leistung Heizen",FORMATS.PERCENTAGE,TYPES.NUMBER_RO,DEVICES.WP,RANGE_PERCENTAGE), - ModbusItem(43105,"Pumpe Leistung Kühlen",FORMATS.PERCENTAGE,TYPES.NUMBER_RO,DEVICES.WP,RANGE_PERCENTAGE), - ModbusItem(43106,"Pumpe Leistung Warmwasser",FORMATS.PERCENTAGE,TYPES.NUMBER_RO,DEVICES.WP,RANGE_PERCENTAGE), - ModbusItem(43107,"Pumpe Leistung Abtaubetrieb",FORMATS.PERCENTAGE,TYPES.NUMBER_RO,DEVICES.WP,RANGE_PERCENTAGE), - ModbusItem(43108,"Volumenstrom Heizen",FORMATS.VOLUMENSTROM,TYPES.NUMBER_RO,DEVICES.WP, RANGE_FLOWRATE), - ModbusItem(43109,"Volumenstrom Kühlen",FORMATS.VOLUMENSTROM,TYPES.NUMBER_RO,DEVICES.WP,RANGE_FLOWRATE), - ModbusItem(43110,"Volumenstrom Warmwasser",FORMATS.VOLUMENSTROM,TYPES.NUMBER_RO,DEVICES.WP,RANGE_FLOWRATE), - - ModbusItem(31101,"Raumsolltemperatur",FORMATS.TEMPERATUR,TYPES.SENSOR,DEVICES.HZ, TEMPRANGE_ROOM), - ModbusItem(31102,"Raumtemperatur",FORMATS.TEMPERATUR,TYPES.SENSOR,DEVICES.HZ, TEMPRANGE_ROOM), - ModbusItem(31103,"Raumfeuchte",FORMATS.PERCENTAGE,TYPES.SENSOR,DEVICES.HZ), - ModbusItem(31104,"Vorlaufsolltemperatur",FORMATS.TEMPERATUR,TYPES.SENSOR,DEVICES.HZ, TEMPRANGE_STD), - ModbusItem(31105,"HZ_Vorlauftemperatur",FORMATS.TEMPERATUR,TYPES.SENSOR,DEVICES.HZ, TEMPRANGE_STD), - ModbusItem(41101,"HZ_Konfiguration",FORMATS.STATUS,TYPES.NUMBER_RO,DEVICES.HZ, HZ_KONFIGURATION), - ModbusItem(41102,"Anforderung Typ",FORMATS.STATUS,TYPES.NUMBER_RO,DEVICES.HZ, HZ_ANFORDERUNG), - ModbusItem(41103,"Betriebsart",FORMATS.STATUS,TYPES.SELECT,DEVICES.HZ, HZ_BETRIEBSART), - ModbusItem(41104,"Pause / Party",FORMATS.STATUS,TYPES.SELECT,DEVICES.HZ, HZ_PARTY_PAUSE), - ModbusItem(41105,"Raumsolltemperatur Komfort",FORMATS.TEMPERATUR,TYPES.NUMBER,DEVICES.HZ,TEMPRANGE_ROOM), - ModbusItem(41106,"Raumsolltemperatur Normal",FORMATS.TEMPERATUR,TYPES.NUMBER,DEVICES.HZ,TEMPRANGE_ROOM), - ModbusItem(41107,"Raumsolltemperatur Absenk",FORMATS.TEMPERATUR,TYPES.NUMBER,DEVICES.HZ,TEMPRANGE_ROOM), - ModbusItem(41108,"Heizkennlinie",FORMATS.KENNLINIE,TYPES.NUMBER,DEVICES.HZ,RANGE_HZKENNLINIE), - ModbusItem(41109,"Sommer Winter Umschaltung",FORMATS.TEMPERATUR,TYPES.NUMBER,DEVICES.HZ,TEMPRANGE_ROOM), - ModbusItem(41110,"Heizen Konstanttemperatur",FORMATS.TEMPERATUR,TYPES.NUMBER_RO,DEVICES.HZ,TEMPRANGE_ROOM), - ModbusItem(41111,"Heizen Konstanttemp Absenk",FORMATS.TEMPERATUR,TYPES.NUMBER_RO,DEVICES.HZ,TEMPRANGE_ROOM), - ModbusItem(41112,"Kühlen Konstanttemperatur",FORMATS.TEMPERATUR,TYPES.NUMBER_RO,DEVICES.HZ,TEMPRANGE_ROOM), - - ModbusItem(32101,"Warmwassersolltemperatur",FORMATS.TEMPERATUR,TYPES.SENSOR,DEVICES.WW,TEMPRANGE_WATER), - ModbusItem(32102,"Warmwassertemperatur",FORMATS.TEMPERATUR,TYPES.SENSOR,DEVICES.WW,TEMPRANGE_WATER), - ModbusItem(42101,"WW_Konfiguration",FORMATS.STATUS,TYPES.NUMBER_RO,DEVICES.WW,WW_KONFIGURATION), - ModbusItem(42102,"Warmwasser Push",FORMATS.TIME_MIN,TYPES.NUMBER,DEVICES.WW,TIMERANGE_WWPUSH), - ModbusItem(42103,"Warmwasser Normal",FORMATS.TEMPERATUR,TYPES.NUMBER,DEVICES.WW,TEMPRANGE_WATER), - ModbusItem(42104,"Warmwasser Absenk",FORMATS.TEMPERATUR,TYPES.NUMBER,DEVICES.WW,TEMPRANGE_WATER), - ModbusItem(42105,"SG Ready Anhebung",FORMATS.TEMPERATUR,TYPES.NUMBER,DEVICES.WW,TEMPRANGE_SGREADY), - - ModbusItem(34101,"Status 2. WEZ",FORMATS.STATUS,TYPES.SENSOR,DEVICES.W2,W2_STATUS), - ModbusItem(34102,"Betriebsstunden 2. WEZ",FORMATS.TIME_H,TYPES.SENSOR,DEVICES.W2), - ModbusItem(34103,"Schaltspiele 2. WEZ",FORMATS.NUMBER,TYPES.SENSOR,DEVICES.W2), - ModbusItem(34104,"Status E-Heizung 1",FORMATS.STATUS,TYPES.SENSOR,DEVICES.W2,W2_STATUS), - ModbusItem(34105,"Status E-Heizung 2",FORMATS.STATUS,TYPES.SENSOR,DEVICES.W2,W2_STATUS), - ModbusItem(34106,"Betriebsstunden E1",FORMATS.TIME_H,TYPES.SENSOR,DEVICES.W2), - ModbusItem(34107,"Betriebsstunden E2",FORMATS.TIME_H,TYPES.SENSOR,DEVICES.W2), - ModbusItem(44101,"W2_Konfiguration",FORMATS.STATUS,TYPES.SENSOR,DEVICES.W2,W2_KONFIG), - ModbusItem(44102,"Grenztemperatur",FORMATS.TEMPERATUR,TYPES.NUMBER,DEVICES.W2,TEMPRANGE_BIVALENZ), - ModbusItem(44103,"Bivalenztemperatur",FORMATS.TEMPERATUR,TYPES.NUMBER,DEVICES.W2,TEMPRANGE_BIVALENZ), - ModbusItem(44104,"Bivalenztemperatur WW",FORMATS.TEMPERATUR,TYPES.NUMBER,DEVICES.W2,TEMPRANGE_BIVALENZ), - - ModbusItem(36101,"Gesamt Energie heute",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36102,"Gesamt Energie gestern",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36103,"Gesamt Energie Monat",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36104,"Gesamt Energie Jahr",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36201,"Heizen Energie heute",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36202,"Heizen Energie gestern",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36203,"Heizen Energie Monat",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36204,"Heizen Energie Jahr",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36301,"Warmwasser Energie heute",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36302,"Warmwasser Energie gestern",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36303,"Warmwasser Energie Monat",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36304,"Warmwasser Energie Jahr",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36401,"Kühlen Energie heute",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36402,"Kühlen Energie gestern",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36403,"Kühlen Energie Monat",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36404,"Kühlen Energie Jahr",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36501,"Abtauen Energie heute",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36502,"Abtauen Energie gestern",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36503,"Abtauen Energie Monat",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36504,"Abtauen Energie Jahr",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36601,"Gesamt Energie II heute",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36602,"Gesamt Energie II gestern",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36603,"Gesamt Energie II Monat",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36604,"Gesamt Energie II Jahr",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36701,"Elektr. Energie heute",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36702,"Elektr. Energie gestern",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36703,"Elektr. Energie Monat",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), - ModbusItem(36704,"Elektr. Energie Jahr",FORMATS.ENERGY,TYPES.SENSOR,DEVICES.ST,RANGE_ENERGY), + ModbusItem( + 30001, + "Aussentemperatur", + FORMATS.TEMPERATUR, + TYPES.SENSOR, + DEVICES.SYS, + TEMPRANGE_STD, + ), + ModbusItem( + 30002, + "Luftansaugtemperatur", + FORMATS.TEMPERATUR, + TYPES.SENSOR, + DEVICES.SYS, + TEMPRANGE_STD, + ), + ModbusItem(30003, "Fehler", FORMATS.STATUS, TYPES.SENSOR, DEVICES.SYS, SYS_FEHLER), + ModbusItem( + 30004, "Warnung", FORMATS.STATUS, TYPES.SENSOR, DEVICES.SYS, SYS_WARNUNG + ), + ModbusItem( + 30005, "Fehlerfrei", FORMATS.STATUS, TYPES.SENSOR, DEVICES.SYS, SYS_FEHLERFREI + ), + ModbusItem( + 30006, + "Betriebsanzeige", + FORMATS.STATUS, + TYPES.SENSOR, + DEVICES.SYS, + SYS_BETRIEBSANZEIGE, + ), + ModbusItem( + 40001, + "Systembetriebsart", + FORMATS.STATUS, + TYPES.SELECT, + DEVICES.SYS, + SYS_BETRIEBSART, + ), + ModbusItem(33101, "Betrieb", FORMATS.STATUS, TYPES.SENSOR, DEVICES.WP, HP_BETRIEB), + ModbusItem( + 33102, "Störmeldung", FORMATS.STATUS, TYPES.SENSOR, DEVICES.WP, HP_STOERMELDUNG + ), + ModbusItem( + 33103, "Leistungsanforderung", FORMATS.PERCENTAGE, TYPES.SENSOR, DEVICES.WP + ), + ModbusItem( + 33103, + "Wärmeleistung", + FORMATS.POWER, + TYPES.SENSOR_CALC, + DEVICES.WP, + RANGE_CALCPOWER, + ), + ModbusItem( + 33104, + "Vorlauftemperatur", + FORMATS.TEMPERATUR, + TYPES.SENSOR, + DEVICES.WP, + TEMPRANGE_STD, + ), + ModbusItem( + 33105, + "Rücklauftemperatur", + FORMATS.TEMPERATUR, + TYPES.SENSOR, + DEVICES.WP, + TEMPRANGE_STD, + ), + ModbusItem(43101, "Konfiguration ", FORMATS.NUMBER, TYPES.NUMBER_RO, DEVICES.WP), + ModbusItem( + 43102, "Ruhemodus", FORMATS.STATUS, TYPES.NUMBER_RO, DEVICES.WP, HP_RUHEMODUS + ), + ModbusItem( + 43103, "Pumpe Einschaltart", FORMATS.NUMBER, TYPES.NUMBER_RO, DEVICES.WP + ), + ModbusItem( + 43104, + "Pumpe Leistung Heizen", + FORMATS.PERCENTAGE, + TYPES.NUMBER_RO, + DEVICES.WP, + RANGE_PERCENTAGE, + ), + ModbusItem( + 43105, + "Pumpe Leistung Kühlen", + FORMATS.PERCENTAGE, + TYPES.NUMBER_RO, + DEVICES.WP, + RANGE_PERCENTAGE, + ), + ModbusItem( + 43106, + "Pumpe Leistung Warmwasser", + FORMATS.PERCENTAGE, + TYPES.NUMBER_RO, + DEVICES.WP, + RANGE_PERCENTAGE, + ), + ModbusItem( + 43107, + "Pumpe Leistung Abtaubetrieb", + FORMATS.PERCENTAGE, + TYPES.NUMBER_RO, + DEVICES.WP, + RANGE_PERCENTAGE, + ), + ModbusItem( + 43108, + "Volumenstrom Heizen", + FORMATS.VOLUMENSTROM, + TYPES.NUMBER_RO, + DEVICES.WP, + RANGE_FLOWRATE, + ), + ModbusItem( + 43109, + "Volumenstrom Kühlen", + FORMATS.VOLUMENSTROM, + TYPES.NUMBER_RO, + DEVICES.WP, + RANGE_FLOWRATE, + ), + ModbusItem( + 43110, + "Volumenstrom Warmwasser", + FORMATS.VOLUMENSTROM, + TYPES.NUMBER_RO, + DEVICES.WP, + RANGE_FLOWRATE, + ), + ModbusItem( + 31101, + "Raumsolltemperatur", + FORMATS.TEMPERATUR, + TYPES.SENSOR, + DEVICES.HZ, + TEMPRANGE_ROOM, + ), + ModbusItem( + 31102, + "Raumtemperatur", + FORMATS.TEMPERATUR, + TYPES.SENSOR, + DEVICES.HZ, + TEMPRANGE_ROOM, + ), + ModbusItem(31103, "Raumfeuchte", FORMATS.PERCENTAGE, TYPES.SENSOR, DEVICES.HZ), + ModbusItem( + 31104, + "Vorlaufsolltemperatur", + FORMATS.TEMPERATUR, + TYPES.SENSOR, + DEVICES.HZ, + TEMPRANGE_STD, + ), + ModbusItem( + 31105, + "HZ_Vorlauftemperatur", + FORMATS.TEMPERATUR, + TYPES.SENSOR, + DEVICES.HZ, + TEMPRANGE_STD, + ), + ModbusItem( + 41101, + "HZ_Konfiguration", + FORMATS.STATUS, + TYPES.NUMBER_RO, + DEVICES.HZ, + HZ_KONFIGURATION, + ), + ModbusItem( + 41102, + "Anforderung Typ", + FORMATS.STATUS, + TYPES.NUMBER_RO, + DEVICES.HZ, + HZ_ANFORDERUNG, + ), + ModbusItem( + 41103, "Betriebsart", FORMATS.STATUS, TYPES.SELECT, DEVICES.HZ, HZ_BETRIEBSART + ), + ModbusItem( + 41104, "Pause / Party", FORMATS.STATUS, TYPES.SELECT, DEVICES.HZ, HZ_PARTY_PAUSE + ), + ModbusItem( + 41105, + "Raumsolltemperatur Komfort", + FORMATS.TEMPERATUR, + TYPES.NUMBER, + DEVICES.HZ, + TEMPRANGE_ROOM, + ), + ModbusItem( + 41106, + "Raumsolltemperatur Normal", + FORMATS.TEMPERATUR, + TYPES.NUMBER, + DEVICES.HZ, + TEMPRANGE_ROOM, + ), + ModbusItem( + 41107, + "Raumsolltemperatur Absenk", + FORMATS.TEMPERATUR, + TYPES.NUMBER, + DEVICES.HZ, + TEMPRANGE_ROOM, + ), + ModbusItem( + 41108, + "Heizkennlinie", + FORMATS.KENNLINIE, + TYPES.NUMBER, + DEVICES.HZ, + RANGE_HZKENNLINIE, + ), + ModbusItem( + 41109, + "Sommer Winter Umschaltung", + FORMATS.TEMPERATUR, + TYPES.NUMBER, + DEVICES.HZ, + TEMPRANGE_ROOM, + ), + ModbusItem( + 41110, + "Heizen Konstanttemperatur", + FORMATS.TEMPERATUR, + TYPES.NUMBER_RO, + DEVICES.HZ, + TEMPRANGE_ROOM, + ), + ModbusItem( + 41111, + "Heizen Konstanttemp Absenk", + FORMATS.TEMPERATUR, + TYPES.NUMBER_RO, + DEVICES.HZ, + TEMPRANGE_ROOM, + ), + ModbusItem( + 41112, + "Kühlen Konstanttemperatur", + FORMATS.TEMPERATUR, + TYPES.NUMBER_RO, + DEVICES.HZ, + TEMPRANGE_ROOM, + ), + ModbusItem( + 32101, + "Warmwassersolltemperatur", + FORMATS.TEMPERATUR, + TYPES.SENSOR, + DEVICES.WW, + TEMPRANGE_WATER, + ), + ModbusItem( + 32102, + "Warmwassertemperatur", + FORMATS.TEMPERATUR, + TYPES.SENSOR, + DEVICES.WW, + TEMPRANGE_WATER, + ), + ModbusItem( + 42101, + "WW_Konfiguration", + FORMATS.STATUS, + TYPES.NUMBER_RO, + DEVICES.WW, + WW_KONFIGURATION, + ), + ModbusItem( + 42102, + "Warmwasser Push", + FORMATS.TIME_MIN, + TYPES.NUMBER, + DEVICES.WW, + TIMERANGE_WWPUSH, + ), + ModbusItem( + 42103, + "Warmwasser Normal", + FORMATS.TEMPERATUR, + TYPES.NUMBER, + DEVICES.WW, + TEMPRANGE_WATER, + ), + ModbusItem( + 42104, + "Warmwasser Absenk", + FORMATS.TEMPERATUR, + TYPES.NUMBER, + DEVICES.WW, + TEMPRANGE_WATER, + ), + ModbusItem( + 42105, + "SG Ready Anhebung", + FORMATS.TEMPERATUR, + TYPES.NUMBER, + DEVICES.WW, + TEMPRANGE_SGREADY, + ), + ModbusItem( + 34101, "Status 2. WEZ", FORMATS.STATUS, TYPES.SENSOR, DEVICES.W2, W2_STATUS + ), + ModbusItem( + 34102, "Schaltspiele E-Heizung 1", FORMATS.NUMBER, TYPES.SENSOR, DEVICES.W2 + ), + ModbusItem( + 34103, "Schaltspiele E-Heizung 2", FORMATS.NUMBER, TYPES.SENSOR, DEVICES.W2 + ), + ModbusItem( + 34104, "Status E-Heizung 1", FORMATS.STATUS, TYPES.SENSOR, DEVICES.W2, W2_STATUS + ), + ModbusItem( + 34105, "Status E-Heizung 2", FORMATS.STATUS, TYPES.SENSOR, DEVICES.W2, W2_STATUS + ), + ModbusItem(34106, "Betriebsstunden E1", FORMATS.TIME_H, TYPES.SENSOR, DEVICES.W2), + ModbusItem(34107, "Betriebsstunden E2", FORMATS.TIME_H, TYPES.SENSOR, DEVICES.W2), + ModbusItem( + 44101, "W2_Konfiguration", FORMATS.STATUS, TYPES.SENSOR, DEVICES.W2, W2_KONFIG + ), + ModbusItem( + 44102, + "Grenztemperatur", + FORMATS.TEMPERATUR, + TYPES.NUMBER, + DEVICES.W2, + TEMPRANGE_BIVALENZ, + ), + ModbusItem( + 44103, + "Bivalenztemperatur", + FORMATS.TEMPERATUR, + TYPES.NUMBER, + DEVICES.W2, + TEMPRANGE_BIVALENZ, + ), + ModbusItem( + 44104, + "Bivalenztemperatur WW", + FORMATS.TEMPERATUR, + TYPES.NUMBER, + DEVICES.W2, + TEMPRANGE_BIVALENZ, + ), + ModbusItem( + 36101, + "Gesamt Energie heute", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36102, + "Gesamt Energie gestern", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36103, + "Gesamt Energie Monat", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36104, + "Gesamt Energie Jahr", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36201, + "Heizen Energie heute", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36202, + "Heizen Energie gestern", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36203, + "Heizen Energie Monat", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36204, + "Heizen Energie Jahr", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36301, + "Warmwasser Energie heute", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36302, + "Warmwasser Energie gestern", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36303, + "Warmwasser Energie Monat", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36304, + "Warmwasser Energie Jahr", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36401, + "Kühlen Energie heute", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36402, + "Kühlen Energie gestern", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36403, + "Kühlen Energie Monat", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36404, + "Kühlen Energie Jahr", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36501, + "Abtauen Energie heute", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36502, + "Abtauen Energie gestern", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36503, + "Abtauen Energie Monat", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36504, + "Abtauen Energie Jahr", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36601, + "Gesamt Energie II heute", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36602, + "Gesamt Energie II gestern", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36603, + "Gesamt Energie II Monat", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36604, + "Gesamt Energie II Jahr", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36701, + "Elektr. Energie heute", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36702, + "Elektr. Energie gestern", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36703, + "Elektr. Energie Monat", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), + ModbusItem( + 36704, + "Elektr. Energie Jahr", + FORMATS.ENERGY, + TYPES.SENSOR, + DEVICES.ST, + RANGE_ENERGY, + ), ] diff --git a/custom_components/weishaupt_modbus/manifest.json b/custom_components/weishaupt_modbus/manifest.json index 322d9b9..3462f0c 100644 --- a/custom_components/weishaupt_modbus/manifest.json +++ b/custom_components/weishaupt_modbus/manifest.json @@ -6,7 +6,7 @@ "documentation": "https://github.com/OStrama/weishaupt_modbus/", "iot_class": "local_polling", "issue_tracker": "https://github.com/OStrama/weishaupt_modbus/issues", - "requirements": [], - "version": "0.0.6" + "requirements": ["pymodbus"], + "version": "0.0.7" } From 9a29e9ac8cdf1a581a6bb4781ac1d746146f2dfb Mon Sep 17 00:00:00 2001 From: Olaf Strama Date: Mon, 21 Oct 2024 17:55:42 +0000 Subject: [PATCH 2/6] better formatting --- custom_components/weishaupt_modbus/items.py | 17 +- .../weishaupt_modbus/kennfeld.py | 149 +++++++++++------- custom_components/weishaupt_modbus/number.py | 6 +- custom_components/weishaupt_modbus/select.py | 6 +- custom_components/weishaupt_modbus/sensor.py | 11 +- 5 files changed, 120 insertions(+), 69 deletions(-) diff --git a/custom_components/weishaupt_modbus/items.py b/custom_components/weishaupt_modbus/items.py index df3e83c..b81c735 100644 --- a/custom_components/weishaupt_modbus/items.py +++ b/custom_components/weishaupt_modbus/items.py @@ -1,14 +1,15 @@ from .const import TYPES + # An item of a status, e.g. error code and error text along with a precise description -# A class is intentionally defined here because the assignment via dictionaries would not work so elegantly in the end, +# A class is intentionally defined here because the assignment via dictionaries would not work so elegantly in the end, # especially when searching backwards. (At least I don't know how...) -class StatusItem(): +class StatusItem: _number = None _text = None _description = None - def __init__(self, number, text, description = None): + def __init__(self, number, text, description=None): self._number = number self._text = text self._description = description @@ -37,13 +38,14 @@ def description(self): def description(self, value) -> None: self._description = value -# A Modbus item, consisting of address, name, + +# A Modbus item, consisting of address, name, # format (temperature, status, ..), # type (sensor, number, ..), # device (System, Heatpump, ..) and # optional result list from status items # (number entities: status = limits? -class ModbusItem(): +class ModbusItem: _address = None _name = "empty" _format = None @@ -51,17 +53,18 @@ class ModbusItem(): _resultlist = None _device = None - def __init__(self, address, name, format, type, device, resultlist = None): + def __init__(self, address, name, format, type, device, resultlist=None): self._address = address self._name = name self._format = format self._type = type self._device = device self._resultlist = resultlist - + @property def address(self): return self._address + @property def name(self): return self._name diff --git a/custom_components/weishaupt_modbus/kennfeld.py b/custom_components/weishaupt_modbus/kennfeld.py index 495a646..ebeca48 100644 --- a/custom_components/weishaupt_modbus/kennfeld.py +++ b/custom_components/weishaupt_modbus/kennfeld.py @@ -1,27 +1,64 @@ -#from scipy.interpolate import CubicSpline +# from scipy.interpolate import CubicSpline from numpy.polynomial import Chebyshev import numpy as np -#import matplotlib.pyplot as plt +# import matplotlib.pyplot as plt import json from .const import CONST -class PowerMap(): + +class PowerMap: # these are values extracted from the characteristic curves of heating power found ion the documentation of my heat pump. - # there are two diagrams: + # there are two diagrams: # - heating power vs. outside temperature @ 35 °C flow temperature # - heating power vs. outside temperature @ 55 °C flow temperature - known_x = [ -30, -25, -22, -20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40] + known_x = [-30, -25, -22, -20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40] # known power values read out from the graphs plotted in documentation. Only 35 °C and 55 °C available - known_y = [[ 5700, 5700, 5700, 5700, 6290, 7580, 8660, 9625, 10300, 10580, 10750, 10790, 10830, 11000, 11000, 11000 ], - [ 5700, 5700, 5700, 5700, 6860, 7300, 8150, 9500, 10300, 10580, 10750, 10790, 10830, 11000, 11000, 11000 ]] + known_y = [ + [ + 5700, + 5700, + 5700, + 5700, + 6290, + 7580, + 8660, + 9625, + 10300, + 10580, + 10750, + 10790, + 10830, + 11000, + 11000, + 11000, + ], + [ + 5700, + 5700, + 5700, + 5700, + 6860, + 7300, + 8150, + 9500, + 10300, + 10580, + 10750, + 10790, + 10830, + 11000, + 11000, + 11000, + ], + ] # the known x values for linear interpolation known_t = [35, 55] # the aim is generating a 2D power map that gives back the actual power for a certain flow temperature and a given outside temperature # the map should have values on every integer temperature point - # at first, all flow temoperatures are lineary interpolated + # at first, all flow temoperatures are lineary interpolated steps = 21 r_to_interpolate = np.linspace(35, 55, steps) @@ -31,36 +68,38 @@ class PowerMap(): interp_y = [] def __init__(self) -> None: - #try to load values from json file - + # try to load values from json file + try: openfile = open(CONST.KENNFELDFILE, "r") except IOError: - kennfeld = {'known_x': self.known_x, - 'known_y': self.known_y, - 'known_t': self.known_t} + kennfeld = { + "known_x": self.known_x, + "known_y": self.known_y, + "known_t": self.known_t, + } with open(CONST.KENNFELDFILE, "w") as outfile: json.dump(kennfeld, outfile) else: json_object = json.load(openfile) - self.known_x = json_object['known_x'] - self.known_y = json_object['known_y'] - self.known_t = json_object['known_t'] + self.known_x = json_object["known_x"] + self.known_y = json_object["known_y"] + self.known_t = json_object["known_t"] openfile.close() # build the matrix with linear interpolated samples # 1st and last row are populated by known values from diagrem, the rest is zero self.interp_y.append(self.known_y[0]) - v = np.linspace(0, self.steps-3, self.steps-2) + v = np.linspace(0, self.steps - 3, self.steps - 2) for idx in v: self.interp_y.append(np.zeros_like(self.known_x)) self.interp_y.append(self.known_y[1]) for idx in range(0, len(self.known_x)): # the known y for every column - yk = [self.interp_y[0][idx], self.interp_y[self.steps-1][idx]] + yk = [self.interp_y[0][idx], self.interp_y[self.steps - 1][idx]] - #linear interpolation + # linear interpolation ip = np.interp(self.r_to_interpolate, self.known_t, yk) # sort the interpolated values into the array @@ -72,59 +111,55 @@ def __init__(self) -> None: t = np.linspace(-30, 40, 71) # cubic spline interpolation of power curves for idx in range(0, len(self.r_to_interpolate)): - #f = CubicSpline(self.known_x, self.interp_y[idx], bc_type='natural') - f = Chebyshev.fit(self.known_x, self.interp_y[idx], deg = 8) + # f = CubicSpline(self.known_x, self.interp_y[idx], bc_type='natural') + f = Chebyshev.fit(self.known_x, self.interp_y[idx], deg=8) self.max_power.append(f(t)) - def map(self,x,y): - - numrows = len(self.max_power) # 3 rows in your example - - numcols = len(self.max_power[0]) # 2 columns in your example - x=x-self.known_x[0] - if x<0: - x=0 - if x>70: - x= 70 - y=y-self.known_t[0] - if y<0: - y=0 - if y> (self.steps-1): - y=self.steps-1 - + def map(self, x, y): + numrows = len(self.max_power) # 3 rows in your example + + numcols = len(self.max_power[0]) # 2 columns in your example + x = x - self.known_x[0] + if x < 0: + x = 0 + if x > 70: + x = 70 + y = y - self.known_t[0] + if y < 0: + y = 0 + if y > (self.steps - 1): + y = self.steps - 1 + return self.max_power[int(y)][int(x)] -#map = PowerMap() +# map = PowerMap() -#plt.plot(t,np.transpose(map.max_power)) -#plt.ylabel('Max Power') -#plt.xlabel('°C') -#plt.show() +# plt.plot(t,np.transpose(map.max_power)) +# plt.ylabel('Max Power') +# plt.xlabel('°C') +# plt.show() -#kennfeld = {'known_x': map.known_x, +# kennfeld = {'known_x': map.known_x, # 'known_y': map.known_y, # 'known_t': map.known_t} -#with open("sample1.json", "w") as outfile: +# with open("sample1.json", "w") as outfile: # outfile.write(kennfeld) - -#with open("sample2.json", "w") as outfile: +# with open("sample2.json", "w") as outfile: # json.dump(kennfeld, outfile) -#with open('sample2.json', 'r') as openfile: - - # Reading from json file - #json_object = json.load(openfile) - -#map.known_x = json_object['known_x'] -#map.known_y = json_object['known_y'] -#map.known_t = json_object['known_t'] +# with open('sample2.json', 'r') as openfile: -#print(map.known_x) -#print(map.known_y) -#print(map.known_t) +# Reading from json file +# json_object = json.load(openfile) +# map.known_x = json_object['known_x'] +# map.known_y = json_object['known_y'] +# map.known_t = json_object['known_t'] +# print(map.known_x) +# print(map.known_y) +# print(map.known_t) diff --git a/custom_components/weishaupt_modbus/number.py b/custom_components/weishaupt_modbus/number.py index 459d1a0..14106d6 100644 --- a/custom_components/weishaupt_modbus/number.py +++ b/custom_components/weishaupt_modbus/number.py @@ -10,6 +10,7 @@ from .hpconst import MODBUS_SYS_ITEMS from .entities import BuildEntityList + async def async_setup_entry( hass: HomeAssistant, # config: ConfigType, @@ -20,4 +21,7 @@ async def async_setup_entry( """Set up the sensor platform.""" Entries = [] - async_add_entities(BuildEntityList(Entries, config_entry, MODBUS_SYS_ITEMS,TYPES.NUMBER), update_before_add=True) + async_add_entities( + BuildEntityList(Entries, config_entry, MODBUS_SYS_ITEMS, TYPES.NUMBER), + update_before_add=True, + ) diff --git a/custom_components/weishaupt_modbus/select.py b/custom_components/weishaupt_modbus/select.py index 0470c2e..da70ca8 100644 --- a/custom_components/weishaupt_modbus/select.py +++ b/custom_components/weishaupt_modbus/select.py @@ -6,6 +6,7 @@ from .hpconst import MODBUS_SYS_ITEMS from .entities import BuildEntityList + async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, @@ -14,4 +15,7 @@ async def async_setup_entry( """Select entry setup.""" Entries = [] - async_add_entities(BuildEntityList(Entries, config_entry, MODBUS_SYS_ITEMS,TYPES.SELECT), update_before_add=True) + async_add_entities( + BuildEntityList(Entries, config_entry, MODBUS_SYS_ITEMS, TYPES.SELECT), + update_before_add=True, + ) diff --git a/custom_components/weishaupt_modbus/sensor.py b/custom_components/weishaupt_modbus/sensor.py index 1e485fa..568e7d3 100644 --- a/custom_components/weishaupt_modbus/sensor.py +++ b/custom_components/weishaupt_modbus/sensor.py @@ -9,6 +9,7 @@ from .hpconst import MODBUS_SYS_ITEMS from .entities import BuildEntityList + async def async_setup_entry( hass: HomeAssistant, # config: ConfigType, @@ -20,6 +21,10 @@ async def async_setup_entry( Entries = [] Entries = BuildEntityList(Entries, config_entry, MODBUS_SYS_ITEMS, TYPES.NUMBER_RO) - Entries = BuildEntityList(Entries, config_entry, MODBUS_SYS_ITEMS, TYPES.SENSOR_CALC) - async_add_entities(BuildEntityList(Entries, config_entry, MODBUS_SYS_ITEMS,TYPES.SENSOR), update_before_add=True) - + Entries = BuildEntityList( + Entries, config_entry, MODBUS_SYS_ITEMS, TYPES.SENSOR_CALC + ) + async_add_entities( + BuildEntityList(Entries, config_entry, MODBUS_SYS_ITEMS, TYPES.SENSOR), + update_before_add=True, + ) From 15a9ee96c615069f1fac68345d86dba57a765fb7 Mon Sep 17 00:00:00 2001 From: Olaf Strama Date: Mon, 21 Oct 2024 17:57:03 +0000 Subject: [PATCH 3/6] better formatting --- .../weishaupt_modbus/modbusobject.py | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/custom_components/weishaupt_modbus/modbusobject.py b/custom_components/weishaupt_modbus/modbusobject.py index c9890df..4ea588a 100644 --- a/custom_components/weishaupt_modbus/modbusobject.py +++ b/custom_components/weishaupt_modbus/modbusobject.py @@ -8,9 +8,10 @@ # log = logging.getLogger() # log.setLevel(logging.DEBUG) + # A Modbus object that contains a Modbus item and communicates with the Modbus # it contains a ModbusClient for setting and getting Modbus register values -class ModbusObject(): +class ModbusObject: _ModbusItem = None _DataFormat = None @@ -20,7 +21,7 @@ class ModbusObject(): def __init__(self, config_entry, modbus_item): self._ModbusItem = modbus_item - #self._HeatPump = heatpump + # self._HeatPump = heatpump self._ip = config_entry.data[CONF_HOST] self._port = config_entry.data[CONF_PORT] @@ -40,21 +41,27 @@ def value(self): match self._ModbusItem.type: case TYPES.SENSOR | TYPES.SENSOR_CALC: # Sensor entities are read-only - return self._ModbusClient.read_input_registers(self._ModbusItem.address, slave=1).registers[0] + return self._ModbusClient.read_input_registers( + self._ModbusItem.address, slave=1 + ).registers[0] case TYPES.SELECT | TYPES.NUMBER | TYPES.NUMBER_RO: - return self._ModbusClient.read_holding_registers(self._ModbusItem.address, slave=1).registers[0] + return self._ModbusClient.read_holding_registers( + self._ModbusItem.address, slave=1 + ).registers[0] except: # noqa: E722 return None @value.setter - def value(self,value) -> None: + def value(self, value) -> None: try: match self._ModbusItem.type: case TYPES.SENSOR | TYPES.NUMBER_RO | TYPES.SENSOR_CALC: - # Sensor entities are read-only + # Sensor entities are read-only return case _: self.connect() - self._ModbusClient.write_register(self._ModbusItem.address, int(value), slave=1) + self._ModbusClient.write_register( + self._ModbusItem.address, int(value), slave=1 + ) except: # noqua: E722 return None From 9f5d3c87829a2acbd679f10b3acf7aadc8d7048f Mon Sep 17 00:00:00 2001 From: Olaf Strama Date: Mon, 21 Oct 2024 18:20:26 +0000 Subject: [PATCH 4/6] added async modbus handling according to https://github.com/MadOne/weishaupt_modbus/commit/e1b531ce3255e932bcd0fe12cfa749980e1b6dc4 --- .../weishaupt_modbus/entities.py | 29 +++++++++--------- .../weishaupt_modbus/modbusobject.py | 30 +++++++++++-------- 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/custom_components/weishaupt_modbus/entities.py b/custom_components/weishaupt_modbus/entities.py index a240b42..ab7575b 100644 --- a/custom_components/weishaupt_modbus/entities.py +++ b/custom_components/weishaupt_modbus/entities.py @@ -1,3 +1,4 @@ +import warnings from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_PORT from homeassistant.components.sensor import ( @@ -90,12 +91,12 @@ def calcPercentage(self, val: float): return val / self._divider @property - def translateVal(self): + async def translateVal(self): # reads an translates a value from the modbus mbo = ModbusObject(self._config_entry, self._modbus_item) if mbo == None: return None - val = mbo.value + val = await mbo.value match self._modbus_item.format: case FORMATS.TEMPERATUR: return self.calcTemperature(val) @@ -109,7 +110,7 @@ def translateVal(self): return val / self._divider @translateVal.setter - def translateVal(self, value): + async def translateVal(self, value): # translates and writes a value to the modbus mbo = ModbusObject(self._config_entry, self._modbus_item) if mbo == None: @@ -146,7 +147,7 @@ def __init__(self, config_entry, modbus_item) -> None: async def async_update(self) -> None: # the synching is done by the ModbusObject of the entity - self._attr_native_value = self.translateVal + self._attr_native_value = await self.translateVal @property def device_info(self) -> DeviceInfo: @@ -164,7 +165,7 @@ def __init__(self, config_entry, modbus_item) -> None: async def async_update(self) -> None: # the synching is done by the ModbusObject of the entity - self._attr_native_value = self.translateVal + self._attr_native_value = await self.translateVal def calcPower(self, val, x, y): if val == None: @@ -172,7 +173,7 @@ def calcPower(self, val, x, y): return (val / 100) * self.my_map.map(x, y) @property - def translateVal(self): + async def translateVal(self): # reads an translates a value from the modbus mbo = ModbusObject(self._config_entry, self._modbus_item) val = self.calcPercentage(mbo.value) @@ -188,7 +189,7 @@ def translateVal(self): mbo_x = ModbusObject(self._config_entry, mb_x) if mbo_x == None: return None - val_x = self.calcTemperature(mbo_x.value) / 10 + val_x = self.calcTemperature(await mbo_x.value) / 10 mb_y = ModbusItem( self._modbus_item.getNumberFromText("y"), "y", @@ -200,7 +201,7 @@ def translateVal(self): mbo_y = ModbusObject(self._config_entry, mb_y) if mbo_x == None: return None - val_y = self.calcTemperature(mbo_y.value) / 10 + val_y = self.calcTemperature(await mbo_y.value) / 10 match self._modbus_item.format: case FORMATS.POWER: @@ -209,7 +210,7 @@ def translateVal(self): return val / self._divider @property - def device_info(self) -> DeviceInfo: + async def device_info(self) -> DeviceInfo: return MySensorEntity.my_device_info(self) @@ -232,12 +233,12 @@ def __init__(self, config_entry, modbus_item) -> None: async def async_set_native_value(self, value: float) -> None: self.translateVal = value - self._attr_native_value = self.translateVal + self._attr_native_value = await self.translateVal self.async_write_ha_state() async def async_update(self) -> None: # the synching is done by the ModbusObject of the entity - self._attr_native_value = self.translateVal + self._attr_native_value = await self.translateVal @property def device_info(self) -> DeviceInfo: @@ -263,14 +264,14 @@ def __init__(self, config_entry, modbus_item) -> None: async def async_select_option(self, option: str) -> None: # the synching is done by the ModbusObject of the entity self.translateVal = option - self._attr_current_option = self.translateVal + self._attr_current_option = await self.translateVal self.async_write_ha_state() async def async_update(self) -> None: # the synching is done by the ModbusObject of the entity # await self.coordinator.async_request_refresh() - self._attr_current_option = self.translateVal + self._attr_current_option = await self.translateVal @property - def device_info(self) -> DeviceInfo: + async def device_info(self) -> DeviceInfo: return MyEntity.my_device_info(self) diff --git a/custom_components/weishaupt_modbus/modbusobject.py b/custom_components/weishaupt_modbus/modbusobject.py index 4ea588a..4a5f4a4 100644 --- a/custom_components/weishaupt_modbus/modbusobject.py +++ b/custom_components/weishaupt_modbus/modbusobject.py @@ -1,6 +1,6 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_HOST, CONF_PORT -from pymodbus.client import ModbusTcpClient as ModbusClient +from pymodbus.client import AsyncModbusTcpClient from .const import FORMATS, TYPES # import logging @@ -21,46 +21,50 @@ class ModbusObject: def __init__(self, config_entry, modbus_item): self._ModbusItem = modbus_item - # self._HeatPump = heatpump self._ip = config_entry.data[CONF_HOST] self._port = config_entry.data[CONF_PORT] self._ModbusClient = None - def connect(self): + async def connect(self): try: - self._ModbusClient = ModbusClient(host=self._ip, port=self._port) + self._ModbusClient = AsyncModbusTcpClient(host=self._ip, port=self._port) + await self._ModbusClient.connect() return self._ModbusClient.connected # noqa: TRY300 except: # noqa: E722 return None @property - def value(self): + async def value(self): try: - self.connect() + await self.connect() match self._ModbusItem.type: case TYPES.SENSOR | TYPES.SENSOR_CALC: # Sensor entities are read-only - return self._ModbusClient.read_input_registers( - self._ModbusItem.address, slave=1 + return ( + await self._ModbusClient.read_input_registers( + self._ModbusItem.address, slave=1 + ) ).registers[0] case TYPES.SELECT | TYPES.NUMBER | TYPES.NUMBER_RO: - return self._ModbusClient.read_holding_registers( - self._ModbusItem.address, slave=1 + return ( + await self._ModbusClient.read_holding_registers( + self._ModbusItem.address, slave=1 + ) ).registers[0] except: # noqa: E722 return None @value.setter - def value(self, value) -> None: + async def value(self, value) -> None: try: match self._ModbusItem.type: case TYPES.SENSOR | TYPES.NUMBER_RO | TYPES.SENSOR_CALC: # Sensor entities are read-only return case _: - self.connect() - self._ModbusClient.write_register( + await self.connect() + await self._ModbusClient.write_register( self._ModbusItem.address, int(value), slave=1 ) except: # noqua: E722 From ab0a83c2c8260b361e3231e1c71c99efbda94a75 Mon Sep 17 00:00:00 2001 From: Olaf Strama Date: Mon, 21 Oct 2024 19:09:56 +0000 Subject: [PATCH 5/6] debugging async modbus --- .../weishaupt_modbus/entities.py | 24 ++++++++++--------- .../weishaupt_modbus/modbusobject.py | 4 ++-- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/custom_components/weishaupt_modbus/entities.py b/custom_components/weishaupt_modbus/entities.py index ab7575b..378ad8e 100644 --- a/custom_components/weishaupt_modbus/entities.py +++ b/custom_components/weishaupt_modbus/entities.py @@ -109,8 +109,8 @@ async def translateVal(self): return val return val / self._divider - @translateVal.setter - async def translateVal(self, value): + # @translateVal.setter + async def settranslateVal(self, value): # translates and writes a value to the modbus mbo = ModbusObject(self._config_entry, self._modbus_item) if mbo == None: @@ -122,7 +122,7 @@ async def translateVal(self, value): val = self._modbus_item.getNumberFromText(value) case _: val = value * self._divider - mbo.value = val + await mbo.setvalue(val) # = val def my_device_info(self) -> DeviceInfo: # helper to build the device info @@ -176,7 +176,7 @@ def calcPower(self, val, x, y): async def translateVal(self): # reads an translates a value from the modbus mbo = ModbusObject(self._config_entry, self._modbus_item) - val = self.calcPercentage(mbo.value) + val = self.calcPercentage(await mbo.value) mb_x = ModbusItem( self._modbus_item.getNumberFromText("x"), @@ -189,7 +189,8 @@ async def translateVal(self): mbo_x = ModbusObject(self._config_entry, mb_x) if mbo_x == None: return None - val_x = self.calcTemperature(await mbo_x.value) / 10 + t_temp = await mbo_x.value + val_x = self.calcTemperature(t_temp) / 10 mb_y = ModbusItem( self._modbus_item.getNumberFromText("y"), "y", @@ -199,9 +200,10 @@ async def translateVal(self): TEMPRANGE_STD, ) mbo_y = ModbusObject(self._config_entry, mb_y) - if mbo_x == None: + if mbo_y == None: return None - val_y = self.calcTemperature(await mbo_y.value) / 10 + t_temp = await mbo_y.value + val_y = self.calcTemperature(t_temp) / 10 match self._modbus_item.format: case FORMATS.POWER: @@ -210,7 +212,7 @@ async def translateVal(self): return val / self._divider @property - async def device_info(self) -> DeviceInfo: + def device_info(self) -> DeviceInfo: return MySensorEntity.my_device_info(self) @@ -232,7 +234,7 @@ def __init__(self, config_entry, modbus_item) -> None: self._attr_native_step = self._modbus_item.getNumberFromText("step") async def async_set_native_value(self, value: float) -> None: - self.translateVal = value + await self.settranslateVal(value) self._attr_native_value = await self.translateVal self.async_write_ha_state() @@ -263,7 +265,7 @@ def __init__(self, config_entry, modbus_item) -> None: async def async_select_option(self, option: str) -> None: # the synching is done by the ModbusObject of the entity - self.translateVal = option + await self.settranslateVal(option) self._attr_current_option = await self.translateVal self.async_write_ha_state() @@ -273,5 +275,5 @@ async def async_update(self) -> None: self._attr_current_option = await self.translateVal @property - async def device_info(self) -> DeviceInfo: + def device_info(self) -> DeviceInfo: return MyEntity.my_device_info(self) diff --git a/custom_components/weishaupt_modbus/modbusobject.py b/custom_components/weishaupt_modbus/modbusobject.py index 4a5f4a4..02cceba 100644 --- a/custom_components/weishaupt_modbus/modbusobject.py +++ b/custom_components/weishaupt_modbus/modbusobject.py @@ -55,8 +55,8 @@ async def value(self): except: # noqa: E722 return None - @value.setter - async def value(self, value) -> None: + # @value.setter + async def setvalue(self, value) -> None: try: match self._ModbusItem.type: case TYPES.SENSOR | TYPES.NUMBER_RO | TYPES.SENSOR_CALC: From f7f8c180790291f325efcafbf9fcd9f59e2e91d2 Mon Sep 17 00:00:00 2001 From: OStrama <66820413+OStrama@users.noreply.github.com> Date: Mon, 21 Oct 2024 21:36:54 +0200 Subject: [PATCH 6/6] Update manifest.json --- custom_components/weishaupt_modbus/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/weishaupt_modbus/manifest.json b/custom_components/weishaupt_modbus/manifest.json index 3462f0c..c0531f7 100644 --- a/custom_components/weishaupt_modbus/manifest.json +++ b/custom_components/weishaupt_modbus/manifest.json @@ -7,6 +7,6 @@ "iot_class": "local_polling", "issue_tracker": "https://github.com/OStrama/weishaupt_modbus/issues", "requirements": ["pymodbus"], - "version": "0.0.7" + "version": "0.0.8" }