Add HmIP-ESI (#116863)

This commit is contained in:
hahn-th 2024-06-26 11:33:44 +02:00 committed by GitHub
parent d527113d59
commit ae73500beb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 733 additions and 8 deletions

View File

@ -7,6 +7,7 @@ from typing import Any
from homematicip.aio.device import AsyncDevice from homematicip.aio.device import AsyncDevice
from homematicip.aio.group import AsyncGroup from homematicip.aio.group import AsyncGroup
from homematicip.base.functionalChannels import FunctionalChannel
from homeassistant.const import ATTR_ID from homeassistant.const import ATTR_ID
from homeassistant.core import callback from homeassistant.core import callback
@ -91,6 +92,7 @@ class HomematicipGenericEntity(Entity):
self._post = post self._post = post
self._channel = channel self._channel = channel
self._is_multi_channel = is_multi_channel self._is_multi_channel = is_multi_channel
self.functional_channel = self.get_current_channel()
# Marker showing that the HmIP device hase been removed. # Marker showing that the HmIP device hase been removed.
self.hmip_device_removed = False self.hmip_device_removed = False
_LOGGER.info("Setting up %s (%s)", self.name, self._device.modelType) _LOGGER.info("Setting up %s (%s)", self.name, self._device.modelType)
@ -214,13 +216,14 @@ class HomematicipGenericEntity(Entity):
@property @property
def unique_id(self) -> str: def unique_id(self) -> str:
"""Return a unique ID.""" """Return a unique ID."""
unique_id = f"{self.__class__.__name__}_{self._device.id}" suffix = ""
if self._is_multi_channel: if self._post is not None:
unique_id = ( suffix = f"_{self._post}"
f"{self.__class__.__name__}_Channel{self._channel}_{self._device.id}"
)
return unique_id if self._is_multi_channel:
return f"{self.__class__.__name__}_Channel{self._channel}_{self._device.id}{suffix}"
return f"{self.__class__.__name__}_{self._device.id}{suffix}"
@property @property
def icon(self) -> str | None: def icon(self) -> str | None:
@ -251,3 +254,14 @@ class HomematicipGenericEntity(Entity):
state_attr[ATTR_IS_GROUP] = True state_attr[ATTR_IS_GROUP] = True
return state_attr return state_attr
def get_current_channel(self) -> FunctionalChannel:
"""Return the FunctionalChannel for device."""
if hasattr(self._device, "functionalChannels"):
if self._is_multi_channel:
return self._device.functionalChannels[self._channel]
if len(self._device.functionalChannels) > 1:
return self._device.functionalChannels[1]
return None

View File

@ -8,6 +8,9 @@ import json
import logging import logging
from typing import Any, Concatenate, TypeGuard from typing import Any, Concatenate, TypeGuard
from homematicip.base.enums import FunctionalChannelType
from homematicip.device import Device
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
from . import HomematicipGenericEntity from . import HomematicipGenericEntity
@ -47,3 +50,12 @@ def handle_errors[_HomematicipGenericEntityT: HomematicipGenericEntity, **_P](
) )
return inner return inner
def get_channels_from_device(device: Device, channel_type: FunctionalChannelType):
"""Get all channels matching with channel_type from device."""
return [
ch
for ch in device.functionalChannels
if ch.functionalChannelType == channel_type
]

View File

