1 """Support for HomematicIP Cloud devices."""
3 from __future__
import annotations
6 from pathlib
import Path
8 from homematicip.aio.device
import AsyncSwitchMeasuring
9 from homematicip.aio.group
import AsyncHeatingGroup
10 from homematicip.aio.home
import AsyncHome
11 from homematicip.base.helpers
import handle_config
12 import voluptuous
as vol
20 async_register_admin_service,
21 verify_domain_control,
24 from .const
import DOMAIN
26 _LOGGER = logging.getLogger(__name__)
28 ATTR_ACCESSPOINT_ID =
"accesspoint_id"
29 ATTR_ANONYMIZE =
"anonymize"
30 ATTR_CLIMATE_PROFILE_INDEX =
"climate_profile_index"
31 ATTR_CONFIG_OUTPUT_FILE_PREFIX =
"config_output_file_prefix"
32 ATTR_CONFIG_OUTPUT_PATH =
"config_output_path"
33 ATTR_DURATION =
"duration"
34 ATTR_ENDTIME =
"endtime"
35 ATTR_COOLING =
"cooling"
37 DEFAULT_CONFIG_FILE_PREFIX =
"hmip-config"
39 SERVICE_ACTIVATE_ECO_MODE_WITH_DURATION =
"activate_eco_mode_with_duration"
40 SERVICE_ACTIVATE_ECO_MODE_WITH_PERIOD =
"activate_eco_mode_with_period"
41 SERVICE_ACTIVATE_VACATION =
"activate_vacation"
42 SERVICE_DEACTIVATE_ECO_MODE =
"deactivate_eco_mode"
43 SERVICE_DEACTIVATE_VACATION =
"deactivate_vacation"
44 SERVICE_DUMP_HAP_CONFIG =
"dump_hap_config"
45 SERVICE_RESET_ENERGY_COUNTER =
"reset_energy_counter"
46 SERVICE_SET_ACTIVE_CLIMATE_PROFILE =
"set_active_climate_profile"
47 SERVICE_SET_HOME_COOLING_MODE =
"set_home_cooling_mode"
50 SERVICE_ACTIVATE_ECO_MODE_WITH_DURATION,
51 SERVICE_ACTIVATE_ECO_MODE_WITH_PERIOD,
52 SERVICE_ACTIVATE_VACATION,
53 SERVICE_DEACTIVATE_ECO_MODE,
54 SERVICE_DEACTIVATE_VACATION,
55 SERVICE_DUMP_HAP_CONFIG,
56 SERVICE_RESET_ENERGY_COUNTER,
57 SERVICE_SET_ACTIVE_CLIMATE_PROFILE,
58 SERVICE_SET_HOME_COOLING_MODE,
61 SCHEMA_ACTIVATE_ECO_MODE_WITH_DURATION = vol.Schema(
63 vol.Required(ATTR_DURATION): cv.positive_int,
64 vol.Optional(ATTR_ACCESSPOINT_ID): vol.All(str, vol.Length(min=24, max=24)),
68 SCHEMA_ACTIVATE_ECO_MODE_WITH_PERIOD = vol.Schema(
70 vol.Required(ATTR_ENDTIME): cv.datetime,
71 vol.Optional(ATTR_ACCESSPOINT_ID): vol.All(str, vol.Length(min=24, max=24)),
75 SCHEMA_ACTIVATE_VACATION = vol.Schema(
77 vol.Required(ATTR_ENDTIME): cv.datetime,
78 vol.Required(ATTR_TEMPERATURE, default=18.0): vol.All(
79 vol.Coerce(float), vol.Range(min=0, max=55)
81 vol.Optional(ATTR_ACCESSPOINT_ID): vol.All(str, vol.Length(min=24, max=24)),
85 SCHEMA_DEACTIVATE_ECO_MODE = vol.Schema(
86 {vol.Optional(ATTR_ACCESSPOINT_ID): vol.All(str, vol.Length(min=24, max=24))}
89 SCHEMA_DEACTIVATE_VACATION = vol.Schema(
90 {vol.Optional(ATTR_ACCESSPOINT_ID): vol.All(str, vol.Length(min=24, max=24))}
93 SCHEMA_SET_ACTIVE_CLIMATE_PROFILE = vol.Schema(
95 vol.Required(ATTR_ENTITY_ID): comp_entity_ids,
96 vol.Required(ATTR_CLIMATE_PROFILE_INDEX): cv.positive_int,
100 SCHEMA_DUMP_HAP_CONFIG = vol.Schema(
102 vol.Optional(ATTR_CONFIG_OUTPUT_PATH): cv.string,
104 ATTR_CONFIG_OUTPUT_FILE_PREFIX, default=DEFAULT_CONFIG_FILE_PREFIX
106 vol.Optional(ATTR_ANONYMIZE, default=
True): cv.boolean,
110 SCHEMA_RESET_ENERGY_COUNTER = vol.Schema(
111 {vol.Required(ATTR_ENTITY_ID): comp_entity_ids}
114 SCHEMA_SET_HOME_COOLING_MODE = vol.Schema(
116 vol.Optional(ATTR_COOLING, default=
True): cv.boolean,
117 vol.Optional(ATTR_ACCESSPOINT_ID): vol.All(str, vol.Length(min=24, max=24)),
123 """Set up the HomematicIP Cloud services."""
125 if hass.services.async_services_for_domain(DOMAIN):
128 @verify_domain_control(hass, DOMAIN)
129 async
def async_call_hmipc_service(service: ServiceCall) ->
None:
130 """Call correct HomematicIP Cloud service."""
131 service_name = service.service
133 if service_name == SERVICE_ACTIVATE_ECO_MODE_WITH_DURATION:
135 elif service_name == SERVICE_ACTIVATE_ECO_MODE_WITH_PERIOD:
137 elif service_name == SERVICE_ACTIVATE_VACATION:
139 elif service_name == SERVICE_DEACTIVATE_ECO_MODE:
141 elif service_name == SERVICE_DEACTIVATE_VACATION:
143 elif service_name == SERVICE_DUMP_HAP_CONFIG:
145 elif service_name == SERVICE_RESET_ENERGY_COUNTER:
147 elif service_name == SERVICE_SET_ACTIVE_CLIMATE_PROFILE:
149 elif service_name == SERVICE_SET_HOME_COOLING_MODE:
152 hass.services.async_register(
154 service=SERVICE_ACTIVATE_ECO_MODE_WITH_DURATION,
155 service_func=async_call_hmipc_service,
156 schema=SCHEMA_ACTIVATE_ECO_MODE_WITH_DURATION,
159 hass.services.async_register(
161 service=SERVICE_ACTIVATE_ECO_MODE_WITH_PERIOD,
162 service_func=async_call_hmipc_service,
163 schema=SCHEMA_ACTIVATE_ECO_MODE_WITH_PERIOD,
166 hass.services.async_register(
168 service=SERVICE_ACTIVATE_VACATION,
169 service_func=async_call_hmipc_service,
170 schema=SCHEMA_ACTIVATE_VACATION,
173 hass.services.async_register(
175 service=SERVICE_DEACTIVATE_ECO_MODE,
176 service_func=async_call_hmipc_service,
177 schema=SCHEMA_DEACTIVATE_ECO_MODE,
180 hass.services.async_register(
182 service=SERVICE_DEACTIVATE_VACATION,
183 service_func=async_call_hmipc_service,
184 schema=SCHEMA_DEACTIVATE_VACATION,
187 hass.services.async_register(
189 service=SERVICE_SET_ACTIVE_CLIMATE_PROFILE,
190 service_func=async_call_hmipc_service,
191 schema=SCHEMA_SET_ACTIVE_CLIMATE_PROFILE,
197 service=SERVICE_DUMP_HAP_CONFIG,
198 service_func=async_call_hmipc_service,
199 schema=SCHEMA_DUMP_HAP_CONFIG,
205 service=SERVICE_RESET_ENERGY_COUNTER,
206 service_func=async_call_hmipc_service,
207 schema=SCHEMA_RESET_ENERGY_COUNTER,
213 service=SERVICE_SET_HOME_COOLING_MODE,
214 service_func=async_call_hmipc_service,
215 schema=SCHEMA_SET_HOME_COOLING_MODE,
220 """Unload HomematicIP Cloud services."""
221 if hass.data[DOMAIN]:
224 for hmipc_service
in HMIPC_SERVICES:
225 hass.services.async_remove(domain=DOMAIN, service=hmipc_service)
229 hass: HomeAssistant, service: ServiceCall
231 """Service to activate eco mode with duration."""
232 duration = service.data[ATTR_DURATION]
234 if hapid := service.data.get(ATTR_ACCESSPOINT_ID):
236 await home.activate_absence_with_duration(duration)
238 for hap
in hass.data[DOMAIN].values():
239 await hap.home.activate_absence_with_duration(duration)
243 hass: HomeAssistant, service: ServiceCall
245 """Service to activate eco mode with period."""
246 endtime = service.data[ATTR_ENDTIME]
248 if hapid := service.data.get(ATTR_ACCESSPOINT_ID):
250 await home.activate_absence_with_period(endtime)
252 for hap
in hass.data[DOMAIN].values():
253 await hap.home.activate_absence_with_period(endtime)
257 """Service to activate vacation."""
258 endtime = service.data[ATTR_ENDTIME]
259 temperature = service.data[ATTR_TEMPERATURE]
261 if hapid := service.data.get(ATTR_ACCESSPOINT_ID):
263 await home.activate_vacation(endtime, temperature)
265 for hap
in hass.data[DOMAIN].values():
266 await hap.home.activate_vacation(endtime, temperature)
270 """Service to deactivate eco mode."""
271 if hapid := service.data.get(ATTR_ACCESSPOINT_ID):
273 await home.deactivate_absence()
275 for hap
in hass.data[DOMAIN].values():
276 await hap.home.deactivate_absence()
280 """Service to deactivate vacation."""
281 if hapid := service.data.get(ATTR_ACCESSPOINT_ID):
283 await home.deactivate_vacation()
285 for hap
in hass.data[DOMAIN].values():
286 await hap.home.deactivate_vacation()
290 hass: HomeAssistant, service: ServiceCall
292 """Service to set the active climate profile."""
293 entity_id_list = service.data[ATTR_ENTITY_ID]
294 climate_profile_index = service.data[ATTR_CLIMATE_PROFILE_INDEX] - 1
296 for hap
in hass.data[DOMAIN].values():
297 if entity_id_list !=
"all":
298 for entity_id
in entity_id_list:
299 group = hap.hmip_device_by_entity_id.get(entity_id)
300 if group
and isinstance(group, AsyncHeatingGroup):
301 await group.set_active_profile(climate_profile_index)
303 for group
in hap.home.groups:
304 if isinstance(group, AsyncHeatingGroup):
305 await group.set_active_profile(climate_profile_index)
309 """Service to dump the configuration of a Homematic IP Access Point."""
311 service.data.get(ATTR_CONFIG_OUTPUT_PATH)
or hass.config.config_dir
313 config_file_prefix = service.data[ATTR_CONFIG_OUTPUT_FILE_PREFIX]
314 anonymize = service.data[ATTR_ANONYMIZE]
316 for hap
in hass.data[DOMAIN].values():
317 hap_sgtin = hap.config_entry.unique_id
320 hap_sgtin = hap_sgtin[-4:]
322 file_name = f
"{config_file_prefix}_{hap_sgtin}.json"
323 path = Path(config_path)
324 config_file = path / file_name
326 json_state = await hap.home.download_configuration()
327 json_state = handle_config(json_state, anonymize)
329 config_file.write_text(json_state, encoding=
"utf8")
333 """Service to reset the energy counter."""
334 entity_id_list = service.data[ATTR_ENTITY_ID]
336 for hap
in hass.data[DOMAIN].values():
337 if entity_id_list !=
"all":
338 for entity_id
in entity_id_list:
339 device = hap.hmip_device_by_entity_id.get(entity_id)
340 if device
and isinstance(device, AsyncSwitchMeasuring):
341 await device.reset_energy_counter()
343 for device
in hap.home.devices:
344 if isinstance(device, AsyncSwitchMeasuring):
345 await device.reset_energy_counter()
349 """Service to set the cooling mode."""
350 cooling = service.data[ATTR_COOLING]
352 if hapid := service.data.get(ATTR_ACCESSPOINT_ID):
354 await home.set_cooling(cooling)
356 for hap
in hass.data[DOMAIN].values():
357 await hap.home.set_cooling(cooling)
360 def _get_home(hass: HomeAssistant, hapid: str) -> AsyncHome |
None:
361 """Return a HmIP home."""
362 if hap := hass.data[DOMAIN].
get(hapid):
366 translation_domain=DOMAIN,
367 translation_key=
"access_point_not_found",
368 translation_placeholders={
"id": hapid},
web.Response get(self, web.Request request, str config_key)
None _async_dump_hap_config(HomeAssistant hass, ServiceCall service)
None _async_activate_eco_mode_with_period(HomeAssistant hass, ServiceCall service)
def _async_reset_energy_counter(HomeAssistant hass, ServiceCall service)
None _async_deactivate_eco_mode(HomeAssistant hass, ServiceCall service)
None _set_active_climate_profile(HomeAssistant hass, ServiceCall service)
None _async_deactivate_vacation(HomeAssistant hass, ServiceCall service)
None _async_activate_vacation(HomeAssistant hass, ServiceCall service)
def async_unload_services(HomeAssistant hass)
AsyncHome|None _get_home(HomeAssistant hass, str hapid)
None _async_activate_eco_mode_with_duration(HomeAssistant hass, ServiceCall service)
None async_setup_services(HomeAssistant hass)
def _async_set_home_cooling_mode(HomeAssistant hass, ServiceCall service)
None async_register_admin_service(HomeAssistant hass, str domain, str service, Callable[[ServiceCall], Awaitable[None]|None] service_func, VolSchemaType schema=vol.Schema({}, extra=vol.PREVENT_EXTRA))