diff --git a/custom_components/senec/__init__.py b/custom_components/senec/__init__.py index 2518394..8f42029 100644 --- a/custom_components/senec/__init__.py +++ b/custom_components/senec/__init__.py @@ -17,6 +17,18 @@ from custom_components.senec.pysenec_ha import Senec, Inverter, MySenecWebPortal +from custom_components.senec.pysenec_ha.constants import ( + SENEC_SECTION_BMS, + SENEC_SECTION_ENERGY, + SENEC_SECTION_FAN_SPEED, + SENEC_SECTION_STATISTIC, + SENEC_SECTION_PM1OBJ1, + SENEC_SECTION_PM1OBJ2, + SENEC_SECTION_PV1, + SENEC_SECTION_PWR_UNIT, + SENEC_SECTION_TEMPMEASURE, + SENEC_SECTION_WALLBOX +) from .const import ( DOMAIN, @@ -35,6 +47,9 @@ CONF_SYSTYPE_WEB, CONF_DEV_MASTER_NUM, MAIN_SENSOR_TYPES, + MAIN_BIN_SENSOR_TYPES, + QUERY_BMS_KEY, + QUERY_FANDATA_KEY, QUERY_WALLBOX_KEY, QUERY_SPARE_CAPACITY_KEY, ) @@ -145,19 +160,43 @@ def __init__(self, hass: HomeAssistant, session, config_entry): # check if any of the wallbox-sensors is enabled... and only THEN # we will include the 'WALLBOX' in our POST to the lala.cgi - opt = {QUERY_WALLBOX_KEY: False} + opt = {QUERY_WALLBOX_KEY: False, QUERY_BMS_KEY: False, QUERY_FANDATA_KEY: False} if hass is not None and config_entry.title is not None: registry = entity_registry.async_get(hass) if registry is not None: sluged_title = slugify(config_entry.title) for description in MAIN_SENSOR_TYPES: - if not opt[QUERY_WALLBOX_KEY] and 'wallbox_' in description.key: + if not opt[QUERY_WALLBOX_KEY] and SENEC_SECTION_WALLBOX == description.senec_lala_section: a_sensor_id = f"sensor.{sluged_title}_{description.key}" a_entity = registry.async_get(a_sensor_id) if a_entity is not None and a_entity.disabled_by is None: _LOGGER.info("***** QUERY_WALLBOX-DATA ********") opt[QUERY_WALLBOX_KEY] = True + if not opt[QUERY_BMS_KEY] and SENEC_SECTION_BMS == description.senec_lala_section: + a_sensor_id = f"sensor.{sluged_title}_{description.key}" + a_entity = registry.async_get(a_sensor_id) + if a_entity is not None and a_entity.disabled_by is None: + _LOGGER.info("***** QUERY_BMS-DATA ********") + opt[QUERY_BMS_KEY] = True + + # yes - currently only the 'MAIN_BIN_SENSOR's will contain the SENEC_SECTION_FAN_SPEED but + # I want to have here the complete code/overview 'what should be checked' + if not opt[QUERY_FANDATA_KEY] and SENEC_SECTION_FAN_SPEED == description.senec_lala_section: + a_sensor_id = f"sensor.{sluged_title}_{description.key}" + a_entity = registry.async_get(a_sensor_id) + if a_entity is not None and a_entity.disabled_by is None: + _LOGGER.info("***** QUERY_FANSPEED-DATA ********") + opt[QUERY_FANDATA_KEY] = True + + for description in MAIN_BIN_SENSOR_TYPES: + if not opt[QUERY_FANDATA_KEY] and SENEC_SECTION_FAN_SPEED == description.senec_lala_section: + a_sensor_id = f"sensor.{sluged_title}_{description.key}" + a_entity = registry.async_get(a_sensor_id) + if a_entity is not None and a_entity.disabled_by is None: + _LOGGER.info("***** QUERY_FANSPEED-DATA ********") + opt[QUERY_FANDATA_KEY] = True + self.senec = Senec(host=self._host, use_https=self._use_https, websession=session, options=opt) self.name = config_entry.title diff --git a/custom_components/senec/const.py b/custom_components/senec/const.py index 413f9e8..ae38500 100644 --- a/custom_components/senec/const.py +++ b/custom_components/senec/const.py @@ -24,6 +24,19 @@ ) from homeassistant.helpers.entity import EntityCategory +from custom_components.senec.pysenec_ha.constants import ( + SENEC_SECTION_BMS, + SENEC_SECTION_ENERGY, + SENEC_SECTION_FAN_SPEED, + SENEC_SECTION_STATISTIC, + SENEC_SECTION_PM1OBJ1, + SENEC_SECTION_PM1OBJ2, + SENEC_SECTION_PV1, + SENEC_SECTION_PWR_UNIT, + SENEC_SECTION_TEMPMEASURE, + SENEC_SECTION_WALLBOX +) + DOMAIN: Final = "senec" MANUFACTURE: Final = "SENEC GmbH" SYSTYPE_SENECV4: Final = "systype_senecv4" @@ -69,17 +82,20 @@ DEFAULT_SCAN_INTERVAL_WEB = 300 DEFAULT_SCAN_INTERVAL_WEB_SENECV4 = 60 +QUERY_BMS_KEY = "query_bms_data" +QUERY_FANDATA_KEY = "query_fan_data" QUERY_WALLBOX_KEY = "query_wallbox_data" QUERY_SPARE_CAPACITY_KEY = "query_spare_capacity" @dataclass class ExtSensorEntityDescription(SensorEntityDescription): controls: list[str] | None = None - + senec_lala_section: str | None = None @dataclass class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): icon_off: str | None = None + senec_lala_section: str | None = None """Supported number implementations""" WEB_NUMBER_SENYOR_TYPES = [ @@ -115,6 +131,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): """Supported main unit binary_sensor types.""" MAIN_BIN_SENSOR_TYPES = [ ExtBinarySensorEntityDescription( + senec_lala_section = SENEC_SECTION_FAN_SPEED, key="fan_inv_lv", name="Fan LV-Inverter", icon="mdi:fan", @@ -122,6 +139,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): entity_category=EntityCategory.DIAGNOSTIC, ), ExtBinarySensorEntityDescription( + senec_lala_section = SENEC_SECTION_FAN_SPEED, entity_registry_enabled_default=False, key="fan_inv_hv", name="Fan HV-Inverter", @@ -667,6 +685,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_temp_A1", name="Module A: Cell Temperature A1", @@ -677,6 +696,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): entity_category=EntityCategory.DIAGNOSTIC, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_temp_A2", name="Module A: Cell Temperature A2", @@ -687,6 +707,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): entity_category=EntityCategory.DIAGNOSTIC, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_temp_A3", name="Module A: Cell Temperature A3", @@ -697,6 +718,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): entity_category=EntityCategory.DIAGNOSTIC, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_temp_A4", name="Module A: Cell Temperature A4", @@ -707,6 +729,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): entity_category=EntityCategory.DIAGNOSTIC, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_temp_A5", name="Module A: Cell Temperature A5", @@ -717,6 +740,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): entity_category=EntityCategory.DIAGNOSTIC, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_temp_A6", name="Module A: Cell Temperature A6", @@ -727,6 +751,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): entity_category=EntityCategory.DIAGNOSTIC, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_temp_B1", name="Module B: Cell Temperature B1", @@ -737,6 +762,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): entity_category=EntityCategory.DIAGNOSTIC, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_temp_B2", name="Module B: Cell Temperature B2", @@ -747,6 +773,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): entity_category=EntityCategory.DIAGNOSTIC, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_temp_B3", name="Module B: Cell Temperature B3", @@ -757,6 +784,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): entity_category=EntityCategory.DIAGNOSTIC, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_temp_B4", name="Module B: Cell Temperature B4", @@ -767,6 +795,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): entity_category=EntityCategory.DIAGNOSTIC, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_temp_B5", name="Module B: Cell Temperature B5", @@ -777,6 +806,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): entity_category=EntityCategory.DIAGNOSTIC, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_temp_B6", name="Module B: Cell Temperature B6", @@ -787,6 +817,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): entity_category=EntityCategory.DIAGNOSTIC, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_temp_C1", name="Module C: Cell Temperature C1", @@ -797,6 +828,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): entity_category=EntityCategory.DIAGNOSTIC, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_temp_C2", name="Module C: Cell Temperature C2", @@ -807,6 +839,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): entity_category=EntityCategory.DIAGNOSTIC, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_temp_C3", name="Module C: Cell Temperature C3", @@ -817,6 +850,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): entity_category=EntityCategory.DIAGNOSTIC, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_temp_C4", name="Module C: Cell Temperature C4", @@ -827,6 +861,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): entity_category=EntityCategory.DIAGNOSTIC, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_temp_C5", name="Module C: Cell Temperature C5", @@ -837,6 +872,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): entity_category=EntityCategory.DIAGNOSTIC, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_temp_C6", name="Module C: Cell Temperature C6", @@ -847,6 +883,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): entity_category=EntityCategory.DIAGNOSTIC, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_temp_D1", name="Module D: Cell Temperature D1", @@ -857,6 +894,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): entity_category=EntityCategory.DIAGNOSTIC, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_temp_D2", name="Module D: Cell Temperature D2", @@ -867,6 +905,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): entity_category=EntityCategory.DIAGNOSTIC, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_temp_D3", name="Module D: Cell Temperature D3", @@ -877,6 +916,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): entity_category=EntityCategory.DIAGNOSTIC, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_temp_D4", name="Module D: Cell Temperature D4", @@ -887,6 +927,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): entity_category=EntityCategory.DIAGNOSTIC, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_temp_D5", name="Module D: Cell Temperature D5", @@ -897,6 +938,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): entity_category=EntityCategory.DIAGNOSTIC, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_temp_D6", name="Module D: Cell Temperature D6", @@ -908,6 +950,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_A1", name="Module A: Cell Voltage A1", @@ -917,6 +960,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_A2", name="Module A: Cell Voltage A2", @@ -926,6 +970,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_A3", name="Module A: Cell Voltage A3", @@ -935,6 +980,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_A4", name="Module A: Cell Voltage A4", @@ -944,6 +990,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_A5", name="Module A: Cell Voltage A5", @@ -953,6 +1000,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_A6", name="Module A: Cell Voltage A6", @@ -962,6 +1010,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_A7", name="Module A: Cell Voltage A7", @@ -971,6 +1020,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_A8", name="Module A: Cell Voltage A8", @@ -980,6 +1030,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_A9", name="Module A: Cell Voltage A9", @@ -989,6 +1040,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_A10", name="Module A: Cell Voltage A10", @@ -998,6 +1050,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_A11", name="Module A: Cell Voltage A11", @@ -1007,6 +1060,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_A12", name="Module A: Cell Voltage A12", @@ -1016,6 +1070,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_A13", name="Module A: Cell Voltage A13", @@ -1025,6 +1080,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_A14", name="Module A: Cell Voltage A14", @@ -1034,6 +1090,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_B1", name="Module B: Cell Voltage B1", @@ -1043,6 +1100,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_B2", name="Module B: Cell Voltage B2", @@ -1052,6 +1110,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_B3", name="Module B: Cell Voltage B3", @@ -1061,6 +1120,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_B4", name="Module B: Cell Voltage B4", @@ -1070,6 +1130,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_B5", name="Module B: Cell Voltage B5", @@ -1079,6 +1140,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_B6", name="Module B: Cell Voltage B6", @@ -1088,6 +1150,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_B7", name="Module B: Cell Voltage B7", @@ -1097,6 +1160,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_B8", name="Module B: Cell Voltage B8", @@ -1106,6 +1170,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_B9", name="Module B: Cell Voltage B9", @@ -1115,6 +1180,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_B10", name="Module B: Cell Voltage B10", @@ -1124,6 +1190,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_B11", name="Module B: Cell Voltage B11", @@ -1133,6 +1200,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_B12", name="Module B: Cell Voltage B12", @@ -1142,6 +1210,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_B13", name="Module B: Cell Voltage B13", @@ -1151,6 +1220,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_B14", name="Module B: Cell Voltage B14", @@ -1160,6 +1230,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_C1", name="Module C: Cell Voltage C1", @@ -1169,6 +1240,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_C2", name="Module C: Cell Voltage C2", @@ -1178,6 +1250,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_C3", name="Module C: Cell Voltage C3", @@ -1187,6 +1260,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_C4", name="Module C: Cell Voltage C4", @@ -1196,6 +1270,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_C5", name="Module C: Cell Voltage C5", @@ -1205,6 +1280,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_C6", name="Module C: Cell Voltage C6", @@ -1214,6 +1290,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_C7", name="Module C: Cell Voltage C7", @@ -1223,6 +1300,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_C8", name="Module C: Cell Voltage C8", @@ -1232,6 +1310,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_C9", name="Module C: Cell Voltage C9", @@ -1241,6 +1320,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_C10", name="Module C: Cell Voltage C10", @@ -1250,6 +1330,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_C11", name="Module C: Cell Voltage C11", @@ -1259,6 +1340,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_C12", name="Module C: Cell Voltage C12", @@ -1268,6 +1350,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_C13", name="Module C: Cell Voltage C13", @@ -1277,6 +1360,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_C14", name="Module C: Cell Voltage C14", @@ -1286,6 +1370,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_D1", name="Module D: Cell Voltage D1", @@ -1295,6 +1380,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_D2", name="Module D: Cell Voltage D2", @@ -1304,6 +1390,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_D3", name="Module D: Cell Voltage D3", @@ -1313,6 +1400,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_D4", name="Module D: Cell Voltage D4", @@ -1322,6 +1410,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_D5", name="Module D: Cell Voltage D5", @@ -1331,6 +1420,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_D6", name="Module D: Cell Voltage D6", @@ -1340,6 +1430,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_D7", name="Module D: Cell Voltage D7", @@ -1349,6 +1440,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_D8", name="Module D: Cell Voltage D8", @@ -1358,6 +1450,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_D9", name="Module D: Cell Voltage D9", @@ -1367,6 +1460,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_D10", name="Module D: Cell Voltage D10", @@ -1376,6 +1470,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_D11", name="Module D: Cell Voltage D11", @@ -1385,6 +1480,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_D12", name="Module D: Cell Voltage D12", @@ -1394,6 +1490,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_D13", name="Module D: Cell Voltage D13", @@ -1403,6 +1500,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, entity_registry_enabled_default=False, key="bms_cell_volt_D14", name="Module D: Cell Voltage D14", @@ -1413,6 +1511,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, key="bms_voltage_A", name="Module A: Voltage", icon="mdi:lightning-bolt", @@ -1421,6 +1520,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, key="bms_voltage_B", name="Module B: Voltage", icon="mdi:lightning-bolt", @@ -1429,6 +1529,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, key="bms_voltage_C", name="Module C: Voltage", icon="mdi:lightning-bolt", @@ -1437,6 +1538,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, key="bms_voltage_D", name="Module D: Voltage", icon="mdi:lightning-bolt", @@ -1446,6 +1548,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, key="bms_current_A", name="Module A: Current", icon="mdi:current-dc", @@ -1454,6 +1557,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, key="bms_current_B", name="Module B: Current", icon="mdi:current-dc", @@ -1462,6 +1566,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, key="bms_current_C", name="Module C: Current", icon="mdi:current-dc", @@ -1470,6 +1575,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, key="bms_current_D", name="Module D: Current", icon="mdi:current-dc", @@ -1479,6 +1585,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, key="bms_soc_A", name="Module A: State of charge", icon="mdi:battery-charging-high", @@ -1486,6 +1593,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, key="bms_soc_B", name="Module B: State of charge", icon="mdi:battery-charging-high", @@ -1493,6 +1601,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, key="bms_soc_C", name="Module C: State of charge", icon="mdi:battery-charging-high", @@ -1500,6 +1609,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, key="bms_soc_D", name="Module D: State of charge", icon="mdi:battery-charging-high", @@ -1508,6 +1618,8 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, + entity_registry_enabled_default=False, key="bms_soh_A", name="Module A: State of Health", icon="mdi:battery-heart-variant", @@ -1515,6 +1627,8 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, + entity_registry_enabled_default=False, key="bms_soh_B", name="Module B: State of Health", icon="mdi:battery-heart-variant", @@ -1522,6 +1636,8 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, + entity_registry_enabled_default=False, key="bms_soh_C", name="Module C: State of Health", icon="mdi:battery-heart-variant", @@ -1529,6 +1645,8 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, + entity_registry_enabled_default=False, key="bms_soh_D", name="Module D: State of Health", icon="mdi:battery-heart-variant", @@ -1537,6 +1655,8 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, + entity_registry_enabled_default=False, key="bms_cycles_A", name="Module A: Cycles", icon="mdi:battery-sync", @@ -1544,6 +1664,8 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.TOTAL_INCREASING, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, + entity_registry_enabled_default=False, key="bms_cycles_B", name="Module B: Cycles", icon="mdi:battery-sync", @@ -1551,6 +1673,8 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.TOTAL_INCREASING, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, + entity_registry_enabled_default=False, key="bms_cycles_C", name="Module C: Cycles", icon="mdi:battery-sync", @@ -1558,6 +1682,8 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.TOTAL_INCREASING, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_BMS, + entity_registry_enabled_default=False, key="bms_cycles_D", name="Module D: Cycles", icon="mdi:battery-sync", @@ -1567,6 +1693,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): # wallbox stuff ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_WALLBOX, entity_registry_enabled_default=False, key="wallbox_power", name="Wallbox Power", @@ -1576,12 +1703,14 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_WALLBOX, entity_registry_enabled_default=False, key="wallbox_ev_connected", name="Wallbox EV Connected", icon="mdi:car-electric", ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_WALLBOX, entity_registry_enabled_default=False, controls=("require_stats_fields"), key="wallbox_energy", @@ -1592,6 +1721,7 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.TOTAL_INCREASING, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_WALLBOX, entity_registry_enabled_default=False, key="wallbox_2_power", name="Wallbox II Power", @@ -1601,12 +1731,14 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_WALLBOX, entity_registry_enabled_default=False, key="wallbox_2_ev_connected", name="Wallbox II EV Connected", icon="mdi:car-electric", ), ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_WALLBOX, entity_registry_enabled_default=False, controls=("require_stats_fields"), key="wallbox_2_energy", @@ -1616,6 +1748,62 @@ class ExtBinarySensorEntityDescription(BinarySensorEntityDescription): device_class=SensorDeviceClass.ENERGY, state_class=SensorStateClass.TOTAL_INCREASING, ), + ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_WALLBOX, + entity_registry_enabled_default=False, + key="wallbox_3_power", + name="Wallbox III Power", + native_unit_of_measurement=POWER_WATT, + icon="mdi:car-arrow-left", + device_class=SensorDeviceClass.POWER, + state_class=SensorStateClass.MEASUREMENT, + ), + ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_WALLBOX, + entity_registry_enabled_default=False, + key="wallbox_3_ev_connected", + name="Wallbox III EV Connected", + icon="mdi:car-electric", + ), + ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_WALLBOX, + entity_registry_enabled_default=False, + controls=("require_stats_fields"), + key="wallbox_3_energy", + name="Wallbox III charged", + native_unit_of_measurement=ENERGY_KILO_WATT_HOUR, + icon="mdi:ev-station", + device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.TOTAL_INCREASING, + ), + ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_WALLBOX, + entity_registry_enabled_default=False, + key="wallbox_4_power", + name="Wallbox VI Power", + native_unit_of_measurement=POWER_WATT, + icon="mdi:car-arrow-left", + device_class=SensorDeviceClass.POWER, + state_class=SensorStateClass.MEASUREMENT, + ), + ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_WALLBOX, + entity_registry_enabled_default=False, + key="wallbox_4_ev_connected", + name="Wallbox IV EV Connected", + icon="mdi:car-electric", + ), + ExtSensorEntityDescription( + senec_lala_section = SENEC_SECTION_WALLBOX, + entity_registry_enabled_default=False, + controls=("require_stats_fields"), + key="wallbox_4_energy", + name="Wallbox IV charged", + native_unit_of_measurement=ENERGY_KILO_WATT_HOUR, + icon="mdi:ev-station", + device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.TOTAL_INCREASING, + ), ] INVERTER_SENSOR_TYPES = [ diff --git a/custom_components/senec/pysenec_ha/__init__.py b/custom_components/senec/pysenec_ha/__init__.py index c49c23d..3c8e062 100644 --- a/custom_components/senec/pysenec_ha/__init__.py +++ b/custom_components/senec/pysenec_ha/__init__.py @@ -17,10 +17,31 @@ from typing import Union, cast from custom_components.senec.const import ( + QUERY_BMS_KEY, + QUERY_FANDATA_KEY, QUERY_WALLBOX_KEY, QUERY_SPARE_CAPACITY_KEY, ) +from constants import ( + SENEC_SECTION_BMS, + SENEC_SECTION_ENERGY, + SENEC_SECTION_FAN_SPEED, + SENEC_SECTION_STATISTIC, + SENEC_SECTION_TEMPMEASURE, + SENEC_SECTION_PWR_UNIT, + SENEC_SECTION_PV1, + SENEC_SECTION_PM1OBJ1, + SENEC_SECTION_PM1OBJ2, + SENEC_SECTION_WALLBOX, + + SENEC_SECTION_FACTORY, + SENEC_SECTION_SYS_UPDATE, + SENEC_SECTION_BAT1, + SENEC_SECTION_WIZARD, +) + + # 4: "INITIAL CHARGE", # 5: "MAINTENANCE CHARGE", # 8: "MAN. SAFETY CHARGE", @@ -47,15 +68,25 @@ class Senec: """Senec Home Battery Sensor""" def __init__(self, host, use_https, websession, options: dict = None): - _LOGGER.info("restarting Senec... with options: " + str(options)) + _LOGGER.info(f"restarting Senec lala.cgi integration... for host: '{host}' with options: {options}") + - self._QUERY_BMS = True self._QUERY_STATS = True + if options is not None and QUERY_BMS_KEY in options: + self._QUERY_BMS = options[QUERY_BMS_KEY] + else: + self._QUERY_BMS = False + if options is not None and QUERY_WALLBOX_KEY in options: self._QUERY_WALLBOX = options[QUERY_WALLBOX_KEY] else: self._QUERY_WALLBOX = False + if options is not None and QUERY_FANDATA_KEY in options: + self._QUERY_FANDATA = options[QUERY_FANDATA_KEY] + else: + self._QUERY_FANDATA = False + self.host = host self.websession: aiohttp.websession = websession if use_https: @@ -65,29 +96,29 @@ def __init__(self, host, use_https, websession, options: dict = None): @property def device_id(self) -> str: - return self._raw["FACTORY"]["DEVICE_ID"] + return self._raw[SENEC_SECTION_FACTORY]["DEVICE_ID"] @property def versions(self) -> str: - a = self._raw["WIZARD"]["APPLICATION_VERSION"] - b = self._raw["WIZARD"]["FIRMWARE_VERSION"] - c = self._raw["WIZARD"]["INTERFACE_VERSION"] - d = str(self._raw["SYS_UPDATE"]["NPU_VER"]) - e = str(self._raw["SYS_UPDATE"]["NPU_IMAGE_VERSION"]) - return 'App:' + a + ' FW:' + b + ' NPU-Image:' + e + '(v' + d + ')' + a = self._raw[SENEC_SECTION_WIZARD]["APPLICATION_VERSION"] + b = self._raw[SENEC_SECTION_WIZARD]["FIRMWARE_VERSION"] + c = self._raw[SENEC_SECTION_WIZARD]["INTERFACE_VERSION"] + d = str(self._raw[SENEC_SECTION_SYS_UPDATE]["NPU_VER"]) + e = str(self._raw[SENEC_SECTION_SYS_UPDATE]["NPU_IMAGE_VERSION"]) + return f"App:{a} FW:{b} NPU-Image:{e}(v{d})" @property def device_type(self) -> str: - value = self._raw["FACTORY"]["SYS_TYPE"] + value = self._raw[SENEC_SECTION_FACTORY]["SYS_TYPE"] return SYSTEM_TYPE_NAME.get(value, "UNKNOWN") @property def device_type_internal(self) -> str: - return self._raw["FACTORY"]["SYS_TYPE"] + return self._raw[SENEC_SECTION_FACTORY]["SYS_TYPE"] @property def batt_type(self) -> str: - value = self._raw["BAT1"]["TYPE"] + value = self._raw[SENEC_SECTION_BAT1]["TYPE"] return BATT_TYPE_NAME.get(value, "UNKNOWN") async def update_version(self): @@ -95,12 +126,12 @@ async def update_version(self): async def read_version(self): form = { - "FACTORY": { + SENEC_SECTION_FACTORY: { "SYS_TYPE": "", "COUNTRY": "", "DEVICE_ID": "" }, - "WIZARD": { + SENEC_SECTION_WIZARD: { "APPLICATION_VERSION": "", "FIRMWARE_VERSION": "", "INTERFACE_VERSION": "", @@ -109,17 +140,17 @@ async def read_version(self): # "MASTER_SLAVE_MODE": "u8_00", # "SETUP_NUMBER_WALLBOXES": "u8_00" }, - "BAT1": { + SENEC_SECTION_BAT1: { "TYPE": "", # "ISLAND_ENABLE": "u8_00", # "NSP_FW": "u1_0000", # "NSP2_FW": "u1_0000" }, - "SYS_UPDATE": { + SENEC_SECTION_SYS_UPDATE: { "NPU_VER": "", "NPU_IMAGE_VERSION": "" }, - "STATISTIC": {} + SENEC_SECTION_STATISTIC: {} } async with self.websession.post(self.url, json=form, ssl=False) as res: @@ -132,7 +163,7 @@ def system_state(self) -> str: Textual descritpion of energy status """ - value = self._raw["ENERGY"]["STAT_STATE"] + value = self._raw[SENEC_SECTION_ENERGY]["STAT_STATE"] return SYSTEM_STATE_NAME.get(value, "UNKNOWN") @property @@ -149,7 +180,7 @@ def house_power(self) -> float: Current power consumption (W) """ - return self._raw["ENERGY"]["GUI_HOUSE_POW"] + return self._raw[SENEC_SECTION_ENERGY]["GUI_HOUSE_POW"] @property def house_total_consumption(self) -> float: @@ -157,37 +188,37 @@ def house_total_consumption(self) -> float: Total energy used by house (kWh) Does not include Wallbox. """ - if hasattr(self, '_raw') and "STATISTIC" in self._raw and "LIVE_HOUSE_CONS" in self._raw["STATISTIC"]: - return self._raw["STATISTIC"]["LIVE_HOUSE_CONS"] + if hasattr(self, '_raw') and SENEC_SECTION_STATISTIC in self._raw and "LIVE_HOUSE_CONS" in self._raw[SENEC_SECTION_STATISTIC]: + return self._raw[SENEC_SECTION_STATISTIC]["LIVE_HOUSE_CONS"] @property def solar_generated_power(self) -> float: """ Current power generated by solar panels (W) """ - return abs(self._raw["ENERGY"]["GUI_INVERTER_POWER"]) + return abs(self._raw[SENEC_SECTION_ENERGY]["GUI_INVERTER_POWER"]) @property def solar_total_generated(self) -> float: """ Total energy generated by solar panels (kWh) """ - if hasattr(self, '_raw') and "STATISTIC" in self._raw and "LIVE_PV_GEN" in self._raw["STATISTIC"]: - return self._raw["STATISTIC"]["LIVE_PV_GEN"] + if hasattr(self, '_raw') and SENEC_SECTION_STATISTIC in self._raw and "LIVE_PV_GEN" in self._raw[SENEC_SECTION_STATISTIC]: + return self._raw[SENEC_SECTION_STATISTIC]["LIVE_PV_GEN"] @property def battery_charge_percent(self) -> float: """ Current battery charge value (%) """ - return self._raw["ENERGY"]["GUI_BAT_DATA_FUEL_CHARGE"] + return self._raw[SENEC_SECTION_ENERGY]["GUI_BAT_DATA_FUEL_CHARGE"] @property def battery_charge_power(self) -> float: """ Current battery charging power (W) """ - value = self._raw["ENERGY"]["GUI_BAT_DATA_POWER"] + value = self._raw[SENEC_SECTION_ENERGY]["GUI_BAT_DATA_POWER"] if value > 0: if self.is_battery_state_charging(): return value @@ -198,7 +229,7 @@ def battery_discharge_power(self) -> float: """ Current battery discharging power (W) """ - value = self._raw["ENERGY"]["GUI_BAT_DATA_POWER"] + value = self._raw[SENEC_SECTION_ENERGY]["GUI_BAT_DATA_POWER"] if value < 0: if self.is_battery_state_discharging(): return abs(value) @@ -211,30 +242,30 @@ def battery_state_power(self) -> float: Value is positive when battery is charging Value is negative when battery is discharging. """ - return self._raw["ENERGY"]["GUI_BAT_DATA_POWER"] + return self._raw[SENEC_SECTION_ENERGY]["GUI_BAT_DATA_POWER"] @property def battery_total_charged(self) -> float: """ Total energy charged to battery (kWh) """ - if hasattr(self, '_raw') and "STATISTIC" in self._raw and "LIVE_BAT_CHARGE" in self._raw["STATISTIC"]: - return self._raw["STATISTIC"]["LIVE_BAT_CHARGE"] + if hasattr(self, '_raw') and SENEC_SECTION_STATISTIC in self._raw and "LIVE_BAT_CHARGE" in self._raw[SENEC_SECTION_STATISTIC]: + return self._raw[SENEC_SECTION_STATISTIC]["LIVE_BAT_CHARGE"] @property def battery_total_discharged(self) -> float: """ Total energy discharged from battery (kWh) """ - if hasattr(self, '_raw') and "STATISTIC" in self._raw and "LIVE_BAT_DISCHARGE" in self._raw["STATISTIC"]: - return self._raw["STATISTIC"]["LIVE_BAT_DISCHARGE"] + if hasattr(self, '_raw') and SENEC_SECTION_STATISTIC in self._raw and "LIVE_BAT_DISCHARGE" in self._raw[SENEC_SECTION_STATISTIC]: + return self._raw[SENEC_SECTION_STATISTIC]["LIVE_BAT_DISCHARGE"] @property def grid_imported_power(self) -> float: """ Current power imported from grid (W) """ - value = self._raw["ENERGY"]["GUI_GRID_POW"] + value = self._raw[SENEC_SECTION_ENERGY]["GUI_GRID_POW"] if value > 0: return value return 0 @@ -244,7 +275,7 @@ def grid_exported_power(self) -> float: """ Current power exported to grid (W) """ - value = self._raw["ENERGY"]["GUI_GRID_POW"] + value = self._raw[SENEC_SECTION_ENERGY]["GUI_GRID_POW"] if value < 0: return abs(value) return 0 @@ -257,181 +288,181 @@ def grid_state_power(self) -> float: Value is positive when power is imported from grid. Value is negative when power is exported to grid. """ - return self._raw["ENERGY"]["GUI_GRID_POW"] + return self._raw[SENEC_SECTION_ENERGY]["GUI_GRID_POW"] @property def grid_total_export(self) -> float: """ Total energy exported to grid export (kWh) """ - if hasattr(self, '_raw') and "STATISTIC" in self._raw and "LIVE_GRID_EXPORT" in self._raw["STATISTIC"] and \ - self._raw["STATISTIC"]["LIVE_GRID_EXPORT"] != "VARIABLE_NOT_FOUND": - return self._raw["STATISTIC"]["LIVE_GRID_EXPORT"] + if hasattr(self, '_raw') and SENEC_SECTION_STATISTIC in self._raw and "LIVE_GRID_EXPORT" in self._raw[SENEC_SECTION_STATISTIC] and \ + self._raw[SENEC_SECTION_STATISTIC]["LIVE_GRID_EXPORT"] != "VARIABLE_NOT_FOUND": + return self._raw[SENEC_SECTION_STATISTIC]["LIVE_GRID_EXPORT"] @property def grid_total_import(self) -> float: """ Total energy imported from grid (kWh) """ - if hasattr(self, '_raw') and "STATISTIC" in self._raw and "LIVE_GRID_IMPORT" in self._raw["STATISTIC"]: - return self._raw["STATISTIC"]["LIVE_GRID_IMPORT"] + if hasattr(self, '_raw') and SENEC_SECTION_STATISTIC in self._raw and "LIVE_GRID_IMPORT" in self._raw[SENEC_SECTION_STATISTIC]: + return self._raw[SENEC_SECTION_STATISTIC]["LIVE_GRID_IMPORT"] @property def battery_temp(self) -> float: """ Current battery temperature """ - return self._raw["TEMPMEASURE"]["BATTERY_TEMP"] + return self._raw[SENEC_SECTION_TEMPMEASURE]["BATTERY_TEMP"] @property def case_temp(self) -> float: """ Current case temperature """ - return self._raw["TEMPMEASURE"]["CASE_TEMP"] + return self._raw[SENEC_SECTION_TEMPMEASURE]["CASE_TEMP"] @property def mcu_temp(self) -> float: """ Current controller temperature """ - return self._raw["TEMPMEASURE"]["MCU_TEMP"] + return self._raw[SENEC_SECTION_TEMPMEASURE]["MCU_TEMP"] @property def solar_mpp1_potential(self) -> float: - return self._raw["PV1"]["MPP_VOL"][0] + return self._raw[SENEC_SECTION_PV1]["MPP_VOL"][0] @property def solar_mpp1_current(self) -> float: - return self._raw["PV1"]["MPP_CUR"][0] + return self._raw[SENEC_SECTION_PV1]["MPP_CUR"][0] @property def solar_mpp1_power(self) -> float: - return self._raw["PV1"]["MPP_POWER"][0] + return self._raw[SENEC_SECTION_PV1]["MPP_POWER"][0] @property def solar_mpp2_potential(self) -> float: - return self._raw["PV1"]["MPP_VOL"][1] + return self._raw[SENEC_SECTION_PV1]["MPP_VOL"][1] @property def solar_mpp2_current(self) -> float: - return self._raw["PV1"]["MPP_CUR"][1] + return self._raw[SENEC_SECTION_PV1]["MPP_CUR"][1] @property def solar_mpp2_power(self) -> float: - return self._raw["PV1"]["MPP_POWER"][1] + return self._raw[SENEC_SECTION_PV1]["MPP_POWER"][1] @property def solar_mpp3_potential(self) -> float: - return self._raw["PV1"]["MPP_VOL"][2] + return self._raw[SENEC_SECTION_PV1]["MPP_VOL"][2] @property def solar_mpp3_current(self) -> float: - return self._raw["PV1"]["MPP_CUR"][2] + return self._raw[SENEC_SECTION_PV1]["MPP_CUR"][2] @property def solar_mpp3_power(self) -> float: - return self._raw["PV1"]["MPP_POWER"][2] + return self._raw[SENEC_SECTION_PV1]["MPP_POWER"][2] @property def enfluri_net_freq(self) -> float: - return self._raw["PM1OBJ1"]["FREQ"] + return self._raw[SENEC_SECTION_PM1OBJ1]["FREQ"] @property def enfluri_net_potential_p1(self) -> float: - return self._raw["PM1OBJ1"]["U_AC"][0] + return self._raw[SENEC_SECTION_PM1OBJ1]["U_AC"][0] @property def enfluri_net_potential_p2(self) -> float: - return self._raw["PM1OBJ1"]["U_AC"][1] + return self._raw[SENEC_SECTION_PM1OBJ1]["U_AC"][1] @property def enfluri_net_potential_p3(self) -> float: - return self._raw["PM1OBJ1"]["U_AC"][2] + return self._raw[SENEC_SECTION_PM1OBJ1]["U_AC"][2] @property def enfluri_net_current_p1(self) -> float: - return self._raw["PM1OBJ1"]["I_AC"][0] + return self._raw[SENEC_SECTION_PM1OBJ1]["I_AC"][0] @property def enfluri_net_current_p2(self) -> float: - return self._raw["PM1OBJ1"]["I_AC"][1] + return self._raw[SENEC_SECTION_PM1OBJ1]["I_AC"][1] @property def enfluri_net_current_p3(self) -> float: - return self._raw["PM1OBJ1"]["I_AC"][2] + return self._raw[SENEC_SECTION_PM1OBJ1]["I_AC"][2] @property def enfluri_net_power_p1(self) -> float: - return self._raw["PM1OBJ1"]["P_AC"][0] + return self._raw[SENEC_SECTION_PM1OBJ1]["P_AC"][0] @property def enfluri_net_power_p2(self) -> float: - return self._raw["PM1OBJ1"]["P_AC"][1] + return self._raw[SENEC_SECTION_PM1OBJ1]["P_AC"][1] @property def enfluri_net_power_p3(self) -> float: - return self._raw["PM1OBJ1"]["P_AC"][2] + return self._raw[SENEC_SECTION_PM1OBJ1]["P_AC"][2] @property def enfluri_net_power_total(self) -> float: - return self._raw["PM1OBJ1"]["P_TOTAL"] + return self._raw[SENEC_SECTION_PM1OBJ1]["P_TOTAL"] @property def enfluri_usage_freq(self) -> float: - return self._raw["PM1OBJ2"]["FREQ"] + return self._raw[SENEC_SECTION_PM1OBJ2]["FREQ"] @property def enfluri_usage_potential_p1(self) -> float: - return self._raw["PM1OBJ2"]["U_AC"][0] + return self._raw[SENEC_SECTION_PM1OBJ2]["U_AC"][0] @property def enfluri_usage_potential_p2(self) -> float: - return self._raw["PM1OBJ2"]["U_AC"][1] + return self._raw[SENEC_SECTION_PM1OBJ2]["U_AC"][1] @property def enfluri_usage_potential_p3(self) -> float: - return self._raw["PM1OBJ2"]["U_AC"][2] + return self._raw[SENEC_SECTION_PM1OBJ2]["U_AC"][2] @property def enfluri_usage_current_p1(self) -> float: - return self._raw["PM1OBJ2"]["I_AC"][0] + return self._raw[SENEC_SECTION_PM1OBJ2]["I_AC"][0] @property def enfluri_usage_current_p2(self) -> float: - return self._raw["PM1OBJ2"]["I_AC"][1] + return self._raw[SENEC_SECTION_PM1OBJ2]["I_AC"][1] @property def enfluri_usage_current_p3(self) -> float: - return self._raw["PM1OBJ2"]["I_AC"][2] + return self._raw[SENEC_SECTION_PM1OBJ2]["I_AC"][2] @property def enfluri_usage_power_p1(self) -> float: - return self._raw["PM1OBJ2"]["P_AC"][0] + return self._raw[SENEC_SECTION_PM1OBJ2]["P_AC"][0] @property def enfluri_usage_power_p2(self) -> float: - return self._raw["PM1OBJ2"]["P_AC"][1] + return self._raw[SENEC_SECTION_PM1OBJ2]["P_AC"][1] @property def enfluri_usage_power_p3(self) -> float: - return self._raw["PM1OBJ2"]["P_AC"][2] + return self._raw[SENEC_SECTION_PM1OBJ2]["P_AC"][2] @property def enfluri_usage_power_total(self) -> float: - return self._raw["PM1OBJ2"]["P_TOTAL"] + return self._raw[SENEC_SECTION_PM1OBJ2]["P_TOTAL"] def is_battery_empty(self) -> bool: # 15: "BATTERY EMPTY", - bat_state_is_empty = self._raw["ENERGY"]["STAT_STATE"] == 15 - bat_percent_is_zero = self._raw["ENERGY"]["GUI_BAT_DATA_FUEL_CHARGE"] == 0 + bat_state_is_empty = self._raw[SENEC_SECTION_ENERGY]["STAT_STATE"] == 15 + bat_percent_is_zero = self._raw[SENEC_SECTION_ENERGY]["GUI_BAT_DATA_FUEL_CHARGE"] == 0 return bat_state_is_empty or bat_percent_is_zero def is_battery_state_charging(self) -> bool: - return self._raw["ENERGY"]["STAT_STATE"] in BAT_STATUS_CHARGE + return self._raw[SENEC_SECTION_ENERGY]["STAT_STATE"] in BAT_STATUS_CHARGE def is_battery_state_discharging(self) -> bool: - return self._raw["ENERGY"]["STAT_STATE"] in BAT_STATUS_DISCHARGE + return self._raw[SENEC_SECTION_ENERGY]["STAT_STATE"] in BAT_STATUS_DISCHARGE @property def bms_cell_temp_A1(self) -> float: @@ -962,9 +993,9 @@ def wallbox_power(self) -> float: if hasattr(self, '_raw') and "WALLBOX" in self._raw and "L1_CHARGING_CURRENT" in self._raw[ "WALLBOX"] and "L2_CHARGING_CURRENT" in self._raw["WALLBOX"] and "L3_CHARGING_CURRENT" in self._raw[ "WALLBOX"]: - return self._raw["WALLBOX"]["L1_CHARGING_CURRENT"][0] * self._raw["PM1OBJ1"]["U_AC"][0] + \ - self._raw["WALLBOX"]["L2_CHARGING_CURRENT"][0] * self._raw["PM1OBJ1"]["U_AC"][1] + \ - self._raw["WALLBOX"]["L3_CHARGING_CURRENT"][0] * self._raw["PM1OBJ1"]["U_AC"][2] + return self._raw["WALLBOX"]["L1_CHARGING_CURRENT"][0] * self._raw[SENEC_SECTION_PM1OBJ1]["U_AC"][0] + \ + self._raw["WALLBOX"]["L2_CHARGING_CURRENT"][0] * self._raw[SENEC_SECTION_PM1OBJ1]["U_AC"][1] + \ + self._raw["WALLBOX"]["L3_CHARGING_CURRENT"][0] * self._raw[SENEC_SECTION_PM1OBJ1]["U_AC"][2] @property def wallbox_ev_connected(self) -> bool: @@ -979,8 +1010,8 @@ def wallbox_energy(self) -> float: """ Wallbox Total Energy """ - if hasattr(self, '_raw') and "STATISTIC" in self._raw and "LIVE_WB_ENERGY" in self._raw["STATISTIC"]: - return self._raw["STATISTIC"]["LIVE_WB_ENERGY"][0] + if hasattr(self, '_raw') and SENEC_SECTION_STATISTIC in self._raw and "LIVE_WB_ENERGY" in self._raw[SENEC_SECTION_STATISTIC]: + return self._raw[SENEC_SECTION_STATISTIC]["LIVE_WB_ENERGY"][0] @property def wallbox_2_power(self) -> float: @@ -991,9 +1022,9 @@ def wallbox_2_power(self) -> float: if hasattr(self, '_raw') and "WALLBOX" in self._raw and "L1_CHARGING_CURRENT" in self._raw[ "WALLBOX"] and "L2_CHARGING_CURRENT" in self._raw["WALLBOX"] and "L3_CHARGING_CURRENT" in self._raw[ "WALLBOX"]: - return self._raw["WALLBOX"]["L1_CHARGING_CURRENT"][1] * self._raw["PM1OBJ1"]["U_AC"][0] + \ - self._raw["WALLBOX"]["L2_CHARGING_CURRENT"][1] * self._raw["PM1OBJ1"]["U_AC"][1] + \ - self._raw["WALLBOX"]["L3_CHARGING_CURRENT"][1] * self._raw["PM1OBJ1"]["U_AC"][2] + return self._raw["WALLBOX"]["L1_CHARGING_CURRENT"][1] * self._raw[SENEC_SECTION_PM1OBJ1]["U_AC"][0] + \ + self._raw["WALLBOX"]["L2_CHARGING_CURRENT"][1] * self._raw[SENEC_SECTION_PM1OBJ1]["U_AC"][1] + \ + self._raw["WALLBOX"]["L3_CHARGING_CURRENT"][1] * self._raw[SENEC_SECTION_PM1OBJ1]["U_AC"][2] @property def wallbox_2_ev_connected(self) -> bool: @@ -1008,18 +1039,75 @@ def wallbox_2_energy(self) -> float: """ Wallbox Total Energy """ - if hasattr(self, '_raw') and "STATISTIC" in self._raw and "LIVE_WB_ENERGY" in self._raw["STATISTIC"]: - return self._raw["STATISTIC"]["LIVE_WB_ENERGY"][1] + if hasattr(self, '_raw') and SENEC_SECTION_STATISTIC in self._raw and "LIVE_WB_ENERGY" in self._raw[SENEC_SECTION_STATISTIC]: + return self._raw[SENEC_SECTION_STATISTIC]["LIVE_WB_ENERGY"][1] + + @property + def wallbox_3_power(self) -> float: + """ + Wallbox Total Charging Power (W) + Derived from the 3 phase voltages multiplied with the phase currents from the wallbox + """ + if hasattr(self, '_raw') and "WALLBOX" in self._raw and "L1_CHARGING_CURRENT" in self._raw[ + "WALLBOX"] and "L2_CHARGING_CURRENT" in self._raw["WALLBOX"] and "L3_CHARGING_CURRENT" in self._raw[ + "WALLBOX"]: + return self._raw["WALLBOX"]["L1_CHARGING_CURRENT"][2] * self._raw[SENEC_SECTION_PM1OBJ1]["U_AC"][0] + \ + self._raw["WALLBOX"]["L2_CHARGING_CURRENT"][2] * self._raw[SENEC_SECTION_PM1OBJ1]["U_AC"][1] + \ + self._raw["WALLBOX"]["L3_CHARGING_CURRENT"][2] * self._raw[SENEC_SECTION_PM1OBJ1]["U_AC"][2] + + @property + def wallbox_3_ev_connected(self) -> bool: + """ + Wallbox EV Connected + """ + if hasattr(self, '_raw') and "WALLBOX" in self._raw and "EV_CONNECTED" in self._raw["WALLBOX"]: + return self._raw["WALLBOX"]["EV_CONNECTED"][2] + + @property + def wallbox_3_energy(self) -> float: + """ + Wallbox Total Energy + """ + if hasattr(self, '_raw') and SENEC_SECTION_STATISTIC in self._raw and "LIVE_WB_ENERGY" in self._raw[SENEC_SECTION_STATISTIC]: + return self._raw[SENEC_SECTION_STATISTIC]["LIVE_WB_ENERGY"][2] + @property + def wallbox_4_power(self) -> float: + """ + Wallbox Total Charging Power (W) + Derived from the 3 phase voltages multiplied with the phase currents from the wallbox + """ + if hasattr(self, '_raw') and "WALLBOX" in self._raw and "L1_CHARGING_CURRENT" in self._raw[ + "WALLBOX"] and "L2_CHARGING_CURRENT" in self._raw["WALLBOX"] and "L3_CHARGING_CURRENT" in self._raw[ + "WALLBOX"]: + return self._raw["WALLBOX"]["L1_CHARGING_CURRENT"][3] * self._raw[SENEC_SECTION_PM1OBJ1]["U_AC"][0] + \ + self._raw["WALLBOX"]["L2_CHARGING_CURRENT"][3] * self._raw[SENEC_SECTION_PM1OBJ1]["U_AC"][1] + \ + self._raw["WALLBOX"]["L3_CHARGING_CURRENT"][3] * self._raw[SENEC_SECTION_PM1OBJ1]["U_AC"][2] + + @property + def wallbox_4_ev_connected(self) -> bool: + """ + Wallbox EV Connected + """ + if hasattr(self, '_raw') and "WALLBOX" in self._raw and "EV_CONNECTED" in self._raw["WALLBOX"]: + return self._raw["WALLBOX"]["EV_CONNECTED"][3] + + @property + def wallbox_4_energy(self) -> float: + """ + Wallbox Total Energy + """ + if hasattr(self, '_raw') and SENEC_SECTION_STATISTIC in self._raw and "LIVE_WB_ENERGY" in self._raw[SENEC_SECTION_STATISTIC]: + return self._raw[SENEC_SECTION_STATISTIC]["LIVE_WB_ENERGY"][3] @property def fan_inv_lv(self) -> bool: - if hasattr(self, '_raw') and "FAN_SPEED" in self._raw and "INV_LV" in self._raw["FAN_SPEED"]: - return self._raw["FAN_SPEED"]["INV_LV"] + if hasattr(self, '_raw') and SENEC_SECTION_FAN_SPEED in self._raw and "INV_LV" in self._raw[SENEC_SECTION_FAN_SPEED]: + return self._raw[SENEC_SECTION_FAN_SPEED]["INV_LV"] @property def fan_inv_hv(self) -> bool: - if hasattr(self, '_raw') and "FAN_SPEED" in self._raw and "INV_HV" in self._raw["FAN_SPEED"]: - return self._raw["FAN_SPEED"]["INV_HV"] + if hasattr(self, '_raw') and SENEC_SECTION_FAN_SPEED in self._raw and "INV_HV" in self._raw[SENEC_SECTION_FAN_SPEED]: + return self._raw[SENEC_SECTION_FAN_SPEED]["INV_HV"] async def update(self): await self.read_senec_v31() @@ -1030,7 +1118,7 @@ async def read_senec_v31(self): Note: Not all values are "high priority" and reading everything causes problems with Senec device, i.e. no sync with Senec cloud possible. """ form = { - "ENERGY": { + SENEC_SECTION_ENERGY: { "STAT_STATE": "", "GUI_BAT_DATA_POWER": "", "GUI_INVERTER_POWER": "", @@ -1047,7 +1135,7 @@ async def read_senec_v31(self): "SAFE_CHARGE_RUNNING": "", "LI_STORAGE_MODE_RUNNING": "", }, - # "STATISTIC": { + # SENEC_SECTION_STATISTIC: { # "LIVE_BAT_CHARGE": "", # "LIVE_BAT_DISCHARGE": "", # "LIVE_GRID_EXPORT": "", @@ -1056,21 +1144,22 @@ async def read_senec_v31(self): # "LIVE_PV_GEN": "", # "LIVE_WB_ENERGY": "", # }, - "TEMPMEASURE": { + SENEC_SECTION_TEMPMEASURE: { "BATTERY_TEMP": "", "CASE_TEMP": "", "MCU_TEMP": "", }, - "PV1": {"POWER_RATIO": "", - "POWER_RATIO_L1": "", - "POWER_RATIO_L2": "", - "POWER_RATIO_L3": "", - "MPP_VOL": "", - "MPP_CUR": "", - "MPP_POWER": ""}, - "PWR_UNIT": {"POWER_L1": "", "POWER_L2": "", "POWER_L3": ""}, - "PM1OBJ1": {"FREQ": "", "U_AC": "", "I_AC": "", "P_AC": "", "P_TOTAL": ""}, - "PM1OBJ2": {"FREQ": "", "U_AC": "", "I_AC": "", "P_AC": "", "P_TOTAL": ""}, + SENEC_SECTION_PV1: { + "POWER_RATIO": "", + "POWER_RATIO_L1": "", + "POWER_RATIO_L2": "", + "POWER_RATIO_L3": "", + "MPP_VOL": "", + "MPP_CUR": "", + "MPP_POWER": ""}, + SENEC_SECTION_PWR_UNIT: {"POWER_L1": "", "POWER_L2": "", "POWER_L3": ""}, + SENEC_SECTION_PM1OBJ1: {"FREQ": "", "U_AC": "", "I_AC": "", "P_AC": "", "P_TOTAL": ""}, + SENEC_SECTION_PM1OBJ2: {"FREQ": "", "U_AC": "", "I_AC": "", "P_AC": "", "P_TOTAL": ""}, # "BMS": { # "CELL_TEMPERATURES_MODULE_A": "", # "CELL_TEMPERATURES_MODULE_B": "", @@ -1092,14 +1181,38 @@ async def read_senec_v31(self): # "L3_CHARGING_CURRENT": "", # "EV_CONNECTED": "" # }, - "FAN_SPEED": {}, + #SENEC_SECTION_FAN_SPEED: {}, } - if self._QUERY_BMS: - form.update({"BMS": {}}) if self._QUERY_STATS: - form.update({"STATISTIC": {}}) + form.update({SENEC_SECTION_STATISTIC: {}}) + + if self._QUERY_FANDATA: + form.update({SENEC_SECTION_FAN_SPEED: {}}) + + if self._QUERY_BMS: + form.update({SENEC_SECTION_BMS: { + "CELL_TEMPERATURES_MODULE_A": "", + "CELL_TEMPERATURES_MODULE_B": "", + "CELL_TEMPERATURES_MODULE_C": "", + "CELL_TEMPERATURES_MODULE_D": "", + "CELL_VOLTAGES_MODULE_A": "", + "CELL_VOLTAGES_MODULE_B": "", + "CELL_VOLTAGES_MODULE_C": "", + "CELL_VOLTAGES_MODULE_D": "", + "CURRENT": "", + "VOLTAGE": "", + "SOC": "", + "SOH": "", + "CYCLES": ""} + }) + if self._QUERY_WALLBOX: - form.update({"WALLBOX": {}}) + form.update({SENEC_SECTION_WALLBOX: { + "L1_CHARGING_CURRENT": "", + "L2_CHARGING_CURRENT": "", + "L3_CHARGING_CURRENT": "", + "EV_CONNECTED": ""} + }) async with self.websession.post(self.url, json=form, ssl=False) as res: res.raise_for_status() @@ -1198,16 +1311,16 @@ async def read_senec_v21_all(self): @property def safe_charge(self) -> bool: if hasattr(self, '_raw'): - return self._raw["ENERGY"]["SAFE_CHARGE_RUNNING"] == 1 + return self._raw[SENEC_SECTION_ENERGY]["SAFE_CHARGE_RUNNING"] == 1 async def switch_safe_charge(self, value): postdata = {} if (value): - postdata = {"ENERGY": {"SAFE_CHARGE_FORCE": "u8_01", "SAFE_CHARGE_PROHIBIT": "", "SAFE_CHARGE_RUNNING": "", + postdata = {SENEC_SECTION_ENERGY: {"SAFE_CHARGE_FORCE": "u8_01", "SAFE_CHARGE_PROHIBIT": "", "SAFE_CHARGE_RUNNING": "", "LI_STORAGE_MODE_START": "", "LI_STORAGE_MODE_STOP": "", "LI_STORAGE_MODE_RUNNING": ""}} else: - postdata = {"ENERGY": {"SAFE_CHARGE_FORCE": "", "SAFE_CHARGE_PROHIBIT": "u8_01", "SAFE_CHARGE_RUNNING": "", + postdata = {SENEC_SECTION_ENERGY: {"SAFE_CHARGE_FORCE": "", "SAFE_CHARGE_PROHIBIT": "u8_01", "SAFE_CHARGE_RUNNING": "", "LI_STORAGE_MODE_START": "", "LI_STORAGE_MODE_STOP": "", "LI_STORAGE_MODE_RUNNING": ""}} @@ -1216,16 +1329,16 @@ async def switch_safe_charge(self, value): @property def li_storage_mode(self) -> bool: if hasattr(self, '_raw'): - return self._raw["ENERGY"]["LI_STORAGE_MODE_RUNNING"] == 1 + return self._raw[SENEC_SECTION_ENERGY]["LI_STORAGE_MODE_RUNNING"] == 1 async def switch_li_storage_mode(self, value): postdata = {} if (value): - postdata = {"ENERGY": {"SAFE_CHARGE_FORCE": "", "SAFE_CHARGE_PROHIBIT": "", "SAFE_CHARGE_RUNNING": "", + postdata = {SENEC_SECTION_ENERGY: {"SAFE_CHARGE_FORCE": "", "SAFE_CHARGE_PROHIBIT": "", "SAFE_CHARGE_RUNNING": "", "LI_STORAGE_MODE_START": "u8_01", "LI_STORAGE_MODE_STOP": "", "LI_STORAGE_MODE_RUNNING": ""}} else: - postdata = {"ENERGY": {"SAFE_CHARGE_FORCE": "", "SAFE_CHARGE_PROHIBIT": "", "SAFE_CHARGE_RUNNING": "", + postdata = {SENEC_SECTION_ENERGY: {"SAFE_CHARGE_FORCE": "", "SAFE_CHARGE_PROHIBIT": "", "SAFE_CHARGE_RUNNING": "", "LI_STORAGE_MODE_START": "", "LI_STORAGE_MODE_STOP": "u8_01", "LI_STORAGE_MODE_RUNNING": ""}} @@ -1283,7 +1396,7 @@ async def update(self): await self.read_inverter() async def read_inverter(self): - async with self.websession.get(self.url2 + '?' + str(datetime.now())) as res: + async with self.websession.get(f"{self.url2}?{datetime.now()}") as res: res.raise_for_status() txt = await res.text() self._raw = xmltodict.parse(txt) @@ -1502,7 +1615,7 @@ def derating(self) -> float: class MySenecWebPortal: def __init__(self, user, pwd, websession, master_plant_number: int = 0, options: dict = None): - _LOGGER.info("restarting MySenecWebPortal... with options: " + str(options)) + _LOGGER.info(f"restarting MySenecWebPortal... for user: '{user}' with options: {options}") if options is not None and QUERY_SPARE_CAPACITY_KEY in options: self._QUERY_SPARE_CAPACITY = options[QUERY_SPARE_CAPACITY_KEY] @@ -1595,7 +1708,7 @@ async def authenticateClassic(self, doUpdate: bool): if doUpdate: self.updateClassic() else: - _LOGGER.warning("Login failed with Code " + str(res.status)) + _LOGGER.warning(f"Login failed with Code {res.status}") async def updateClassic(self): _LOGGER.debug("***** updateClassic(self) ********") @@ -1632,7 +1745,7 @@ async def authenticate(self, doUpdate: bool, throw401: bool): if doUpdate: await self.update() else: - _LOGGER.error("Login failed with Code " + str(res.status)) + _LOGGER.warning(f"Login failed with Code {res.status}") self.purgeSenecCookies() except ClientResponseError as exc: # _LOGGER.error(str(exc)) @@ -1643,7 +1756,7 @@ async def authenticate(self, doUpdate: bool, throw401: bool): self.purgeSenecCookies() self._isAuthenticated = False else: - _LOGGER.error("Login exception with Code " + str(exc.status)) + _LOGGER.warning(f"Login exception with Code {res.status}") self.purgeSenecCookies() async def update(self): diff --git a/custom_components/senec/pysenec_ha/constants.py b/custom_components/senec/pysenec_ha/constants.py index 5fed78c..9d5179d 100644 --- a/custom_components/senec/pysenec_ha/constants.py +++ b/custom_components/senec/pysenec_ha/constants.py @@ -1,3 +1,41 @@ +SENEC_SECTION_BAT1 = "BAT1" +SENEC_SECTION_BAT1OBJ1 = "BAT1OBJ1" +SENEC_SECTION_BMS = "BMS" +SENEC_SECTION_BMS_PARA = "BMS_PARA" +SENEC_SECTION_CASC = "CASC" +SENEC_SECTION_DEBUG = "DEBUG" +SENEC_SECTION_DISPLAY = "DISPLAY" +SENEC_SECTION_ENERGY = "ENERGY" +SENEC_SECTION_FACTORY = "FACTORY" +SENEC_SECTION_FEATURES = "FEATURES" +SENEC_SECTION_FILE = "FILE" +SENEC_SECTION_GRIDCONFIG = "GRIDCONFIG" +SENEC_SECTION_LOG = "LOG" +SENEC_SECTION_PM1 = "PM1" +SENEC_SECTION_PM1OBJ1 = "PM1OBJ1" +SENEC_SECTION_PM1OBJ2 = "PM1OBJ2" +SENEC_SECTION_PV1 = "PV1" +SENEC_SECTION_PWR_UNIT = "PWR_UNIT" +SENEC_SECTION_RTC = "RTC" +SENEC_SECTION_SELFTEST_RESULTS = "SELFTEST_RESULTS" +SENEC_SECTION_SOCKETS = "SOCKETS" +SENEC_SECTION_STATISTIC = "STATISTIC" +SENEC_SECTION_STECA = "STECA" +SENEC_SECTION_SYS_UPDATE = "SYS_UPDATE" +SENEC_SECTION_TEMPMEASURE = "TEMPMEASURE" +SENEC_SECTION_TEST = "TEST" +SENEC_SECTION_UPDATE = "UPDATE" +SENEC_SECTION_WALLBOX = "WALLBOX" +SENEC_SECTION_WIZARD = "WIZARD" +SENEC_SECTION_CURRENT_IMBALANCE_CONTROL = "CURRENT_IMBALANCE_CONTROL" +SENEC_SECTION_BMZ_CURRENT_LIMITS = "BMZ_CURRENT_LIMITS" +SENEC_SECTION_CELL_DEVIATION_ROC = "CELL_DEVIATION_ROC" +SENEC_SECTION_SENEC_IO_INPUT = "SENEC_IO_INPUT" +SENEC_SECTION_SENEC_IO_OUTPUT = "SENEC_IO_OUTPUT" +SENEC_SECTION_IPU = "IPU" +SENEC_SECTION_FAN_TEST = "FAN_TEST" +SENEC_SECTION_FAN_SPEED = "FAN_SPEED" + BATT_TYPE_NAME = { 0: "Studer Xtender", 1: "SenecBatt",