Fix lumi.gateway.mitw01 gateway mappings - #2871
Conversation
Add local miio2miot mappings for the Taiwan Mi Control Hub light, illumination, guard/alarm, volume, doorbell, and night-light properties. Support raw dict miio params so set_device_prop can update alarm_time_len and en_alarm_light.
There was a problem hiding this comment.
Code Review
This pull request adds support for the Taiwan Mi Control Hub (lumi.gateway.mitw01) by extending the MIOT specifications and mapping its properties. It also introduces a raw_params flag to handle raw parameter payloads and updates set_callback_via_param_index to support dictionary parameters. The feedback suggests adding a defensive type check in set_callback_via_param_index to ensure params is a list or tuple before checking its length, preventing potential TypeError crashes when raw_params is used.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| elif len(params) > index: | ||
| value = params[index] | ||
| if key and isinstance(value, dict): | ||
| value = value.get(key) | ||
| props[prop] = value |
There was a problem hiding this comment.
If raw_params is enabled, params can potentially be None or a non-sequence type (e.g., if the template returns null for the params key). In such cases, calling len(params) will raise a TypeError: object of type 'NoneType' has no len(). Defensively checking if params is an instance of list or tuple before checking its length prevents potential runtime crashes.
| elif len(params) > index: | |
| value = params[index] | |
| if key and isinstance(value, dict): | |
| value = value.get(key) | |
| props[prop] = value | |
| elif isinstance(params, (list, tuple)) and len(params) > index: | |
| value = params[index] | |
| if key and isinstance(value, dict): | |
| value = value.get(key) | |
| props[prop] = value |
There was a problem hiding this comment.
Thanks, fixed in bc64930 by checking for list/tuple before len(params).
Defensively handle non-sequence params in set_callback_via_param_index when raw_params templates are used.
Summary
lumi.gateway.mitw01(Taiwan Mi Control Hub) miio2miot mappings for light on/off, brightness, color, illumination, guard/alarm, volume, doorbell, and night-light properties.set_templateoutput to opt into raw dict params so legacyset_device_propcalls can send{ "sid": "lumi.0", ... }without being wrapped in a list.Testing
python3 -m py_compile custom_components/xiaomi_miot/core/miio2miot.py custom_components/xiaomi_miot/core/miio2miot_specs.pycustom_components/xiaomi_miot/core/miot_specs_extend.jsonand assertedlumi.gateway.mitw01contains light, illumination, and legacy gateway services.miio2miot_specs.pydirectly and smoke-tested the newset_callback_via_param_index(..., key=...)path with raw dict params.lumi.gateway.mitw01hub:en_alarm_lightchanged via Home Assistantnumber.set_value, direct localget_device_propread back the changed value, then restored;alarm_time_lenwas tested the same way and restored.Notes
For this gateway,
alarm_time_lenanden_alarm_lightare legacy miio device props. The working write form is:{"method": "set_device_prop", "params": {"sid": "lumi.0", "alarm_time_len": 30}}Wrapping that dict in a list returns a params error, so this PR adds
raw_paramssupport for these mappings.