Hi. I'm new to Home Assistant and currently facing the issue described as title. Below is the analysis process provided by AI and I was persuaded to post an issue for this. I read the issue pulled last year and saw the major contributor didn't have the bandwidth for supporting new devices. So I'm considering pulling a merge request for this with the help of AI.
However, I'm completely new to Home Assistant while with a little experience for Python coding and device communicating. Maybe you can first help me judge if the analysis listed below is correct. Thanks!
Problem
Hualing (logo as WAHIN) (华凌)
(2HP wall-mounted AC, a Midea sub-brand) can be discovered and authenticated, and state queries work correctly, but all control/write commands are silently ignored by the device — HA UI controls have no effect, and the device state never changes.
The same issue affects both midea_ac_lan (midea-local) and midea_ac (msmart-ng).
Environment
| Item |
Value |
| Device model |
Hualing 华凌 KFR-50G/N8HA1lII (超省电 2P) |
| Device IP / Port |
192.168.5.208:6444 |
| Device ID |
212305748114131 |
| Device type |
172 (0xAC) |
| Library |
msmart-ng 2026.7.0 (also reproduced on 2026.8.0) |
| Home Assistant |
2026.2.1 (HAOS) |
| Integration |
midea_ac 2026.7.2 |
Steps to Reproduce
- Add the device via
midea_ac integration (discovery + authentication succeed)
- Observe that state polling works — temperature, mode, fan speed are read correctly
- Attempt any control action via HA (power toggle, mode change, temperature set)
- Control times out; device state never changes
Expected Behavior
Control commands (SetState / frame_type=0x02) should be acknowledged by the device and the state should update.
Actual Behavior
| Command |
Hex (truncated) |
Result |
| State query |
aa21ac... (frame_type=0x03) |
OK — ~1s response |
| Capability query |
aa0fac...b50100... (frame_type=0x03) |
TIMEOUT — no response |
| Control / SetState |
aa24ac...4043... (frame_type=0x02) |
TIMEOUT — no response |
Full log snippet:
# Capability query — device never responds
DEBUG [msmart.base_device] Sending command to 192.168.5.208:6444: aa0fac00000000000003b5010001e5a6
DEBUG [msmart.lan] Read timeout. Resending to 192.168.5.208:6444. (retry 1)
DEBUG [msmart.lan] Read timeout. Resending to 192.168.5.208:6444. (retry 2)
WARNING [msmart.base_device] Network timeout 192.168.5.208:6444: No response from host.
ERROR [msmart.device.AC.device] Failed to query capabilities from device 212305748114131.
# State query — works fine
DEBUG [msmart.base_device] Sending command to 192.168.5.208:6444: aa21ac00000000000003418100ff03ff000200000000000000000000000003028bdb
DEBUG [msmart.base_device] Response from 192.168.5.208:6444 in 1.090000 seconds.
DEBUG [msmart.device.AC.device] State response payload from device 212305748114131: c000aa507f7f...
# Control command — device never responds
WARNING [msmart.device.AC.device] Device is not capable of aux mode <AuxHeatMode.AUX_HEAT: 1>.
DEBUG [msmart.base_device] Sending command to 192.168.5.208:6444: aa24ac000000000000024043aa507f7f00300008000000000000000000000000000003adcb
DEBUG [msmart.lan] Read timeout. Resending ... (retry 1)
DEBUG [msmart.lan] Read timeout. Resending ... (retry 2)
WARNING [msmart.base_device] Network timeout ... No response from host.
Root Cause Analysis (Code-Level)
1. The device silently drops all CONTROL frames (frame_type=0x02)
The most definitive test: I took a successful state response frame (aa2aac, frame_type=0x03), changed only byte 9 from 0x03 (QUERY) to 0x02 (CONTROL) and byte 10 from 0xC0 (response) to 0x40 (command), and sent it back. The device did not respond.
→ The issue is not about payload content. The device simply does not recognize frame_type=0x02 frames at all.
| Experiment |
Description |
Result |
| Standard SetState |
aa24ac...4043... (CONTROL, code-generated payload) |
TIMEOUT |
| Mirrored state as control |
Take state response, flip frame_type 0x03→0x02, resend |
TIMEOUT |
| Control with protocol_version=1 |
Same payload, header byte 8 set to 1 |
TIMEOUT |
| Control with device_type=0xA0 |
Same payload, header byte 2 set to 0xA0 |
TIMEOUT |
All four variants failed identically — the device is rejecting the frame type, not the content.
2. Capability query is also silently ignored
GetCapabilitiesCommand sends aa0fac...b50100... (frame_type=0x03). This also times out. Capabilities fall back to defaults in device.py:272, so the control payload is built with guessed parameters rather than the device's actual capabilities.
3. Device actually DOES send capability data — but with non-standard frame_type
The device sends unsolicited b5 capability responses spontaneously, but the library drops them because they use non-standard frame_type values (0x04 and 0x05) instead of the expected 0x03 (QUERY).
From the log, three b5 responses were received and discarded:
Received response: aa59ac0000000000 [08 05] b5 01 7e... → frame_type=0x05, dropped
Received response: aa78ac0000000000 [08 05] b5 03 e0... → frame_type=0x05, dropped
Received response: aa97ac0000000000 [08 04] b5 01 f0... → frame_type=0x04, dropped
The rejection happens in command.py:503:
# Only matches if frame_type == FrameType.QUERY (0x03)
elif response_id == ResponseId.CAPABILITIES and frame_type == FrameType.QUERY:
response_class = CapabilitiesResponse
Since frame_type is 0x04 or 0x05 (not 0x03), the condition fails, and the response falls through to the generic Response handler → device.py:464 logs Ignored unknown response.
Key Source Locations
| File |
Line(s) |
Issue |
msmart/device/AC/command.py |
503 |
Capability response only matches frame_type=QUERY; should also accept 0x04/0x05 |
msmart/device/AC/command.py |
270-379 |
SetStateCommand generates payload based on default capabilities when get_capabilities() fails |
msmart/device/AC/device.py |
665-703 |
get_capabilities() calls GetCapabilitiesCommand which times out; no fallback to parsing spontaneous b5 data |
msmart/device/AC/device.py |
463-465 |
Unsolicited b5 data from non-standard frame types is silently discarded |
msmart/device/AC/device.py |
787-862 |
apply() uses capabilities that were never properly obtained from this model |
Suggested Fix Paths
Short-term (low-hanging fruit)
-
Relax frame_type check in command.py:503 to also accept frame_type values 0x04 and 0x05 for CapabilitiesResponse. This would at least allow the library to parse the b5 data the device is already sending, providing accurate capabilities for control command construction.
-
Catch and parse spontaneous b5 responses in _update_state() (device.py:463) when they arrive outside of an explicit capability query.
Long-term
- The core issue of
frame_type=0x02 being rejected likely means this model uses a different protocol for writes. Possible avenues:
- Investigate whether writes must use
frame_type=0x04 or 0x05 (the types the device uses for spontaneous data)
- Capture LAN packets from the official Midea/Meiju (美的美居) app while sending a control command, and compare the frame format with msmart-ng's
SetStateCommand output
- Check if the
msmart-ng download command can fetch a protocol plugin from the cloud that contains the correct command format for this model
Additional Context
- The affected model is a newer Hualing unit (2024 model year), which may use an updated firmware protocol compared to older Midea AC units that
msmart-ng was originally developed for.
- Two other Midea AC units (美的静新风 1.5P ×2) on the same network work perfectly with the same integration — confirming the issue is model-specific.
- The same problem exists with
midea_ac_lan (using midea-local library), suggesting the protocol difference is at the frame/transport layer, not the integration layer.
Attachments
home-assistant_2026-08-06T06-20-37.105Z.log
config_entry-midea_ac-01KZASJENGMFDJKGRDNQYMDRDH.json
Hi. I'm new to Home Assistant and currently facing the issue described as title. Below is the analysis process provided by AI and I was persuaded to post an issue for this. I read the issue pulled last year and saw the major contributor didn't have the bandwidth for supporting new devices. So I'm considering pulling a merge request for this with the help of AI.
However, I'm completely new to Home Assistant while with a little experience for Python coding and device communicating. Maybe you can first help me judge if the analysis listed below is correct. Thanks!
Problem
Hualing (logo as WAHIN) (华凌)
(2HP wall-mounted AC, a Midea sub-brand) can be discovered and authenticated, and state queries work correctly, but all control/write commands are silently ignored by the device — HA UI controls have no effect, and the device state never changes.
The same issue affects both
midea_ac_lan(midea-local) andmidea_ac(msmart-ng).Environment
Steps to Reproduce
midea_acintegration (discovery + authentication succeed)Expected Behavior
Control commands (SetState /
frame_type=0x02) should be acknowledged by the device and the state should update.Actual Behavior
aa21ac...(frame_type=0x03)aa0fac...b50100...(frame_type=0x03)aa24ac...4043...(frame_type=0x02)Full log snippet:
Root Cause Analysis (Code-Level)
1. The device silently drops all CONTROL frames (frame_type=0x02)
The most definitive test: I took a successful state response frame (
aa2aac, frame_type=0x03), changed only byte 9 from0x03(QUERY) to0x02(CONTROL) and byte 10 from0xC0(response) to0x40(command), and sent it back. The device did not respond.→ The issue is not about payload content. The device simply does not recognize
frame_type=0x02frames at all.aa24ac...4043...(CONTROL, code-generated payload)All four variants failed identically — the device is rejecting the frame type, not the content.
2. Capability query is also silently ignored
GetCapabilitiesCommandsendsaa0fac...b50100...(frame_type=0x03). This also times out. Capabilities fall back to defaults indevice.py:272, so the control payload is built with guessed parameters rather than the device's actual capabilities.3. Device actually DOES send capability data — but with non-standard frame_type
The device sends unsolicited
b5capability responses spontaneously, but the library drops them because they use non-standardframe_typevalues (0x04and0x05) instead of the expected0x03(QUERY).From the log, three
b5responses were received and discarded:The rejection happens in
command.py:503:Since
frame_typeis0x04or0x05(not0x03), the condition fails, and the response falls through to the genericResponsehandler →device.py:464logsIgnored unknown response.Key Source Locations
msmart/device/AC/command.pyframe_type=QUERY; should also accept0x04/0x05msmart/device/AC/command.pySetStateCommandgenerates payload based on default capabilities whenget_capabilities()failsmsmart/device/AC/device.pyget_capabilities()callsGetCapabilitiesCommandwhich times out; no fallback to parsing spontaneousb5datamsmart/device/AC/device.pyb5data from non-standard frame types is silently discardedmsmart/device/AC/device.pyapply()uses capabilities that were never properly obtained from this modelSuggested Fix Paths
Short-term (low-hanging fruit)
Relax
frame_typecheck incommand.py:503to also acceptframe_typevalues0x04and0x05forCapabilitiesResponse. This would at least allow the library to parse theb5data the device is already sending, providing accurate capabilities for control command construction.Catch and parse spontaneous
b5responses in_update_state()(device.py:463) when they arrive outside of an explicit capability query.Long-term
frame_type=0x02being rejected likely means this model uses a different protocol for writes. Possible avenues:frame_type=0x04or0x05(the types the device uses for spontaneous data)SetStateCommandoutputmsmart-ng downloadcommand can fetch a protocol plugin from the cloud that contains the correct command format for this modelAdditional Context
msmart-ngwas originally developed for.midea_ac_lan(usingmidea-locallibrary), suggesting the protocol difference is at the frame/transport layer, not the integration layer.Attachments
home-assistant_2026-08-06T06-20-37.105Z.log
config_entry-midea_ac-01KZASJENGMFDJKGRDNQYMDRDH.json