From 80fb0072627a70fbbf5f84155b324deb084f2963 Mon Sep 17 00:00:00 2001 From: BenPru Date: Tue, 31 Oct 2023 20:54:16 +0100 Subject: [PATCH] * Fix entity migration * Add switch silent mode * Re-Add service write --- custom_components/luxtronik/__init__.py | 22 +++++++++++++++++++ custom_components/luxtronik/climate.py | 3 ++- custom_components/luxtronik/const.py | 20 ++++++++++++++--- custom_components/luxtronik/manifest.json | 2 +- custom_components/luxtronik/services.yaml | 9 ++++++++ .../luxtronik/switch_entities_predefined.py | 7 ++++++ .../luxtronik/translations/en.json | 3 +++ 7 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 custom_components/luxtronik/services.yaml diff --git a/custom_components/luxtronik/__init__.py b/custom_components/luxtronik/__init__.py index 6dee291..561db6f 100644 --- a/custom_components/luxtronik/__init__.py +++ b/custom_components/luxtronik/__init__.py @@ -11,6 +11,8 @@ ) from .const import ( + ATTR_PARAMETER, + ATTR_VALUE, CONF_COORDINATOR, CONF_HA_SENSOR_PREFIX, CONF_MAX_DATA_LENGTH, @@ -19,6 +21,8 @@ DOMAIN, LOGGER, PLATFORMS, + SERVICE_WRITE, + SERVICE_WRITE_SCHEMA, SensorKey as SK, ) from .coordinator import LuxtronikCoordinator @@ -48,9 +52,26 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: # hass.config_entries.async_setup_platforms(entry, PLATFORMS) + await hass.async_add_executor_job(setup_hass_services, hass, entry) + return True +def setup_hass_services(hass: HomeAssistant, entry: ConfigEntry): + """Home Assistant services.""" + + def write_parameter(service): + """Write a parameter to the Luxtronik heatpump.""" + parameter = service.data.get(ATTR_PARAMETER) + value = service.data.get(ATTR_VALUE) + coordinator = LuxtronikCoordinator.connect(hass, entry) + coordinator.write(parameter, value) + + hass.services.register( + DOMAIN, SERVICE_WRITE, write_parameter, schema=SERVICE_WRITE_SCHEMA + ) + + async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload a config entry.""" if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS): @@ -107,6 +128,7 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> ent_reg = None def _up(ident: str, new_id: SK, platform: P = P.SENSOR) -> None: + nonlocal prefix, ent_reg if prefix is None or ent_reg is None: prefix = config_entry.data[CONF_HA_SENSOR_PREFIX] ent_reg = async_get(hass) diff --git a/custom_components/luxtronik/climate.py b/custom_components/luxtronik/climate.py index 6a5a31f..d124e6d 100644 --- a/custom_components/luxtronik/climate.py +++ b/custom_components/luxtronik/climate.py @@ -91,7 +91,8 @@ HVAC_PRESET_MAPPING: dict[str, str] = { LuxMode.off.value: PRESET_NONE, LuxMode.automatic.value: PRESET_NONE, - LuxMode.party.value: PRESET_BOOST, + LuxMode.party.value: PRESET_COMFORT, + LuxMode.second_heatsource.value: PRESET_BOOST, LuxMode.holidays.value: PRESET_AWAY, } diff --git a/custom_components/luxtronik/const.py b/custom_components/luxtronik/const.py index f3084d5..2245cbb 100644 --- a/custom_components/luxtronik/const.py +++ b/custom_components/luxtronik/const.py @@ -53,6 +53,18 @@ DEFAULT_PORT: Final = 8889 DEFAULT_TIMEOUT: Final = 60.0 DEFAULT_MAX_DATA_LENGTH: Final = 10000 + + +SERVICE_WRITE: Final = "write" +ATTR_PARAMETER: Final = "parameter" +ATTR_VALUE: Final = "value" + +SERVICE_WRITE_SCHEMA = vol.Schema( + { + vol.Required(ATTR_PARAMETER): cv.string, + vol.Required(ATTR_VALUE): vol.Any(cv.Number, cv.string), + } +) # endregion Conf # region Lux Definitions @@ -330,9 +342,6 @@ class LuxParameter(StrEnum): # "879 ID_Waermemenge_SW ": "0", # "880 ID_Waermemenge_Datum ": "1483648906", <-- Unix timestamp! 5.1.2017 - # "1060 ID_Waermemenge_Reset ": "535051", - # "1061 ID_Waermemenge_Reset_2 ": "0", - P0882_SOLAR_OPERATION_HOURS: Final = "parameters.ID_BSTD_Solar" P0883_SOLAR_PUMP_MAX_TEMPERATURE_COLLECTOR: Final = ( "parameters.ID_Einst_TDC_Koll_Max_akt" @@ -355,6 +364,9 @@ class LuxParameter(StrEnum): P1059_ADDITIONAL_HEAT_GENERATOR_AMOUNT_COUNTER: Final = ( "parameters.ID_Waermemenge_ZWE" ) + # "1060 ID_Waermemenge_Reset ": "535051", + # "1061 ID_Waermemenge_Reset_2 ": "0", + P1087_SILENT_MODE: Final = "parameters.Unknown_Parameter_1087" # Silent mode On/Off P1119_LAST_DEFROST_TIMESTAMP: Final = ( "parameters.Unknown_Parameter_1119" # 1685073431 -> 26.5.23 05:57 ) @@ -545,6 +557,7 @@ class LuxVisibility(StrEnum): V0324_ADDITIONAL_HEAT_GENERATOR_AMOUNT_COUNTER: Final = ( "visibilities.ID_Visi_Waermemenge_ZWE" ) + V0357_SILENT_MODE_TIME_MENU: Final = "visibilities.Unknown_Parameter_357" # endregion visibilities @@ -681,6 +694,7 @@ class SensorKey(StrEnum): COOLING_TARGET_TEMPERATURE_MK2 = "cooling_target_temperature_mk2" COOLING_TARGET_TEMPERATURE_MK3 = "cooling_target_temperature_mk3" SWITCHOFF_REASON = "switchoff_reason" + SILENT_MODE = "silent_mode" # endregion Keys diff --git a/custom_components/luxtronik/manifest.json b/custom_components/luxtronik/manifest.json index 82313a2..e835d4d 100755 --- a/custom_components/luxtronik/manifest.json +++ b/custom_components/luxtronik/manifest.json @@ -9,7 +9,7 @@ "after_dependencies": [], "codeowners": ["@BenPru"], "iot_class": "local_polling", - "version": "2023.10.30", + "version": "2023.10.31", "homeassistant": "2023.1.0", "dhcp": [ { "macaddress": "000E8C*" }, diff --git a/custom_components/luxtronik/services.yaml b/custom_components/luxtronik/services.yaml new file mode 100644 index 0000000..af60f59 --- /dev/null +++ b/custom_components/luxtronik/services.yaml @@ -0,0 +1,9 @@ +write: + description: Write a parameter on the luxtronik heatpump. + fields: + parameter: + description: ID of the value to write. + example: "ID_Ba_Bw_akt" + value: + description: Value to write. + example: "Automatic" diff --git a/custom_components/luxtronik/switch_entities_predefined.py b/custom_components/luxtronik/switch_entities_predefined.py index b7f6c1b..218ae23 100644 --- a/custom_components/luxtronik/switch_entities_predefined.py +++ b/custom_components/luxtronik/switch_entities_predefined.py @@ -37,6 +37,13 @@ entity_registry_enabled_default=False, # device_class=SensorDeviceClass.HEAT ), + LuxtronikSwitchDescription( + luxtronik_key=LP.P1087_SILENT_MODE, + key=SensorKey.SILENT_MODE, + icon="mdi:volume-minus", + entity_category=EntityCategory.CONFIG, + visibility=LV.V0357_SILENT_MODE_TIME_MENU, + ), # LuxtronikSwitchDescription( # luxtronik_key=LP.P0870_AMOUNT_COUNTER_ACTIVE, # key="amount_counter_active", diff --git a/custom_components/luxtronik/translations/en.json b/custom_components/luxtronik/translations/en.json index be37057..64b78b6 100644 --- a/custom_components/luxtronik/translations/en.json +++ b/custom_components/luxtronik/translations/en.json @@ -91,6 +91,9 @@ }, "cooling": { "name": "Cooling" + }, + "silent_mode": { + "name": "Silent mode" } }, "update": {