@ -2,10 +2,13 @@
from __future__ import annotations from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from typing import Any from typing import Any
from homematicip.aio.device import ( from homematicip.aio.device import (
AsyncBrandSwitchMeasuring, AsyncBrandSwitchMeasuring,
AsyncEnergySensorsInterface,
AsyncFullFlushSwitchMeasuring, AsyncFullFlushSwitchMeasuring,
AsyncHeatingThermostat, AsyncHeatingThermostat,
AsyncHeatingThermostatCompact, AsyncHeatingThermostatCompact,
@ -27,11 +30,13 @@ from homematicip.aio.device import (
AsyncWeatherSensorPlus, AsyncWeatherSensorPlus,
AsyncWeatherSensorPro, AsyncWeatherSensorPro,
) )
from homematicip.base.enums import ValveState from homematicip.base.enums import FunctionalChannelType, ValveState
from homematicip.base.functionalChannels import FunctionalChannel
from homeassistant.components.sensor import ( from homeassistant.components.sensor import (
SensorDeviceClass, SensorDeviceClass,
SensorEntity, SensorEntity,
SensorEntityDescription,
SensorStateClass, SensorStateClass,
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
@ -43,12 +48,16 @@ from homeassistant.const import (
UnitOfPrecipitationDepth, UnitOfPrecipitationDepth,
UnitOfSpeed, UnitOfSpeed,
UnitOfTemperature, UnitOfTemperature,
UnitOfVolume,
UnitOfVolumeFlowRate,
) )
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
from . import DOMAIN as HMIPC_DOMAIN, HomematicipGenericEntity from . import DOMAIN as HMIPC_DOMAIN, HomematicipGenericEntity
from .hap import HomematicipHAP from .hap import HomematicipHAP
from .helpers import get_channels_from_device
ATTR_CURRENT_ILLUMINATION = "current_illumination" ATTR_CURRENT_ILLUMINATION = "current_illumination"
ATTR_LOWEST_ILLUMINATION = "lowest_illumination" ATTR_LOWEST_ILLUMINATION = "lowest_illumination"
@ -58,6 +67,18 @@ ATTR_RIGHT_COUNTER = "right_counter"
ATTR_TEMPERATURE_OFFSET = "temperature_offset" ATTR_TEMPERATURE_OFFSET = "temperature_offset"
ATTR_WIND_DIRECTION = "wind_direction" ATTR_WIND_DIRECTION = "wind_direction"
ATTR_WIND_DIRECTION_VARIATION = "wind_direction_variation_in_degree" ATTR_WIND_DIRECTION_VARIATION = "wind_direction_variation_in_degree"
ATTR_ESI_TYPE = "type"
ESI_TYPE_UNKNOWN = "UNKNOWN"
ESI_CONNECTED_SENSOR_TYPE_IEC = "ES_IEC"
ESI_CONNECTED_SENSOR_TYPE_GAS = "ES_GAS"
ESI_CONNECTED_SENSOR_TYPE_LED = "ES_LED"
ESI_TYPE_CURRENT_POWER_CONSUMPTION = "CurrentPowerConsumption"
ESI_TYPE_ENERGY_COUNTER_USAGE_HIGH_TARIFF = "ENERGY_COUNTER_USAGE_HIGH_TARIFF"
ESI_TYPE_ENERGY_COUNTER_USAGE_LOW_TARIFF = "ENERGY_COUNTER_USAGE_LOW_TARIFF"
ESI_TYPE_ENERGY_COUNTER_INPUT_SINGLE_TARIFF = "ENERGY_COUNTER_INPUT_SINGLE_TARIFF"
ESI_TYPE_CURRENT_GAS_FLOW = "CurrentGasFlow"
ESI_TYPE_CURRENT_GAS_VOLUME = "GasVolume"
ILLUMINATION_DEVICE_ATTRIBUTES = { ILLUMINATION_DEVICE_ATTRIBUTES = {
"currentIllumination": ATTR_CURRENT_ILLUMINATION, "currentIllumination": ATTR_CURRENT_ILLUMINATION,
@ -138,6 +159,23 @@ async def async_setup_entry(
entities.append(HomematicpTemperatureExternalSensorCh1(hap, device)) entities.append(HomematicpTemperatureExternalSensorCh1(hap, device))
entities.append(HomematicpTemperatureExternalSensorCh2(hap, device)) entities.append(HomematicpTemperatureExternalSensorCh2(hap, device))
entities.append(HomematicpTemperatureExternalSensorDelta(hap, device)) entities.append(HomematicpTemperatureExternalSensorDelta(hap, device))
if isinstance(device, AsyncEnergySensorsInterface):
for ch in get_channels_from_device(
device, FunctionalChannelType.ENERGY_SENSORS_INTERFACE_CHANNEL
):
if ch.connectedEnergySensorType not in SENSORS_ESI:
continue
new_entities = [
HmipEsiSensorEntity(hap, device, ch.index, description)
for description in SENSORS_ESI[ch.connectedEnergySensorType]
]
entities.extend(
entity
for entity in new_entities
if entity.entity_description.exists_fn(ch)
)
async_add_entities(entities) async_add_entities(entities)
@ -396,6 +434,134 @@ class HomematicpTemperatureExternalSensorDelta(HomematicipGenericEntity, SensorE
return self._device.temperatureExternalDelta return self._device.temperatureExternalDelta
@dataclass(kw_only=True, frozen=True)
class HmipEsiSensorEntityDescription(SensorEntityDescription):
"""SensorEntityDescription for HmIP Sensors."""
value_fn: Callable[[AsyncEnergySensorsInterface], StateType]
exists_fn: Callable[[FunctionalChannel], bool]
type_fn: Callable[[AsyncEnergySensorsInterface], str]
SENSORS_ESI = {
ESI_CONNECTED_SENSOR_TYPE_IEC: [
HmipEsiSensorEntityDescription(
key=ESI_TYPE_CURRENT_POWER_CONSUMPTION,
native_unit_of_measurement=UnitOfPower.WATT,
device_class=SensorDeviceClass.POWER,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda device: device.functional_channel.currentPowerConsumption,
exists_fn=lambda channel: channel.currentPowerConsumption is not None,
type_fn=lambda device: "CurrentPowerConsumption",
),
HmipEsiSensorEntityDescription(
key=ESI_TYPE_ENERGY_COUNTER_USAGE_HIGH_TARIFF,
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
device_class=SensorDeviceClass.ENERGY,
state_class=SensorStateClass.TOTAL_INCREASING,
value_fn=lambda device: device.functional_channel.energyCounterOne,
exists_fn=lambda channel: channel.energyCounterOneType != ESI_TYPE_UNKNOWN,
type_fn=lambda device: device.functional_channel.energyCounterOneType,
),
HmipEsiSensorEntityDescription(
key=ESI_TYPE_ENERGY_COUNTER_USAGE_LOW_TARIFF,
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
device_class=SensorDeviceClass.ENERGY,
state_class=SensorStateClass.TOTAL_INCREASING,
value_fn=lambda device: device.functional_channel.energyCounterTwo,
exists_fn=lambda channel: channel.energyCounterTwoType != ESI_TYPE_UNKNOWN,
type_fn=lambda device: device.functional_channel.energyCounterTwoType,
),
HmipEsiSensorEntityDescription(
key=ESI_TYPE_ENERGY_COUNTER_INPUT_SINGLE_TARIFF,
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
device_class=SensorDeviceClass.ENERGY,
state_class=SensorStateClass.TOTAL_INCREASING,
value_fn=lambda device: device.functional_channel.energyCounterThree,
exists_fn=lambda channel: channel.energyCounterThreeType
!= ESI_TYPE_UNKNOWN,
type_fn=lambda device: device.functional_channel.energyCounterThreeType,
),
],
ESI_CONNECTED_SENSOR_TYPE_LED: [
HmipEsiSensorEntityDescription(
key=ESI_TYPE_CURRENT_POWER_CONSUMPTION,
native_unit_of_measurement=UnitOfPower.WATT,
device_class=SensorDeviceClass.POWER,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda device: device.functional_channel.currentPowerConsumption,
exists_fn=lambda channel: channel.currentPowerConsumption is not None,
type_fn=lambda device: "CurrentPowerConsumption",
),
HmipEsiSensorEntityDescription(
key=ESI_TYPE_ENERGY_COUNTER_USAGE_HIGH_TARIFF,
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
device_class=SensorDeviceClass.ENERGY,
state_class=SensorStateClass.TOTAL_INCREASING,
value_fn=lambda device: device.functional_channel.energyCounterOne,
exists_fn=lambda channel: channel.energyCounterOne is not None,
type_fn=lambda device: ESI_TYPE_ENERGY_COUNTER_USAGE_HIGH_TARIFF,
),
],
ESI_CONNECTED_SENSOR_TYPE_GAS: [
HmipEsiSensorEntityDescription(
key=ESI_TYPE_CURRENT_GAS_FLOW,
native_unit_of_measurement=UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR,
device_class=SensorDeviceClass.VOLUME_FLOW_RATE,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda device: device.functional_channel.currentGasFlow,
exists_fn=lambda channel: channel.currentGasFlow is not None,
type_fn=lambda device: "CurrentGasFlow",
),
HmipEsiSensorEntityDescription(
key=ESI_TYPE_CURRENT_GAS_VOLUME,
native_unit_of_measurement=UnitOfVolume.CUBIC_METERS,
device_class=SensorDeviceClass.VOLUME,
state_class=SensorStateClass.TOTAL_INCREASING,
value_fn=lambda device: device.functional_channel.gasVolume,
exists_fn=lambda channel: channel.gasVolume is not None,
type_fn=lambda device: "GasVolume",
),
],
}
class HmipEsiSensorEntity(HomematicipGenericEntity, SensorEntity):
"""EntityDescription for HmIP-ESI Sensors."""
entity_description: HmipEsiSensorEntityDescription
def __init__(
self,
hap: HomematicipHAP,
device: HomematicipGenericEntity,
channel_index: int,
entity_description: HmipEsiSensorEntityDescription,
) -> None:
"""Initialize Sensor Entity."""
super().__init__(
hap=hap,
device=device,
channel=channel_index,
post=entity_description.key,
is_multi_channel=False,
)
self.entity_description = entity_description
@property
def extra_state_attributes(self) -> dict[str, Any]:
"""Return the state attributes of the esi sensor."""
state_attr = super().extra_state_attributes
state_attr[ATTR_ESI_TYPE] = self.entity_description.type_fn(self)
return state_attr
@property
def native_value(self) -> str | None:
"""Return the state of the sensor."""
return str(self.entity_description.value_fn(self))
class HomematicipPassageDetectorDeltaCounter(HomematicipGenericEntity, SensorEntity): class HomematicipPassageDetectorDeltaCounter(HomematicipGenericEntity, SensorEntity):
"""Representation of the HomematicIP passage detector delta counter.""" """Representation of the HomematicIP passage detector delta counter."""

View File

@ -7347,6 +7347,416 @@
"serializedGlobalTradeItemNumber": "3014F7110000000000000DLD", "serializedGlobalTradeItemNumber": "3014F7110000000000000DLD",
"type": "DOOR_LOCK_DRIVE", "type": "DOOR_LOCK_DRIVE",
"updateState": "UP_TO_DATE" "updateState": "UP_TO_DATE"
},
"3014F7110000000000ESIGAS": {
"availableFirmwareVersion": "1.2.2",
"connectionType": "HMIP_RF",
"deviceArchetype": "HMIP",
"firmwareVersion": "1.2.2",
"firmwareVersionInteger": 66050,
"functionalChannels": {
"0": {
"busConfigMismatch": null,
"coProFaulty": false,
"coProRestartNeeded": false,
"coProUpdateFailure": false,
"configPending": false,
"controlsMountingOrientation": null,
"daliBusState": null,
"defaultLinkedGroup": [],
"deviceCommunicationError": null,
"deviceDriveError": null,
"deviceDriveModeError": null,
"deviceId": "3014F7110000000000ESIGAS",
"deviceOperationMode": null,
"deviceOverheated": false,
"deviceOverloaded": false,
"devicePowerFailureDetected": false,
"deviceUndervoltage": false,
"displayContrast": null,
"dutyCycle": false,
"functionalChannelType": "DEVICE_BASE",
"groupIndex": 0,
"groups": ["00000000-0000-0000-0000-000000000047"],
"index": 0,
"label": "",
"lockJammed": null,
"lowBat": false,
"mountingOrientation": null,
"multicastRoutingEnabled": false,
"particulateMatterSensorCommunicationError": null,
"particulateMatterSensorError": null,
"powerShortCircuit": null,
"profilePeriodLimitReached": null,
"routerModuleEnabled": false,
"routerModuleSupported": false,
"rssiDeviceValue": -73,
"rssiPeerValue": null,
"sensorCommunicationError": false,
"sensorError": false,
"shortCircuitDataLine": null,
"supportedOptionalFeatures": {
"IFeatureBusConfigMismatch": false,
"IFeatureDeviceCoProError": false,
"IFeatureDeviceCoProRestart": false,
"IFeatureDeviceCoProUpdate": false,
"IFeatureDeviceCommunicationError": false,
"IFeatureDeviceDaliBusError": false,
"IFeatureDeviceDriveError": false,
"IFeatureDeviceDriveModeError": false,
"IFeatureDeviceIdentify": false,
"IFeatureDeviceOverheated": false,
"IFeatureDeviceOverloaded": false,
"IFeatureDeviceParticulateMatterSensorCommunicationError": false,
"IFeatureDeviceParticulateMatterSensorError": false,
"IFeatureDevicePowerFailure": false,
"IFeatureDeviceSensorCommunicationError": true,
"IFeatureDeviceSensorError": true,
"IFeatureDeviceTemperatureHumiditySensorCommunicationError": false,
"IFeatureDeviceTemperatureHumiditySensorError": false,
"IFeatureDeviceTemperatureOutOfRange": false,
"IFeatureDeviceUndervoltage": false,
"IFeatureMulticastRouter": false,
"IFeaturePowerShortCircuit": false,
"IFeatureProfilePeriodLimit": false,
"IFeatureRssiValue": true,
"IFeatureShortCircuitDataLine": false,
"IOptionalFeatureDefaultLinkedGroup": false,
"IOptionalFeatureDeviceErrorLockJammed": false,
"IOptionalFeatureDeviceOperationMode": false,
"IOptionalFeatureDisplayContrast": false,
"IOptionalFeatureDutyCycle": true,
"IOptionalFeatureLowBat": true,
"IOptionalFeatureMountingOrientation": false
},
"temperatureHumiditySensorCommunicationError": null,
"temperatureHumiditySensorError": null,
"temperatureOutOfRange": false,
"unreach": false
},
"1": {
"channelRole": "ENERGY_SENSOR",
"connectedEnergySensorType": "ES_GAS",
"currentGasFlow": 1.03,
"currentPowerConsumption": null,
"deviceId": "3014F7110000000000ESIGAS",
"energyCounterOne": null,
"energyCounterOneType": "UNKNOWN",
"energyCounterThree": null,
"energyCounterThreeType": "UNKNOWN",
"energyCounterTwo": null,
"energyCounterTwoType": "UNKNOWN",
"functionalChannelType": "ENERGY_SENSORS_INTERFACE_CHANNEL",
"gasVolume": 1019.26,
"gasVolumePerImpulse": 0.01,
"groupIndex": 1,
"groups": ["00000000-0000-0000-0000-000000000077"],
"impulsesPerKWH": 10000,
"index": 1,
"label": "",
"supportedOptionalFeatures": {
"IOptionalFeatureCounterOffset": true,
"IOptionalFeatureCurrentGasFlow": true,
"IOptionalFeatureCurrentPowerConsumption": false,
"IOptionalFeatureEnergyCounterOne": false,
"IOptionalFeatureEnergyCounterThree": false,
"IOptionalFeatureEnergyCounterTwo": false,
"IOptionalFeatureGasVolume": true,
"IOptionalFeatureGasVolumePerImpulse": true,
"IOptionalFeatureImpulsesPerKWH": false
}
}
},
"homeId": "00000000-0000-0000-0000-000000000001",
"id": "3014F7110000000000ESIGAS",
"label": "esi_gas",
"lastStatusUpdate": 1708880308351,
"liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED",
"manuallyUpdateForced": false,
"manufacturerCode": 1,
"measuredAttributes": {
"1": {
"currentGasFlow": true,
"gasVolume": true
}
},
"modelId": 509,
"modelType": "HmIP-ESI",
"oem": "eQ-3",
"permanentlyReachable": false,
"serializedGlobalTradeItemNumber": "3014F7110000000000ESIGAS",
"type": "ENERGY_SENSORS_INTERFACE",
"updateState": "UP_TO_DATE"
},
"3014F7110000000000ESIIEC": {
"availableFirmwareVersion": "0.0.0",
"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,
"daliBusState": null,
"defaultLinkedGroup": [],
"deviceCommunicationError": null,
"deviceDriveError": null,
"deviceDriveModeError": null,
"deviceId": "3014F7110000000000ESIIEC",
"deviceOperationMode": null,
"deviceOverheated": false,
"deviceOverloaded": false,
"devicePowerFailureDetected": false,
"deviceUndervoltage": false,
"displayContrast": null,
"dutyCycle": false,
"functionalChannelType": "DEVICE_BASE",
"groupIndex": 0,
"groups": ["00000000-0000-0000-0000-000000000031"],
"index": 0,
"label": "",
"lockJammed": null,
"lowBat": false,
"mountingOrientation": null,
"multicastRoutingEnabled": false,
"particulateMatterSensorCommunicationError": null,
"particulateMatterSensorError": null,
"powerShortCircuit": null,
"profilePeriodLimitReached": null,
"routerModuleEnabled": false,
"routerModuleSupported": false,
"rssiDeviceValue": -94,
"rssiPeerValue": null,
"sensorCommunicationError": false,
"sensorError": true,
"shortCircuitDataLine": null,
"supportedOptionalFeatures": {
"IFeatureBusConfigMismatch": false,
"IFeatureDeviceCoProError": false,
"IFeatureDeviceCoProRestart": false,
"IFeatureDeviceCoProUpdate": false,
"IFeatureDeviceCommunicationError": false,
"IFeatureDeviceDaliBusError": false,
"IFeatureDeviceDriveError": false,
"IFeatureDeviceDriveModeError": false,
"IFeatureDeviceIdentify": false,
"IFeatureDeviceOverheated": false,
"IFeatureDeviceOverloaded": false,
"IFeatureDeviceParticulateMatterSensorCommunicationError": false,
"IFeatureDeviceParticulateMatterSensorError": false,
"IFeatureDevicePowerFailure": false,
"IFeatureDeviceSensorCommunicationError": true,
"IFeatureDeviceSensorError": true,
"IFeatureDeviceTemperatureHumiditySensorCommunicationError": false,
"IFeatureDeviceTemperatureHumiditySensorError": false,
"IFeatureDeviceTemperatureOutOfRange": false,
"IFeatureDeviceUndervoltage": false,
"IFeatureMulticastRouter": false,
"IFeaturePowerShortCircuit": false,
"IFeatureProfilePeriodLimit": false,
"IFeatureRssiValue": true,
"IFeatureShortCircuitDataLine": false,
"IOptionalFeatureDefaultLinkedGroup": false,
"IOptionalFeatureDeviceErrorLockJammed": false,
"IOptionalFeatureDeviceOperationMode": false,
"IOptionalFeatureDisplayContrast": false,
"IOptionalFeatureDutyCycle": true,
"IOptionalFeatureLowBat": true,
"IOptionalFeatureMountingOrientation": false
},
"temperatureHumiditySensorCommunicationError": null,
"temperatureHumiditySensorError": null,
"temperatureOutOfRange": false,
"unreach": false
},
"1": {
"channelRole": null,
"connectedEnergySensorType": "ES_IEC",
"currentGasFlow": null,
"currentPowerConsumption": 432,
"deviceId": "3014F7110000000000ESIIEC",
"energyCounterOne": 194.0,
"energyCounterOneType": "ENERGY_COUNTER_USAGE_HIGH_TARIFF",
"energyCounterThree": 3.0,
"energyCounterThreeType": "ENERGY_COUNTER_INPUT_SINGLE_TARIFF",
"energyCounterTwo": 0.0,
"energyCounterTwoType": "ENERGY_COUNTER_USAGE_LOW_TARIFF",
"functionalChannelType": "ENERGY_SENSORS_INTERFACE_CHANNEL",
"gasVolume": null,
"gasVolumePerImpulse": 0.01,
"groupIndex": 1,
"groups": ["00000000-0000-0000-0000-000000000051"],
"impulsesPerKWH": 10000,
"index": 1,
"label": "",
"supportedOptionalFeatures": {
"IOptionalFeatureCounterOffset": false,
"IOptionalFeatureCurrentGasFlow": false,
"IOptionalFeatureCurrentPowerConsumption": true,
"IOptionalFeatureEnergyCounterOne": true,
"IOptionalFeatureEnergyCounterThree": true,
"IOptionalFeatureEnergyCounterTwo": true,
"IOptionalFeatureGasVolume": false,
"IOptionalFeatureGasVolumePerImpulse": false,
"IOptionalFeatureImpulsesPerKWH": false
}
}
},
"homeId": "00000000-0000-0000-0000-000000000001",
"id": "3014F7110000000000ESIIEC",
"label": "esi_iec",
"lastStatusUpdate": 1702420986697,
"liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED",
"manuallyUpdateForced": false,
"manufacturerCode": 1,
"measuredAttributes": {},
"modelId": 509,
"modelType": "HmIP-ESI",
"oem": "eQ-3",
"permanentlyReachable": false,
"serializedGlobalTradeItemNumber": "3014F7110000000000ESIIEC",
"type": "ENERGY_SENSORS_INTERFACE",
"updateState": "UP_TO_DATE"
},
"3014F711000000000ESIIEC2": {
"availableFirmwareVersion": "0.0.0",
"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,
"daliBusState": null,
"defaultLinkedGroup": [],
"deviceCommunicationError": null,
"deviceDriveError": null,
"deviceDriveModeError": null,
"deviceId": "3014F711000000000ESIIEC2",
"deviceOperationMode": null,
"deviceOverheated": false,
"deviceOverloaded": false,
"devicePowerFailureDetected": false,
"deviceUndervoltage": false,
"displayContrast": null,
"dutyCycle": false,
"functionalChannelType": "DEVICE_BASE",
"groupIndex": 0,
"groups": ["00000000-0000-0000-0000-000000000031"],
"index": 0,
"label": "",
"lockJammed": null,
"lowBat": false,
"mountingOrientation": null,
"multicastRoutingEnabled": false,
"particulateMatterSensorCommunicationError": null,
"particulateMatterSensorError": null,
"powerShortCircuit": null,
"profilePeriodLimitReached": null,
"routerModuleEnabled": false,
"routerModuleSupported": false,
"rssiDeviceValue": -94,
"rssiPeerValue": null,
"sensorCommunicationError": false,
"sensorError": true,
"shortCircuitDataLine": null,
"supportedOptionalFeatures": {
"IFeatureBusConfigMismatch": false,
"IFeatureDeviceCoProError": false,
"IFeatureDeviceCoProRestart": false,
"IFeatureDeviceCoProUpdate": false,
"IFeatureDeviceCommunicationError": false,
"IFeatureDeviceDaliBusError": false,
"IFeatureDeviceDriveError": false,
"IFeatureDeviceDriveModeError": false,
"IFeatureDeviceIdentify": false,
"IFeatureDeviceOverheated": false,
"IFeatureDeviceOverloaded": false,
"IFeatureDeviceParticulateMatterSensorCommunicationError": false,
"IFeatureDeviceParticulateMatterSensorError": false,
"IFeatureDevicePowerFailure": false,
"IFeatureDeviceSensorCommunicationError": true,
"IFeatureDeviceSensorError": true,
"IFeatureDeviceTemperatureHumiditySensorCommunicationError": false,
"IFeatureDeviceTemperatureHumiditySensorError": false,
"IFeatureDeviceTemperatureOutOfRange": false,
"IFeatureDeviceUndervoltage": false,
"IFeatureMulticastRouter": false,
"IFeaturePowerShortCircuit": false,
"IFeatureProfilePeriodLimit": false,
"IFeatureRssiValue": true,
"IFeatureShortCircuitDataLine": false,
"IOptionalFeatureDefaultLinkedGroup": false,
"IOptionalFeatureDeviceErrorLockJammed": false,
"IOptionalFeatureDeviceOperationMode": false,
"IOptionalFeatureDisplayContrast": false,
"IOptionalFeatureDutyCycle": true,
"IOptionalFeatureLowBat": true,
"IOptionalFeatureMountingOrientation": false
},
"temperatureHumiditySensorCommunicationError": null,
"temperatureHumiditySensorError": null,
"temperatureOutOfRange": false,
"unreach": false
},
"1": {
"channelRole": null,
"connectedEnergySensorType": "ES_IEC",
"currentGasFlow": null,
"currentPowerConsumption": 432,
"deviceId": "3014F711000000000ESIIEC2",
"energyCounterOne": 194.0,
"energyCounterOneType": "ENERGY_COUNTER_USAGE_HIGH_TARIFF",
"energyCounterThree": 3.0,
"energyCounterThreeType": "UNKNOWN",
"energyCounterTwo": 0.0,
"energyCounterTwoType": "ENERGY_COUNTER_USAGE_LOW_TARIFF",
"functionalChannelType": "ENERGY_SENSORS_INTERFACE_CHANNEL",
"gasVolume": null,
"gasVolumePerImpulse": 0.01,
"groupIndex": 1,
"groups": ["00000000-0000-0000-0000-000000000051"],
"impulsesPerKWH": 10000,
"index": 1,
"label": "",
"supportedOptionalFeatures": {
"IOptionalFeatureCounterOffset": false,
"IOptionalFeatureCurrentGasFlow": false,
"IOptionalFeatureCurrentPowerConsumption": true,
"IOptionalFeatureEnergyCounterOne": true,
"IOptionalFeatureEnergyCounterThree": true,
"IOptionalFeatureEnergyCounterTwo": true,
"IOptionalFeatureGasVolume": false,
"IOptionalFeatureGasVolumePerImpulse": false,
"IOptionalFeatureImpulsesPerKWH": false
}
}
},
"homeId": "00000000-0000-0000-0000-000000000001",
"id": "3014F711000000000ESIIEC2",
"label": "esi_iec2",
"lastStatusUpdate": 1702420986697,
"liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED",
"manuallyUpdateForced": false,
"manufacturerCode": 1,
"measuredAttributes": {},
"modelId": 509,
"modelType": "HmIP-ESI",
"oem": "eQ-3",
"permanentlyReachable": false,
"serializedGlobalTradeItemNumber": "3014F711000000000ESIIEC2",
"type": "ENERGY_SENSORS_INTERFACE",
"updateState": "UP_TO_DATE"
} }
}, },
"groups": { "groups": {

View File

@ -26,7 +26,7 @@ async def test_hmip_load_all_supported_devices(
test_devices=None, test_groups=None test_devices=None, test_groups=None
) )
assert len(mock_hap.hmip_device_by_entity_id) == 278 assert len(mock_hap.hmip_device_by_entity_id) == 290
async def test_hmip_remove_device( async def test_hmip_remove_device(

View File

@ -511,3 +511,126 @@ async def test_hmip_passage_detector_delta_counter(
await async_manipulate_test_data(hass, hmip_device, "leftRightCounterDelta", 190) await async_manipulate_test_data(hass, hmip_device, "leftRightCounterDelta", 190)
ha_state = hass.states.get(entity_id) ha_state = hass.states.get(entity_id)
assert ha_state.state == "190" assert ha_state.state == "190"
async def test_hmip_esi_iec_current_power_consumption(
hass: HomeAssistant, default_mock_hap_factory
) -> None:
"""Test ESI-IEC currentPowerConsumption Sensor."""
entity_id = "sensor.esi_iec_currentPowerConsumption"
entity_name = "esi_iec CurrentPowerConsumption"
device_model = "HmIP-ESI"
mock_hap = await default_mock_hap_factory.async_get_mock_hap(
test_devices=["esi_iec"]
)
ha_state, hmip_device = get_and_check_entity_basics(
hass, mock_hap, entity_id, entity_name, device_model
)
assert ha_state.state == "432"
async def test_hmip_esi_iec_energy_counter_usage_high_tariff(
hass: HomeAssistant, default_mock_hap_factory
) -> None:
"""Test ESI-IEC ENERGY_COUNTER_USAGE_HIGH_TARIFF."""
entity_id = "sensor.esi_iec_energy_counter_usage_high_tariff"
entity_name = "esi_iec ENERGY_COUNTER_USAGE_HIGH_TARIFF"
device_model = "HmIP-ESI"
mock_hap = await default_mock_hap_factory.async_get_mock_hap(
test_devices=["esi_iec"]
)
ha_state, hmip_device = get_and_check_entity_basics(
hass, mock_hap, entity_id, entity_name, device_model
)
assert ha_state.state == "194.0"
async def test_hmip_esi_iec_energy_counter_usage_low_tariff(
hass: HomeAssistant, default_mock_hap_factory
) -> None:
"""Test ESI-IEC ENERGY_COUNTER_USAGE_LOW_TARIFF."""
entity_id = "sensor.esi_iec_energy_counter_usage_low_tariff"
entity_name = "esi_iec ENERGY_COUNTER_USAGE_LOW_TARIFF"
device_model = "HmIP-ESI"
mock_hap = await default_mock_hap_factory.async_get_mock_hap(
test_devices=["esi_iec"]
)
ha_state, hmip_device = get_and_check_entity_basics(
hass, mock_hap, entity_id, entity_name, device_model
)
assert ha_state.state == "0.0"
async def test_hmip_esi_iec_energy_counter_input_single_tariff(
hass: HomeAssistant, default_mock_hap_factory
) -> None:
"""Test ESI-IEC ENERGY_COUNTER_INPUT_SINGLE_TARIFF."""
entity_id = "sensor.esi_iec_energy_counter_input_single_tariff"
entity_name = "esi_iec ENERGY_COUNTER_INPUT_SINGLE_TARIFF"
device_model = "HmIP-ESI"
mock_hap = await default_mock_hap_factory.async_get_mock_hap(
test_devices=["esi_iec"]
)
ha_state, hmip_device = get_and_check_entity_basics(
hass, mock_hap, entity_id, entity_name, device_model
)
assert ha_state.state == "3.0"
async def test_hmip_esi_iec_unknown_channel(
hass: HomeAssistant, default_mock_hap_factory
) -> None:
"""Test devices are loaded partially."""
not_existing_entity_id = "sensor.esi_iec2_energy_counter_input_single_tariff"
existing_entity_id = "sensor.esi_iec2_energy_counter_usage_high_tariff"
await default_mock_hap_factory.async_get_mock_hap(test_devices=["esi_iec2"])
not_existing_ha_state = hass.states.get(not_existing_entity_id)
existing_ha_state = hass.states.get(existing_entity_id)
assert not_existing_ha_state is None
assert existing_ha_state.state == "194.0"
async def test_hmip_esi_gas_current_gas_flow(
hass: HomeAssistant, default_mock_hap_factory
) -> None:
"""Test ESI-IEC CurrentGasFlow."""
entity_id = "sensor.esi_gas_currentgasflow"
entity_name = "esi_gas CurrentGasFlow"
device_model = "HmIP-ESI"
mock_hap = await default_mock_hap_factory.async_get_mock_hap(
test_devices=["esi_gas"]
)
ha_state, hmip_device = get_and_check_entity_basics(
hass, mock_hap, entity_id, entity_name, device_model
)
assert ha_state.state == "1.03"
async def test_hmip_esi_gas_gas_volume(
hass: HomeAssistant, default_mock_hap_factory
) -> None:
"""Test ESI-IEC GasVolume."""
entity_id = "sensor.esi_gas_gasvolume"
entity_name = "esi_gas GasVolume"
device_model = "HmIP-ESI"
mock_hap = await default_mock_hap_factory.async_get_mock_hap(
test_devices=["esi_gas"]
)
ha_state, hmip_device = get_and_check_entity_basics(
hass, mock_hap, entity_id, entity_name, device_model
)
assert ha_state.state == "1019.26"