From bd407872b0ee03432b75652690382ddcc9fe432b Mon Sep 17 00:00:00 2001 From: TheJulianJES Date: Wed, 25 Mar 2026 07:10:00 +0100 Subject: [PATCH] Bump ZHA to 1.1.0 (#166438) --- homeassistant/components/zha/manifest.json | 2 +- homeassistant/components/zha/strings.json | 135 +++++++++++++++++++++ requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/zha/test_update.py | 18 +++ 5 files changed, 156 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/zha/manifest.json b/homeassistant/components/zha/manifest.json index 0e67aab7f10..31f0d0d9e83 100644 --- a/homeassistant/components/zha/manifest.json +++ b/homeassistant/components/zha/manifest.json @@ -23,7 +23,7 @@ "universal_silabs_flasher", "serialx" ], - "requirements": ["zha==1.0.2", "serialx==0.6.2"], + "requirements": ["zha==1.1.0", "serialx==0.6.2"], "usb": [ { "description": "*2652*", diff --git a/homeassistant/components/zha/strings.json b/homeassistant/components/zha/strings.json index 12391d01bb6..cc1816bf480 100644 --- a/homeassistant/components/zha/strings.json +++ b/homeassistant/components/zha/strings.json @@ -294,30 +294,51 @@ "ias_zone": { "name": "IAS zone" }, + "interconnectable": { + "name": "Interconnectable" + }, "led_indicator": { "name": "LED indicator" }, + "lifecycle": { + "name": "Lifecycle" + }, "linkage_alarm_state": { "name": "Linkage alarm state" }, "mounting_mode_active": { "name": "Mounting mode active" }, + "muted": { + "name": "Muted" + }, "open_window_detection_status": { "name": "Open window detection status" }, + "preheat": { + "name": "Preheat" + }, "preheat_active": { "name": "Preheat active" }, "preheat_status": { "name": "Pre-heat status" }, + "rain_detected": { + "name": "Rain detected" + }, "replace_filter": { "name": "Replace filter" }, + "self_test_state": { + "name": "Self-test" + }, "silence_alarm": { "name": "Silence alarm" }, + "test": { + "name": "Test" + }, "valve_alarm": { "name": "Valve alarm" }, @@ -335,15 +356,27 @@ } }, "button": { + "allow_remote_binding": { + "name": "Allow remote binding" + }, "boost_mode": { "name": "Boost mode" }, + "calibrate_sensor": { + "name": "Calibrate sensor" + }, + "calibrate_tvoc_sensor": { + "name": "Calibrate TVOC sensor" + }, "calibrate_valve": { "name": "Calibrate valve" }, "calibrate_z_axis": { "name": "Calibrate Z axis" }, + "configure_limits": { + "name": "Configure cover limits" + }, "delete_all_limits": { "name": "Delete all limits" }, @@ -368,6 +401,9 @@ "prepare_manual_calibration": { "name": "Prepare manual calibration" }, + "remote_test": { + "name": "Remote test" + }, "reset_alarm": { "name": "Reset alarm" }, @@ -461,6 +497,9 @@ "additional_steps": { "name": "Additional steps" }, + "air_threshold": { + "name": "Air threshold" + }, "alarm_duration": { "name": "Alarm duration" }, @@ -677,6 +716,9 @@ "installation_height": { "name": "Height from sensor to tank bottom" }, + "integral_factor": { + "name": "Integral factor" + }, "interval_time": { "name": "Interval time" }, @@ -707,6 +749,9 @@ "led_intensity_when_on": { "name": "Default all LED on intensity" }, + "length": { + "name": "Length" + }, "lift_drive_down_time": { "name": "Lift drive down time" }, @@ -869,9 +914,18 @@ "presence_sensitivity": { "name": "Presence sensitivity" }, + "presence_sensor_sensitivity": { + "name": "Presence sensor sensitivity" + }, "presence_timeout": { "name": "Fade time" }, + "proportional_gain": { + "name": "Proportional gain (Kp)" + }, + "proportional_shift": { + "name": "Proportional shift (N)" + }, "pulse_configuration": { "name": "Pulse configuration" }, @@ -911,6 +965,9 @@ "sensitivity_level": { "name": "Sensitivity level" }, + "sensor_sensitivity": { + "name": "Sensor sensitivity" + }, "serving_size": { "name": "Serving to dispense" }, @@ -938,6 +995,9 @@ "sound_volume": { "name": "Sound volume" }, + "speed": { + "name": "Speed" + }, "start_up_color_temperature": { "name": "Start-up color temperature" }, @@ -956,6 +1016,9 @@ "static_detection_sensitivity": { "name": "Static detection sensitivity" }, + "summer_backup_heating_demand": { + "name": "Summer backup heating demand" + }, "sustain_time": { "name": "Sustain time" }, @@ -998,6 +1061,9 @@ "timer_time_left": { "name": "Timer time left" }, + "total_cycle_times": { + "name": "Total cycle times" + }, "transmit_power": { "name": "Transmit power" }, @@ -1060,6 +1126,9 @@ }, "water_interval": { "name": "Water interval" + }, + "winter_backup_heating_demand": { + "name": "Winter backup heating demand" } }, "select": { @@ -1087,6 +1156,15 @@ "approach_distance": { "name": "Approach distance" }, + "audio": { + "name": "Audio" + }, + "audio_effect": { + "name": "Audio effect" + }, + "audio_sensitivity": { + "name": "Audio sensitivity" + }, "backlight_mode": { "name": "Backlight mode" }, @@ -1105,6 +1183,9 @@ "click_mode": { "name": "Click mode" }, + "color_temperature_channel": { + "name": "Color temperature channel" + }, "control_type": { "name": "Control type" }, @@ -1126,6 +1207,9 @@ "default_strobe_level": { "name": "Default strobe level" }, + "detach_relay": { + "name": "Detach relay" + }, "detection_distance": { "name": "Detection distance" }, @@ -1401,6 +1485,12 @@ "brightness_level": { "name": "Brightness level" }, + "calibrated": { + "name": "Calibrated" + }, + "chamber_contamination": { + "name": "Chamber contamination" + }, "control_status": { "name": "Control status" }, @@ -1464,6 +1554,9 @@ "formaldehyde": { "name": "Formaldehyde concentration" }, + "gust_speed": { + "name": "Gust speed" + }, "heating_demand": { "name": "Heating demand" }, @@ -1532,6 +1625,9 @@ "last_pin_code": { "name": "Last PIN code" }, + "last_remaining_battery_percentage": { + "name": "Last remaining battery percentage" + }, "last_valve_open_duration": { "name": "Last valve open duration" }, @@ -1544,6 +1640,9 @@ "lifetime": { "name": "Lifetime" }, + "light_level": { + "name": "Light level" + }, "liquid_depth": { "name": "Liquid depth" }, @@ -1607,9 +1706,18 @@ "preheat_time": { "name": "Pre-heat time" }, + "rebooted_count": { + "name": "Rebooted count" + }, + "rejoined_count": { + "name": "Rejoined count" + }, "remaining_watering_time": { "name": "Remaining watering time" }, + "reported_packages": { + "name": "Reported packages" + }, "rms_current_ph_b": { "name": "Current phase B" }, @@ -1646,6 +1754,9 @@ "smoke_density": { "name": "Smoke density" }, + "smoke_level": { + "name": "Smoke level" + }, "software_error": { "name": "Software error", "state": { @@ -1742,6 +1853,12 @@ "total_power_factor": { "name": "Total power factor" }, + "total_volatile_organic_compounds": { + "name": "Total volatile organic compounds" + }, + "uv_index": { + "name": "UV index" + }, "valve_adapt_status": { "name": "Valve adaptation status" }, @@ -1771,6 +1888,9 @@ }, "window_covering_type": { "name": "Window covering type" + }, + "work_mode": { + "name": "Work mode" } }, "switch": { @@ -1780,6 +1900,9 @@ "adaptive_mode": { "name": "Adaptive mode" }, + "alarm_switch": { + "name": "Alarm switch" + }, "auto_clean": { "name": "Autoclean" }, @@ -1810,6 +1933,9 @@ "detach_relay": { "name": "Detach relay" }, + "detach_relay_id": { + "name": "Detach relay {id}" + }, "detached": { "name": "Detached mode" }, @@ -1822,6 +1948,9 @@ "disable_clear_notifications_double_tap": { "name": "Disable config 2x tap to clear notifications" }, + "disable_double_click": { + "name": "Disable double click" + }, "disable_led": { "name": "Disable LED" }, @@ -1921,6 +2050,9 @@ "mute_siren": { "name": "Mute siren" }, + "network_led": { + "name": "Network LED" + }, "on_only_when_dark": { "name": "On only when dark" }, @@ -1972,6 +2104,9 @@ "sound_enabled": { "name": "Sound enabled" }, + "summer_mode": { + "name": "Summer mode" + }, "switch": { "name": "[%key:component::switch::title%]" }, diff --git a/requirements_all.txt b/requirements_all.txt index d86a5100604..c7c1519a8f3 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -3389,7 +3389,7 @@ zeroconf==0.148.0 zeversolar==0.3.2 # homeassistant.components.zha -zha==1.0.2 +zha==1.1.0 # homeassistant.components.zhong_hong zhong-hong-hvac==1.0.13 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 39eaa188667..defe00827ca 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -2865,7 +2865,7 @@ zeroconf==0.148.0 zeversolar==0.3.2 # homeassistant.components.zha -zha==1.0.2 +zha==1.1.0 # homeassistant.components.zinvolt zinvolt==0.3.0 diff --git a/tests/components/zha/test_update.py b/tests/components/zha/test_update.py index 58d1c8d8779..f5e30e84072 100644 --- a/tests/components/zha/test_update.py +++ b/tests/components/zha/test_update.py @@ -375,10 +375,17 @@ async def test_firmware_update_success( attrs[ATTR_LATEST_VERSION] == f"0x{fw_image.firmware.header.file_version:08x}" ) + ota_completed = False + async def endpoint_reply(cluster, sequence, data, **kwargs): + nonlocal ota_completed if cluster == general.Ota.cluster_id: _hdr, cmd = ota_cluster.deserialize(data) if isinstance(cmd, general.Ota.ImageNotifyCommand): + if ota_completed: + # Post-OTA image_notify: ignore or don't respond + return + zha_device.device.device.packet_received( make_packet( zha_device.device.device, @@ -394,6 +401,12 @@ async def test_firmware_update_success( elif isinstance( cmd, general.Ota.ClientCommandDefs.query_next_image_response.schema ): + # After a successful OTA, zigpy sends a post-OTA image_notify + # which triggers a query_next_image -> NO_IMAGE_AVAILABLE exchange + if cmd.status == foundation.Status.NO_IMAGE_AVAILABLE: + assert ota_completed + return + assert cmd.status == foundation.Status.SUCCESS assert cmd.manufacturer_code == fw_image.firmware.header.manufacturer_id assert cmd.image_type == fw_image.firmware.header.image_type @@ -486,6 +499,8 @@ async def test_firmware_update_success( assert cmd.current_time == 0 assert cmd.upgrade_time == 0 + ota_completed = True + def read_new_fw_version(*args, **kwargs): ota_cluster.update_attribute( attrid=general.Ota.AttributeDefs.current_file_version.id, @@ -590,6 +605,9 @@ async def test_firmware_update_raises( elif isinstance( cmd, general.Ota.ClientCommandDefs.query_next_image_response.schema ): + if cmd.status == foundation.Status.NO_IMAGE_AVAILABLE: + return + assert cmd.status == foundation.Status.SUCCESS assert cmd.manufacturer_code == fw_image.firmware.header.manufacturer_id assert cmd.image_type == fw_image.firmware.header.image_type