Close
0%
0%

ESP32 Smart Thermostat for 120V Fan Coil System

A fully custom ESP32-based thermostat designed for 120V fan coil systems with dimmable OLED, HA integration, and a clean wall-mount design.

Similar projects worth following
550 views
Designed for a condo with a building-controlled two-pipe HVAC system, where the thermostat can only switch the fan coil unit, this project adds a dimmable OLED display, rotary encoder UI, IR receiver/blaster, and ambient light sensing. The device runs ESPHome with custom logic for display rendering, control, and mode handling, while pulling external weather data from Home Assistant. It operates fully standalone but integrates deeply into HA for automation and monitoring. Housed in a modified Wiremold enclosure with a brushed aluminum knob, the final build aims for a clean, industrial look rather than a typical DIY aesthetic. The thermostat is smarter than the HVAC system it controls.

Overview

This project replaces a basic on/off condo thermostat with a custom ESP32-S3 thermostat for 120V fan coil systems, designed around the quirks of two-pipe building HVAC.

Rather than trying to fight the limitations of seasonal heat/cool changeover, the design adds a smarter local interface around them—bringing environmental visibility, physical control, and Home Assistant integration to an otherwise simple fan switch.

The control loop runs locally on the ESP32, with Home Assistant used for weather data and optional integrations.

Key Features

  • Custom OLED thermostat UI with automatic dimming
  • Rotary encoder-driven local interface
  • ESPHome firmware with standalone operation
  • Custom pixel weather sprites (18 conditions, day/night variants)
  • Relay switching for 120V fan coil control
  • IR receive (with IR transmit expansion underway)
  • Wall-mounted custom enclosure with hidden line voltage wiring

Hardware

Core components include:

  • Waveshare ESP32-S3 Zero
  • 2.42” SSD1309 OLED
  • SHTC3 temp/humidity sensor
  • KY-040 rotary encoder
  • KY-018 ambient light sensor
  • Opto-isolated relay
  • Internal 120V→5V supply module

(Full BOM and schematic now linked on GitHub.)

Display / UI

The display was designed to be glanceable rather than menu-heavy:

  • Center: indoor temperature
  • Left: outdoor temp + dew point
  • Right: setpoint + humidity
  • Corner: custom weather sprite
  • Bottom: Heat / Cool / Off mode

Ambient light automatically dims the display and subtle piezo tones provide button feedback.

Firmware

Built in ESPHome with custom lambdas handling:

  • Display rendering
  • Encoder navigation
  • Relay logic
  • Mode behavior
  • Weather sprite rendering

The thermostat runs independently, with Home Assistant augmenting rather than driving core operation.

Enclosure Design

The final enclosure moved away from a vintage thermostat concept and became a purpose-built design using:

  • Wiremold NMW3 enclosure
  • Screwless metal faceplate
  • 40mm aluminum encoder knob

Goal: something industrial and intentional rather than “prototype on a wall.”

Electrical Design

  • Mains switching isolated in gang box
  • 5V supply behind wall
  • Low-voltage electronics in removable front assembly
  • JST harness allows servicing without exposing line voltage

Future Work

  • Higher-power IR blaster upgrade
  • Expanded IR control via Home Assistant
  • Additional UI refinements
  • Possible Matter-oriented firmware variant

my_ssd1309.h

SSD1309 helper

h - 2.10 kB - 04/27/2026 at 02:10

Download

thermostat_reference.yaml

Firmware. Requires ESPHome and a Home Assistant instance for full functionality but runs standalone without HA.

x-yaml - 46.11 kB - 04/27/2026 at 02:10

Download

  • 1 × 2.42" OLED (SPI) - SSD1309
  • 1 × Nonmetallic Raceway Deep Outlet Box - NMW3
  • 1 × Temperature and Humidity Sensor (I2C) - SHTC3
  • 1 × IR Reciever - V1222
  • 1 × ESP32-S3-Zero Dev Board - ESP32-S3FH4R2

View all 14 components

  • Initial Build Complete: From Basic Relay to Full Smart Thermostat

    mackswan04/23/2026 at 16:48 0 comments

    This project started with a pretty simple goal: replace a basic on/off thermostat in a condo building where the HVAC system is centrally controlled.

    The building uses a two-pipe fan coil system, so the thermostat can’t actually control heating vs cooling—it can only switch the fan coil unit on and off. That constraint ended up shaping the entire design.

    Since I was already putting an ESP32-S3 on the wall, I decided to build something more than just a relay:

    • A full OLED interface showing indoor and outdoor conditions
    • A rotary encoder UI instead of buttons
    • Ambient light sensing for automatic dimming
    • Integration with Home Assistant for weather and automation
    • IR receiver (and soon IR blaster) to extend control beyond the thermostat

    The enclosure went through a few iterations. The original plan was to reuse a vintage Honeywell housing, but space constraints pushed the design toward a Wiremold surface-mount box. With a screwless faceplate and a 40mm aluminum knob, it ended up with a much cleaner, more intentional look than expected.

    Electrically, the high-voltage relay is isolated in the gang box, with a 5V supply mounted behind the wall. The front unit contains only low-voltage components and connects via a small harness so it can be removed without exposing line voltage.

    The firmware is built entirely in ESPHome with custom logic for display rendering and control. It runs fully standalone, but integrates tightly with Home Assistant for data and automation.

    Still in progress:

    • Upgrading the IR blaster hardware (current module is underpowered)
    • Expanding IR-based control for other devices
    • Refining the UI and interaction model

    Overall, this ended up being less about “making a thermostat” and more about building a smarter interface around a very limited HVAC system.

View project log

Enjoy this project?

Share

Discussions

Jason wrote 04/25/2026 at 01:32 point

Build looks good but as I don't use Home Assistant any more I might do build it and add a Matter firmware.

  Are you sure? yes | no

mackswan wrote 04/27/2026 at 02:07 point

Thanks, I appreciate that!

I probably undersold in the post that the control loop is actually local on the ESP32, with Home Assistant mostly used for weather and optional integrations, so it can stand on its own.

A Matter version would be a fun evolution of it. If you end up building one that way, I’d genuinely be interested to compare notes.

I also just added a GitHub repo (referenced above) with the schematic, BOM, and reference ESPHome config since you commented, in case any of that is useful if you experiment with it.

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates