Skip to content

Commit

Permalink
Fix mapping of HmIP-HDM (#1430)
Browse files Browse the repository at this point in the history
* Fix mapping of HmIP-HDM

* Update changelog.md

* Update definition.py

* Update test_central_pydevccu.py
  • Loading branch information
SukramJ authored Feb 11, 2024
1 parent 387537b commit a646dd7
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 9 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

- Add option to un ignore mechanism to ignore the automatic creation of custom entities by device type
- Remove incomplete/wrong custom mapping for HBW-LC-RGBWW-IN6-DR
- Fix mapping of HmIP-HDM

# Version 2024.2.1 (2024-02-02)

Expand Down
1 change: 1 addition & 0 deletions hahomematic/platforms/custom/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class DeviceProfile(StrEnum):
IP_DIMMER = "IPDimmer"
IP_FIXED_COLOR_LIGHT = "IPFixedColorLight"
IP_GARAGE = "IPGarage"
IP_HDM = "IPHdm"
IP_LOCK = "IPLock"
IP_RGBW_LIGHT = "IPRGBW"
IP_SIMPLE_FIXED_COLOR_LIGHT = "IPSimpleFixedColorLight"
Expand Down
17 changes: 16 additions & 1 deletion hahomematic/platforms/custom/cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,21 @@ def make_ip_garage(
)


def make_ip_hdm(
device: hmd.HmDevice,
group_base_channels: tuple[int, ...],
extended: ExtendedConfig | None = None,
) -> tuple[CustomEntity, ...]:
"""Create HomematicIP cover entities."""
return hmed.make_custom_entity(
device=device,
entity_class=CeIpBlind,
device_profile=DeviceProfile.IP_HDM,
group_base_channels=group_base_channels,
extended=extended,
)


def make_rf_blind(
device: hmd.HmDevice,
group_base_channels: tuple[int, ...],
Expand Down Expand Up @@ -650,7 +665,7 @@ def make_rf_window_drive(
),
"HmIP-FBL": CustomConfig(func=make_ip_blind, channels=(3,)),
"HmIP-FROLL": CustomConfig(func=make_ip_cover, channels=(3,)),
"HmIP-HDM": CustomConfig(func=make_ip_blind, channels=(0,)),
"HmIP-HDM": CustomConfig(func=make_ip_hdm, channels=(0,)),
"HmIP-MOD-HO": CustomConfig(func=make_ip_garage, channels=(1,)),
"HmIP-MOD-TM": CustomConfig(func=make_ip_garage, channels=(1,)),
"HmIPW-DRBL4": CustomConfig(
Expand Down
16 changes: 16 additions & 0 deletions hahomematic/platforms/custom/definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,22 @@
1: (Parameter.STATE,),
},
},
DeviceProfile.IP_HDM: {
ED.DEVICE_GROUP: {
ED.PRIMARY_CHANNEL: 1,
ED.FIELDS: {
1: {
Field.DIRECTION: Parameter.ACTIVITY_STATE,
Field.LEVEL: Parameter.LEVEL,
Field.LEVEL_2: Parameter.LEVEL_2,
Field.STOP: Parameter.STOP,
},
2: {
Field.COMBINED_PARAMETER: Parameter.COMBINED_PARAMETER,
},
},
},
},
DeviceProfile.IP_FIXED_COLOR_LIGHT: {
ED.DEVICE_GROUP: {
ED.PRIMARY_CHANNEL: 1,
Expand Down
4 changes: 2 additions & 2 deletions requirements_test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ pylint-per-file-ignores==1.3.2
pylint-strict-informational==0.1
pylint==3.0.3
pytest-aiohttp==1.0.5
pytest-asyncio==0.23.4
pytest-asyncio==0.23.5
pytest-cov==4.1.0
pytest-rerunfailures==13.0
pytest-socket==0.7.0
pytest-timeout==2.2.0
pytest==7.4.4
pytest==8.0.0
types-python-slugify==8.0.2.20240127
2 changes: 1 addition & 1 deletion tests/test_central_pydevccu.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ async def test_central_full(central_unit_full) -> None:
assert usage_types[EntityUsage.CE_PRIMARY] == 181
assert usage_types[EntityUsage.ENTITY] == 3745
assert usage_types[EntityUsage.CE_VISIBLE] == 102
assert usage_types[EntityUsage.CE_SECONDARY] == 148
assert usage_types[EntityUsage.CE_SECONDARY] == 146

assert len(ce_channels) == 115
assert len(entity_types) == 6
Expand Down
132 changes: 127 additions & 5 deletions tests/test_cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@
from tests import const, helper

TEST_DEVICES: dict[str, str] = {
"VCU8537918": "HmIP-BROLL.json",
"VCU7807849": "HmIPW-DRBL4.json",
"VCU1223813": "HmIP-FBL.json",
"VCU0000045": "HM-LC-Bl1-FM.json",
"VCU3574044": "HmIP-MOD-HO.json",
"VCU6166407": "HmIP-MOD-TM.json",
"VCU0000145": "HM-LC-JaX.json",
"VCU0000350": "HM-Sec-Win.json",
"VCU1223813": "HmIP-FBL.json",
"VCU3560967": "HmIP-HDM1.json",
"VCU3574044": "HmIP-MOD-HO.json",
"VCU6166407": "HmIP-MOD-TM.json",
"VCU7807849": "HmIPW-DRBL4.json",
"VCU8537918": "HmIP-BROLL.json",
}

# pylint: disable=protected-access
Expand Down Expand Up @@ -429,6 +430,127 @@ async def test_ceipblind(factory: helper.Factory) -> None:
assert cover._channel_tilt_level == _CLOSED_LEVEL
assert cover.current_tilt_position == 0

central.event(const.INTERFACE_ID, "VCU1223813:3", "ACTIVITY_STATE", 1)
assert cover.is_opening

central.event(const.INTERFACE_ID, "VCU1223813:3", "ACTIVITY_STATE", 2)
assert cover.is_closing

central.event(const.INTERFACE_ID, "VCU1223813:3", "ACTIVITY_STATE", 3)
assert cover.is_opening is False
assert cover.is_closing is False

await cover.stop()
assert mock_client.method_calls[-1] == call.set_value(
channel_address="VCU1223813:4", paramset_key="VALUES", parameter="STOP", value=True
)


@pytest.mark.asyncio
async def test_ceipblind_hdm(factory: helper.Factory) -> None:
"""Test CeIpBlind HDM."""
central, mock_client = await factory.get_default_central(TEST_DEVICES)
cover: CeIpBlind = cast(CeIpBlind, helper.get_prepared_custom_entity(central, "VCU3560967", 1))
assert cover.usage == EntityUsage.CE_PRIMARY

assert cover.current_position == 0
assert cover.current_tilt_position == 0
await cover.set_position(position=81)
assert mock_client.method_calls[-1] == call.set_value(
channel_address="VCU3560967:2",
paramset_key="VALUES",
parameter="COMBINED_PARAMETER",
value="L2=0,L=81",
)
central.event(const.INTERFACE_ID, "VCU3560967:1", "LEVEL", 0.81)
assert cover.current_position == 81
assert cover.current_tilt_position == 0

await cover.open()
assert mock_client.method_calls[-1] == call.set_value(
channel_address="VCU3560967:2",
paramset_key="VALUES",
parameter="COMBINED_PARAMETER",
value="L2=100,L=100",
)
central.event(const.INTERFACE_ID, "VCU3560967:1", "LEVEL_2", 1.0)
central.event(const.INTERFACE_ID, "VCU3560967:1", "LEVEL", 1.0)
assert cover.current_position == 100
assert cover.current_tilt_position == 100

await cover.close()
assert mock_client.method_calls[-1] == call.set_value(
channel_address="VCU3560967:2",
paramset_key="VALUES",
parameter="COMBINED_PARAMETER",
value="L2=0,L=0",
)
central.event(const.INTERFACE_ID, "VCU3560967:1", "LEVEL_2", 0.0)
central.event(const.INTERFACE_ID, "VCU3560967:1", "LEVEL", 0.0)
assert cover.current_position == 0
assert cover.current_tilt_position == 0

await cover.open_tilt()
assert mock_client.method_calls[-1] == call.set_value(
channel_address="VCU3560967:2",
paramset_key="VALUES",
parameter="COMBINED_PARAMETER",
value="L2=100,L=0",
)
central.event(const.INTERFACE_ID, "VCU3560967:1", "LEVEL_2", 1.0)
assert cover.current_position == 0
assert cover.current_tilt_position == 100

await cover.set_position(tilt_position=45)
assert mock_client.method_calls[-1] == call.set_value(
channel_address="VCU3560967:2",
paramset_key="VALUES",
parameter="COMBINED_PARAMETER",
value="L2=45,L=0",
)
central.event(const.INTERFACE_ID, "VCU3560967:1", "LEVEL_2", 0.45)
assert cover.current_position == 0
assert cover.current_tilt_position == 45

await cover.close_tilt()
assert mock_client.method_calls[-1] == call.set_value(
channel_address="VCU3560967:2",
paramset_key="VALUES",
parameter="COMBINED_PARAMETER",
value="L2=0,L=0",
)
central.event(const.INTERFACE_ID, "VCU3560967:1", "LEVEL_2", 0.0)
central.event(const.INTERFACE_ID, "VCU3560967:1", "LEVEL", 0.0)
assert cover.current_position == 0
assert cover.current_tilt_position == 0

await cover.set_position(position=10, tilt_position=20)
assert mock_client.method_calls[-1] == call.set_value(
channel_address="VCU3560967:2",
paramset_key="VALUES",
parameter="COMBINED_PARAMETER",
value="L2=20,L=10",
)
central.event(const.INTERFACE_ID, "VCU3560967:1", "LEVEL", 0.1)
central.event(const.INTERFACE_ID, "VCU3560967:1", "LEVEL_2", 0.2)
assert cover.current_position == 10
assert cover.current_tilt_position == 20

central.event(const.INTERFACE_ID, "VCU3560967:1", "ACTIVITY_STATE", 1)
assert cover.is_opening

central.event(const.INTERFACE_ID, "VCU3560967:1", "ACTIVITY_STATE", 2)
assert cover.is_closing

central.event(const.INTERFACE_ID, "VCU3560967:1", "ACTIVITY_STATE", 3)
assert cover.is_opening is False
assert cover.is_closing is False

await cover.stop()
assert mock_client.method_calls[-1] == call.set_value(
channel_address="VCU3560967:1", paramset_key="VALUES", parameter="STOP", value=True
)


@pytest.mark.asyncio
async def test_cegarageho(factory: helper.Factory) -> None:
Expand Down

0 comments on commit a646dd7

Please sign in to comment.