Skip to content

Latest commit

 

History

123 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Bambu Chamber Heater - ESPHome Temp Controller

ESPHome implementation to remotely control Sinilink XY-SA/ST series temperature controllers for Bambu Lab P1S/X1 Carbon 3D printers. The repository now supports both the ESP8285-based XY-WFPOW module and the Waveshare ESP32-C6-Zero from one shared codebase.

This project allows you to automatically manage a chamber heater, link it to print jobs, and control it through Home Assistant or the built-in web interface. It was inspired by the BambuSauna project.

Assembled BambuSauna chamber heater installed on a Bambu Lab printer Sinilink XY-SA temperature controller module

Table of Contents

Supported Devices

Device ESPHome Entry File Notes
ESP8285 / XY-WFPOW esphome/temp_controller_esp8285.yaml Original Sinilink Wi-Fi module, built-in status LED, no fan RPM monitoring
ESP32-C6-Zero esphome/temp_controller_esp32.yaml External module retrofit, WS2812 status LED, fan RPM monitoring, Wi-Fi protocol sensor
Manual selector esphome/temp_controller.yaml Main YAML with package toggles for device and temperature unit

Features

Shared Features

  • ESPHome integration for Home Assistant
  • Standalone web interface
  • Automatic chamber temperature control based on print state and filament type
  • Filament presets plus user-defined mode
  • Emergency stop handling
  • Over-temperature protection
  • Runaway heating detection
  • Sensor fault detection
  • Modbus communication watchdog
  • End-of-job shutoff
  • Celsius and Fahrenheit builds
  • OTA firmware updates

ESP32-C6-Zero Extras

  • RPM monitoring for 3-wire fans with emergency-stop interlock
  • Wi-Fi 6 support with protocol diagnostic sensor via include/wifi_protocol_helper.h
  • WS2812 RGB status LED (GPIO8) with state-based colors and effects:
LED State Color Effect Meaning
Emergency Stop Red Solid System emergency stopped
WiFi Disconnected Blue Fast Pulse Network connection lost
Over Temperature Red Strobe Temperature >60°C warning
Heating Active Orange Slow Pulse Heater is running
Normal/Idle Green Solid (dim) Everything OK

The LED updates automatically via state-change triggers (for example Wi-Fi connect/disconnect) plus periodic refresh, providing at-a-glance status without needing to check the web interface or Home Assistant.

Filament Presets

When a print starts, the controller reads the active filament type from the Bambu Lab Home Assistant integration and automatically selects the matching chamber temperature preset. You can also select a preset manually (including for pre-heating before a print), or use User-defined mode to set your own thresholds. Selecting Off engages the emergency stop.

Each preset targets the temperature below with a ±1°C hysteresis band (for example, PLA at 22°C starts heating at 21°C and stops at 23°C) to prevent rapid relay cycling. The defaults are defined as substitutions in esphome/settings.yaml — adjust them there for your filament brands, printer, and enclosure.

Preset Default Target (°C) Preset Default Target (°C)
PLA 22 PA 60
TPU 25 PA6 80
PETG 35 PA12 60
PCTG 35 PA612 25
ABS 55 PPA 70
ASA 55 PPS 80
PC 80 PP 55
PET 50 PE 75
PAHT 55

Repository Layout

  • esphome/settings.yaml contains the shared substitutions, default build settings, and additional shared configuration options you may want to customize.
  • esphome/packages/controller_shared.yaml contains the shared controller logic, Modbus entities, automations, and safety behavior.
  • esphome/packages/device_esp8285.yaml contains ESP8285-only framework, GPIO, and hardware configuration.
  • esphome/packages/device_esp32.yaml contains ESP32-C6-Zero-only framework, GPIO, fan monitoring, LED logic, and helper include usage.
  • esphome/packages/celsius.yaml and esphome/packages/fahrenheit.yaml contain unit-specific number ranges and preset math.
  • esphome/temp_controller.yaml is the main entrypoint if you want to switch device and unit by editing one file.
  • include/ contains the shared C++ helper headers used by the YAML lambdas (see include/README.md).
  • assets/web/ contains the custom web UI CSS and JavaScript assets used by ESPHome's web server.
  • docs/images/ contains README screenshots, wiring diagrams, and source artwork; docs/home-assistant-dashboard.md has a ready-made Lovelace dashboard.
  • hardware/3d-models/ contains printable enclosure and adapter .3mf files (print in ASA or PC — see 3D Printed Parts).
  • test/ contains host-side unit tests for the helper headers (./test/run_tests.sh).
  • .github/workflows/ci.yml runs the unit tests, validates every device/unit combination, and compiles both device targets on each push.
  • CHANGELOG.md tracks notable changes for each tagged release.

