Skip to content

Commit

Permalink
Bump dependency to add more multi channel devices to HomematicIP Cloud (
Browse files Browse the repository at this point in the history
  • Loading branch information
SukramJ authored Dec 7, 2020
1 parent 8632ab9 commit 34a3188
Show file tree
Hide file tree
Showing 14 changed files with 823 additions and 117 deletions.
45 changes: 22 additions & 23 deletions homeassistant/components/homematicip_cloud/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
AsyncContactInterface,
AsyncDevice,
AsyncFullFlushContactInterface,
AsyncFullFlushContactInterface6,
AsyncMotionDetectorIndoor,
AsyncMotionDetectorOutdoor,
AsyncMotionDetectorPushButton,
Expand Down Expand Up @@ -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)
):
Expand Down Expand Up @@ -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:
Expand All @@ -244,44 +258,29 @@ def is_on(self) -> bool:
)


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
def device_class(self) -> str:
"""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."""
Expand Down
150 changes: 131 additions & 19 deletions homeassistant/components/homematicip_cloud/cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from homematicip.aio.device import (
AsyncBlindModule,
AsyncDinRailBlind4,
AsyncFullFlushBlind,
AsyncFullFlushShutter,
AsyncGarageDoorModuleTormatic,
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -130,71 +136,118 @@ async def async_stop_cover_tilt(self, **kwargs) -> None:
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:
"""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)
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:
"""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)
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):
Expand Down Expand Up @@ -229,10 +282,69 @@ async def async_stop_cover(self, **kwargs) -> None:
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()
8 changes: 5 additions & 3 deletions homeassistant/components/homematicip_cloud/generic_entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,15 @@ def __init__(
device,
post: Optional[str] = None,
channel: Optional[int] = None,
is_multi_channel: Optional[bool] = False,
) -> None:
"""Initialize the generic entity."""
self._hap = hap
self._home = hap.home
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)
Expand Down Expand Up @@ -179,7 +181,7 @@ def name(self) -> str:
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:
Expand All @@ -190,7 +192,7 @@ def name(self) -> str:
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.
Expand All @@ -213,7 +215,7 @@ def available(self) -> bool:
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}"
)
Expand Down
Loading

0 comments on commit 34a3188

Please sign in to comment.