diff --git a/custom_components/uhomeuponor/__init__.py b/custom_components/uhomeuponor/__init__.py index 33aafa5..b7200e9 100644 --- a/custom_components/uhomeuponor/__init__.py +++ b/custom_components/uhomeuponor/__init__.py @@ -3,11 +3,12 @@ For more details about this platform, please refer to the documentation at https://github.com/fcastroruiz/uhomeuponor """ -from homeassistant.const import CONF_HOST from logging import getLogger +import asyncio from homeassistant.core import HomeAssistant from homeassistant.const import Platform from homeassistant.config_entries import ConfigEntry +from homeassistant.helpers import device_registry, entity_registry _LOGGER = getLogger(__name__) DOMAIN = "uhomeuponor" @@ -15,22 +16,38 @@ async def async_setup(hass: HomeAssistant, config: dict): """Set up this integration using UI.""" - _LOGGER.info("Loading setup") hass.data.setdefault(DOMAIN, {}) hass.data[DOMAIN]["config"] = config.get(DOMAIN) or {} return True async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry): """Set up this integration using UI.""" - #host = config_entry.data[CONF_HOST] _LOGGER.info("Loading setup entry") - # hass.async_create_task(hass.config_entries.async_forward_entry_setup(config_entry, "climate")) - # hass.async_create_task(hass.config_entries.async_forward_entry_setup(config_entry, "sensor")) - hass.config_entries.async_setup_platforms(config_entry, PLATFORMS) + # hass.config_entries.async_setup_platforms(config_entry, PLATFORMS) + if config_entry.options: + if config_entry.data != config_entry.options: + dev_reg = device_registry.async_get(hass) + ent_reg = entity_registry.async_get(hass) + dev_reg.async_clear_config_entry(config_entry.entry_id) + ent_reg.async_clear_config_entry(config_entry.entry_id) + hass.config_entries.async_update_entry(config_entry, data=config_entry.options) + await hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS) + config_entry.async_on_unload(config_entry.add_update_listener(async_update_options)) + return True +async def async_update_options(hass: HomeAssistant, entry: ConfigEntry) -> None: + """Update options.""" + _LOGGER.debug("Update setup entry: %s, data: %s, options: %s", entry.entry_id, entry.data, entry.options) + await hass.config_entries.async_reload(entry.entry_id) + async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: """Unload a config entry.""" - return await hass.config_entries.async_unload_platforms(config_entry, PLATFORMS) + _LOGGER.debug("Unloading setup entry: %s, data: %s, options: %s", config_entry.entry_id, config_entry.data, config_entry.options) + unload_ok = await hass.config_entries.async_unload_platforms(config_entry, PLATFORMS) + return unload_ok + #if unload_ok: + # hass.data[DOMAIN].pop(config_entry.entry_id) + diff --git a/custom_components/uhomeuponor/climate.py b/custom_components/uhomeuponor/climate.py index 1ac0f1f..adfe15e 100644 --- a/custom_components/uhomeuponor/climate.py +++ b/custom_components/uhomeuponor/climate.py @@ -30,13 +30,6 @@ CONF_SUPPORTS_HEATING = "supports_heating" CONF_SUPPORTS_COOLING = "supports_cooling" -PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ - vol.Required(CONF_HOST): cv.string, - vol.Optional(CONF_PREFIX): cv.string, - vol.Optional(CONF_SUPPORTS_HEATING, default=True): cv.boolean, - vol.Optional(CONF_SUPPORTS_COOLING, default=True): cv.boolean, -}) - ATTR_TECHNICAL_ALARM = "technical_alarm" ATTR_RF_SIGNAL_ALARM = "rf_alarm" ATTR_BATTERY_ALARM = "battery_alarm" @@ -45,22 +38,20 @@ async def async_setup_entry(hass, config_entry, async_add_entities): - _LOGGER.info("init setup climate platform for %s", config_entry) - return await async_setup_platform( - hass, config_entry.data, async_add_entities, discovery_info=None + _LOGGER.info("init setup climate platform for id: %s data: %s, options: %s", config_entry.entry_id, config_entry.data, config_entry.options) + config = config_entry.data + return await async_setup_climate( + hass, config, async_add_entities, discovery_info=None ) -async def async_setup_platform( +async def async_setup_climate( hass, config, async_add_entities, discovery_info=None ) -> bool: - """Set up the Alexa alarm control panel platform.""" """Set up climate for device.""" - _LOGGER.info("init setup climate platform for %s", config) - host = config[CONF_HOST] prefix = config[CONF_PREFIX] - supports_heating = True - supports_cooling = True + supports_heating = config[CONF_SUPPORTS_HEATING] or True + supports_cooling = config[CONF_SUPPORTS_COOLING] or True _LOGGER.info("init setup host %s", host) diff --git a/custom_components/uhomeuponor/config_flow.py b/custom_components/uhomeuponor/config_flow.py index 1b37a27..e603705 100644 --- a/custom_components/uhomeuponor/config_flow.py +++ b/custom_components/uhomeuponor/config_flow.py @@ -1,4 +1,5 @@ from __future__ import annotations +import asyncio from homeassistant import config_entries from homeassistant.config_entries import ConfigEntry from homeassistant.core import callback @@ -8,6 +9,8 @@ _LOGGER = logging.getLogger(__name__) DOMAIN = "uhomeuponor" +CONF_SUPPORTS_HEATING = "supports_heating" +CONF_SUPPORTS_COOLING = "supports_cooling" class UhomeuponorConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): """Uponor config flow.""" @@ -16,22 +19,25 @@ class UhomeuponorConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): async def async_step_user(self, user_input=None): errors = {} + _LOGGER.info("Init config step uhomeuponor") if self._async_current_entries(): return self.async_abort(reason="single_instance_allowed") if user_input is not None: - _LOGGER.info ("user_input: %s", user_input) + _LOGGER.debug("user_input: %s", user_input) # Validate user input #valid = await is_valid(user_input) #if valid: #title = f"{self.info[CONF_HOST]} - {self.device_id}" title = f"Uhome Uponor" - prefix = user_input.get(CONF_PREFIX) if user_input.get(CONF_PREFIX) else "" + data={ + CONF_HOST: user_input[CONF_HOST], + CONF_PREFIX: (user_input.get(CONF_PREFIX) if user_input.get(CONF_PREFIX) else ""), + CONF_SUPPORTS_HEATING: user_input[CONF_SUPPORTS_HEATING], + CONF_SUPPORTS_COOLING: user_input[CONF_SUPPORTS_COOLING]} return self.async_create_entry( title=title, - data={ - "host": user_input[CONF_HOST], - "prefix": prefix, - }, + data=data + # options=data ) return self.async_show_form( @@ -40,56 +46,58 @@ async def async_step_user(self, user_input=None): { vol.Required(CONF_HOST): str, vol.Optional(CONF_PREFIX): str, + vol.Optional(CONF_SUPPORTS_HEATING, default=True): bool, + vol.Optional(CONF_SUPPORTS_COOLING, default=True): bool, } ), errors=errors ) - # @staticmethod - # @callback - # def async_get_options_flow( - # config_entry: ConfigEntry, - # ) -> UhomeuponorOptionsFlowHandler: - # """Options callback for uponor.""" - # return UhomeuponorOptionsFlowHandler(config_entry) + @staticmethod + @callback + def async_get_options_flow(entry: config_entries.ConfigEntry): + return OptionsFlowHandler(entry) +class OptionsFlowHandler(config_entries.OptionsFlow): -# class UhomeuponorOptionsFlowHandler(config_entries.OptionsFlow): -# """Config flow options for uponor.""" + def __init__(self, config_entry): + """Initialize options flow.""" + self.config_entry = config_entry -# def __init__(self, entry: ConfigEntry) -> None: -# """Initialize AccuWeather options flow.""" -# self.config_entry = entry - -# async def async_step_init(self, user_input=None): -# """Manage the options.""" -# return await self.async_step_user() - -# async def async_step_user(self, user_input=None): -# errors = {} -# if user_input is not None: -# _LOGGER.info ("Aqui debemos hacer algo con user_input: %s", user_input) -# # Validate user input -# #valid = await is_valid(user_input) -# #if valid: -# #title = f"{self.info[CONF_HOST]} - {self.device_id}" -# title = f"Uhome Uponor" -# return self.async_create_entry( -# title=title, -# data={ -# "host": user_input[CONF_HOST], -# "prefix": user_input[CONF_PREFIX], -# }, -# ) + async def async_step_init(self, _user_input=None): + """Manage the options.""" + return await self.async_step_user() + + async def async_step_user(self, user_input=None): + """Handle a flow initialized by the user.""" + _LOGGER.debug("entra en step user: %s", user_input) + _LOGGER.info("Init Option config step uhomeuponor") + errors = {} + options = self.config_entry.data + if user_input is not None: + data={ + CONF_HOST: user_input[CONF_HOST], + CONF_PREFIX: user_input[CONF_PREFIX], + CONF_SUPPORTS_HEATING: user_input[CONF_SUPPORTS_HEATING], + CONF_SUPPORTS_COOLING: user_input[CONF_SUPPORTS_COOLING], + } + _LOGGER.debug("user_input data: %s, id: %s", data, self.config_entry.entry_id) + title = f"Uhome Uponor" + return self.async_create_entry( + title=title, + data=data + ) -# return self.async_show_form( -# step_id="user", -# data_schema=vol.Schema( -# { -# vol.Required(CONF_HOST): str, -# vol.Optional(CONF_PREFIX): str, -# } -# ), errors=errors -# ) + return self.async_show_form( + step_id="user", + data_schema=vol.Schema( + { + vol.Required(CONF_HOST, default=options.get(CONF_HOST)): str, + vol.Optional(CONF_PREFIX, default=options.get(CONF_PREFIX)): str, + vol.Optional(CONF_SUPPORTS_HEATING, default=options.get(CONF_SUPPORTS_HEATING)): bool, + vol.Optional(CONF_SUPPORTS_COOLING, default=options.get(CONF_SUPPORTS_COOLING)): bool, + } + ), errors=errors + ) # class UhomeuponorDicoveryFlow(DiscoveryFlowHandler[Awaitable[bool]], domain=DOMAIN): # """Discovery flow handler.""" diff --git a/custom_components/uhomeuponor/sensor.py b/custom_components/uhomeuponor/sensor.py index ca52852..25b7f6d 100644 --- a/custom_components/uhomeuponor/sensor.py +++ b/custom_components/uhomeuponor/sensor.py @@ -35,16 +35,16 @@ async def async_setup_entry(hass, config_entry, async_add_entities): - _LOGGER.info("init setup sensor platform for %s", config_entry) - return await async_setup_platform( - hass, config_entry.data, async_add_entities, discovery_info=None + _LOGGER.info("init setup sensor platform for id: %s data: %s, options: %s", config_entry.entry_id, config_entry.data, config_entry.options) + config = config_entry.data + return await async_setup_sensor( + hass, config, async_add_entities, discovery_info=None ) -async def async_setup_platform( +async def async_setup_sensor( hass, config, async_add_entities, discovery_info=None ) -> bool: - _LOGGER.info("init setup sensor platform for %s", config) - + host = config[CONF_HOST] prefix = config[CONF_PREFIX] diff --git a/custom_components/uhomeuponor/translations/en.json b/custom_components/uhomeuponor/translations/en.json index abafe29..498bac2 100644 --- a/custom_components/uhomeuponor/translations/en.json +++ b/custom_components/uhomeuponor/translations/en.json @@ -14,7 +14,9 @@ "description": "Config Uponor system", "data": { "host": "Host or IP address of the Uponor Gateway", - "prefix": "Entities prefix" + "prefix": "Entities prefix", + "supports_heating": "Uponor supports heating", + "supports_cooling": "Uponor supports cooling" } } } @@ -26,7 +28,9 @@ "description": "Config Uponor system", "data": { "host": "Host or IP address of the Uponor Gateway", - "prefix": "Entities prefix" + "prefix": "Entities prefix", + "supports_heating": "Uponor supports heating", + "supports_cooling": "Uponor supports cooling" } } } diff --git a/custom_components/uhomeuponor/translations/es.json b/custom_components/uhomeuponor/translations/es.json index 8e994db..61fdc54 100644 --- a/custom_components/uhomeuponor/translations/es.json +++ b/custom_components/uhomeuponor/translations/es.json @@ -14,7 +14,9 @@ "description": "Configurar Uponor", "data": { "host": "Host o dirección IP del Gateway Uponor", - "prefix": "Prefijo para las entidades" + "prefix": "Prefijo para las entidades", + "supports_heating": "Uponor soporta calentar", + "supports_cooling": "Uponor soporta refrigerar" } } } @@ -26,7 +28,9 @@ "description": "Configurar Uponor", "data": { "host": "Host o dirección IP del Gateway Uponor", - "prefix": "Prefijo para las entidades" + "prefix": "Prefijo para las entidades", + "supports_heating": "Uponor soporta calentar", + "supports_cooling": "Uponor soporta refrigerar" } } } diff --git a/custom_components/uhomeuponor/uponor_api/__init__.py b/custom_components/uhomeuponor/uponor_api/__init__.py index ba14449..41f783b 100644 --- a/custom_components/uhomeuponor/uponor_api/__init__.py +++ b/custom_components/uhomeuponor/uponor_api/__init__.py @@ -58,7 +58,7 @@ async def init_controllers(self): # Controller i is present self.controllers.append(UponorController(self, i)) - _LOGGER.debug("Identified %d controllers", len(self.controllers)) + #_LOGGER.debug("Identified %d controllers", len(self.controllers)) # Update all controllers await self.update_devices(self.controllers) @@ -81,7 +81,7 @@ async def init_thermostats(self): # Thermostat i is present self.thermostats.append(UponorThermostat(self, controller.controller_index, i)) - _LOGGER.debug("Identified %d thermostats on %d controllers", len(self.thermostats), len(self.controllers)) + #_LOGGER.debug("Identified %d thermostats on %d controllers", len(self.thermostats), len(self.controllers)) # Update all thermostats await self.update_devices(self.thermostats) @@ -115,7 +115,7 @@ async def do_rest_call(self, requestObject): response_data = json.loads(response.text) - _LOGGER.debug("Issued API request type '%s' for %d objects, return code %d", requestObject['method'], len(requestObject['params']['objects']), response.status_code) + #_LOGGER.debug("Issued API request type '%s' for %d objects, return code %d", requestObject['method'], len(requestObject['params']['objects']), response.status_code) return response_data @@ -141,7 +141,7 @@ async def update_devices(self, *devices): for value in allvalues: allvalue_dict[value.id] = value - _LOGGER.debug("Requested update %d values of %d devices, skipped %d devices", len(values), len(devices_to_update), len(devices) - len(devices_to_update)) + #_LOGGER.debug("Requested update %d values of %d devices, skipped %d devices", len(values), len(devices_to_update), len(devices) - len(devices_to_update)) # Update all values, but at most N at a time for value_list in chunks(values, self.max_values_batch): @@ -157,7 +157,7 @@ async def update_values(self, allvalue_dict, *values): if len(values) == 0: return - _LOGGER.debug("Requested update of %d values", len(values)) + #_LOGGER.debug("Requested update of %d values", len(values)) value_dict = {} for value in values: @@ -260,7 +260,7 @@ def validate_values(self,response_data,allvalue_dict): def set_values(self, *value_tuples): """Writes values to UHome, accepts tuples of (UponorValue, New Value)""" - _LOGGER.debug("Requested write to %d values", len(value_tuples)) + #_LOGGER.debug("Requested write to %d values", len(value_tuples)) req = self.create_request("write") @@ -312,7 +312,7 @@ def attributes(self): return attr async def async_update(self): - _LOGGER.debug("Updating %s, device '%s'", self.__class__.__name__, self.identity_string) + #_LOGGER.debug("Updating %s, device '%s'", self.__class__.__name__, self.identity_string) await self.uponor_client.update_devices(self)