This is an old revision of the document!


ESP32 Home Automation

  • Author: Valentin Radu
  • Email: valentin.radu@valinet.ro
  • Master: SRIC

Introduction

This project implements two functionalities for my smart home setup:

  • Speaker volume control using TV remote
  • Smart Air Conditioning

Both tasks are centered around an ESP32-WROOM board.

Speaker Volume Control using TV remote

The goal for this task was to control the volume for the stereo system using the TV's remote control.

About the current situation

The speakers are connected using the TV's headphone jack. Unfortunately, the software on my TV model is particularly dumb, in that it only allows changing the volume of its internal speakers using the volume controls on the remote. Initially, I wanted to use optical audio, but that does not allow for volume control due to its nature (optical audio transmits digital audio over infrared which simply carries the soundwave without any volume information - traditionally, it is the job of the receiver unit to regulate the volume). Then, I looked into using the HDMI ARC (audio return channel) feature, but, again, this is poorly implemented and does not allow for volume change. Lastly, I chose to connect the speakers via the headphone jack, which allows change via the “Sound” section of the TV menu, but not directly using the IR remote control.

Out of sheer luck, while researching something totally unrelated, I found out that the Sharp 42LE756EN TV that I have is actually made by Vestel . It is an old TV, but it has a 3D panel, which are basically impossible to buy nowadays, so that's why I keep it around. Anyway, Vestel is a pretty large enterprise and they also sell panels for usage in industrial/commercial signage for example. In those kinds of applications, the panels are not controlled via an IR remote control, but rather using some protocol over some sort of physical link, like serial or Ethernet. Turns out, Vestel actually ships similar software on all of their panels and just skin it according to the service are of the product; thus, their consumer LCDs still have the “customer control” implemented, which allows controlling the TV functionality via Ethernet (or an RS-232 header which I do not really have access to and an easy way to interface with). The “customer control” protocol is a VERY simple protocol: connect via port

Hardware

So, for this task, I have decided to use and ESP32 board which connects to my home network.

Smart Air Conditioning

The goal for this task was to be able to smart control the AC unit that I have in my home, bypassing the included remote control. The end goal was to have them controlled from anywhere around the globe.

About the AC units

The AC units are Bosch Climate 3000i . These are actually manufactured by Midea and sold under the Bosch brand in Romania . The units feature an OEM dongle option, but the functionality is limited and it comes with a steep price .

The logic board of the AC is hidden away by a plastic tray underneath the front lid. A standard Phillips screw and a set of plastic clips hold the tray and have to be carefully removed. The logic board features a female USB-A receptacle. Despite this, the electrical wiring is not for USB, but for UART . Communication with the AC unit can happen over this port using the Midea protocol .

Hardware

So, for this task, I have decided to use an ESP32 board which is wired for communication to the UART port on the AC unit logic board. I have determined that both boards use the same logic voltage levels, so there is no need for level shifters when wiring the RX/TX pins. Since some of the commands of the protocol do not work over the UART connection, I have also connected a standard 940nm infrared LED to the board, through which the remote control's commands are replicated in order to send the unsupported commands. I decided for this hybrid solution instead of going with the IR alone since the UART communication also offers feedback about the current status of the AC unit (current room temperature and other sensor data, for example).

Circuit diagram

  • USB red wire (USB 5V) > ESP32 5V pin
  • USB green wire (USB D+) > ESP32 GPIO1 (TX) pin
  • USB white wire (USB D-) > ESP32 GPIO3 (RX) pin
  • USB black wire (USB GND) > ESP32 GND pin
  • IR LED long pin > ESP32 GPIO19 pin
  • IR LED short pin > ESP32 GND pin

Software

Since a standalone dashboard would introduce too much friction, I have decided to have this board connected to my WiFi network and integrate it with my Home Assistant setup as an additional “service”. This is best achieved by writing an ESPHome description file and having the framework glue modules together in order to produce the desired functionality. Getting a usable prototype is accelerated compared to the traditional approach of writing boiler code that links various libraries together at a high level. ESPHome is a mature ecosystem supported by Nabu Casa, the same team that delivers the world renowned Home Assistant ecosystem.

esphome:
  name: ac-esp
  friendly_name: AC_ESP

esp32:
  board: esp32dev
  framework:
    type: arduino

logger:
  baud_rate: 0

api:
  encryption:
    key: "fjkhgusyfhygskfhgbvfxkhvbjkdhgxukhxkghxkxrg="

ota:
  password: "d76v87687db8ebmdbfjdjb8d789bdbd7"

wifi:
  ssid: REPLACE_WITH_YOUR_SSID
  password: REPLACE_WITH_YOUR_PASSWORD

  ap:
    ssid: "Fallback Hotspot"
    password: "473958869456"

uart:
  tx_pin: 1
  rx_pin: 3
  baud_rate: 9600

remote_transmitter:
  pin: GPIO19                       # For iot-uni-stick.
  carrier_duty_percent: 50%         # 50% for IR LED, 100% for direct 
                                    # connect to TSOP IR receiver output.

climate:
  - platform: midea
    name: AC_ESP               # Use a unique name.
    period: 1s                  # Optional
    timeout: 2s                 # Optional
    num_attempts: 3             # Optional
    autoconf: true              # Autoconfigure most options.
    beeper: false               # Beep on commands.
    visual:                     # Optional.
      min_temperature: 17 °C    # min: 17
      max_temperature: 30 °C    # max: 30
      temperature_step: 1 °C  # min: 0.5
    supported_modes:            # Optional. 
      - FAN_ONLY
      - HEAT_COOL
      - COOL
      - HEAT
      - DRY
    custom_fan_modes:           # Optional
      - SILENT
      - TURBO
    supported_presets:          # Optional. 
      - ECO
      - BOOST
      - SLEEP
    custom_presets:             # Optional.
      - FREEZE_PROTECTION
    supported_swing_modes:      # Optional
      - VERTICAL
      - HORIZONTAL
      - BOTH
    outdoor_temperature:        # Optional. 
      name: Temp

switch:
  - platform: template
    name: Beeper
    icon: mdi:volume-source
    restore_mode: 'RESTORE_DEFAULT_OFF'
    optimistic: true
    turn_on_action:
      midea_ac.beeper_on:
    turn_off_action:
      midea_ac.beeper_off:

binary_sensor:
  - platform: status
    name: Connection Status
    id: climate_AC_ESP_connection_status

text_sensor:
  - platform: template
    name: Uptime
    id: uptime_human
    icon: mdi:clock-start

  - platform: version
    name: ESPHome Version
    id: climate_AC_ESP_esphome_version

  - platform: wifi_info
    ip_address:
      name: IP
      id: climate_AC_ESP_ip_address
      icon: mdi:ip-network

sensor:
  - platform: uptime
    name: Uptime Sensor
    id: uptime_sensor
    update_interval: 60s
    on_raw_value:
      then:
        - text_sensor.template.publish:
            id: uptime_human
            state: !lambda |-
              int seconds = round(id(uptime_sensor).raw_state);
              int days = seconds / (24 * 3600);
              seconds = seconds % (24 * 3600);
              int hours = seconds / 3600;
              seconds = seconds % 3600;
              int minutes = seconds /  60;
              seconds = seconds % 60;
              return (
                (days ? to_string(days) + "d " : "") +
                (hours ? to_string(hours) + "h " : "") +
                (minutes ? to_string(minutes) + "m " : "") +
                (to_string(seconds) + "s")
              ).c_str();
  - platform: wifi_signal
    name: WiFi Signal
    id: climate_AC_ESP_wifi_signal
    update_interval: 60s

button:
  - platform: restart
    name: Reboot
    id: climate_AC_ESP_restart
    icon: "mdi:restart"
  - platform: shutdown
    name: Shutdown
    id: climate_AC_ESP_shutdown
  - platform: safe_mode
    name: Reboot (Safe Mode)
    id: climate_AC_ESP_safe_mode
  - platform: template
    name: Display Toggle
    id: climate_AC_ESP_display_toggle
    icon: mdi:theme-light-dark
    on_press:
      midea_ac.display_toggle:
  - platform: template
    name: Swing Step
    icon: mdi:tailwind
    on_press:
      midea_ac.swing_step:

Remote Access

Home Assistant offers a HomeKit bridge service that integrates it within the Apple Home. Apple Home can be managed remotely if it contains a home hub device, such as an Apple TV or a HomePod speaker. An alternative outside the Apple ecosystem is an yearly subscription to Nabu Casa which allows access to your Home Assistant instance via their web site (75 EUR). Or the totally DIY way is to enable port forwarding on your ISP's AP/router combo, and use a service like DuckDNS on Home Assistant, along with switching it to using HTTPS using a free Let's Encrypt certificate instead and access your instance over the public web directly.

Gotchas

When crafting the male receptacle that connects with the female one on the AC's logic board, usually by sacrificing some cheap USB cable laying around, pay extra attention and I recommend to verify the pinout of the connector against the wires: cheap Chinese cables often use different colors for the wires or use the traditional colors (red/green/white/black), but connect them in a random order (I have seen 5V via the black wire and GND via the red wire, for example). Use a multimeter and check each wire against the connector - failure to do so may lead to damaged equipment, as things aren't usually protected against reverse connection, for example. You have been warned!

2. Design

a. Hardware

  • ESP32-WROOM-S microcontroller

b. Software

Title

uint8_t i[];
const unsigned int t;

3. Conclusion

4. References

iothings/proiecte/2023sric/esp32_home_automation.1717017311.txt.gz · Last modified: 2024/05/30 00:15 by valentin.radu2005
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0