From a4c830b5e40645181e1520698fe91ff5c29695b2 Mon Sep 17 00:00:00 2001 From: SukramJ Date: Tue, 7 Jan 2020 16:24:46 +0100 Subject: [PATCH] Add reset_energy_counter service to Homematic IP Cloud (#30256) * Add reset_energy_counter service to Homematic IP Cloud * Fix isort * Register service as admin service --- .../components/homematicip_cloud/__init__.py | 30 ++++++++++++++++++- .../homematicip_cloud/services.yaml | 7 +++++ .../homematicip_cloud/test_device.py | 27 +++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/homematicip_cloud/__init__.py b/homeassistant/components/homematicip_cloud/__init__.py index 62f3f9ec5d4..f3e1fc9fbec 100644 --- a/homeassistant/components/homematicip_cloud/__init__.py +++ b/homeassistant/components/homematicip_cloud/__init__.py @@ -3,6 +3,7 @@ import logging from pathlib import Path from typing import Optional +from homematicip.aio.device import AsyncSwitchMeasuring from homematicip.aio.group import AsyncHeatingGroup from homematicip.aio.home import AsyncHome from homematicip.base.helpers import handle_config @@ -47,6 +48,7 @@ SERVICE_ACTIVATE_VACATION = "activate_vacation" SERVICE_DEACTIVATE_ECO_MODE = "deactivate_eco_mode" SERVICE_DEACTIVATE_VACATION = "deactivate_vacation" SERVICE_DUMP_HAP_CONFIG = "dump_hap_config" +SERVICE_RESET_ENERGY_COUNTER = "reset_energy_counter" SERVICE_SET_ACTIVE_CLIMATE_PROFILE = "set_active_climate_profile" CONFIG_SCHEMA = vol.Schema( @@ -116,6 +118,10 @@ SCHEMA_DUMP_HAP_CONFIG = vol.Schema( } ) +SCHEMA_RESET_ENERGY_COUNTER = vol.Schema( + {vol.Required(ATTR_ENTITY_ID): comp_entity_ids} +) + async def async_setup(hass: HomeAssistantType, config: ConfigType) -> bool: """Set up the HomematicIP Cloud component.""" @@ -245,7 +251,7 @@ async def async_setup(hass: HomeAssistantType, config: ConfigType) -> bool: if entity_id_list != "all": for entity_id in entity_id_list: group = hap.hmip_device_by_entity_id.get(entity_id) - if group: + if group and isinstance(group, AsyncHeatingGroup): await group.set_active_profile(climate_profile_index) else: for group in hap.home.groups: @@ -289,6 +295,28 @@ async def async_setup(hass: HomeAssistantType, config: ConfigType) -> bool: schema=SCHEMA_DUMP_HAP_CONFIG, ) + async def _async_reset_energy_counter(service): + """Service to reset the energy counter.""" + entity_id_list = service.data[ATTR_ENTITY_ID] + + for hap in hass.data[DOMAIN].values(): + if entity_id_list != "all": + for entity_id in entity_id_list: + device = hap.hmip_device_by_entity_id.get(entity_id) + if device and isinstance(device, AsyncSwitchMeasuring): + await device.reset_energy_counter() + else: + for device in hap.home.devices: + if isinstance(device, AsyncSwitchMeasuring): + await device.reset_energy_counter() + + hass.helpers.service.async_register_admin_service( + DOMAIN, + SERVICE_RESET_ENERGY_COUNTER, + _async_reset_energy_counter, + schema=SCHEMA_RESET_ENERGY_COUNTER, + ) + def _get_home(hapid: str) -> Optional[AsyncHome]: """Return a HmIP home.""" hap = hass.data[DOMAIN].get(hapid) diff --git a/homeassistant/components/homematicip_cloud/services.yaml b/homeassistant/components/homematicip_cloud/services.yaml index 9a7d90eba9c..750528eddf8 100644 --- a/homeassistant/components/homematicip_cloud/services.yaml +++ b/homeassistant/components/homematicip_cloud/services.yaml @@ -69,3 +69,10 @@ dump_hap_config: anonymize: description: (Default is True) Should the Configuration be anonymized? example: True + +reset_energy_counter: + description: Reset the energy counter of a measuring entity. + fields: + entity_id: + description: The ID of the measuring entity. Use 'all' keyword to reset all energy counters. + example: switch.livingroom diff --git a/tests/components/homematicip_cloud/test_device.py b/tests/components/homematicip_cloud/test_device.py index 77f99655c98..9626cc0620f 100644 --- a/tests/components/homematicip_cloud/test_device.py +++ b/tests/components/homematicip_cloud/test_device.py @@ -130,3 +130,30 @@ async def test_hap_with_name(hass, mock_connection, hmip_config_entry): assert hmip_device assert ha_state.state == STATE_ON assert ha_state.attributes["friendly_name"] == entity_name + + +async def test_hmip_reset_energy_counter_services(hass, mock_hap_with_service): + """Test reset_energy_counter service.""" + entity_id = "switch.pc" + entity_name = "Pc" + device_model = "HMIP-PSM" + + ha_state, hmip_device = get_and_check_entity_basics( + hass, mock_hap_with_service, entity_id, entity_name, device_model + ) + assert ha_state + + await hass.services.async_call( + "homematicip_cloud", + "reset_energy_counter", + {"entity_id": "switch.pc"}, + blocking=True, + ) + assert hmip_device.mock_calls[-1][0] == "reset_energy_counter" + assert len(hmip_device._connection.mock_calls) == 2 # pylint: disable=W0212 + + await hass.services.async_call( + "homematicip_cloud", "reset_energy_counter", {"entity_id": "all"}, blocking=True + ) + assert hmip_device.mock_calls[-1][0] == "reset_energy_counter" + assert len(hmip_device._connection.mock_calls) == 12 # pylint: disable=W0212