Bump dependency to add more multi channel devices to HomematicIP Cloud (#43914)

This commit is contained in:
SukramJ 2020-12-08 00:16:22 +01:00 committed by GitHub
parent 8632ab9d35
commit 34a31884b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 823 additions and 117 deletions

View File

@ -6,6 +6,7 @@ from homematicip.aio.device import (
AsyncContactInterface,
AsyncDevice,
AsyncFullFlushContactInterface,
AsyncFullFlushContactInterface6,
AsyncMotionDetectorIndoor,
AsyncMotionDetectorOutdoor,
AsyncMotionDetectorPushButton,
@ -91,6 +92,11 @@ async def async_setup_entry(
entities.append(
HomematicipMultiContactInterface(hap, device, channel=channel)
)
elif isinstance(device, AsyncFullFlushContactInterface6):
for channel in range(1, 7):
entities.append(
HomematicipMultiContactInterface(hap, device, channel=channel)
)
elif isinstance(
device, (AsyncContactInterface, AsyncFullFlushContactInterface)
):
@ -224,9 +230,17 @@ class HomematicipTiltVibrationSensor(HomematicipBaseActionSensor):
class HomematicipMultiContactInterface(HomematicipGenericEntity, BinarySensorEntity):
"""Representation of the HomematicIP multi room/area contact interface."""
def __init__(self, hap: HomematicipHAP, device, channel: int) -> None:
def __init__(
self,
hap: HomematicipHAP,
device,
channel=1,
is_multi_channel=True,
) -> None:
"""Initialize the multi contact entity."""
super().__init__(hap, device, channel=channel)
super().__init__(
hap, device, channel=channel, is_multi_channel=is_multi_channel
)
@property
def device_class(self) -> str:
@ -244,30 +258,22 @@ class HomematicipMultiContactInterface(HomematicipGenericEntity, BinarySensorEnt
)
class HomematicipContactInterface(HomematicipGenericEntity, BinarySensorEntity):
class HomematicipContactInterface(HomematicipMultiContactInterface, BinarySensorEntity):
"""Representation of the HomematicIP contact interface."""
@property
def device_class(self) -> str:
"""Return the class of this sensor."""
return DEVICE_CLASS_OPENING
@property
def is_on(self) -> bool:
"""Return true if the contact interface is on/open."""
if self._device.windowState is None:
return None
return self._device.windowState != WindowState.CLOSED
def __init__(self, hap: HomematicipHAP, device) -> None:
"""Initialize the multi contact entity."""
super().__init__(hap, device, is_multi_channel=False)
class HomematicipShutterContact(HomematicipGenericEntity, BinarySensorEntity):
class HomematicipShutterContact(HomematicipMultiContactInterface, BinarySensorEntity):
"""Representation of the HomematicIP shutter contact."""
def __init__(
self, hap: HomematicipHAP, device, has_additional_state: bool = False
) -> None:
"""Initialize the shutter contact."""
super().__init__(hap, device)
super().__init__(hap, device, is_multi_channel=False)
self.has_additional_state = has_additional_state
@property
@ -275,13 +281,6 @@ class HomematicipShutterContact(HomematicipGenericEntity, BinarySensorEntity):
"""Return the class of this sensor."""
return DEVICE_CLASS_DOOR
@property
def is_on(self) -> bool:
"""Return true if the shutter contact is on/open."""
if self._device.windowState is None:
return None
return self._device.windowState != WindowState.CLOSED
@property
def device_state_attributes(self) -> Dict[str, Any]:
"""Return the state attributes of the Shutter Contact."""

View File

@ -3,6 +3,7 @@ from typing import Optional
from homematicip.aio.device import (
AsyncBlindModule,
AsyncDinRailBlind4,
AsyncFullFlushBlind,
AsyncFullFlushShutter,
AsyncGarageDoorModuleTormatic,
@ -37,6 +38,11 @@ async def async_setup_entry(
for device in hap.home.devices:
if isinstance(device, AsyncBlindModule):
entities.append(HomematicipBlindModule(hap, device))
elif isinstance(device, AsyncDinRailBlind4):
for channel in range(1, 5):
entities.append(
HomematicipMultiCoverSlats(hap, device, channel=channel)
)
elif isinstance(device, AsyncFullFlushBlind):
entities.append(HomematicipCoverSlats(hap, device))
elif isinstance(device, AsyncFullFlushShutter):
@ -130,14 +136,28 @@ class HomematicipBlindModule(HomematicipGenericEntity, CoverEntity):
await self._device.stop()
class HomematicipCoverShutter(HomematicipGenericEntity, CoverEntity):
class HomematicipMultiCoverShutter(HomematicipGenericEntity, CoverEntity):
"""Representation of the HomematicIP cover shutter."""
def __init__(
self,
hap: HomematicipHAP,
device,
channel=1,
is_multi_channel=True,
) -> None:
"""Initialize the multi cover entity."""
super().__init__(
hap, device, channel=channel, is_multi_channel=is_multi_channel
)
@property
def current_cover_position(self) -> int:
"""Return current position of cover."""
if self._device.shutterLevel is not None:
return int((1 - self._device.shutterLevel) * 100)
if self._device.functionalChannels[self._channel].shutterLevel is not None:
return int(
(1 - self._device.functionalChannels[self._channel].shutterLevel) * 100
)
return None
async def async_set_cover_position(self, **kwargs) -> None:
@ -145,36 +165,61 @@ class HomematicipCoverShutter(HomematicipGenericEntity, CoverEntity):
position = kwargs[ATTR_POSITION]
# HmIP cover is closed:1 -> open:0
level = 1 - position / 100.0
await self._device.set_shutter_level(level)
await self._device.set_shutter_level(level, self._channel)
@property
def is_closed(self) -> Optional[bool]:
"""Return if the cover is closed."""
if self._device.shutterLevel is not None:
return self._device.shutterLevel == HMIP_COVER_CLOSED
if self._device.functionalChannels[self._channel].shutterLevel is not None:
return (
self._device.functionalChannels[self._channel].shutterLevel
== HMIP_COVER_CLOSED
)
return None
async def async_open_cover(self, **kwargs) -> None:
"""Open the cover."""
await self._device.set_shutter_level(HMIP_COVER_OPEN)
await self._device.set_shutter_level(HMIP_COVER_OPEN, self._channel)
async def async_close_cover(self, **kwargs) -> None:
"""Close the cover."""
await self._device.set_shutter_level(HMIP_COVER_CLOSED)
await self._device.set_shutter_level(HMIP_COVER_CLOSED, self._channel)
async def async_stop_cover(self, **kwargs) -> None:
"""Stop the device if in motion."""
await self._device.set_shutter_stop()
await self._device.set_shutter_stop(self._channel)
class HomematicipCoverSlats(HomematicipCoverShutter, CoverEntity):
"""Representation of the HomematicIP cover slats."""
class HomematicipCoverShutter(HomematicipMultiCoverShutter, CoverEntity):
"""Representation of the HomematicIP cover shutter."""
def __init__(self, hap: HomematicipHAP, device) -> None:
"""Initialize the multi cover entity."""
super().__init__(hap, device, is_multi_channel=False)
class HomematicipMultiCoverSlats(HomematicipMultiCoverShutter, CoverEntity):
"""Representation of the HomematicIP multi cover slats."""
def __init__(
self,
hap: HomematicipHAP,
device,
channel=1,
is_multi_channel=True,
) -> None:
"""Initialize the multi slats entity."""
super().__init__(
hap, device, channel=channel, is_multi_channel=is_multi_channel
)
@property
def current_cover_tilt_position(self) -> int:
"""Return current tilt position of cover."""
if self._device.slatsLevel is not None:
return int((1 - self._device.slatsLevel) * 100)
if self._device.functionalChannels[self._channel].slatsLevel is not None:
return int(
(1 - self._device.functionalChannels[self._channel].slatsLevel) * 100
)
return None
async def async_set_cover_tilt_position(self, **kwargs) -> None:
@ -182,19 +227,27 @@ class HomematicipCoverSlats(HomematicipCoverShutter, CoverEntity):
position = kwargs[ATTR_TILT_POSITION]
# HmIP slats is closed:1 -> open:0
level = 1 - position / 100.0
await self._device.set_slats_level(level)
await self._device.set_slats_level(level, self._channel)
async def async_open_cover_tilt(self, **kwargs) -> None:
"""Open the slats."""
await self._device.set_slats_level(HMIP_SLATS_OPEN)
await self._device.set_slats_level(HMIP_SLATS_OPEN, self._channel)
async def async_close_cover_tilt(self, **kwargs) -> None:
"""Close the slats."""
await self._device.set_slats_level(HMIP_SLATS_CLOSED)
await self._device.set_slats_level(HMIP_SLATS_CLOSED, self._channel)
async def async_stop_cover_tilt(self, **kwargs) -> None:
"""Stop the device if in motion."""
await self._device.set_shutter_stop()
await self._device.set_shutter_stop(self._channel)
class HomematicipCoverSlats(HomematicipMultiCoverSlats, CoverEntity):
"""Representation of the HomematicIP cover slats."""
def __init__(self, hap: HomematicipHAP, device) -> None:
"""Initialize the multi slats entity."""
super().__init__(hap, device, is_multi_channel=False)
class HomematicipGarageDoorModule(HomematicipGenericEntity, CoverEntity):
@ -229,10 +282,69 @@ class HomematicipGarageDoorModule(HomematicipGenericEntity, CoverEntity):
await self._device.send_door_command(DoorCommand.STOP)
class HomematicipCoverShutterGroup(HomematicipCoverSlats, CoverEntity):
class HomematicipCoverShutterGroup(HomematicipGenericEntity, CoverEntity):
"""Representation of the HomematicIP cover shutter group."""
def __init__(self, hap: HomematicipHAP, device, post: str = "ShutterGroup") -> None:
"""Initialize switching group."""
device.modelType = f"HmIP-{post}"
super().__init__(hap, device, post)
super().__init__(hap, device, post, is_multi_channel=False)
@property
def current_cover_position(self) -> int:
"""Return current position of cover."""
if self._device.shutterLevel is not None:
return int((1 - self._device.shutterLevel) * 100)
return None
@property
def current_cover_tilt_position(self) -> int:
"""Return current tilt position of cover."""
if self._device.slatsLevel is not None:
return int((1 - self._device.slatsLevel) * 100)
return None
@property
def is_closed(self) -> Optional[bool]:
"""Return if the cover is closed."""
if self._device.shutterLevel is not None:
return self._device.shutterLevel == HMIP_COVER_CLOSED
return None
async def async_set_cover_position(self, **kwargs) -> None:
"""Move the cover to a specific position."""
position = kwargs[ATTR_POSITION]
# HmIP cover is closed:1 -> open:0
level = 1 - position / 100.0
await self._device.set_shutter_level(level)
async def async_set_cover_tilt_position(self, **kwargs) -> None:
"""Move the cover to a specific tilt position."""
position = kwargs[ATTR_TILT_POSITION]
# HmIP slats is closed:1 -> open:0
level = 1 - position / 100.0
await self._device.set_slats_level(level)
async def async_open_cover(self, **kwargs) -> None:
"""Open the cover."""
await self._device.set_shutter_level(HMIP_COVER_OPEN)
async def async_close_cover(self, **kwargs) -> None:
"""Close the cover."""
await self._device.set_shutter_level(HMIP_COVER_CLOSED)
async def async_stop_cover(self, **kwargs) -> None:
"""Stop the group if in motion."""
await self._device.set_shutter_stop()
async def async_open_cover_tilt(self, **kwargs) -> None:
"""Open the slats."""
await self._device.set_slats_level(HMIP_SLATS_OPEN)
async def async_close_cover_tilt(self, **kwargs) -> None:
"""Close the slats."""
await self._device.set_slats_level(HMIP_SLATS_CLOSED)
async def async_stop_cover_tilt(self, **kwargs) -> None:
"""Stop the group if in motion."""
await self._device.set_shutter_stop()

View File

@ -76,6 +76,7 @@ class HomematicipGenericEntity(Entity):
device,
post: Optional[str] = None,
channel: Optional[int] = None,
is_multi_channel: Optional[bool] = False,
) -> None:
"""Initialize the generic entity."""
self._hap = hap
@ -83,6 +84,7 @@ class HomematicipGenericEntity(Entity):
self._device = device
self._post = post
self._channel = channel
self._is_multi_channel = is_multi_channel
# Marker showing that the HmIP device hase been removed.
self.hmip_device_removed = False
_LOGGER.info("Setting up %s (%s)", self.name, self._device.modelType)
@ -179,7 +181,7 @@ class HomematicipGenericEntity(Entity):
name = None
# Try to get a label from a channel.
if hasattr(self._device, "functionalChannels"):
if self._channel:
if self._is_multi_channel:
name = self._device.functionalChannels[self._channel].label
else:
if len(self._device.functionalChannels) > 1:
@ -190,7 +192,7 @@ class HomematicipGenericEntity(Entity):
name = self._device.label
if self._post:
name = f"{name} {self._post}"
elif self._channel:
elif self._is_multi_channel:
name = f"{name} Channel{self._channel}"
# Add a prefix to the name if the homematic ip home has a name.
@ -213,7 +215,7 @@ class HomematicipGenericEntity(Entity):
def unique_id(self) -> str:
"""Return a unique ID."""
unique_id = f"{self.__class__.__name__}_{self._device.id}"
if self._channel:
if self._is_multi_channel:
unique_id = (
f"{self.__class__.__name__}_Channel{self._channel}_{self._device.id}"
)

View File

@ -106,9 +106,17 @@ class HomematicipLightMeasuring(HomematicipLight):
class HomematicipMultiDimmer(HomematicipGenericEntity, LightEntity):
"""Representation of HomematicIP Cloud dimmer."""
def __init__(self, hap: HomematicipHAP, device, channel: int) -> None:
def __init__(
self,
hap: HomematicipHAP,
device,
channel=1,
is_multi_channel=True,
) -> None:
"""Initialize the dimmer light entity."""
super().__init__(hap, device, channel=channel)
super().__init__(
hap, device, channel=channel, is_multi_channel=is_multi_channel
)
@property
def is_on(self) -> bool:
@ -142,38 +150,12 @@ class HomematicipMultiDimmer(HomematicipGenericEntity, LightEntity):
await self._device.set_dim_level(0, self._channel)
class HomematicipDimmer(HomematicipGenericEntity, LightEntity):
class HomematicipDimmer(HomematicipMultiDimmer, LightEntity):
"""Representation of HomematicIP Cloud dimmer."""
def __init__(self, hap: HomematicipHAP, device) -> None:
"""Initialize the dimmer light entity."""
super().__init__(hap, device)
@property
def is_on(self) -> bool:
"""Return true if dimmer is on."""
return self._device.dimLevel is not None and self._device.dimLevel > 0.0
@property
def brightness(self) -> int:
"""Return the brightness of this light between 0..255."""
return int((self._device.dimLevel or 0.0) * 255)
@property
def supported_features(self) -> int:
"""Flag supported features."""
return SUPPORT_BRIGHTNESS
async def async_turn_on(self, **kwargs) -> None:
"""Turn the dimmer on."""
if ATTR_BRIGHTNESS in kwargs:
await self._device.set_dim_level(kwargs[ATTR_BRIGHTNESS] / 255.0)
else:
await self._device.set_dim_level(1)
async def async_turn_off(self, **kwargs) -> None:
"""Turn the dimmer off."""
await self._device.set_dim_level(0)
super().__init__(hap, device, is_multi_channel=False)
class HomematicipNotificationLight(HomematicipGenericEntity, LightEntity):
@ -182,9 +164,13 @@ class HomematicipNotificationLight(HomematicipGenericEntity, LightEntity):
def __init__(self, hap: HomematicipHAP, device, channel: int) -> None:
"""Initialize the notification light entity."""
if channel == 2:
super().__init__(hap, device, post="Top", channel=channel)
super().__init__(
hap, device, post="Top", channel=channel, is_multi_channel=True
)
else:
super().__init__(hap, device, post="Bottom", channel=channel)
super().__init__(
hap, device, post="Bottom", channel=channel, is_multi_channel=True
)
self._color_switcher = {
RGBColorState.WHITE: [0.0, 0.0],

View File

@ -3,7 +3,7 @@
"name": "HomematicIP Cloud",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/homematicip_cloud",
"requirements": ["homematicip==0.12.1"],
"requirements": ["homematicip==0.13.0"],
"codeowners": ["@SukramJ"],
"quality_scale": "platinum"
}

View File

@ -3,6 +3,7 @@ from typing import Any, Dict
from homematicip.aio.device import (
AsyncBrandSwitchMeasuring,
AsyncDinRailSwitch4,
AsyncFullFlushInputSwitch,
AsyncFullFlushSwitchMeasuring,
AsyncHeatingSwitch2,
@ -44,6 +45,9 @@ async def async_setup_entry(
elif isinstance(device, AsyncWiredSwitch8):
for channel in range(1, 9):
entities.append(HomematicipMultiSwitch(hap, device, channel=channel))
elif isinstance(device, AsyncDinRailSwitch4):
for channel in range(1, 5):
entities.append(HomematicipMultiSwitch(hap, device, channel=channel))
elif isinstance(
device,
(
@ -77,9 +81,17 @@ async def async_setup_entry(
class HomematicipMultiSwitch(HomematicipGenericEntity, SwitchEntity):
"""Representation of the HomematicIP multi switch."""
def __init__(self, hap: HomematicipHAP, device, channel: int) -> None:
def __init__(
self,
hap: HomematicipHAP,
device,
channel=1,
is_multi_channel=True,
) -> None:
"""Initialize the multi switch device."""
super().__init__(hap, device, channel=channel)
super().__init__(
hap, device, channel=channel, is_multi_channel=is_multi_channel
)
@property
def is_on(self) -> bool:
@ -95,25 +107,12 @@ class HomematicipMultiSwitch(HomematicipGenericEntity, SwitchEntity):
await self._device.turn_off(self._channel)
class HomematicipSwitch(HomematicipGenericEntity, SwitchEntity):
class HomematicipSwitch(HomematicipMultiSwitch, SwitchEntity):
"""Representation of the HomematicIP switch."""
def __init__(self, hap: HomematicipHAP, device) -> None:
"""Initialize the switch device."""
super().__init__(hap, device)
@property
def is_on(self) -> bool:
"""Return true if device is on."""
return self._device.on
async def async_turn_on(self, **kwargs) -> None:
"""Turn the device on."""
await self._device.turn_on()
async def async_turn_off(self, **kwargs) -> None:
"""Turn the device off."""
await self._device.turn_off()
super().__init__(hap, device, is_multi_channel=False)
class HomematicipGroupSwitch(HomematicipGenericEntity, SwitchEntity):

View File

@ -774,7 +774,7 @@ homeassistant-pyozw==0.1.10
homeconnect==0.6.3
# homeassistant.components.homematicip_cloud
homematicip==0.12.1
homematicip==0.13.0
# homeassistant.components.horizon
horimote==0.4.1

View File

@ -403,7 +403,7 @@ homeassistant-pyozw==0.1.10
homeconnect==0.6.3
# homeassistant.components.homematicip_cloud
homematicip==0.12.1
homematicip==0.13.0
# homeassistant.components.google
# homeassistant.components.remember_the_milk

View File

@ -540,13 +540,13 @@ async def test_hmip_security_sensor_group(hass, default_mock_hap_factory):
assert ha_state.state == STATE_ON
async def test_hmip_wired_multi_contact_interface(hass, default_mock_hap_factory):
async def test_hmip_multi_contact_interface(hass, default_mock_hap_factory):
"""Test HomematicipMultiContactInterface."""
entity_id = "binary_sensor.wired_eingangsmodul_32_fach_channel5"
entity_name = "Wired Eingangsmodul 32-fach Channel5"
device_model = "HmIPW-DRI32"
mock_hap = await default_mock_hap_factory.async_get_mock_hap(
test_devices=["Wired Eingangsmodul 32-fach"]
test_devices=["Wired Eingangsmodul 32-fach", "Licht Flur"]
)
ha_state, hmip_device = get_and_check_entity_basics(
@ -563,3 +563,13 @@ async def test_hmip_wired_multi_contact_interface(hass, default_mock_hap_factory
await async_manipulate_test_data(hass, hmip_device, "windowState", None, channel=5)
ha_state = hass.states.get(entity_id)
assert ha_state.state == STATE_OFF
ha_state, hmip_device = get_and_check_entity_basics(
hass,
mock_hap,
"binary_sensor.licht_flur_5",
"Licht Flur 5",
"HmIP-FCI6",
)
assert ha_state.state == STATE_OFF

View File

@ -43,7 +43,7 @@ async def test_hmip_cover_shutter(hass, default_mock_hap_factory):
)
assert len(hmip_device.mock_calls) == service_call_counter + 1
assert hmip_device.mock_calls[-1][0] == "set_shutter_level"
assert hmip_device.mock_calls[-1][1] == (0,)
assert hmip_device.mock_calls[-1][1] == (0, 1)
await async_manipulate_test_data(hass, hmip_device, "shutterLevel", 0)
ha_state = hass.states.get(entity_id)
assert ha_state.state == STATE_OPEN
@ -57,7 +57,7 @@ async def test_hmip_cover_shutter(hass, default_mock_hap_factory):
)
assert len(hmip_device.mock_calls) == service_call_counter + 3
assert hmip_device.mock_calls[-1][0] == "set_shutter_level"
assert hmip_device.mock_calls[-1][1] == (0.5,)
assert hmip_device.mock_calls[-1][1] == (0.5, 1)
await async_manipulate_test_data(hass, hmip_device, "shutterLevel", 0.5)
ha_state = hass.states.get(entity_id)
assert ha_state.state == STATE_OPEN
@ -68,7 +68,7 @@ async def test_hmip_cover_shutter(hass, default_mock_hap_factory):
)
assert len(hmip_device.mock_calls) == service_call_counter + 5
assert hmip_device.mock_calls[-1][0] == "set_shutter_level"
assert hmip_device.mock_calls[-1][1] == (1,)
assert hmip_device.mock_calls[-1][1] == (1, 1)
await async_manipulate_test_data(hass, hmip_device, "shutterLevel", 1)
ha_state = hass.states.get(entity_id)
assert ha_state.state == STATE_CLOSED
@ -79,7 +79,7 @@ async def test_hmip_cover_shutter(hass, default_mock_hap_factory):
)
assert len(hmip_device.mock_calls) == service_call_counter + 7
assert hmip_device.mock_calls[-1][0] == "set_shutter_stop"
assert hmip_device.mock_calls[-1][1] == ()
assert hmip_device.mock_calls[-1][1] == (1,)
await async_manipulate_test_data(hass, hmip_device, "shutterLevel", None)
ha_state = hass.states.get(entity_id)
@ -109,7 +109,7 @@ async def test_hmip_cover_slats(hass, default_mock_hap_factory):
)
assert len(hmip_device.mock_calls) == service_call_counter + 1
assert hmip_device.mock_calls[-1][0] == "set_slats_level"
assert hmip_device.mock_calls[-1][1] == (0,)
assert hmip_device.mock_calls[-1][1] == (0, 1)
await async_manipulate_test_data(hass, hmip_device, "shutterLevel", 0)
await async_manipulate_test_data(hass, hmip_device, "slatsLevel", 0)
ha_state = hass.states.get(entity_id)
@ -125,7 +125,7 @@ async def test_hmip_cover_slats(hass, default_mock_hap_factory):
)
assert len(hmip_device.mock_calls) == service_call_counter + 4
assert hmip_device.mock_calls[-1][0] == "set_slats_level"
assert hmip_device.mock_calls[-1][1] == (0.5,)
assert hmip_device.mock_calls[-1][1] == (0.5, 1)
await async_manipulate_test_data(hass, hmip_device, "slatsLevel", 0.5)
ha_state = hass.states.get(entity_id)
assert ha_state.state == STATE_OPEN
@ -137,7 +137,7 @@ async def test_hmip_cover_slats(hass, default_mock_hap_factory):
)
assert len(hmip_device.mock_calls) == service_call_counter + 6
assert hmip_device.mock_calls[-1][0] == "set_slats_level"
assert hmip_device.mock_calls[-1][1] == (1,)
assert hmip_device.mock_calls[-1][1] == (1, 1)
await async_manipulate_test_data(hass, hmip_device, "slatsLevel", 1)
ha_state = hass.states.get(entity_id)
assert ha_state.state == STATE_OPEN
@ -149,7 +149,7 @@ async def test_hmip_cover_slats(hass, default_mock_hap_factory):
)
assert len(hmip_device.mock_calls) == service_call_counter + 8
assert hmip_device.mock_calls[-1][0] == "set_shutter_stop"
assert hmip_device.mock_calls[-1][1] == ()
assert hmip_device.mock_calls[-1][1] == (1,)
await async_manipulate_test_data(hass, hmip_device, "slatsLevel", None)
ha_state = hass.states.get(entity_id)
@ -160,6 +160,84 @@ async def test_hmip_cover_slats(hass, default_mock_hap_factory):
assert ha_state.state == STATE_UNKNOWN
async def test_hmip_multi_cover_slats(hass, default_mock_hap_factory):
"""Test HomematicipCoverSlats."""
entity_id = "cover.wohnzimmer_fenster"
entity_name = "Wohnzimmer Fenster"
device_model = "HmIP-DRBLI4"
mock_hap = await default_mock_hap_factory.async_get_mock_hap(
test_devices=["Jalousieaktor 1 für Hutschienenmontage 4-fach"]
)
ha_state, hmip_device = get_and_check_entity_basics(
hass, mock_hap, entity_id, entity_name, device_model
)
await async_manipulate_test_data(hass, hmip_device, "shutterLevel", 1, channel=4)
await async_manipulate_test_data(hass, hmip_device, "slatsLevel", 1, channel=4)
ha_state = hass.states.get(entity_id)
assert ha_state.state == STATE_CLOSED
assert ha_state.attributes[ATTR_CURRENT_POSITION] == 0
assert ha_state.attributes[ATTR_CURRENT_TILT_POSITION] == 0
service_call_counter = len(hmip_device.mock_calls)
await hass.services.async_call(
"cover", "open_cover_tilt", {"entity_id": entity_id}, blocking=True
)
assert len(hmip_device.mock_calls) == service_call_counter + 1
assert hmip_device.mock_calls[-1][0] == "set_slats_level"
assert hmip_device.mock_calls[-1][1] == (0, 4)
await async_manipulate_test_data(hass, hmip_device, "shutterLevel", 0, channel=4)
await async_manipulate_test_data(hass, hmip_device, "slatsLevel", 0, channel=4)
ha_state = hass.states.get(entity_id)
assert ha_state.state == STATE_OPEN
assert ha_state.attributes[ATTR_CURRENT_POSITION] == 100
assert ha_state.attributes[ATTR_CURRENT_TILT_POSITION] == 100
await hass.services.async_call(
"cover",
"set_cover_tilt_position",
{"entity_id": entity_id, "tilt_position": "50"},
blocking=True,
)
assert len(hmip_device.mock_calls) == service_call_counter + 4
assert hmip_device.mock_calls[-1][0] == "set_slats_level"
assert hmip_device.mock_calls[-1][1] == (0.5, 4)
await async_manipulate_test_data(hass, hmip_device, "slatsLevel", 0.5, channel=4)
ha_state = hass.states.get(entity_id)
assert ha_state.state == STATE_OPEN
assert ha_state.attributes[ATTR_CURRENT_POSITION] == 100
assert ha_state.attributes[ATTR_CURRENT_TILT_POSITION] == 50
await hass.services.async_call(
"cover", "close_cover_tilt", {"entity_id": entity_id}, blocking=True
)
assert len(hmip_device.mock_calls) == service_call_counter + 6
assert hmip_device.mock_calls[-1][0] == "set_slats_level"
assert hmip_device.mock_calls[-1][1] == (1, 4)
await async_manipulate_test_data(hass, hmip_device, "slatsLevel", 1, channel=4)
ha_state = hass.states.get(entity_id)
assert ha_state.state == STATE_OPEN
assert ha_state.attributes[ATTR_CURRENT_POSITION] == 100
assert ha_state.attributes[ATTR_CURRENT_TILT_POSITION] == 0
await hass.services.async_call(
"cover", "stop_cover_tilt", {"entity_id": entity_id}, blocking=True
)
assert len(hmip_device.mock_calls) == service_call_counter + 8
assert hmip_device.mock_calls[-1][0] == "set_shutter_stop"
assert hmip_device.mock_calls[-1][1] == (4,)
await async_manipulate_test_data(hass, hmip_device, "slatsLevel", None, channel=4)
ha_state = hass.states.get(entity_id)
assert not ha_state.attributes.get(ATTR_CURRENT_TILT_POSITION)
await async_manipulate_test_data(hass, hmip_device, "shutterLevel", None, channel=4)
ha_state = hass.states.get(entity_id)
assert ha_state.state == STATE_UNKNOWN
async def test_hmip_blind_module(hass, default_mock_hap_factory):
"""Test HomematicipBlindModule."""
entity_id = "cover.sonnenschutz_balkontur"
@ -254,6 +332,13 @@ async def test_hmip_blind_module(hass, default_mock_hap_factory):
assert hmip_device.mock_calls[-1][0] == "stop"
assert hmip_device.mock_calls[-1][1] == ()
await hass.services.async_call(
"cover", "stop_cover_tilt", {"entity_id": entity_id}, blocking=True
)
assert len(hmip_device.mock_calls) == service_call_counter + 14
assert hmip_device.mock_calls[-1][0] == "stop"
assert hmip_device.mock_calls[-1][1] == ()
await async_manipulate_test_data(hass, hmip_device, "secondaryShadingLevel", None)
ha_state = hass.states.get(entity_id)
assert not ha_state.attributes.get(ATTR_CURRENT_TILT_POSITION)

View File

@ -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) == 236
assert len(mock_hap.hmip_device_by_entity_id) == 250
async def test_hmip_remove_device(hass, default_mock_hap_factory):

View File

@ -175,7 +175,7 @@ async def test_hmip_dimmer(hass, default_mock_hap_factory):
"light", "turn_on", {"entity_id": entity_id}, blocking=True
)
assert hmip_device.mock_calls[-1][0] == "set_dim_level"
assert hmip_device.mock_calls[-1][1] == (1,)
assert hmip_device.mock_calls[-1][1] == (1, 1)
await hass.services.async_call(
"light",
@ -185,7 +185,7 @@ async def test_hmip_dimmer(hass, default_mock_hap_factory):
)
assert len(hmip_device.mock_calls) == service_call_counter + 2
assert hmip_device.mock_calls[-1][0] == "set_dim_level"
assert hmip_device.mock_calls[-1][1] == (1.0,)
assert hmip_device.mock_calls[-1][1] == (1.0, 1)
await async_manipulate_test_data(hass, hmip_device, "dimLevel", 1)
ha_state = hass.states.get(entity_id)
assert ha_state.state == STATE_ON
@ -196,7 +196,7 @@ async def test_hmip_dimmer(hass, default_mock_hap_factory):
)
assert len(hmip_device.mock_calls) == service_call_counter + 4
assert hmip_device.mock_calls[-1][0] == "set_dim_level"
assert hmip_device.mock_calls[-1][1] == (0,)
assert hmip_device.mock_calls[-1][1] == (0, 1)
await async_manipulate_test_data(hass, hmip_device, "dimLevel", 0)
ha_state = hass.states.get(entity_id)
assert ha_state.state == STATE_OFF

View File

@ -43,7 +43,7 @@ async def test_hmip_switch(hass, default_mock_hap_factory):
)
assert len(hmip_device.mock_calls) == service_call_counter + 1
assert hmip_device.mock_calls[-1][0] == "turn_off"
assert hmip_device.mock_calls[-1][1] == ()
assert hmip_device.mock_calls[-1][1] == (1,)
await async_manipulate_test_data(hass, hmip_device, "on", False)
ha_state = hass.states.get(entity_id)
assert ha_state.state == STATE_OFF
@ -53,7 +53,7 @@ async def test_hmip_switch(hass, default_mock_hap_factory):
)
assert len(hmip_device.mock_calls) == service_call_counter + 3
assert hmip_device.mock_calls[-1][0] == "turn_on"
assert hmip_device.mock_calls[-1][1] == ()
assert hmip_device.mock_calls[-1][1] == (1,)
await async_manipulate_test_data(hass, hmip_device, "on", True)
ha_state = hass.states.get(entity_id)
assert ha_state.state == STATE_ON
@ -80,7 +80,7 @@ async def test_hmip_switch_input(hass, default_mock_hap_factory):
)
assert len(hmip_device.mock_calls) == service_call_counter + 1
assert hmip_device.mock_calls[-1][0] == "turn_off"
assert hmip_device.mock_calls[-1][1] == ()
assert hmip_device.mock_calls[-1][1] == (1,)
await async_manipulate_test_data(hass, hmip_device, "on", False)
ha_state = hass.states.get(entity_id)
assert ha_state.state == STATE_OFF
@ -90,7 +90,7 @@ async def test_hmip_switch_input(hass, default_mock_hap_factory):
)
assert len(hmip_device.mock_calls) == service_call_counter + 3
assert hmip_device.mock_calls[-1][0] == "turn_on"
assert hmip_device.mock_calls[-1][1] == ()
assert hmip_device.mock_calls[-1][1] == (1,)
await async_manipulate_test_data(hass, hmip_device, "on", True)
ha_state = hass.states.get(entity_id)
assert ha_state.state == STATE_ON
@ -117,7 +117,7 @@ async def test_hmip_switch_measuring(hass, default_mock_hap_factory):
)
assert len(hmip_device.mock_calls) == service_call_counter + 1
assert hmip_device.mock_calls[-1][0] == "turn_off"
assert hmip_device.mock_calls[-1][1] == ()
assert hmip_device.mock_calls[-1][1] == (1,)
await async_manipulate_test_data(hass, hmip_device, "on", False)
ha_state = hass.states.get(entity_id)
assert ha_state.state == STATE_OFF
@ -127,7 +127,7 @@ async def test_hmip_switch_measuring(hass, default_mock_hap_factory):
)
assert len(hmip_device.mock_calls) == service_call_counter + 3
assert hmip_device.mock_calls[-1][0] == "turn_on"
assert hmip_device.mock_calls[-1][1] == ()
assert hmip_device.mock_calls[-1][1] == (1,)
await async_manipulate_test_data(hass, hmip_device, "on", True)
await async_manipulate_test_data(hass, hmip_device, "currentPowerConsumption", 50)
ha_state = hass.states.get(entity_id)
@ -191,6 +191,7 @@ async def test_hmip_multi_switch(hass, default_mock_hap_factory):
"Multi IO Box",
"Heizungsaktor",
"ioBroker",
"Schaltaktor Verteiler",
]
)
@ -221,6 +222,16 @@ async def test_hmip_multi_switch(hass, default_mock_hap_factory):
ha_state = hass.states.get(entity_id)
assert ha_state.state == STATE_OFF
ha_state, hmip_device = get_and_check_entity_basics(
hass,
mock_hap,
"switch.schaltaktor_verteiler_channel3",
"Schaltaktor Verteiler Channel3",
"HmIP-DRSI4",
)
assert ha_state.state == STATE_OFF
async def test_hmip_wired_multi_switch(hass, default_mock_hap_factory):
"""Test HomematicipMultiSwitch."""

View File

@ -6116,6 +6116,508 @@
"serializedGlobalTradeItemNumber": "3014F0000000000000FAF9B4",
"type": "TORMATIC_MODULE",
"updateState": "UP_TO_DATE"
},
"3014F7110000000000005521": {
"availableFirmwareVersion": "1.4.2",
"connectionType": "HMIP_RF",
"firmwareVersion": "1.4.2",
"firmwareVersionInteger": 66562,
"functionalChannels": {
"0": {
"busConfigMismatch": null,
"coProFaulty": false,
"coProRestartNeeded": false,
"coProUpdateFailure": false,
"configPending": false,
"deviceId": "3014F7110000000000005521",
"deviceOverheated": false,
"deviceOverloaded": false,
"devicePowerFailureDetected": false,
"deviceUndervoltage": false,
"dutyCycle": false,
"functionalChannelType": "DEVICE_BASE",
"groupIndex": 0,
"groups": [
"00000000-0000-0000-0000-000000000034"
],
"index": 0,
"label": "",
"lowBat": null,
"multicastRoutingEnabled": false,
"powerShortCircuit": null,
"routerModuleEnabled": false,
"routerModuleSupported": false,
"rssiDeviceValue": -82,
"rssiPeerValue": -78,
"shortCircuitDataLine": null,
"supportedOptionalFeatures": {
"IFeatureBusConfigMismatch": false,
"IFeatureDeviceCoProError": false,
"IFeatureDeviceCoProRestart": false,
"IFeatureDeviceCoProUpdate": false,
"IFeatureDeviceIdentify": true,
"IFeatureDeviceOverheated": true,
"IFeatureDeviceOverloaded": false,
"IFeatureDevicePowerFailure": true,
"IFeatureDeviceTemperatureOutOfRange": false,
"IFeatureDeviceUndervoltage": false,
"IFeatureMulticastRouter": false,
"IFeaturePowerShortCircuit": false,
"IFeatureRssiValue": true,
"IFeatureShortCircuitDataLine": false,
"IOptionalFeatureDutyCycle": true,
"IOptionalFeatureLowBat": false
},
"temperatureOutOfRange": false,
"unreach": false
},
"1": {
"binaryBehaviorType": "NORMALLY_CLOSE",
"deviceId": "3014F7110000000000005521",
"functionalChannelType": "MULTI_MODE_INPUT_SWITCH_CHANNEL",
"groupIndex": 1,
"groups": [
"00000000-0000-0000-0000-000000000035"
],
"index": 1,
"label": "Poolpumpe",
"multiModeInputMode": "KEY_BEHAVIOR",
"on": false,
"profileMode": "AUTOMATIC",
"userDesiredProfileMode": "AUTOMATIC"
},
"2": {
"binaryBehaviorType": "NORMALLY_CLOSE",
"deviceId": "3014F7110000000000005521",
"functionalChannelType": "MULTI_MODE_INPUT_SWITCH_CHANNEL",
"groupIndex": 2,
"groups": [
"00000000-0000-0000-0000-000000000035"
],
"index": 2,
"label": "Poollicht",
"multiModeInputMode": "KEY_BEHAVIOR",
"on": false,
"profileMode": "AUTOMATIC",
"userDesiredProfileMode": "AUTOMATIC"
},
"3": {
"binaryBehaviorType": "NORMALLY_CLOSE",
"deviceId": "3014F7110000000000005521",
"functionalChannelType": "MULTI_MODE_INPUT_SWITCH_CHANNEL",
"groupIndex": 3,
"groups": [],
"index": 3,
"label": "",
"multiModeInputMode": "KEY_BEHAVIOR",
"on": false,
"profileMode": "AUTOMATIC",
"userDesiredProfileMode": "AUTOMATIC"
},
"4": {
"binaryBehaviorType": "NORMALLY_CLOSE",
"deviceId": "3014F7110000000000005521",
"functionalChannelType": "MULTI_MODE_INPUT_SWITCH_CHANNEL",
"groupIndex": 4,
"groups": [],
"index": 4,
"label": "",
"multiModeInputMode": "KEY_BEHAVIOR",
"on": false,
"profileMode": "AUTOMATIC",
"userDesiredProfileMode": "AUTOMATIC"
}
},
"homeId": "00000000-0000-0000-0000-000000000001",
"id": "3014F7110000000000005521",
"label": "Schaltaktor Verteiler",
"lastStatusUpdate": 1605271783993,
"liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED",
"manufacturerCode": 1,
"modelId": 405,
"modelType": "HmIP-DRSI4",
"oem": "eQ-3",
"permanentlyReachable": true,
"serializedGlobalTradeItemNumber": "3014F7110000000000005521",
"type": "DIN_RAIL_SWITCH_4",
"updateState": "UP_TO_DATE"
},
"3014F7110000000000022311": {
"availableFirmwareVersion": "1.6.0",
"connectionType": "HMIP_RF",
"firmwareVersion": "1.6.0",
"firmwareVersionInteger": 67072,
"functionalChannels": {
"0": {
"busConfigMismatch": null,
"coProFaulty": false,
"coProRestartNeeded": false,
"coProUpdateFailure": false,
"configPending": false,
"deviceId": "3014F7110000000000022311",
"deviceOverheated": false,
"deviceOverloaded": false,
"devicePowerFailureDetected": false,
"deviceUndervoltage": false,
"dutyCycle": false,
"functionalChannelType": "DEVICE_BASE",
"groupIndex": 0,
"groups": [
"00000000-0000-0000-0000-000000000026"
],
"index": 0,
"label": "",
"lowBat": null,
"multicastRoutingEnabled": false,
"powerShortCircuit": null,
"routerModuleEnabled": false,
"routerModuleSupported": false,
"rssiDeviceValue": -70,
"rssiPeerValue": -63,
"shortCircuitDataLine": null,
"supportedOptionalFeatures": {
"IFeatureBusConfigMismatch": false,
"IFeatureDeviceCoProError": false,
"IFeatureDeviceCoProRestart": false,
"IFeatureDeviceCoProUpdate": false,
"IFeatureDeviceIdentify": true,
"IFeatureDeviceOverheated": true,
"IFeatureDeviceOverloaded": false,
"IFeatureDevicePowerFailure": true,
"IFeatureDeviceTemperatureOutOfRange": false,
"IFeatureDeviceUndervoltage": false,
"IFeatureMulticastRouter": false,
"IFeaturePowerShortCircuit": false,
"IFeatureRssiValue": true,
"IFeatureShortCircuitDataLine": false,
"IOptionalFeatureDutyCycle": true,
"IOptionalFeatureLowBat": false
},
"temperatureOutOfRange": false,
"unreach": false
},
"1": {
"binaryBehaviorType": "NORMALLY_CLOSE",
"blindModeActive": false,
"bottomToTopReferenceTime": 18.19999999999999,
"changeOverDelay": 0.5,
"delayCompensationValue": 0.0,
"deviceId": "3014F7110000000000022311",
"endpositionAutoDetectionEnabled": false,
"favoritePrimaryShadingPosition": 0.5,
"favoriteSecondaryShadingPosition": 0.5,
"functionalChannelType": "MULTI_MODE_INPUT_BLIND_CHANNEL",
"groupIndex": 1,
"groups": [
"00000000-0000-0000-0000-000000000027"
],
"index": 1,
"label": "Badezimmer ",
"multiModeInputMode": "KEY_BEHAVIOR",
"previousShutterLevel": null,
"previousSlatsLevel": null,
"processing": false,
"profileMode": "AUTOMATIC",
"selfCalibrationInProgress": null,
"shutterLevel": 0.0,
"slatsLevel": null,
"slatsReferenceTime": 0.0,
"supportedOptionalFeatures": {
"IOptionalFeatureSlatsState": false
},
"supportingDelayCompensation": true,
"supportingEndpositionAutoDetection": false,
"supportingSelfCalibration": false,
"topToBottomReferenceTime": 17.49999999999998,
"userDesiredProfileMode": "AUTOMATIC"
},
"2": {
"binaryBehaviorType": "NORMALLY_CLOSE",
"blindModeActive": false,
"bottomToTopReferenceTime": 17.899999999999984,
"changeOverDelay": 0.5,
"delayCompensationValue": 0.0,
"deviceId": "3014F7110000000000022311",
"endpositionAutoDetectionEnabled": false,
"favoritePrimaryShadingPosition": 0.5,
"favoriteSecondaryShadingPosition": 0.5,
"functionalChannelType": "MULTI_MODE_INPUT_BLIND_CHANNEL",
"groupIndex": 2,
"groups": [
"00000000-0000-0000-0000-000000000028"
],
"index": 2,
"label": "Schlafzimmer ",
"multiModeInputMode": "KEY_BEHAVIOR",
"previousShutterLevel": null,
"previousSlatsLevel": null,
"processing": false,
"profileMode": "AUTOMATIC",
"selfCalibrationInProgress": null,
"shutterLevel": 0.0,
"slatsLevel": null,
"slatsReferenceTime": 0.0,
"supportedOptionalFeatures": {
"IOptionalFeatureSlatsState": false
},
"supportingDelayCompensation": true,
"supportingEndpositionAutoDetection": false,
"supportingSelfCalibration": false,
"topToBottomReferenceTime": 17.399999999999977,
"userDesiredProfileMode": "AUTOMATIC"
},
"3": {
"binaryBehaviorType": "NORMALLY_CLOSE",
"blindModeActive": false,
"bottomToTopReferenceTime": 27.300000000000118,
"changeOverDelay": 0.5,
"delayCompensationValue": 0.0,
"deviceId": "3014F7110000000000022311",
"endpositionAutoDetectionEnabled": false,
"favoritePrimaryShadingPosition": 0.5,
"favoriteSecondaryShadingPosition": 0.5,
"functionalChannelType": "MULTI_MODE_INPUT_BLIND_CHANNEL",
"groupIndex": 3,
"groups": [
"00000000-0000-0000-0000-000000000029"
],
"index": 3,
"label": "Wohnzimmer T\u00fcr",
"multiModeInputMode": "KEY_BEHAVIOR",
"previousShutterLevel": null,
"previousSlatsLevel": null,
"processing": false,
"profileMode": "AUTOMATIC",
"selfCalibrationInProgress": null,
"shutterLevel": 0.0,
"slatsLevel": null,
"slatsReferenceTime": 0.0,
"supportedOptionalFeatures": {
"IOptionalFeatureSlatsState": false
},
"supportingDelayCompensation": true,
"supportingEndpositionAutoDetection": false,
"supportingSelfCalibration": false,
"topToBottomReferenceTime": 24.400000000000077,
"userDesiredProfileMode": "AUTOMATIC"
},
"4": {
"binaryBehaviorType": "NORMALLY_CLOSE",
"blindModeActive": false,
"bottomToTopReferenceTime": 25.900000000000098,
"changeOverDelay": 0.5,
"delayCompensationValue": 0.0,
"deviceId": "3014F7110000000000022311",
"endpositionAutoDetectionEnabled": false,
"favoritePrimaryShadingPosition": 0.5,
"favoriteSecondaryShadingPosition": 0.5,
"functionalChannelType": "MULTI_MODE_INPUT_BLIND_CHANNEL",
"groupIndex": 4,
"groups": [
"00000000-0000-0000-0000-000000000029"
],
"index": 4,
"label": "Wohnzimmer Fenster",
"multiModeInputMode": "KEY_BEHAVIOR",
"previousShutterLevel": null,
"previousSlatsLevel": null,
"processing": false,
"profileMode": "AUTOMATIC",
"selfCalibrationInProgress": null,
"shutterLevel": 0.0,
"slatsLevel": null,
"slatsReferenceTime": 0.0,
"supportedOptionalFeatures": {
"IOptionalFeatureSlatsState": false
},
"supportingDelayCompensation": true,
"supportingEndpositionAutoDetection": false,
"supportingSelfCalibration": false,
"topToBottomReferenceTime": 25.000000000000085,
"userDesiredProfileMode": "AUTOMATIC"
}
},
"homeId": "00000000-0000-0000-0000-000000000001",
"id": "3014F7110000000000022311",
"label": "Jalousieaktor 1 f\u00fcr Hutschienenmontage \u2013 4-fach",
"lastStatusUpdate": 1604414124509,
"liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED",
"manufacturerCode": 1,
"modelId": 406,
"modelType": "HmIP-DRBLI4",
"oem": "eQ-3",
"permanentlyReachable": true,
"serializedGlobalTradeItemNumber": "3014F7110000000000022311",
"type": "DIN_RAIL_BLIND_4",
"updateState": "UP_TO_DATE"
},
"3014F7110000000000056775": {
"availableFirmwareVersion": "1.0.16",
"connectionType": "HMIP_RF",
"firmwareVersion": "1.0.16",
"firmwareVersionInteger": 65552,
"functionalChannels": {
"0": {
"busConfigMismatch": null,
"coProFaulty": false,
"coProRestartNeeded": false,
"coProUpdateFailure": false,
"configPending": false,
"deviceId": "3014F7110000000000056775",
"deviceOverheated": false,
"deviceOverloaded": false,
"devicePowerFailureDetected": false,
"deviceUndervoltage": false,
"dutyCycle": null,
"functionalChannelType": "DEVICE_BASE",
"groupIndex": 0,
"groups": [
"00000000-0000-0000-0000-000000000043"
],
"index": 0,
"label": "",
"lowBat": null,
"multicastRoutingEnabled": false,
"powerShortCircuit": null,
"routerModuleEnabled": false,
"routerModuleSupported": false,
"rssiDeviceValue": null,
"rssiPeerValue": null,
"shortCircuitDataLine": null,
"supportedOptionalFeatures": {
"IFeatureBusConfigMismatch": false,
"IFeatureDeviceCoProError": false,
"IFeatureDeviceCoProRestart": false,
"IFeatureDeviceCoProUpdate": false,
"IFeatureDeviceIdentify": false,
"IFeatureDeviceOverheated": false,
"IFeatureDeviceOverloaded": false,
"IFeatureDevicePowerFailure": false,
"IFeatureDeviceTemperatureOutOfRange": false,
"IFeatureDeviceUndervoltage": false,
"IFeatureMulticastRouter": false,
"IFeaturePowerShortCircuit": false,
"IFeatureRssiValue": true,
"IFeatureShortCircuitDataLine": false,
"IOptionalFeatureDutyCycle": true,
"IOptionalFeatureLowBat": true
},
"temperatureOutOfRange": false,
"unreach": null
},
"1": {
"binaryBehaviorType": "NORMALLY_CLOSE",
"deviceId": "3014F7110000000000056775",
"functionalChannelType": "MULTI_MODE_INPUT_CHANNEL",
"groupIndex": 1,
"groups": [
"00000000-0000-0000-0000-000000000044",
"00000000-0000-0000-0000-000000000045"
],
"index": 1,
"label": "Licht Flur 1",
"multiModeInputMode": "KEY_BEHAVIOR",
"supportedOptionalFeatures": {
"IOptionalFeatureWindowState": false
},
"windowState": null
},
"2": {
"binaryBehaviorType": "NORMALLY_CLOSE",
"deviceId": "3014F7110000000000056775",
"functionalChannelType": "MULTI_MODE_INPUT_CHANNEL",
"groupIndex": 2,
"groups": [
"00000000-0000-0000-0000-000000000044",
"00000000-0000-0000-0000-000000000006",
"00000000-0000-0000-0000-000000000047"
],
"index": 2,
"label": "Licht Flur 2",
"multiModeInputMode": "KEY_BEHAVIOR",
"supportedOptionalFeatures": {
"IOptionalFeatureWindowState": false
},
"windowState": null
},
"3": {
"binaryBehaviorType": "NORMALLY_CLOSE",
"deviceId": "3014F7110000000000056775",
"functionalChannelType": "MULTI_MODE_INPUT_CHANNEL",
"groupIndex": 3,
"groups": [
"00000000-0000-0000-0000-000000000044"
],
"index": 3,
"label": "Tür",
"multiModeInputMode": "KEY_BEHAVIOR",
"supportedOptionalFeatures": {
"IOptionalFeatureWindowState": true
},
"windowState": "OPEN"
},
"4": {
"binaryBehaviorType": "NORMALLY_CLOSE",
"deviceId": "3014F7110000000000056775",
"functionalChannelType": "MULTI_MODE_INPUT_CHANNEL",
"groupIndex": 4,
"groups": [
"00000000-0000-0000-0000-000000000044"
],
"index": 4,
"label": "Licht Flur 4",
"multiModeInputMode": "KEY_BEHAVIOR",
"supportedOptionalFeatures": {
"IOptionalFeatureWindowState": false
},
"windowState": null
},
"5": {
"binaryBehaviorType": "NORMALLY_CLOSE",
"deviceId": "3014F7110000000000056775",
"functionalChannelType": "MULTI_MODE_INPUT_CHANNEL",
"groupIndex": 5,
"groups": [
"00000000-0000-0000-0000-000000000044"
],
"index": 5,
"label": "Licht Flur 5",
"multiModeInputMode": "KEY_BEHAVIOR",
"supportedOptionalFeatures": {
"IOptionalFeatureWindowState": false
},
"windowState": null
},
"6": {
"binaryBehaviorType": "NORMALLY_CLOSE",
"deviceId": "3014F7110000000000056775",
"functionalChannelType": "MULTI_MODE_INPUT_CHANNEL",
"groupIndex": 6,
"groups": [
"00000000-0000-0000-0000-000000000044"
],
"index": 6,
"label": "Licht Flur 6",
"multiModeInputMode": "KEY_BEHAVIOR",
"supportedOptionalFeatures": {
"IOptionalFeatureWindowState": false
},
"windowState": null
}
},
"homeId": "00000000-0000-0000-0000-000000000001",
"id": "3014F7110000000000056775",
"label": "Licht Flur",
"lastStatusUpdate": 0,
"liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED",
"manufacturerCode": 1,
"modelId": 379,
"modelType": "HmIP-FCI6",
"oem": "eQ-3",
"permanentlyReachable": false,
"serializedGlobalTradeItemNumber": "3014F7110000000000056775",
"type": "FULL_FLUSH_CONTACT_INTERFACE_6",
"updateState": "UP_TO_DATE"
}
},
"groups": {