I reverse-engineered my HVAC because I couldn’t turn it off reliably - BackSlasher
You are using an outdated browser. Please upgrade your browser to improve your experience.
I reverse-engineered my HVAC because I couldn’t turn it off reliably
18 minute read
Nitzan
If this prod is rocking, don’t come a-knocking
Follow
Israel
Backslasher
Custom Social Profile Link
-->
A couple of months ago, I had my HVAC controller replaced in an effort to save on electricity.
I controlled the previous board with an IR blaster that I loaded with a full matrix of {mode,fan_speed, target_temp} (and a special command for “off”). The new one didn’t work like that.
The old blaster’s config: one recorded Base64 blast per {mode, fan, temp} combination
No “off” button
The new remote/controller dialect had no designated “off” command. Instead, it had a “toggle” command, which makes the AC off if it’s on, and on if it’s off.
It sounds innocent enough when it’s a remote button, because an observer knows whether the AC is currently off or on, and therefore whether it needs this button to get to the wanted state. For a smart home solution, it was a problem.<br>If the AC is currently off and I want it set to “cool”, I will need to send a toggle command. However if it’s already on (e.g. fan only) and I send a toggle command, it’ll turn off.
This meant I needed a way to get the AC’s current status in order to decide which command to send.
Reading status is important
The original controller for the AC had no external indication for what it’s currently doing. The “external entity” was a small plastic with a single LED, a single button (on/off toggle) and an IR receiver. It obviously had an internal state (cool/heat, target temp) but didn’t expose it in a way I could read, so my best course of action was remembering the last state I sent it and assuming it landed. It wasn’t perfect, but it worked.
The new controller had a fancy LCD screen
It showed exactly what the AC was thinking, including the part I desperately needed - whether it’s on or not. Knowing that will let me decide whether I need to send a power toggle with a new command (off->on, on->off) or not (on->on but something else).
Naive idea
My original plan was this:
Put a device between the controller and the panel
Learn the secrets of how they communicate
Create a device to permanently tap that channel and read/write AC state
Which sounds good, if you discount the fact I know very little about electronics or signaling.
1. Cutting things
I bothered my HVAC tech enough to learn where they buy their electronics and got myself another HVAC controller (~50$), fully expecting me to destroy some components during my experiments.
The spare HVAC controller. I only care about the white connector on the left.
I disconnected the nice installed LCD panel and connected the spare one, which was placed on my crafts desk.
I cut the cable and started probing it with my multimeter to find it’s 5v. I then consulted a friend who did some hardware reverse engineering.
2. Wiretapping
The friend recommended I get “some hardware you can use to listen in”. I had several Arduinos, but they weren’t good enough. I pushed back against getting an oscilloscope and we settled on a BusPirate. It’s small, programmable, designed to help you crack protocols on other people’s electronics. I chose BusPirate 5, which is not the newest, but probably enough for me.
I thought I was really clever by doing the following:
Splice the BP to the LCD cable, connecting both it and the LCD panel to the controller in a way that showed the data on the BP while keeping the LCD panel working
Connect the BP over USB to a Raspberry PI I had lying around, and setting wifi+ssh on the RPI.
SSHing to the RPI from my laptop, so I don’t have to sit next to the very touchy wires
Opening an account for my friend so they can remote-ssh to the RPI, doing whatever debugging they want
This entire procedure took way way longer than it should have (about 7 work days).
One of the blockers was that the protocol is not standard. e.g. it wasn’t SPI or I2C.
The other was that I connected the wrong cable to BP’s ground wire, meaning it got garbage readings.
During this time of despair, I told my friend “what if those engineers at $COMPANY built a really sophisticated protocol? What chance do we have against the smart people in the lab?”
He replied with “as much as you think you don’t know about electronic signals, these guys don’t know either. They’re not here to reinvent the wheel, they’re here to get something working and move on”.
After that, I found the bad wiring and immediately made progress. My friend was right.
3. Protocol basics
BP was running in “logic analyzer” mode, being connected to sigrok / sigrok-cli on the rpi to read the inputs.
At this stage my friend was bored (“it’s just the bits now”) and I needed another partner, so I got Claude Opus (4.5 I think) to help me. I gave it unfettered access to...