Requirements

Software

Common Hardware

  • Bambu P1S / X1 Carbon 3D Printer
  • Sinilink XY-SA10/SA30-W AC 110V-250V Temperature Controller (the SA10 is sufficient — its 10A relay rating is roughly five times the ~2A a 250W heater draws; the SA30's higher rating is unnecessary here)
  • NOYITO AC 100V-264V to DC 24V 1A Power Supply Module (powers the 24V Fan only)
  • AC 120/240V PTC Heater 200-250W (no need to be more powerful than this)
  • (2) 3-Way WAGO Connectors
  • 16-18Ga silicone wiring (Used: red and black wiring)
  • Heat set inserts: (15) M3x4x5 + (1) M2x2.5x3.2
  • Screws:
    • (7) M3x5MM or 6MM button screws for covers
    • (2) M3x25MM hex head screws for lower aux fan screws
    • (4) M3x25MM hex head screws for 24V Fan
    • (4) M3x4MM button screws for NOYITO AC to DC Power Supply Module
    • (2) M3x8MM hex head screws to connect housing to printer bottom
    • (4) M4x6MM or 8MM self-tapping screws to hold PTC in housing without fan
    • (2) M4x12MM button screws to hold the PTC heater to the front cover
    • (2) M4 self-locking nuts to connect the PTC heater to the front cover
    • (1) M2x3MM machine screw to hold the wireless module to the housing
  • (1) XT30 connector pair set (both ends) (so the chamber heater can be unplugged and removed from the printer)
  • Heatshrink tubing (for XT30 connectors)
  • Soldering equipment (depending on the installation method)

ESP8285 Hardware

  • Sinilink XY-WFPOW (ESP8285-based) wireless module
  • 24V 4020 2-wire fan (Used: SUNON MF40202VX-1000U-A99 with 10.8CFM airflow)
  • USB-to-TTL UART programmer (only needed for the initial flash; highly recommend FTDI-based programmers)

3D Printed Parts

Print the enclosure and adapter parts in hardware/3d-models/ in ASA or PC only. The housing sits against a 200-250W PTC heater and a printer that may itself run a heated chamber — PLA and PETG will soften and deform at these temperatures.

ESP32-C6-Zero Hardware

  • Waveshare ESP32-C6-Zero with 2 x 9-pin headers soldered
  • 24V 4020 3-wire fan (Used: SUNON MF40202VX-1000U-G99 with 10.8CFM airflow)
  • 1/4W 10K resistor (for 3.3V pull-up power for tach)
  • JST MX 1.25mm 4-pin cable to connect ESP32 to Temperature Controller
  • Assorted 2.54mm pitch housings and crimp pins to terminate JST MX 4-Pin cable
  • USB-C-to-USB-C cable for the initial flash

References

Modbus Address Map

ADDRESS TYPE NAME RANGE/VALUES Read/Write DESCRIPTION
0x0000 U_WORD Controller Status 0=Stopped, 1=Active RW Main relay/controller state
0x0001 U_WORD Temp Sensor Status 0=Connected, 1=Disc RO Temperature sensor connection status
0x0002 U_WORD Delay Time Remaining 0-999 seconds RO Countdown timer for delayed start
0x0003 S_WORD Current Temperature -400 to 1100 (*0.1) RO Current measured temperature
0x0004 U_WORD Temperature Unit 0=Celsius, 1=Fahrenheit RW Display and control temperature unit
0x0005 U_WORD Controller Mode 0=Heating, 1=Cooling RO Operating mode
0x0006 S_WORD Low Temp Threshold -400 to 850 (*0.1) RW Temperature to start heating/cooling
0x0007 S_WORD High Temp Threshold -400 to 850 (*0.1) RW Temperature to stop heating/cooling
0x0008 S_WORD High Temp Alarm -400 to 1100 (*0.1) RW High temperature alarm threshold
0x0009 S_WORD Low Temp Alarm -400 to 1100 (*0.1) RW Low temperature alarm threshold
0x000A U_WORD Delay Start Time 0-999 seconds RW Delay start duration setting
0x000B S_WORD Temperature Offset -100 to 100 (*0.1) RW Temperature calibration offset
0x000C BOOL Alarm Active 0=No, 1=Yes RO Temperature alarm status
0x000D BOOL Alarm Sound 0=Off, 1=On RW Enable/disable alarm beeper
0x000E BOOL High Temp Alarm Enable 0=Off, 1=On RW Enable high temperature alarm
0x000F BOOL Low Temp Alarm Enable 0=Off, 1=On RW Enable low temperature alarm
0x0010 BOOL Delay Start Enable 0=Off, 1=On RW Enable delayed start feature
0x0011 BOOL Emergency Stop 0=Off, 1=On RW Emergency stop/disable controller
0x0012 U_WORD Modbus Address 1-247 RW Modbus slave address
0x0013 U_WORD Modbus Baudrate 0-6 RW Serial communication speed
0x0014 BOOL Sleep Mode 0=Off, 1=On RW Display sleep/power saving mode
0x0015 U_WORD Backlight Level 0-7 RW Display backlight brightness

Baudrate map for 0x0013: 0=9600, 1=14400, 2=19200, 3=38400, 4=56000, 5=57600, 6=115200.

Temperature Value Encoding:

  • Stored as signed 16-bit integers representing temperature in tenths of degrees
  • Actual temperature = register_value * 0.1
  • Example: register value 235 = 23.5°C

Safety Notes:

  • Always enable high temp alarm (0x000E) for safety
  • Set high temp alarm (0x0008) above normal operating range
  • Emergency stop (0x0011) immediately disables heating/cooling

Wiring Diagram and Installation Notes

ESP8285 / XY-WFPOW

Use the original Sinilink XY-WFPOW Wi-Fi module. The basic wiring diagram is shown below.

ESP8285 / XY-WFPOW wiring diagram Heater housing interior showing the Sinilink controller and wiring Assembled heater housing mounted beneath the printer

ESP32-C6-Zero

The ESP32-C6-Zero retrofit uses a separate module and adds fan RPM monitoring and RGB LED status indication.

ESP32-C6-Zero wiring diagram Waveshare ESP32-C6-Zero pinout reference ESP32-C6-Zero wiring harness with JST connector Heater housing interior with the ESP32-C6-Zero installed Close-up of the ESP32-C6-Zero module mounted in the housing

Setup

1. Install ESPHome

Follow the official directions on the ESPHome website.

On macOS, the easiest path is Homebrew. If you don't already have Homebrew, install it first:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Then install ESPHome:

brew install esphome

2. Clone the Repository

git clone https://github.com/kedube/bambu-chamber-heater
cd bambu-chamber-heater

3. Configure Secrets

Copy and edit the secrets file:

cp esphome/secrets-example.yaml esphome/secrets.yaml

Important values include:

  • wifi_ssid
  • wifi_password
  • ap_wifi_ssid
  • ap_wifi_password
  • web_server_username
  • web_server_password
  • ota_password
  • encryption_key
  • bambu_printer_id

The example file also contains commented-out keys (static_ip, gateway, subnet, dns1, dns2) for an optional static IP configuration — uncomment them (and the matching manual_ip: block in esphome/packages/controller_shared.yaml) if you need one.

Shared substitutions such as device_name, friendly_name, software version, and filament preset defaults are defined in esphome/settings.yaml. Most runtime behavior, Modbus transport settings, and automations are defined in esphome/packages/controller_shared.yaml. Use those files for shared configuration changes before editing device-specific packages.

Generate a valid 32-byte encryption key (see: ESPHome.io), and insert it under encryption_key.

4. Choose Device and Temperature Unit

If you want one editable selector file, use esphome/temp_controller.yaml and switch the package includes:

packages:
  settings: !include settings.yaml
  controller_shared: !include packages/controller_shared.yaml
  select_units: !include
    file: packages/celsius.yaml
    #file: packages/fahrenheit.yaml
  select_device: !include
    file: packages/device_esp8285.yaml
    #file: packages/device_esp32.yaml

If you prefer a fixed compile target, use one of these:

  • esphome/temp_controller_esp8285.yaml
  • esphome/temp_controller_esp32.yaml

5. Validate the Configuration

esphome config esphome/temp_controller.yaml

6. Build

Example:

esphome run esphome/temp_controller.yaml

7. First Flash

Once ESPHome successfully compiles the YAML configuration, it will prompt you to flash the module. For the first flash, the device must be connected to your computer to upload the firmware.

ESP8285 / XY-WFPOW

For the ESP8285, use the USB-to-TTL adapter programmer at 3.3V and the XY-WFPOW flashing pins:

Sinilink XY-WFPOW flashing pinout (source: creepystefan/ESPhome-Sinilink-XY-WFPOW)

GND -> GND
TXD -> RXD
RXD -> TXD
IO0 -> GND
RST -> not connected
3V3 -> VCC

Adapter board photos: USB-to-TTL programming adapter board, top view USB-to-TTL programming adapter board connected to the XY-WFPOW

ESP32-C6-Zero

For the ESP32-C6-Zero, you must connect the board via USB-C and flash it directly. It will prompt you after a successful build for where to upload the code. Once running, the onboard WS2812 RGB LED shows live system status — see the LED state table under Features.

Upload Firmware Over USB With ESPHome

INFO Build Info: config_hash=0x694d2e36 build_time_str=2026-04-01 14:02:17 -0400
INFO Successfully compiled program.
Found multiple options for uploading, please choose one:
  [1] /dev/cu.usbserial-8320 (USB Serial)
  [2] Over The Air (esp32-remote.local)
(number):

Subsequent Flashes

After the initial flash, both device types can be updated over the air (OTA) using ESPHome.

8. Web UI

A local web server starts on port 80 after installation. You can access it from a browser on your local network using the username and password configured in secrets.yaml.

Chamber heater web interface showing sensors, settings, and system controls

The web UI's animated background is selectable in esphome/packages/controller_shared.yaml under web_server: → js_include. Three effects ship in assets/web/: pixel-stars.js (default), moving-particles.js, and shooting-stars.js — uncomment the one you want (only one at a time) and re-flash.

9. Home Assistant

Once online, the device should be discovered by the ESPHome integration in Home Assistant. Use the same encryption_key configured in esphome/secrets.yaml.

Home Assistant prompting for the ESPHome encryption key Home Assistant device page listing the chamber heater entities

For a ready-made dashboard layout (gauge, controls, and safety diagnostics), see docs/home-assistant-dashboard.md.

Troubleshooting

The device boots with Emergency Stop engaged. This is by design — the heater always starts disarmed. Select a filament preset (or clear the Emergency Stop switch) to begin heating.

Emergency Stop is on and selecting a preset doesn't clear it. When the stop was triggered by a fault — thermal runaway, a temperature alarm, a disconnected sensor, Modbus communication loss, a fan failure, the printer going offline, or Home Assistant disconnecting — presets intentionally cannot clear it (the log shows "Emergency stop remains active because it was triggered by a fault condition"). Fix the underlying issue, then manually turn off the Emergency Stop switch in the web UI or Home Assistant to acknowledge the fault. The Emergency Stop Time sensor (System Management group) shows how long ago it tripped, and the device logs record the cause on lines tagged EMERGENCY.

Heater won't turn on. Check, in order: the Filament Temp Preset isn't Off; Emergency Stop is off; Delay Start isn't holding the relay (watch Delay Time Remaining); and the current temperature isn't already above the High Temp Threshold. Note that when the printer reports an inactive state (finish, failed, offline, or idle), the end-of-job shutoff forces the preset back to Off — you can still pre-heat manually by selecting a preset, but a printer state change to inactive will turn it off again.

"No temperature updates" emergency stop (Modbus watchdog). The watchdog trips if no temperature reading arrives for 90 seconds. Verify the UART wiring (TX/RX not swapped), that the controller's baud rate matches the build default of 115200, and that the Modbus address is 1. Turn on the Modbus Debugging switch to log the raw hex frames and confirm whether the controller is responding.

Fan failure emergency stop, or Fan RPM reads 0 (ESP32-C6-Zero). A fan fault trips when RPM stays below 200 for 10 seconds while the heater is active. Confirm the fan is a 3-wire model with a tachometer lead, the tach line has its 10K pull-up to 3.3V, and the JST harness is seated. The thresholds (fan_min_rpm, fan_fail_timeout_seconds) are adjustable in esphome/settings.yaml.

Emergency stop whenever Home Assistant restarts or drops off the network. Losing the Home Assistant API connection (or the printer's _online sensor going off) is treated as a fail-safe condition because print-state automation is no longer available. This is expected; clear the stop once Home Assistant reconnects. Check the WIFI Signal Strength sensor if it happens frequently.

Can't reach the web UI. If the device can't join your Wi-Fi it starts a fallback access point (default SSID chamber-heater, configurable via ap_wifi_ssid) with a captive portal for reconfiguration. The web UI itself is on port 80 and uses the credentials from secrets.yaml.

The Restart button does nothing. Turn on the Restart Confirmation switch first, then press Restart within 10 seconds — this guards against accidental restarts mid-print.

Known Issues

  • The Sinilink Modbus addresses for the sleep switch (0x0014) and backlight level (0x0015) do not seem to have any effect on the backlight settings for XY-SA10/SA30 controllers.
  • Mixed-material prints will cause the chamber target temperature to fluctuate as the active filament changes.

Safety

The author assumes no liability for injury, damage, or loss resulting from wiring errors, improper installation, or misuse of this project. Electrical work can be hazardous. If you are unsure, consult a qualified professional.

License

This project is licensed under the GNU General Public License v3.0 or later — see LICENSE.

Contributing

Contributions are welcome for bug fixes, documentation improvements, and new hardware support. Please include testing details when possible, and add user-visible changes to the ## Unreleased section of CHANGELOG.md — the release automation turns that section into the published release notes.

Release Process

Releases are fully automated by .github/workflows/release.yml:

  1. Every push to main runs CI (unit tests, ESPHome validation for all device/unit combinations, and firmware compiles).
  2. When CI passes, the Release workflow bumps the patch segment of sw_version in esphome/settings.yaml, rotates the CHANGELOG's ## Unreleased section into the new version, and pushes a chore(release): <version> [skip ci] commit.
  3. A GitHub release is published for that version, with notes generated from the CHANGELOG section (Highlights), the commit list since the previous tag, and a full-changelog compare link.

To cut a minor or major release, set sw_version yourself in a normal commit (e.g. 1.9.0); because that version has no tag yet, the automation publishes it exactly as set, then resumes patch bumps. To re-publish a release for the current version (for example after a failed run), use the Release workflow's Run workflow button.

About

ESPHome-based chamber heater controller for Bambu Lab 3D printers with Home Assistant integration. Manages Sinilink XY-SA/ST-Series temperature controllers via the XY-WFPOW (ESP8285) module for Modbus communication, enabling automated chamber heating for optimal print quality.

Topics

Resources

Stars

14 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages