From 212b9df87d8f5a128f3979dd8edc328915ecfde5 Mon Sep 17 00:00:00 2001 From: SukramJ Date: Wed, 10 Jun 2020 11:34:14 +0200 Subject: [PATCH] Bump dependency & add devices for HomematicIP Cloud (#36595) * update dependency and test data * Add test for HmIP-SWDO-PL * Add device HmIP-MOD-HO * Fix test --- .../components/homematicip_cloud/cover.py | 11 +- .../homematicip_cloud/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- .../homematicip_cloud/test_binary_sensor.py | 30 +++ .../homematicip_cloud/test_cover.py | 47 ++++ .../homematicip_cloud/test_device.py | 2 +- tests/fixtures/homematicip_cloud.json | 204 ++++++++++++++++++ 8 files changed, 292 insertions(+), 8 deletions(-) diff --git a/homeassistant/components/homematicip_cloud/cover.py b/homeassistant/components/homematicip_cloud/cover.py index 580e2d21a11..d11a08d80a6 100644 --- a/homeassistant/components/homematicip_cloud/cover.py +++ b/homeassistant/components/homematicip_cloud/cover.py @@ -6,6 +6,7 @@ from homematicip.aio.device import ( AsyncFullFlushBlind, AsyncFullFlushShutter, AsyncGarageDoorModuleTormatic, + AsyncHoermannDrivesModule, ) from homematicip.aio.group import AsyncExtendedLinkedShutterGroup from homematicip.base.enums import DoorCommand, DoorState @@ -40,8 +41,10 @@ async def async_setup_entry( entities.append(HomematicipCoverSlats(hap, device)) elif isinstance(device, AsyncFullFlushShutter): entities.append(HomematicipCoverShutter(hap, device)) - elif isinstance(device, AsyncGarageDoorModuleTormatic): - entities.append(HomematicipGarageDoorModuleTormatic(hap, device)) + elif isinstance( + device, (AsyncHoermannDrivesModule, AsyncGarageDoorModuleTormatic) + ): + entities.append(HomematicipGarageDoorModule(hap, device)) for group in hap.home.groups: if isinstance(group, AsyncExtendedLinkedShutterGroup): @@ -118,8 +121,8 @@ class HomematicipCoverSlats(HomematicipCoverShutter, CoverEntity): await self._device.set_shutter_stop() -class HomematicipGarageDoorModuleTormatic(HomematicipGenericDevice, CoverEntity): - """Representation of a HomematicIP Garage Door Module for Tormatic.""" +class HomematicipGarageDoorModule(HomematicipGenericDevice, CoverEntity): + """Representation of a HomematicIP Garage Door Module.""" @property def current_cover_position(self) -> int: diff --git a/homeassistant/components/homematicip_cloud/manifest.json b/homeassistant/components/homematicip_cloud/manifest.json index ef362300c66..42efeb73821 100644 --- a/homeassistant/components/homematicip_cloud/manifest.json +++ b/homeassistant/components/homematicip_cloud/manifest.json @@ -3,7 +3,7 @@ "name": "HomematicIP Cloud", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/homematicip_cloud", - "requirements": ["homematicip==0.10.17"], + "requirements": ["homematicip==0.10.18"], "codeowners": ["@SukramJ"], "quality_scale": "platinum" } diff --git a/requirements_all.txt b/requirements_all.txt index 3db119671c7..7a453b6f086 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -743,7 +743,7 @@ homeassistant-pyozw==0.1.10 homeconnect==0.5 # homeassistant.components.homematicip_cloud -homematicip==0.10.17 +homematicip==0.10.18 # homeassistant.components.horizon horimote==0.4.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index c0a07437b88..fda697b3aad 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -333,7 +333,7 @@ homeassistant-pyozw==0.1.10 homeconnect==0.5 # homeassistant.components.homematicip_cloud -homematicip==0.10.17 +homematicip==0.10.18 # homeassistant.components.google # homeassistant.components.remember_the_milk diff --git a/tests/components/homematicip_cloud/test_binary_sensor.py b/tests/components/homematicip_cloud/test_binary_sensor.py index 43b88976043..7fe9a7327ea 100644 --- a/tests/components/homematicip_cloud/test_binary_sensor.py +++ b/tests/components/homematicip_cloud/test_binary_sensor.py @@ -128,6 +128,36 @@ async def test_hmip_shutter_contact(hass, default_mock_hap_factory): assert ha_state.attributes[ATTR_SABOTAGE] +async def test_hmip_shutter_contact_optical(hass, default_mock_hap_factory): + """Test HomematicipShutterContact.""" + entity_id = "binary_sensor.sitzplatzture" + entity_name = "Sitzplatzt\u00fcre" + device_model = "HmIP-SWDO-PL" + mock_hap = await default_mock_hap_factory.async_get_mock_hap( + test_devices=[entity_name] + ) + + ha_state, hmip_device = get_and_check_entity_basics( + hass, mock_hap, entity_id, entity_name, device_model + ) + + assert ha_state.state == STATE_OFF + await async_manipulate_test_data(hass, hmip_device, "windowState", WindowState.OPEN) + ha_state = hass.states.get(entity_id) + assert ha_state.state == STATE_ON + + await async_manipulate_test_data(hass, hmip_device, "windowState", None) + ha_state = hass.states.get(entity_id) + assert ha_state.state == STATE_OFF + + # test common attributes + assert ha_state.attributes[ATTR_RSSI_DEVICE] == -72 + assert not ha_state.attributes.get(ATTR_SABOTAGE) + await async_manipulate_test_data(hass, hmip_device, "sabotage", True) + ha_state = hass.states.get(entity_id) + assert ha_state.attributes[ATTR_SABOTAGE] + + async def test_hmip_motion_detector(hass, default_mock_hap_factory): """Test HomematicipMotionDetector.""" entity_id = "binary_sensor.bewegungsmelder_fur_55er_rahmen_innen" diff --git a/tests/components/homematicip_cloud/test_cover.py b/tests/components/homematicip_cloud/test_cover.py index 7da1a94bdd7..7ef0e3d6703 100644 --- a/tests/components/homematicip_cloud/test_cover.py +++ b/tests/components/homematicip_cloud/test_cover.py @@ -207,6 +207,53 @@ async def test_hmip_garage_door_tormatic(hass, default_mock_hap_factory): assert hmip_device.mock_calls[-1][1] == (DoorCommand.STOP,) +async def test_hmip_garage_door_hoermann(hass, default_mock_hap_factory): + """Test HomematicipCoverShutte.""" + entity_id = "cover.garage_door" + entity_name = "Garage door" + device_model = "HmIP-MOD-HO" + mock_hap = await default_mock_hap_factory.async_get_mock_hap( + test_devices=[entity_name] + ) + + ha_state, hmip_device = get_and_check_entity_basics( + hass, mock_hap, entity_id, entity_name, device_model + ) + + assert ha_state.state == "closed" + assert ha_state.attributes["current_position"] == 0 + service_call_counter = len(hmip_device.mock_calls) + + await hass.services.async_call( + "cover", "open_cover", {"entity_id": entity_id}, blocking=True + ) + assert len(hmip_device.mock_calls) == service_call_counter + 1 + assert hmip_device.mock_calls[-1][0] == "send_door_command" + assert hmip_device.mock_calls[-1][1] == (DoorCommand.OPEN,) + await async_manipulate_test_data(hass, hmip_device, "doorState", DoorState.OPEN) + ha_state = hass.states.get(entity_id) + assert ha_state.state == STATE_OPEN + assert ha_state.attributes[ATTR_CURRENT_POSITION] == 100 + + await hass.services.async_call( + "cover", "close_cover", {"entity_id": entity_id}, blocking=True + ) + assert len(hmip_device.mock_calls) == service_call_counter + 3 + assert hmip_device.mock_calls[-1][0] == "send_door_command" + assert hmip_device.mock_calls[-1][1] == (DoorCommand.CLOSE,) + await async_manipulate_test_data(hass, hmip_device, "doorState", DoorState.CLOSED) + ha_state = hass.states.get(entity_id) + assert ha_state.state == STATE_CLOSED + assert ha_state.attributes[ATTR_CURRENT_POSITION] == 0 + + await hass.services.async_call( + "cover", "stop_cover", {"entity_id": entity_id}, blocking=True + ) + assert len(hmip_device.mock_calls) == service_call_counter + 5 + assert hmip_device.mock_calls[-1][0] == "send_door_command" + assert hmip_device.mock_calls[-1][1] == (DoorCommand.STOP,) + + async def test_hmip_cover_shutter_group(hass, default_mock_hap_factory): """Test HomematicipCoverShutteGroup.""" entity_id = "cover.rollos_shuttergroup" diff --git a/tests/components/homematicip_cloud/test_device.py b/tests/components/homematicip_cloud/test_device.py index 8a8d52d167a..8ea44795c96 100644 --- a/tests/components/homematicip_cloud/test_device.py +++ b/tests/components/homematicip_cloud/test_device.py @@ -22,7 +22,7 @@ async def test_hmip_load_all_supported_devices(hass, default_mock_hap_factory): test_devices=None, test_groups=None ) - assert len(mock_hap.hmip_device_by_entity_id) == 183 + assert len(mock_hap.hmip_device_by_entity_id) == 186 async def test_hmip_remove_device(hass, default_mock_hap_factory): diff --git a/tests/fixtures/homematicip_cloud.json b/tests/fixtures/homematicip_cloud.json index e85401aa1ec..1aa3bfa48ad 100644 --- a/tests/fixtures/homematicip_cloud.json +++ b/tests/fixtures/homematicip_cloud.json @@ -14,6 +14,210 @@ } }, "devices": { + "3014F7110SHUTTER_OPTICAL": { + "availableFirmwareVersion": "1.16.10", + "connectionType": "HMIP_RF", + "firmwareVersion": "1.16.10", + "firmwareVersionInteger": 69642, + "functionalChannels": { + "0": { + "coProFaulty": false, + "coProRestartNeeded": false, + "coProUpdateFailure": false, + "configPending": false, + "deviceId": "3014F7110SHUTTER_OPTICAL", + "deviceOverheated": false, + "deviceOverloaded": false, + "devicePowerFailureDetected": false, + "deviceUndervoltage": false, + "dutyCycle": false, + "functionalChannelType": "DEVICE_SABOTAGE", + "groupIndex": 0, + "groups": [], + "index": 0, + "label": "", + "lowBat": false, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -72, + "rssiPeerValue": null, + "sabotage": false, + "supportedOptionalFeatures": { + "IFeatureDeviceCoProError": false, + "IFeatureDeviceCoProRestart": false, + "IFeatureDeviceCoProUpdate": false, + "IFeatureDeviceIdentify": false, + "IFeatureDeviceOverheated": false, + "IFeatureDeviceOverloaded": false, + "IFeatureDevicePowerFailure": false, + "IFeatureDeviceTemperatureOutOfRange": false, + "IFeatureDeviceUndervoltage": false + }, + "temperatureOutOfRange": false, + "unreach": false + }, + "1": { + "deviceId": "3014F7110SHUTTER_OPTICAL", + "eventDelay": 0, + "functionalChannelType": "SHUTTER_CONTACT_CHANNEL", + "groupIndex": 1, + "groups": [ + "00000000-0000-0000-0000-000000000016", + "00000000-0000-0000-0000-000000000044", + "00000000-0000-0000-0000-000000000009" + ], + "index": 1, + "label": "", + "windowState": "CLOSED" + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110SHUTTER_OPTICAL", + "label": "Sitzplatzt\u00fcre", + "lastStatusUpdate": 1589401621441, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 398, + "modelType": "HmIP-SWDO-PL", + "oem": "eQ-3", + "permanentlyReachable": false, + "serializedGlobalTradeItemNumber": "3014F7110SHUTTER_OPTICAL", + "type": "SHUTTER_CONTACT_OPTICAL_PLUS", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000HmIPFSI16": { + "availableFirmwareVersion": "0.0.0", + "connectionType": "HMIP_RF", + "firmwareVersion": "1.16.2", + "firmwareVersionInteger": 69634, + "functionalChannels": { + "0": { + "coProFaulty": false, + "coProRestartNeeded": false, + "coProUpdateFailure": false, + "configPending": false, + "deviceId": "3014F7110000000HmIPFSI16", + "deviceOverheated": false, + "deviceOverloaded": false, + "devicePowerFailureDetected": false, + "deviceUndervoltage": false, + "dutyCycle": false, + "functionalChannelType": "DEVICE_BASE", + "groupIndex": 0, + "groups": [], + "index": 0, + "label": "", + "lowBat": null, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -57, + "rssiPeerValue": -54, + "supportedOptionalFeatures": { + "IFeatureDeviceCoProError": false, + "IFeatureDeviceCoProRestart": false, + "IFeatureDeviceCoProUpdate": false, + "IFeatureDeviceIdentify": false, + "IFeatureDeviceOverheated": true, + "IFeatureDeviceOverloaded": false, + "IFeatureDevicePowerFailure": false, + "IFeatureDeviceTemperatureOutOfRange": false, + "IFeatureDeviceUndervoltage": false + }, + "temperatureOutOfRange": false, + "unreach": false + }, + "1": { + "binaryBehaviorType": "NORMALLY_CLOSE", + "deviceId": "3014F7110000000HmIPFSI16", + "functionalChannelType": "MULTI_MODE_INPUT_SWITCH_CHANNEL", + "groupIndex": 1, + "groups": [], + "index": 1, + "label": "", + "multiModeInputMode": "KEY_BEHAVIOR", + "on": true, + "profileMode": "AUTOMATIC", + "userDesiredProfileMode": "AUTOMATIC" + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000HmIPFSI16", + "label": "Wohnzimmer Beleuchtung", + "lastStatusUpdate": 1587233145096, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 404, + "modelType": "HmIP-FSI16", + "oem": "eQ-3", + "permanentlyReachable": true, + "serializedGlobalTradeItemNumber": "3014F7110000000HmIPFSI16", + "type": "FULL_FLUSH_INPUT_SWITCH", + "updateState": "UP_TO_DATE" + }, + "3014F7110000000HOERMANN": { + "availableFirmwareVersion": "0.0.0", + "firmwareVersion": "1.0.14", + "firmwareVersionInteger": 65550, + "functionalChannels": { + "0": { + "coProFaulty": false, + "coProRestartNeeded": false, + "coProUpdateFailure": false, + "configPending": false, + "deviceId": "3014F7110000000HOERMANN", + "deviceOverheated": false, + "deviceOverloaded": false, + "deviceUndervoltage": false, + "dutyCycle": false, + "functionalChannelType": "DEVICE_BASE", + "groupIndex": 0, + "groups": [], + "index": 0, + "label": "", + "lowBat": null, + "routerModuleEnabled": false, + "routerModuleSupported": false, + "rssiDeviceValue": -71, + "rssiPeerValue": -76, + "supportedOptionalFeatures": { + "IFeatureDeviceCoProError": false, + "IFeatureDeviceCoProRestart": false, + "IFeatureDeviceCoProUpdate": false, + "IFeatureDeviceOverheated": false, + "IFeatureDeviceOverloaded": false, + "IFeatureDeviceTemperatureOutOfRange": false, + "IFeatureDeviceUndervoltage": false + }, + "temperatureOutOfRange": false, + "unreach": false + }, + "1": { + "deviceId": "3014F7110000000HOERMANN", + "doorState": "CLOSED", + "functionalChannelType": "DOOR_CHANNEL", + "groupIndex": 1, + "groups": [], + "index": 1, + "label": "", + "on": false, + "processing": false, + "ventilationPositionSupported": true + } + }, + "homeId": "00000000-0000-0000-0000-000000000001", + "id": "3014F7110000000HOERMANN", + "label": "Garage door", + "lastStatusUpdate": 1584029477755, + "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED", + "manufacturerCode": 1, + "modelId": 399, + "modelType": "HmIP-MOD-HO", + "oem": "eQ-3", + "permanentlyReachable": true, + "serializedGlobalTradeItemNumber": "3014F7110000000HOERMANN", + "type": "HOERMANN_DRIVES_MODULE", + "updateState": "UP_TO_DATE" + }, "3014F711000BBBB000000000": { "availableFirmwareVersion": "2.0.2", "firmwareVersion": "2.0.2",