From 23200c0aa45136b8814de31598c92fef27d54bb6 Mon Sep 17 00:00:00 2001 From: Thomas Germain <12560542+thomasgermain@users.noreply.github.com> Date: Mon, 9 Jan 2023 14:58:12 +0100 Subject: [PATCH] Multiple instance (#184) multiple instance --- custom_components/multimatic/__init__.py | 60 +++++++++++-------- custom_components/multimatic/binary_sensor.py | 14 ++--- custom_components/multimatic/climate.py | 6 +- custom_components/multimatic/fan.py | 2 +- custom_components/multimatic/manifest.json | 2 +- custom_components/multimatic/sensor.py | 6 +- custom_components/multimatic/service.py | 30 ++++------ custom_components/multimatic/water_heater.py | 2 +- 8 files changed, 64 insertions(+), 58 deletions(-) diff --git a/custom_components/multimatic/__init__.py b/custom_components/multimatic/__init__.py index 83b7de7..6da2922 100644 --- a/custom_components/multimatic/__init__.py +++ b/custom_components/multimatic/__init__.py @@ -9,6 +9,7 @@ from homeassistant.helpers.typing import ConfigType from .const import ( + CONF_SERIAL_NUMBER, COORDINATOR_LIST, COORDINATORS, DEFAULT_SCAN_INTERVAL, @@ -33,8 +34,14 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: api: MultimaticApi = MultimaticApi(hass, entry) hass.data.setdefault(DOMAIN, {}) - hass.data[DOMAIN].setdefault(entry.unique_id, {}) - hass.data[DOMAIN][entry.unique_id].setdefault(COORDINATORS, {}) + hass.data[DOMAIN].setdefault(entry.entry_id, {}) + hass.data[DOMAIN][entry.entry_id].setdefault(COORDINATORS, {}) + + _LOGGER.debug( + "Setting up multimatic for serial %s, id is %s", + entry.data.get(CONF_SERIAL_NUMBER), + entry.entry_id, + ) for coord in COORDINATOR_LIST.items(): update_interval = ( @@ -51,7 +58,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: method="get_" + coord[0], update_interval=update_interval, ) - hass.data[DOMAIN][entry.unique_id][COORDINATORS][coord[0]] = m_coord + hass.data[DOMAIN][entry.entry_id][COORDINATORS][coord[0]] = m_coord _LOGGER.debug("Adding %s coordinator", m_coord.name) await m_coord.async_refresh() @@ -65,30 +72,41 @@ async def logout(event): hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, logout) - await async_setup_service(api, hass) + await async_setup_service(hass, api, entry) return True -async def async_setup_service(api: MultimaticApi, hass): +async def async_setup_service(hass, api: MultimaticApi, entry: ConfigEntry): """Set up services.""" - if not hass.data.get(SERVICES_HANDLER): + serial = api.serial if api.fixed_serial else None + + if not hass.data[DOMAIN][entry.entry_id].get(SERVICES_HANDLER): service_handler = MultimaticServiceHandler(api, hass) - for service_key in SERVICES: - schema = SERVICES[service_key]["schema"] - if not SERVICES[service_key].get("entity", False): + for service_key, data in SERVICES.items(): + schema = data["schema"] + if not data.get("entity", False): + key = service_key + if serial: + key += f"_{serial}" hass.services.async_register( - DOMAIN, service_key, service_handler.service_call, schema=schema + DOMAIN, key, getattr(service_handler, service_key), schema=schema ) - hass.data[DOMAIN][SERVICES_HANDLER] = service_handler + hass.data[DOMAIN][entry.entry_id][SERVICES_HANDLER] = service_handler -async def async_unload_services(hass): - """Remove service when integration is removed.""" - service_handler = hass.data[DOMAIN].get(SERVICES_HANDLER, None) +async def async_unload_services(hass, entry: ConfigEntry): + """Remove services when integration is removed.""" + service_handler = hass.data[DOMAIN][entry.entry_id].get(SERVICES_HANDLER, None) if service_handler: - for service_name in SERVICES: - hass.services.async_remove(DOMAIN, service_name) + serial = ( + service_handler.api.serial if service_handler.api.fixed_serial else None + ) + for service_key in SERVICES: + key = service_key + if serial: + key += f"_{serial}" + hass.services.async_remove(DOMAIN, key) async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: @@ -102,15 +120,9 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: ) ) if unload_ok: - hass.data[DOMAIN].pop(entry.unique_id) + await async_unload_services(hass, entry) + hass.data[DOMAIN].pop(entry.entry_id) _LOGGER.debug("Remaining data for multimatic %s", hass.data[DOMAIN]) - if ( - len(hass.data[DOMAIN]) == 1 - and hass.data[DOMAIN].get(SERVICES_HANDLER, None) is not None - ): - await async_unload_services(hass) - hass.data[DOMAIN].pop(SERVICES_HANDLER) - return unload_ok diff --git a/custom_components/multimatic/binary_sensor.py b/custom_components/multimatic/binary_sensor.py index bdac441..170faa7 100644 --- a/custom_components/multimatic/binary_sensor.py +++ b/custom_components/multimatic/binary_sensor.py @@ -43,13 +43,13 @@ async def async_setup_entry( """Set up the multimatic binary sensor platform.""" sensors: list[MultimaticEntity] = [] - dhw_coo = get_coordinator(hass, DHW, entry.unique_id) + dhw_coo = get_coordinator(hass, DHW, entry.entry_id) if dhw_coo.data and dhw_coo.data.circulation: sensors.append(CirculationSensor(dhw_coo)) - hvac_coo = get_coordinator(hass, HVAC_STATUS, entry.unique_id) - detail_coo = get_coordinator(hass, FACILITY_DETAIL, entry.unique_id) - gw_coo = get_coordinator(hass, GATEWAY, entry.unique_id) + hvac_coo = get_coordinator(hass, HVAC_STATUS, entry.entry_id) + detail_coo = get_coordinator(hass, FACILITY_DETAIL, entry.entry_id) + gw_coo = get_coordinator(hass, GATEWAY, entry.entry_id) if hvac_coo.data: sensors.append(BoxOnline(hvac_coo, detail_coo, gw_coo)) sensors.append(BoxUpdate(hvac_coo, detail_coo, gw_coo)) @@ -58,7 +58,7 @@ async def async_setup_entry( if hvac_coo.data.boiler_status: sensors.append(BoilerStatus(hvac_coo)) - rooms_coo = get_coordinator(hass, ROOMS, entry.unique_id) + rooms_coo = get_coordinator(hass, ROOMS, entry.entry_id) if rooms_coo.data: for room in rooms_coo.data: sensors.append(RoomWindow(rooms_coo, room)) @@ -70,8 +70,8 @@ async def async_setup_entry( sensors.extend( [ - HolidayModeSensor(get_coordinator(hass, HOLIDAY_MODE, entry.unique_id)), - QuickModeSensor(get_coordinator(hass, QUICK_MODE, entry.unique_id)), + HolidayModeSensor(get_coordinator(hass, HOLIDAY_MODE, entry.entry_id)), + QuickModeSensor(get_coordinator(hass, QUICK_MODE, entry.entry_id)), ] ) diff --git a/custom_components/multimatic/climate.py b/custom_components/multimatic/climate.py index 4b6b53a..a0eb1ab 100644 --- a/custom_components/multimatic/climate.py +++ b/custom_components/multimatic/climate.py @@ -71,9 +71,9 @@ async def async_setup_entry( ) -> None: """Set up the multimatic climate platform.""" climates: list[MultimaticClimate] = [] - zones_coo = get_coordinator(hass, ZONES, entry.unique_id) - rooms_coo = get_coordinator(hass, ROOMS, entry.unique_id) - ventilation_coo = get_coordinator(hass, VENTILATION, entry.unique_id) + zones_coo = get_coordinator(hass, ZONES, entry.entry_id) + rooms_coo = get_coordinator(hass, ROOMS, entry.entry_id) + ventilation_coo = get_coordinator(hass, VENTILATION, entry.entry_id) if zones_coo.data: for zone in zones_coo.data: diff --git a/custom_components/multimatic/fan.py b/custom_components/multimatic/fan.py index 6f1b80b..c4475a5 100644 --- a/custom_components/multimatic/fan.py +++ b/custom_components/multimatic/fan.py @@ -32,7 +32,7 @@ async def async_setup_entry( ) -> None: """Set up the multimatic fan platform.""" - coordinator = get_coordinator(hass, VENTILATION, entry.unique_id) + coordinator = get_coordinator(hass, VENTILATION, entry.entry_id) if coordinator.data: _LOGGER.debug("Adding fan entity") diff --git a/custom_components/multimatic/manifest.json b/custom_components/multimatic/manifest.json index 44ef60f..c0dfe9f 100644 --- a/custom_components/multimatic/manifest.json +++ b/custom_components/multimatic/manifest.json @@ -12,6 +12,6 @@ "homekit": {}, "dependencies": [], "codeowners": ["@thomasgermain"], - "version": "1.12.12", + "version": "1.13.0", "iot_class": "cloud_polling" } diff --git a/custom_components/multimatic/sensor.py b/custom_components/multimatic/sensor.py index 57a11d5..be831f4 100644 --- a/custom_components/multimatic/sensor.py +++ b/custom_components/multimatic/sensor.py @@ -39,9 +39,9 @@ async def async_setup_entry( ) -> None: """Set up the multimatic sensors.""" sensors: list[MultimaticEntity] = [] - outdoor_temp_coo = get_coordinator(hass, OUTDOOR_TEMP, entry.unique_id) - reports_coo = get_coordinator(hass, REPORTS, entry.unique_id) - emf_reports_coo = get_coordinator(hass, EMF_REPORTS, entry.unique_id) + outdoor_temp_coo = get_coordinator(hass, OUTDOOR_TEMP, entry.entry_id) + reports_coo = get_coordinator(hass, REPORTS, entry.entry_id) + emf_reports_coo = get_coordinator(hass, EMF_REPORTS, entry.entry_id) if outdoor_temp_coo.data: sensors.append(OutdoorTemperatureSensor(outdoor_temp_coo)) diff --git a/custom_components/multimatic/service.py b/custom_components/multimatic/service.py index 8cfa4a9..87e3989 100644 --- a/custom_components/multimatic/service.py +++ b/custom_components/multimatic/service.py @@ -128,42 +128,36 @@ def __init__(self, hub: MultimaticApi, hass) -> None: self.api = hub self._hass = hass - async def service_call(self, call): - """Handle service calls.""" - service = call.service - method = getattr(self, service) - await method(data=call.data) - - async def remove_quick_mode(self, data): + async def remove_quick_mode(self, call): """Remove quick mode. It has impact on all components.""" await self.api.remove_quick_mode() - async def set_holiday_mode(self, data): + async def set_holiday_mode(self, call): """Set holiday mode.""" - start_str = data.get(ATTR_START_DATE, None) - end_str = data.get(ATTR_END_DATE, None) - temp = data.get(ATTR_TEMPERATURE) + start_str = call.data.get(ATTR_START_DATE, None) + end_str = call.data.get(ATTR_END_DATE, None) + temp = call.data.get(ATTR_TEMPERATURE) start = parse_date(start_str.split("T")[0]) end = parse_date(end_str.split("T")[0]) if end is None or start is None: raise ValueError(f"dates are incorrect {start_str} {end_str}") await self.api.set_holiday_mode(start, end, temp) - async def remove_holiday_mode(self, data): + async def remove_holiday_mode(self, call): """Remove holiday mode.""" await self.api.remove_holiday_mode() - async def set_quick_mode(self, data): + async def set_quick_mode(self, call): """Set quick mode, it may impact the whole system.""" - quick_mode = data.get(ATTR_QUICK_MODE, None) - duration = data.get(ATTR_DURATION, None) + quick_mode = call.data.get(ATTR_QUICK_MODE, None) + duration = call.data.get(ATTR_DURATION, None) await self.api.set_quick_mode(quick_mode, duration) - async def request_hvac_update(self, data): + async def request_hvac_update(self, call): """Ask multimatic API to get data from the installation.""" await self.api.request_hvac_update() - async def set_datetime(self, data): + async def set_datetime(self, call): """Set date time.""" - date_t: datetime = data.get(ATTR_DATE_TIME, datetime.datetime.now()) + date_t: datetime = call.data.get(ATTR_DATE_TIME, datetime.datetime.now()) await self.api.set_datetime(date_t) diff --git a/custom_components/multimatic/water_heater.py b/custom_components/multimatic/water_heater.py index 4ab1ea6..3d5d461 100644 --- a/custom_components/multimatic/water_heater.py +++ b/custom_components/multimatic/water_heater.py @@ -43,7 +43,7 @@ async def async_setup_entry( ) -> None: """Set up water_heater platform.""" entities = [] - coordinator = get_coordinator(hass, DHW, entry.unique_id) + coordinator = get_coordinator(hass, DHW, entry.entry_id) if coordinator.data and coordinator.data.hotwater: entities.append(MultimaticWaterHeater(coordinator))