This is an old revision of the document!
This project implements two functionalities for my smart home setup:
Both tasks are centered around an ESP32-WROOM board.
The goal for this task was to control the volume for the stereo system using the TV's remote control.
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 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.
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 .
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).
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:
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.
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!
uint8_t i[];
const unsigned int t;