Some hardware links on this page are affiliate links. As an Amazon Associate I earn from qualifying purchases. We may earn a commission if you buy through them, at no extra cost to you. See the affiliate disclosure.
The 12-button CYD touch panel is a grid of scenes on the same Cheap Yellow Display. This pack is one job: a wall thermostat. Plus and minus change the target temperature, heat and off change the mode, and the screen shows the room’s current temperature next to the target Home Assistant is actually holding.
Entity ids stay in substitutions (climate.room, sensor.room_temperature). Do not paste a live thermostat name into a published YAML. Wi-Fi credentials stay in secrets.yaml.
If the number on the climate entity should follow the weather, pair this display with adaptive comfort setpoint. If an open sash should shut the equipment off, pair it with window-open climate pause. A TRV that ignores its own sensor can take the same room reading through Sonoff TRVZB external temperature.
What problem it solves
You want to bump the heat from the hallway without unlocking a phone, and you want the number on the wall to be a room sensor, not the probe buried in a radiator valve.
How it works
- One screen, four touches — stock CYD pinout (ILI9341 SPI, XPT2046 touch, backlight on GPIO). The face shows current temperature, target temperature, and four zones: minus, plus, heat, off. It is not a button grid and it does not toggle lights.
- Current from the room — a
homeassistantsensor subscribes tosensor.room_temperature. A valve’s built-in probe sits on the radiator and in the draft from the window, so the pack does not use it for the big number. A commented alternate readscurrent_temperaturefrom the climate entity if that really is the room. - Target from the climate entity — a second sensor reads the
temperatureattribute. The screen follows whatever last wrote the setpoint, including a dashboard, a schedule, or another automation. - Plus and minus — a touch calls
climate.set_temperaturewith the current target plus or minus a step (pack default 0.5). The buttons only run while the entity state isheat, so a tap inoffdoes not invent a setpoint. - Heat and off — those zones call
climate.turn_onandclimate.turn_off. ESPHome is not allowed to call Home Assistant actions until you enable that on the device.
An optional one-hour graph plots the room sensor as a solid line and the target as a dashed line. The graph is a picture of history. It does not control anything.
Hardware notes
- Board. ESP32-2432S028R, the common 2.8″ resistive “CYD”. A capacitive rev needs a different touch component. The stock pinout is the same one the 12-button panel comments. This YAML does not reuse that grid.
- Power. 5 V USB. Flash over USB the first time. Later updates can go over the air. A flickering backlight is usually a weak supply, not the display driver.
- Sensors. Any temperature sensor already in Home Assistant. The display does not measure the room. Put the sensor in the occupied air.
- Climate. Whatever entity already heats.
heatuses thetemperaturefield.heat_cooloften wantstarget_temp_lowinstead. The pack has a substitution for which field to write. Confirm it in Developer Tools before you trust the buttons.
Snippet
Substitutions at the top. One minus zone, trimmed. Plus is the same lambda with the step added.
substitutions:
thermostat_entity: "climate.room"
temperature_entity: "sensor.room_temperature"
step: "0.5"
sensor:
- platform: homeassistant
id: current_temperature
entity_id: ${temperature_entity}
internal: true
- platform: homeassistant
id: target_temperature
entity_id: ${thermostat_entity}
attribute: temperature
internal: true
text_sensor:
- platform: homeassistant
id: thermostat_mode
entity_id: ${thermostat_entity}
internal: true
binary_sensor:
- platform: touchscreen
id: minus_zone
# pixel box for the minus control; the other three zones live in the pack
on_press:
- if:
condition:
text_sensor.state:
id: thermostat_mode
state: "heat"
then:
- homeassistant.action:
action: climate.set_temperature
data:
entity_id: ${thermostat_entity}
temperature: !lambda |-
return id(target_temperature).state - ${step};
# display, touch calibration, heat/off zones: full YAML in the pack
The display prints id(current_temperature).state as the room and id(target_temperature).state as the target, and it prints Off when thermostat_mode is off.
Setup outline
- Add the CYD in ESPHome over USB. Confirm the backlight and that a tap shows up in the log.
- Paste the pack YAML. Set
thermostat_entityandtemperature_entity. Leave the step at 0.5 unless the climate entity only accepts whole degrees. - Adopt the node. In Settings → Devices → ESPHome, allow the device to perform Home Assistant actions.
- With the climate entity in
heat, tap plus and minus. The target on the screen and the attribute in Developer Tools should move by one step. Tap off, then heat, and confirm the mode follows. - Change the setpoint from a dashboard. The target on the CYD should catch up without a tap.
Troubleshooting
- White screen. Backlight GPIO or
dc_pindoes not match this CYD rev (one USB port versus two). Use the stock pin comments in the pack, not a pinout from a different display. - Taps hit the wrong zone. Resistive calibration or
swap_xyis off. Recalibrate. Do not rotate the display a second time if the driver already rotated it. - Tap does nothing. Action permission is off, the entity id is wrong, or the mode is not
heat(plus and minus are gated).heat_coolentities that ignoretemperatureneed the low or high field instead. - Target on screen is stuck, room number moves. The attribute sensor is pointed at the wrong field. Read the climate entity in Developer Tools and match
temperature,target_temp_low, ortarget_temp_high. - Room number is nonsense. The sensor is in °F and the face format assumes °C, or the entity is
unavailable. The pack does not convert units. Fix the sensor, or change the format string to the unit you actually store. - Setpoint runs away. Something else is also writing
climate.set_temperature(a schedule, adaptive comfort, a TRV calibration). This display only sends a step when a zone is pressed.
Credits
Based on cyd-thermostat (ESPHome on an ESP32-2432S028R, touch zones calling the climate entity, room temperature from a separate sensor). This write-up is an original single-purpose thermostat face. It is not the 12-button scene panel, and it is not a paste of that repository.