* 08 jul 2026
Reverse-engineering my AC's "Wireless LED" - one byte at a time
I maintain the community fork of the Toshiba AC integration for Home Assistant and its underlying Python library. The official Toshiba app has a small toggle called Wireless LED - it turns the indicator light on the indoor unit on and off. Useful if the AC is in a bedroom and the LED bothers you at night. The integration didn't have it, because nobody knew where it lived in the protocol.
This is the story of finding it.
The protocol, briefly
Toshiba's cloud talks to your AC units over AMQP. The state of a unit (the "FCU state") travels as a hex string - 19 bytes that the library knows how to parse, covering power, mode, target temperature, fan speed, swing, and so on. But several bytes in that string were unmapped - always present, meaning unknown.
The interesting part is how state changes arrive. When something changes - from the remote, the app, anywhere - the cloud pushes a delta - a state string where every byte is ff except the fields that changed.
That's a gift for reverse-engineering.
The byte hunt
If a delta push only contains what changed, then isolating any feature is a two-step experiment:
- Turn on debug logging and watch the raw
AC state from AMQPhex strings. - Toggle exactly one thing in the app, and diff the pushes.
I toggled Wireless LED off and on. Two pushes arrived, all ff except one position: byte 15. Value 0x01 with the LED on, 0x02 with it off.
That's the whole discovery. No firmware dumps, no MITM proxies - the protocol's own delta mechanism points a big arrow at the byte you're looking for. The same recipe works for any other toggle in the app, and I've been using it since to chase down the remaining unknown bytes.
The gotcha - absent until first use
One wrinkle. The cloud's stored full state only includes a byte once the device has ever reported it. A unit whose LED has never been toggled reports nothing at byte 15 (the library sees it as NONE), so you can't tell "unsupported" apart from "never used" - until the user flips the toggle once.
That shaped the feature design - support detection is simply "the value is not NONE", and the documentation tells users to toggle the LED once in the official app if the switch doesn't appear in Home Assistant. Not elegant, but honest - the alternative was showing a switch that might silently do nothing.
Shipping it
The library got a ToshibaAcWirelessLed enum and a set_ac_wireless_led method in release 0.5.0. The integration shipped the switch in 2026.7.1, as a config-category entity that stays available even while the AC itself is off - the LED is controllable independently, and it would be annoying if turning the AC off at night also locked you out of the light switch.
End-to-end verification was pleasantly physical - send the command from Home Assistant, watch the AC echo the new state within a second, and look at the actual LED on the wall.
Takeaways
- Delta-based protocols document themselves. If a system pushes only what changed, a single toggle is a self-labeling experiment.
- Absence is ambiguous. "The device never said" is not "the device can't". Design the feature around what you can actually know.
- Small features earn trust. A one-byte discovery is a tiny diff, but for people whose bedroom AC blinks at them all night, it's the reason they installed the fork.