Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions zha/application/platforms/number/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,16 @@ class SonoffPresenceSenorTimeout(NumberConfigurationEntity):
models=frozenset({"SNZB-06P", "SNZB-03P"}),
)

_server_cluster_config = {
OccupancySensing.cluster_id: ClusterConfig(
attributes={
OccupancySensing.AttributeDefs.ultrasonic_o_to_u_delay: AttrConfig(
read_on_startup=False,
),
},
),
}


@register_entity(TUYA_MANUFACTURER_CLUSTER)
class TimerDurationMinutes(NumberConfigurationEntity):
Expand Down Expand Up @@ -1542,6 +1552,12 @@ class DanfossExerciseTriggerTime(NumberConfigurationEntity):
exposed_features=frozenset({DANFOSS_ALLY_THERMOSTAT}),
)

_server_cluster_config = {
Thermostat.cluster_id: ClusterConfig(
attributes={"exercise_trigger_time": AttrConfig(read_on_startup=False)},
),
}


@register_entity(Thermostat.cluster_id)
class DanfossExternalMeasuredRoomSensor(ZCLTemperatureEntity):
Expand All @@ -1559,6 +1575,14 @@ class DanfossExternalMeasuredRoomSensor(ZCLTemperatureEntity):
exposed_features=frozenset({DANFOSS_ALLY_THERMOSTAT}),
)

_server_cluster_config = {
Thermostat.cluster_id: ClusterConfig(
attributes={
"external_measured_room_sensor": AttrConfig(read_on_startup=True)
},
),
}


@register_entity(Thermostat.cluster_id)
class DanfossLoadRoomMean(NumberConfigurationEntity):
Expand All @@ -1577,6 +1601,12 @@ class DanfossLoadRoomMean(NumberConfigurationEntity):
exposed_features=frozenset({DANFOSS_ALLY_THERMOSTAT}),
)

_server_cluster_config = {
Thermostat.cluster_id: ClusterConfig(
attributes={"load_room_mean": AttrConfig(read_on_startup=True)},
),
}


@register_entity(Thermostat.cluster_id)
class DanfossRegulationSetpointOffset(NumberConfigurationEntity):
Expand All @@ -1598,6 +1628,14 @@ class DanfossRegulationSetpointOffset(NumberConfigurationEntity):
exposed_features=frozenset({DANFOSS_ALLY_THERMOSTAT}),
)

_server_cluster_config = {
Thermostat.cluster_id: ClusterConfig(
attributes={
"regulation_setpoint_offset": AttrConfig(read_on_startup=False)
},
),
}


@register_entity(SINOPE_MANUFACTURER_CLUSTER)
class SinopeDimmerOnLevelConfigurationEntity(NumberConfigurationEntity):
Expand Down
40 changes: 40 additions & 0 deletions zha/application/platforms/select.py
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,7 @@ class HueV1MotionSensitivity(ZCLEnumSelectEntity):
OccupancySensing.AttributeDefs.pir_u_to_o_delay: AttrConfig(
read_on_startup=False,
),
Comment on lines 539 to 544

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh, I'm not sure how these attributes ended up in the cluster config of this Hue-specific select entity? These are used by a number entity. (Side note: Why does that number entity also include the occupancy attribute for the binary sensor again?)

I'll check to see if other unintentional changes were introduced by that refactor and then remove these in a follow-up PR (to keep this PR as just the fix).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And the binary sensor also re-adds all the same attributes yet again? Why do all three platforms configure the exact same attributes in the cluster config? We merge these, right..?

OccupancySensing.AttributeDefs.occupancy: AttrConfig(
read_on_startup=True,
reporting=ReportingConfig(
min_interval=0, max_interval=900, reportable_change=1
),
),
OccupancySensing.AttributeDefs.pir_o_to_u_delay: AttrConfig(
read_on_startup=False,
),
OccupancySensing.AttributeDefs.pir_u_to_o_delay: AttrConfig(
read_on_startup=False,
),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a wholesale copy of the old OccupancySensingClusterHandler config: #657 translated each pre-refactor cluster handler by copying its full REPORT_CONFIG/ZCL_INIT_ATTRS block onto every entity class that used that handler — the Occupancy binary sensor, the PIR occupied→unoccupied delay number entity, and this Hue select all got the identical occupancy + pir_*_delay block. The handler's dynamic __init__ additions (Hue sensitivity, Sonoff ultrasonic_*) were dropped in that translation, which is exactly the regression this PR fixes.

And yes, they merge: aggregate_cluster_configs() merges all discovered entities' configs per (endpoint, cluster, direction)read_on_startup is OR-ed, the tightest reporting wins, bind is OR-ed — so the duplicates are runtime-harmless, but they hide gaps like this one. Two more side effects of the same copy-paste, for the follow-up:

  • PIRUnoccupiedToOccupiedDelayConfigurationEntity has no cluster config of its own and only works because its sibling's copy happens to include pir_u_to_o_delay.
  • ThermostatLocalTempCalibration (+ Sonoff/Bosch subclasses) and DanfossExerciseDayOfTheWeek carry the entire 22-attribute thermostat handler block (including setpoint_change_source*), and StartupOnOffSelectEntity / OnOffTransitionTimeConfigurationEntity / BegaColorTemperatureChannelSelect carry the OnOff/LevelControl state blocks.

On the entity count: before this PR exactly 12 entity classes are broken on fresh pairing — per device that's 2 missing entities on SNZB-06P/SNZB-03P, 1 on each Hue SML001–SML004, and 8 on a Danfoss Ally. After this PR the only cache-gated entities without a ZHA-side read are the two Tuya 0xEF00 ones, which are quirk-seeded by design. (Full audit in my review.)

I've pushed the dedup as a follow-up basis on top of this branch: zigpy-bot/cluster-config-dedup — 5 commits (OccupancySensing / Thermostat / LevelControl / OnOff dedup, each entity now only declaring the attributes it owns, verified by diffing the aggregated per-(cluster, attribute) config view before/after — byte-identical — plus a full test run; and one restore commit for two more #657 losses: Philips SOC001 0xFC06 bind+reporting and the Legrand cable outlet 0xFC40 bind, details in the follow-up comment). Happy to open it as a PR once this one lands.

"sensitivity": AttrConfig(read_on_startup=False),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, planned to do basically.

},
),
}
Expand Down Expand Up @@ -573,6 +574,14 @@ class HueV2MotionSensitivity(ZCLEnumSelectEntity):
models=frozenset({"SML002", "SML003", "SML004"}),
)

_server_cluster_config = {
OccupancySensing.cluster_id: ClusterConfig(
attributes={
"sensitivity": AttrConfig(read_on_startup=False),
},
),
}


class AqaraMonitoringModess(types.enum8):
"""Aqara monitoring modes."""
Expand Down Expand Up @@ -940,6 +949,16 @@ class SonoffPresenceDetectionSensitivity(ZCLEnumSelectEntity):
models=frozenset({"SNZB-06P", "SNZB-03P"}),
)

_server_cluster_config = {
OccupancySensing.cluster_id: ClusterConfig(
attributes={
OccupancySensing.AttributeDefs.ultrasonic_u_to_o_threshold: AttrConfig(
read_on_startup=False,
),
},
),
}


class KeypadLockoutEnum(types.enum8):
"""Keypad lockout options."""
Expand Down Expand Up @@ -1102,6 +1121,7 @@ class DanfossExerciseDayOfTheWeek(ZCLEnumSelectEntity):
Thermostat.AttributeDefs.setpoint_change_source_timestamp: AttrConfig(
read_on_startup=False,
),
"exercise_day_of_week": AttrConfig(read_on_startup=False),
},
),
}
Expand Down Expand Up @@ -1133,6 +1153,12 @@ class DanfossOrientation(ZCLEnumSelectEntity):
exposed_features=frozenset({DANFOSS_ALLY_THERMOSTAT}),
)

_server_cluster_config = {
Thermostat.cluster_id: ClusterConfig(
attributes={"orientation": AttrConfig(read_on_startup=False)},
),
}


@register_entity(Thermostat.cluster_id)
class DanfossAdaptationRunControl(ZCLEnumSelectEntity):
Expand All @@ -1149,6 +1175,12 @@ class DanfossAdaptationRunControl(ZCLEnumSelectEntity):
exposed_features=frozenset({DANFOSS_ALLY_THERMOSTAT}),
)

_server_cluster_config = {
Thermostat.cluster_id: ClusterConfig(
attributes={"adaptation_run_control": AttrConfig(read_on_startup=False)},
),
}


class DanfossControlAlgorithmScaleFactorEnum(types.enum8):
"""The time scale factor for changing the opening of the valve.
Expand Down Expand Up @@ -1190,6 +1222,14 @@ class DanfossControlAlgorithmScaleFactor(ZCLEnumSelectEntity):
exposed_features=frozenset({DANFOSS_ALLY_THERMOSTAT}),
)

_server_cluster_config = {
Thermostat.cluster_id: ClusterConfig(
attributes={
"control_algorithm_scale_factor": AttrConfig(read_on_startup=False)
},
),
}


@register_entity(UserInterface.cluster_id)
class DanfossViewingDirection(ZCLEnumSelectEntity):
Expand Down
Loading