Add doorbell event to homematicip_cloud (#133269)

This commit is contained in:
hahn-th 2025-01-17 17:54:15 +01:00 committed by GitHub
parent 2a514ebc3f
commit 4a64c797d4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 252 additions and 1 deletions

View File

@ -14,6 +14,7 @@ PLATFORMS = [
Platform.BUTTON,
Platform.CLIMATE,
Platform.COVER,
Platform.EVENT,
Platform.LIGHT,
Platform.LOCK,
Platform.SENSOR,

View File

@ -0,0 +1,94 @@
"""Support for HomematicIP Cloud events."""
from dataclasses import dataclass
from typing import TYPE_CHECKING
from homematicip.aio.device import Device
from homeassistant.components.event import (
EventDeviceClass,
EventEntity,
EventEntityDescription,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN
from .entity import HomematicipGenericEntity
from .hap import HomematicipHAP
@dataclass(frozen=True, kw_only=True)
class HmipEventEntityDescription(EventEntityDescription):
"""Description of a HomematicIP Cloud event."""
EVENT_DESCRIPTIONS = {
"doorbell": HmipEventEntityDescription(
key="doorbell",
translation_key="doorbell",
device_class=EventDeviceClass.DOORBELL,
event_types=["ring"],
),
}
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the HomematicIP cover from a config entry."""
hap = hass.data[DOMAIN][config_entry.unique_id]
async_add_entities(
HomematicipDoorBellEvent(
hap,
device,
channel.index,
EVENT_DESCRIPTIONS["doorbell"],
)
for device in hap.home.devices
for channel in device.functionalChannels
if channel.channelRole == "DOOR_BELL_INPUT"
)
class HomematicipDoorBellEvent(HomematicipGenericEntity, EventEntity):
"""Event class for HomematicIP doorbell events."""
_attr_device_class = EventDeviceClass.DOORBELL
def __init__(
self,
hap: HomematicipHAP,
device: Device,
channel: int,
description: HmipEventEntityDescription,
) -> None:
"""Initialize the event."""
super().__init__(
hap,
device,
post=description.key,
channel=channel,
is_multi_channel=False,
)
self.entity_description = description
async def async_added_to_hass(self) -> None:
"""Register callbacks."""
await super().async_added_to_hass()
self.functional_channel.add_on_channel_event_handler(self._async_handle_event)
@callback
def _async_handle_event(self, *args, **kwargs) -> None:
"""Handle the event fired by the functional channel."""
event_types = self.entity_description.event_types
if TYPE_CHECKING:
assert event_types is not None
self._trigger_event(event_type=event_types[0])
self.async_write_ha_state()

View File

@ -8177,6 +8177,125 @@
"serializedGlobalTradeItemNumber": "3014F7110000000000ESIIE3",
"type": "ENERGY_SENSORS_INTERFACE",
"updateState": "UP_TO_DATE"
},
"3014F7110000000000DSDPCB": {
"availableFirmwareVersion": "1.0.6",
"connectionType": "HMIP_RF",
"deviceArchetype": "HMIP",
"firmwareVersion": "1.0.6",
"firmwareVersionInteger": 65542,
"functionalChannels": {
"0": {
"busConfigMismatch": null,
"coProFaulty": false,
"coProRestartNeeded": false,
"coProUpdateFailure": false,
"configPending": false,
"controlsMountingOrientation": null,
"deviceCommunicationError": null,
"deviceDriveError": null,
"deviceDriveModeError": null,
"deviceId": "3014F7110000000000DSDPCB",
"deviceOperationMode": null,
"deviceOverheated": false,
"deviceOverloaded": false,
"devicePowerFailureDetected": false,
"deviceUndervoltage": false,
"displayContrast": null,
"dutyCycle": false,
"functionalChannelType": "DEVICE_BASE",
"groupIndex": 0,
"groups": ["00000000-0000-0000-0000-000000000042"],
"index": 0,
"label": "",
"lockJammed": null,
"lowBat": false,
"mountingOrientation": null,
"multicastRoutingEnabled": false,
"particulateMatterSensorCommunicationError": null,
"particulateMatterSensorError": null,
"powerShortCircuit": null,
"profilePeriodLimitReached": null,
"routerModuleEnabled": false,
"routerModuleSupported": false,
"rssiDeviceValue": -58,
"rssiPeerValue": null,
"shortCircuitDataLine": null,
"supportedOptionalFeatures": {
"IFeatureBusConfigMismatch": false,
"IFeatureDeviceCoProError": false,
"IFeatureDeviceCoProRestart": false,
"IFeatureDeviceCoProUpdate": false,
"IFeatureDeviceCommunicationError": false,
"IFeatureDeviceDriveError": false,
"IFeatureDeviceDriveModeError": false,
"IFeatureDeviceIdentify": false,
"IFeatureDeviceOverheated": false,
"IFeatureDeviceOverloaded": false,
"IFeatureDeviceParticulateMatterSensorCommunicationError": false,
"IFeatureDeviceParticulateMatterSensorError": false,
"IFeatureDevicePowerFailure": false,
"IFeatureDeviceTemperatureHumiditySensorCommunicationError": false,
"IFeatureDeviceTemperatureHumiditySensorError": false,
"IFeatureDeviceTemperatureOutOfRange": false,
"IFeatureDeviceUndervoltage": false,
"IFeatureMulticastRouter": false,
"IFeaturePowerShortCircuit": false,
"IFeatureProfilePeriodLimit": false,
"IFeatureRssiValue": true,
"IFeatureShortCircuitDataLine": false,
"IOptionalFeatureDeviceErrorLockJammed": false,
"IOptionalFeatureDeviceOperationMode": false,
"IOptionalFeatureDisplayContrast": false,
"IOptionalFeatureDutyCycle": true,
"IOptionalFeatureLowBat": true,
"IOptionalFeatureMountingOrientation": false
},
"temperatureHumiditySensorCommunicationError": null,
"temperatureHumiditySensorError": null,
"temperatureOutOfRange": false,
"unreach": false
},
"1": {
"actionParameter": "NOT_CUSTOMISABLE",
"binaryBehaviorType": "NORMALLY_CLOSE",
"channelRole": "DOOR_BELL_INPUT",
"corrosionPreventionActive": false,
"deviceId": "3014F7110000000000DSDPCB",
"doorBellSensorEventTimestamp": 1673006015756,
"eventDelay": 0,
"functionalChannelType": "MULTI_MODE_INPUT_CHANNEL",
"groupIndex": 1,
"groups": ["00000000-0000-0000-0000-000000000056"],
"index": 1,
"label": "",
"multiModeInputMode": "KEY_BEHAVIOR",
"supportedOptionalFeatures": {
"IFeatureAccessAuthorizationSensorChannel": false,
"IFeatureGarageGroupSensorChannel": true,
"IFeatureLightGroupSensorChannel": false,
"IFeatureShadingGroupSensorChannel": false,
"IOptionalFeatureDoorBellSensorEventTimestamp": true,
"IOptionalFeatureEventDelay": false,
"IOptionalFeatureLongPressSupported": false,
"IOptionalFeatureWindowState": false
},
"windowState": "CLOSED"
}
},
"homeId": "00000000-0000-0000-0000-000000000001",
"id": "3014F7110000000000DSDPCB",
"label": "dsdpcb_klingel",
"lastStatusUpdate": 1673006015756,
"liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED",
"manufacturerCode": 1,
"modelId": 410,
"modelType": "HmIP-DSD-PCB",
"oem": "eQ-3",
"permanentlyReachable": false,
"serializedGlobalTradeItemNumber": "3014F7110000000000DSDPCB",
"type": "DOOR_BELL_CONTACT_INTERFACE",
"updateState": "UP_TO_DATE"
}
},
"groups": {

View File

@ -28,7 +28,7 @@ async def test_hmip_load_all_supported_devices(
test_devices=None, test_groups=None
)
assert len(mock_hap.hmip_device_by_entity_id) == 308
assert len(mock_hap.hmip_device_by_entity_id) == 310
async def test_hmip_remove_device(

View File

@ -0,0 +1,37 @@
"""Tests for the HomematicIP Cloud event."""
from homematicip.base.channel_event import ChannelEvent
from homeassistant.const import STATE_UNKNOWN
from homeassistant.core import HomeAssistant
from .helper import HomeFactory, get_and_check_entity_basics
async def test_door_bell_event(
hass: HomeAssistant,
default_mock_hap_factory: HomeFactory,
) -> None:
"""Test of door bell event of HmIP-DSD-PCB."""
entity_id = "event.dsdpcb_klingel_doorbell"
entity_name = "dsdpcb_klingel doorbell"
device_model = "HmIP-DSD-PCB"
mock_hap = await default_mock_hap_factory.async_get_mock_hap(
test_devices=["dsdpcb_klingel"]
)
ha_state, hmip_device = get_and_check_entity_basics(
hass, mock_hap, entity_id, entity_name, device_model
)
ch = hmip_device.functionalChannels[1]
channel_event = ChannelEvent(
channelEventType="DOOR_BELL_SENSOR_EVENT", channelIndex=1, deviceId=ch.device.id
)
assert ha_state.state == STATE_UNKNOWN
ch.fire_channel_event(channel_event)
ha_state = hass.states.get(entity_id)
assert ha_state.state != STATE_UNKNOWN