Skip to content

Commit

Permalink
Customize HmIP-DRG-DALI pt2
Browse files Browse the repository at this point in the history
  • Loading branch information
SukramJ committed Mar 21, 2024
1 parent 76bd51e commit e93713c
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 6 deletions.
1 change: 1 addition & 0 deletions hahomematic/platforms/custom/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class DeviceProfile(StrEnum):

IP_COVER = "IPCover"
IP_DIMMER = "IPDimmer"
IP_DRG_DALI = "IPDRGDALI"
IP_FIXED_COLOR_LIGHT = "IPFixedColorLight"
IP_GARAGE = "IPGarage"
IP_HDM = "IPHdm"
Expand Down
18 changes: 18 additions & 0 deletions hahomematic/platforms/custom/definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,24 @@
},
},
},
DeviceProfile.IP_DRG_DALI: {
ED.DEVICE_GROUP: {
ED.PRIMARY_CHANNEL: 1,
ED.REPEATABLE_FIELDS: {
Field.COLOR_TEMPERATURE: Parameter.COLOR_TEMPERATURE,
Field.ON_TIME_VALUE: Parameter.DURATION_VALUE,
Field.ON_TIME_UNIT: Parameter.DURATION_UNIT,
Field.EFFECT: Parameter.EFFECT,
Field.HUE: Parameter.HUE,
Field.LEVEL: Parameter.LEVEL,
Field.RAMP_TIME_TO_OFF_UNIT: Parameter.RAMP_TIME_TO_OFF_UNIT,
Field.RAMP_TIME_TO_OFF_VALUE: Parameter.RAMP_TIME_TO_OFF_VALUE,
Field.RAMP_TIME_UNIT: Parameter.RAMP_TIME_UNIT,
Field.RAMP_TIME_VALUE: Parameter.RAMP_TIME_VALUE,
Field.SATURATION: Parameter.SATURATION,
},
},
},
DeviceProfile.IP_SWITCH: {
ED.DEVICE_GROUP: {
ED.PRIMARY_CHANNEL: 1,
Expand Down
129 changes: 123 additions & 6 deletions hahomematic/platforms/custom/light.py
Original file line number Diff line number Diff line change
Expand Up @@ -506,11 +506,6 @@ def supports_hs_color(self) -> bool:
DeviceOperationMode.RGB,
)

@config_property
def supports_transition(self) -> bool:
"""Flag if light supports transition."""
return True

@config_property
def usage(self) -> EntityUsage:
"""
Expand Down Expand Up @@ -592,6 +587,113 @@ async def _set_ramp_time_off_value(
)


class CeIpDrgDaliLight(CeDimmer):
"""Class for HomematicIP HmIP-DRG-DALI light entities."""

def _init_entity_fields(self) -> None:
"""Init the entity fields."""
super()._init_entity_fields()
self._e_color_temperature_kelvin: HmInteger = self._get_entity(
field=Field.COLOR_TEMPERATURE, entity_type=HmInteger
)
self._e_on_time_unit: HmAction = self._get_entity(
field=Field.ON_TIME_UNIT, entity_type=HmAction
)
self._e_effect: HmAction = self._get_entity(field=Field.EFFECT, entity_type=HmAction)
self._e_hue: HmInteger = self._get_entity(field=Field.HUE, entity_type=HmInteger)
self._e_ramp_time_to_off_unit: HmAction = self._get_entity(
field=Field.RAMP_TIME_TO_OFF_UNIT, entity_type=HmAction
)
self._e_ramp_time_to_off_value: HmAction = self._get_entity(
field=Field.RAMP_TIME_TO_OFF_VALUE, entity_type=HmAction
)
self._e_ramp_time_unit: HmAction = self._get_entity(
field=Field.RAMP_TIME_UNIT, entity_type=HmAction
)
self._e_saturation: HmFloat = self._get_entity(field=Field.SATURATION, entity_type=HmFloat)

@value_property
def color_temp(self) -> int | None:
"""Return the color temperature in mireds of this light between min/max mireds."""
if not self._e_color_temperature_kelvin.value:
return None
return math.floor(1000000 / self._e_color_temperature_kelvin.value)

@value_property
def hs_color(self) -> tuple[float, float] | None:
"""Return the hue and saturation color value [float, float]."""
if self._e_hue.value is not None and self._e_saturation.value is not None:
return self._e_hue.value, self._e_saturation.value * 100
return None

@property
def _relevant_entities(self) -> tuple[hmge.GenericEntity, ...]:
"""Returns the list of relevant entities. To be overridden by subclasses."""
return self._e_hue, self._e_level, self._e_saturation, self._e_color_temperature_kelvin

@value_property
def effects(self) -> tuple[str, ...] | None:
"""Return the supported effects."""
return self._e_effect.values or ()

@bind_collector
async def turn_on(
self, collector: CallParameterCollector | None = None, **kwargs: Unpack[LightOnArgs]
) -> None:
"""Turn the light on."""
if not self.is_state_change(on=True, **kwargs):
return
if (hs_color := kwargs.get("hs_color")) is not None:
hue, ksaturation = hs_color
saturation = ksaturation / 100
await self._e_hue.send_value(value=int(hue), collector=collector)
await self._e_saturation.send_value(value=saturation, collector=collector)
if color_temp := kwargs.get("color_temp"):
color_temp_kelvin = math.floor(1000000 / color_temp)
await self._e_color_temperature_kelvin.send_value(
value=color_temp_kelvin, collector=collector
)
if kwargs.get("on_time") is None and kwargs.get("ramp_time"):
# 111600 is a special value for NOT_USED
await self._set_on_time_value(on_time=111600, collector=collector)
if self.supports_effects and (effect := kwargs.get("effect")) is not None:
await self._e_effect.send_value(value=effect, collector=collector)

await super().turn_on(collector=collector, **kwargs)

@bind_collector
async def _set_on_time_value(
self, on_time: float, collector: CallParameterCollector | None = None
) -> None:
"""Set the on time value in seconds."""
on_time, on_time_unit = _recalc_unit_timer(time=on_time)
if on_time_unit:
await self._e_on_time_unit.send_value(value=on_time_unit, collector=collector)
await self._e_on_time_value.send_value(value=float(on_time), collector=collector)

async def _set_ramp_time_on_value(
self, ramp_time: float, collector: CallParameterCollector | None = None
) -> None:
"""Set the ramp time value in seconds."""
ramp_time, ramp_time_unit = _recalc_unit_timer(time=ramp_time)
if ramp_time_unit:
await self._e_ramp_time_unit.send_value(value=ramp_time_unit, collector=collector)
await self._e_ramp_time_value.send_value(value=float(ramp_time), collector=collector)

async def _set_ramp_time_off_value(
self, ramp_time: float, collector: CallParameterCollector | None = None
) -> None:
"""Set the ramp time value in seconds."""
ramp_time, ramp_time_unit = _recalc_unit_timer(time=ramp_time)
if ramp_time_unit:
await self._e_ramp_time_to_off_unit.send_value(
value=ramp_time_unit, collector=collector
)
await self._e_ramp_time_to_off_value.send_value(
value=float(ramp_time), collector=collector
)


class CeIpFixedColorLight(CeDimmer):
"""Class for HomematicIP HmIP-BSL light entities."""

Expand Down Expand Up @@ -907,6 +1009,21 @@ def make_ip_rgbw_light(
)


def make_ip_drg_dali_light(
device: hmd.HmDevice,
group_base_channels: tuple[int, ...],
extended: ExtendedConfig | None = None,
) -> tuple[CustomEntity, ...]:
"""Create color light entities like HmIP-DRG-DALI."""
return hmed.make_custom_entity(
device=device,
entity_class=CeIpDrgDaliLight,
device_profile=DeviceProfile.IP_DRG_DALI,
group_base_channels=group_base_channels,
extended=extended,
)


# Case for device model is not relevant.
# HomeBrew (HB-) devices are always listed as HM-.
DEVICES: Mapping[str, CustomConfig | tuple[CustomConfig, ...]] = {
Expand Down Expand Up @@ -1014,7 +1131,7 @@ def make_ip_rgbw_light(
"HMW-LC-Dim1L-DR": CustomConfig(make_ce_func=make_rf_dimmer, channels=(3,)),
"HSS-DX": CustomConfig(make_ce_func=make_rf_dimmer, channels=(1,)),
"HmIP-DRG-DALI": CustomConfig(
make_ce_func=make_ip_rgbw_light, channels=tuple(range(1, 49, 1))
make_ce_func=make_ip_drg_dali_light, channels=tuple(range(1, 49, 1))
),
"HmIP-BDT": CustomConfig(make_ce_func=make_ip_dimmer, channels=(3,)),
"HmIP-BSL": CustomConfig(make_ce_func=make_ip_fixed_color_light, channels=(7, 11)),
Expand Down

0 comments on commit e93713c

Please sign in to comment.