mirror of
https://github.com/home-assistant/core.git
synced 2025-12-24 21:06:19 +00:00
Add support for valance shades / volants to WMS WebControl pro (#150882)
This commit is contained in:
@@ -6,10 +6,11 @@ from datetime import timedelta
|
||||
from typing import Any
|
||||
|
||||
from wmspro.const import (
|
||||
WMS_WebControl_pro_API_actionDescription,
|
||||
WMS_WebControl_pro_API_actionDescription as ACTION_DESC,
|
||||
WMS_WebControl_pro_API_actionType,
|
||||
WMS_WebControl_pro_API_responseType,
|
||||
)
|
||||
from wmspro.destination import Destination
|
||||
|
||||
from homeassistant.components.cover import ATTR_POSITION, CoverDeviceClass, CoverEntity
|
||||
from homeassistant.core import HomeAssistant
|
||||
@@ -32,11 +33,11 @@ async def async_setup_entry(
|
||||
|
||||
entities: list[WebControlProGenericEntity] = []
|
||||
for dest in hub.dests.values():
|
||||
if dest.hasAction(WMS_WebControl_pro_API_actionDescription.AwningDrive):
|
||||
if dest.hasAction(ACTION_DESC.AwningDrive):
|
||||
entities.append(WebControlProAwning(config_entry.entry_id, dest))
|
||||
elif dest.hasAction(
|
||||
WMS_WebControl_pro_API_actionDescription.RollerShutterBlindDrive
|
||||
):
|
||||
if dest.hasAction(ACTION_DESC.ValanceDrive):
|
||||
entities.append(WebControlProValance(config_entry.entry_id, dest))
|
||||
if dest.hasAction(ACTION_DESC.RollerShutterBlindDrive):
|
||||
entities.append(WebControlProRollerShutter(config_entry.entry_id, dest))
|
||||
|
||||
async_add_entities(entities)
|
||||
@@ -45,7 +46,7 @@ async def async_setup_entry(
|
||||
class WebControlProCover(WebControlProGenericEntity, CoverEntity):
|
||||
"""Base representation of a WMS based cover."""
|
||||
|
||||
_drive_action_desc: WMS_WebControl_pro_API_actionDescription
|
||||
_drive_action_desc: ACTION_DESC
|
||||
_attr_name = None
|
||||
|
||||
@property
|
||||
@@ -79,7 +80,7 @@ class WebControlProCover(WebControlProGenericEntity, CoverEntity):
|
||||
async def async_stop_cover(self, **kwargs: Any) -> None:
|
||||
"""Stop the device if in motion."""
|
||||
action = self._dest.action(
|
||||
WMS_WebControl_pro_API_actionDescription.ManualCommand,
|
||||
ACTION_DESC.ManualCommand,
|
||||
WMS_WebControl_pro_API_actionType.Stop,
|
||||
)
|
||||
await action(responseType=WMS_WebControl_pro_API_responseType.Detailed)
|
||||
@@ -89,13 +90,25 @@ class WebControlProAwning(WebControlProCover):
|
||||
"""Representation of a WMS based awning."""
|
||||
|
||||
_attr_device_class = CoverDeviceClass.AWNING
|
||||
_drive_action_desc = WMS_WebControl_pro_API_actionDescription.AwningDrive
|
||||
_drive_action_desc = ACTION_DESC.AwningDrive
|
||||
|
||||
|
||||
class WebControlProValance(WebControlProCover):
|
||||
"""Representation of a WMS based valance."""
|
||||
|
||||
_attr_translation_key = "valance"
|
||||
_attr_device_class = CoverDeviceClass.SHADE
|
||||
_drive_action_desc = ACTION_DESC.ValanceDrive
|
||||
|
||||
def __init__(self, config_entry_id: str, dest: Destination) -> None:
|
||||
"""Initialize the entity with destination channel."""
|
||||
super().__init__(config_entry_id, dest)
|
||||
if self._attr_unique_id:
|
||||
self._attr_unique_id += "-valance"
|
||||
|
||||
|
||||
class WebControlProRollerShutter(WebControlProCover):
|
||||
"""Representation of a WMS based roller shutter or blind."""
|
||||
|
||||
_attr_device_class = CoverDeviceClass.SHUTTER
|
||||
_drive_action_desc = (
|
||||
WMS_WebControl_pro_API_actionDescription.RollerShutterBlindDrive
|
||||
)
|
||||
_drive_action_desc = ACTION_DESC.RollerShutterBlindDrive
|
||||
|
||||
@@ -70,6 +70,18 @@ def mock_hub_configuration_prod_awning_dimmer() -> Generator[AsyncMock]:
|
||||
yield mock_hub_configuration
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_hub_configuration_prod_awning_valance() -> Generator[AsyncMock]:
|
||||
"""Override WebControlPro._getConfiguration."""
|
||||
with patch(
|
||||
"wmspro.webcontrol.WebControlPro._getConfiguration",
|
||||
return_value=load_json_object_fixture(
|
||||
"config_prod_awning_valance.json", DOMAIN
|
||||
),
|
||||
) as mock_hub_configuration:
|
||||
yield mock_hub_configuration
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_hub_configuration_prod_roller_shutter() -> Generator[AsyncMock]:
|
||||
"""Override WebControlPro._getConfiguration."""
|
||||
@@ -114,6 +126,16 @@ def mock_hub_status_prod_roller_shutter() -> Generator[AsyncMock]:
|
||||
yield mock_hub_status
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_hub_status_prod_valance() -> Generator[AsyncMock]:
|
||||
"""Override WebControlPro._getStatus."""
|
||||
with patch(
|
||||
"wmspro.webcontrol.WebControlPro._getStatus",
|
||||
return_value=load_json_object_fixture("status_prod_valance.json", DOMAIN),
|
||||
) as mock_hub_status:
|
||||
yield mock_hub_status
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_dest_refresh() -> Generator[AsyncMock]:
|
||||
"""Override Destination.refresh."""
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"command": "getConfiguration",
|
||||
"protocolVersion": "1.0.0",
|
||||
"destinations": [
|
||||
{
|
||||
"id": 58717,
|
||||
"animationType": 1,
|
||||
"names": ["Markise", "", "", ""],
|
||||
"actions": [
|
||||
{
|
||||
"id": 0,
|
||||
"actionType": 0,
|
||||
"actionDescription": 0,
|
||||
"minValue": 0,
|
||||
"maxValue": 100
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"actionType": 0,
|
||||
"actionDescription": 1,
|
||||
"minValue": 0,
|
||||
"maxValue": 100
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"actionType": 6,
|
||||
"actionDescription": 12
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"actionType": 8,
|
||||
"actionDescription": 13
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"rooms": [
|
||||
{
|
||||
"id": 62571,
|
||||
"name": "Raum 0",
|
||||
"destinations": [58717],
|
||||
"scenes": []
|
||||
}
|
||||
],
|
||||
"scenes": []
|
||||
}
|
||||
28
tests/components/wmspro/fixtures/status_prod_valance.json
Normal file
28
tests/components/wmspro/fixtures/status_prod_valance.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"command": "getStatus",
|
||||
"protocolVersion": "1.0.0",
|
||||
"details": [
|
||||
{
|
||||
"destinationId": 58717,
|
||||
"data": {
|
||||
"drivingCause": 0,
|
||||
"heartbeatError": false,
|
||||
"blocking": false,
|
||||
"productData": [
|
||||
{
|
||||
"actionId": 0,
|
||||
"value": {
|
||||
"percentage": 100
|
||||
}
|
||||
},
|
||||
{
|
||||
"actionId": 2,
|
||||
"value": {
|
||||
"percentage": 100
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -81,6 +81,11 @@ async def test_cover_update(
|
||||
"mock_hub_status_prod_awning",
|
||||
"cover.markise",
|
||||
),
|
||||
(
|
||||
"mock_hub_configuration_prod_awning_valance",
|
||||
"mock_hub_status_prod_valance",
|
||||
"cover.markise_2",
|
||||
),
|
||||
(
|
||||
"mock_hub_configuration_prod_roller_shutter",
|
||||
"mock_hub_status_prod_roller_shutter",
|
||||
@@ -159,6 +164,11 @@ async def test_cover_open_and_close(
|
||||
"mock_hub_status_prod_awning",
|
||||
"cover.markise",
|
||||
),
|
||||
(
|
||||
"mock_hub_configuration_prod_awning_valance",
|
||||
"mock_hub_status_prod_valance",
|
||||
"cover.markise_2",
|
||||
),
|
||||
(
|
||||
"mock_hub_configuration_prod_roller_shutter",
|
||||
"mock_hub_status_prod_roller_shutter",
|
||||
@@ -218,6 +228,11 @@ async def test_cover_open_to_pos(
|
||||
"mock_hub_status_prod_awning",
|
||||
"cover.markise",
|
||||
),
|
||||
(
|
||||
"mock_hub_configuration_prod_awning_valance",
|
||||
"mock_hub_status_prod_valance",
|
||||
"cover.markise_2",
|
||||
),
|
||||
(
|
||||
"mock_hub_configuration_prod_roller_shutter",
|
||||
"mock_hub_status_prod_roller_shutter",
|
||||
|
||||
Reference in New Issue
Block a user