banner image

These are the plans, bill of materials, and firmware necessary to build your own HVAC controller. Please be aware that I am a self-taught hobbyist in electronics and HVAC and I do not warrant my designs and implementation fit for any particular application. There are likely design flaws and software bugs lurking herein. You take full responsibility for hacking your air conditioner and playing with electricity.

controller circuit schematic

Circuit schematic

controller board components

Controller board v2.0 components

Bill of materials: bom.csv

Controller firmware: etdey/hvac-controller

Server Software

Although the controllers are designed to run autonomously without the need for control inputs from a central server, it is useful to transmit operational statistics to a time-series database for visualization and analysis. For my setup, I chose InfluxDB and Grafana for my database and analysis tool.

The central server has an XBee radio module attached via USB and it runs a Python program that receives these status packets from the HVAC controllers at 60 second intervals. This code is responsible for updating the InfluxDB time-series database.

typedef struct {
    uint8_t packetType;
    uint8_t versionMajor;
    uint8_t versionMinor;
    uint8_t sequenceNumber;
    unsigned long uptime;
    uint8_t systemState;
    uint8_t thermostatState;
    uint8_t currentState;
    uint8_t targetState;
    unsigned long timer_fanOn;
    unsigned long timer_fanOff;
    unsigned long timer_coolOn;
    unsigned long timer_coolOff;
    unsigned long timer_heatOn;
    unsigned long timer_heatOff;
    unsigned long accum_fanOn;
    unsigned long accum_fanOff;
    unsigned long accum_coolOn;
    unsigned long accum_coolOff;
    unsigned long accum_heatOn;
    unsigned long accum_heatOff;
    char nodeName[21];
} XBeeStatusPayload;

Data Packet Payload

packetType is always 1. There is only one type of packet currently.

versionMajor and versionMinor contain the firmware version information.

sequenceNumber increments by one for every transmitted packet and rolls over from 255 to 0.

uptime is how many seconds the controller has been running since last reset. Internally, the controller tracks time as a 64-bit number where the first 32-bits count seconds and the other 32-bits count nanoseconds -- the fractional part of the next whole second.

systemState is a bitmap of the current control lines that the HVAC unit is receiving.

thermostatState is a bitmap of the current control lines that the thermostat is sending.

currentState is an enum of the current FSM state.

targetState is an enum of the desired FSM state once minimum time values and other constraints have been satisfied.

timer_* values record the total seconds that the controller has been continuously asserting a control function. For example, if the fan has been on for 15 minutes, timer_fanOn=900 and timer_fanOff=0.

accum_* values record the total seconds during the interval since the last report that a control function was asserted. For example, if the fan was on for the first 40 seconds of the reporting period and then turned off, accum_fanOn=40, accum_fanOff=20, timer_fanOn=0, and timer_fanOff=20 in the status report.

Lessons Learned and Improvement Ideas

These are notable design and implementation lessons learned from this project.

These are possible improvements to be made in the future or on the next versions of the controller board.


Previous: Building the controller

 

Copyright © 2015 by Eric Dey. All Rights Reserved.