This project intends to replace a plain Electra AC IR receiver with an ESP8266 to give it wifi capabilities and control it over MQTT.
The original receiver itself is "dumb" and doesn't hold any state and all the interaction is handled by the main unit, this makes it expandable so it can easily be replaced by an ESP8266.
The receiver is connected to the main unit with an 8-pin mini din connector, with the following pins:
- 5V
- Heat LED
- IR signal
- Green power LED (LOW for on)
- Timer LED
- Beep
- Button
- Cool LED
So now all we need to do is throw out the old receiver and hook up an ESP8266 to the pins 1, 3, 4.
First you would need:
- ESP8266 (ESP32 would also work)
- 1 NPN transistor
- 2 1kΩ resistors
- A breadboard/PCB
- IR receiver (optional)
Hook everything up according to the following schematic:

To use the code as-is, use GPIO4 for IR send, GPIO5 for power state input and GPIO14 for IR recv (optional).
The code in this repo is based on Homie for MQTT handling and for OTA. Please follow the instructions there to install all the dependencies.
Once the code is installed on the esp, it will boot in configuration mode. Follow the instructions here to upload a JSON configuration file.
A sample json config file is provided under /data/homie/config.json. This file can be edited and uploaded using platform.io under "Platform -> Build Filesystem Image" and the "Platform -> Upload Filesystem Image". Make sure to properly edit the file before uploading.
Building with platform.io is quite simple. But Homie is not compatible with Platform.io 3.0 for ESP8266 and ESP32 out of the box. You need to change files in the Homie library: ./pio/libdeps//Homie/src/Homie/Boot.
-
Start building as usual. You will see some errors regarding the "HTTPClient" calls not being supported.
-
Navigate to the ./pio/libdeps/
<target>/Homie/src/Homie/Boot -
Edit the
BootConfig.hppandBootConfig.cppfiles as follows: -
BootConfig.hpp Add the following line:
WiFiClient _wifiClient;
So that the file looks as follows:
private:
AsyncWebServer _http;
WiFiClient _wifiClient;
HTTPClient _httpClient;
DNSServer _dns;
- BootConfig.cpp Replace the following line:
_httpClient.begin(url);
so that it looks as follows:
// send request to destination (as in incoming host header)
_httpClient.setUserAgent(F("ESP8266-Homie"));
_httpClient.begin(_wifiClient,url);
// copy headers
For esp32 support you need to edit Homie either.
After trying to build, you will see errors regarding arduino events.
Open BootNormal.cpp and replace these strings:
- replace:
WiFiEvent_t::SYSTEM_EVENT_STA_GOT_IPwith:ARDUINO_EVENT_WIFI_STA_GOT_IP - replace:
WiFiEvent_t::SYSTEM_EVENT_STA_DISCONNECTEDwith:ARDUINO_EVENT_WIFI_STA_DISCONNECTED - replace:
info.disconnected.reasonwith:info.wifi_sta_disconnected.reason(2 occurrences)
In addition, there are dependencies conflicts bewtween Async TCP and AsyncTCP libraries, since ESP Async WebServer requires the first and AsyncMqttClient the last, but they use the same function names. adding Async TCP to lib_ignore on platformio.ini should solve this, but if in the future you have linking errors with AsyncTCP - try to seek there for the cause.
After the esp is configured, it will subscribe to the following MQTT topics:
- .../state/json/set
- This topic accepts a json in the following format (all fields are mandatory), updates the state and send it to the AC unit:
{"power": "on|off", "mode": "cool|heat|fan_only|dry|auto", "fan": "low|med|high|auto", "temperature": 15..30, "ifeel": "on|off", "swing":"on|off|hor|both"}
Note:
"fan"is also accepted as an alias for"fan_only"for backward compatibility. - This topic accepts a json in the following format (all fields are mandatory), updates the state and send it to the AC unit:
- .../ifeel_temperature/state/set
- This topic accepts a number between 5 and 36 and sends it to the main unit as a temperature received by the "i feel" function of the remote.
- .../reboot/trigger/set
- Publish
trueto this topic to reboot the device remotely.
- Publish
Monitoring and getting the real state of the AC is also possible by subscribing to the following topics:
- .../power/state
- .../mode/state
- .../fan/state
- .../temperature/state
- .../ifeel/state
- .../swing/state
Since Home Assistant 2022.6, MQTT entities are configured under the top-level mqtt: key in configuration.yaml rather than using platform: mqtt inside each domain. The examples below use this new style.
All entities (climate, iFeel switch, reboot button) belong to the same logical device — the ESP controller. To avoid repeating the device block and to group them together in the HA device registry, define it once using a YAML anchor (&main_ac_device) and reference it in the other entities with an alias (*main_ac_device):
device: &main_ac_device # defines the anchor
identifiers: "main_ac" # unique ID that groups all entities into one device
manufacturer: "Electra"
name: "Main AC"
# later, in another entity:
device: *main_ac_device # reuses the exact same blockAll entities sharing the same identifiers value will appear under one device card in Settings → Devices & Services → MQTT.
mqtt:
climate:
name: AC MQTT
unique_id: mqtt_ac_esp
device: &main_ac_device
identifiers: "main_ac"
manufacturer: "Electra"
name: "Main AC"
modes:
- "heat"
- "cool"
- "dry"
- "fan_only"
- "off"
fan_modes:
- "high"
- "med"
- "low"
- "auto"
swing_modes:
- "off"
- "on"
- "hor"
- "both"
min_temp: 16
max_temp: 30
power_command_topic: "devices/AC/power/state/set"
payload_on: "on"
payload_off: "off"
mode_command_topic: "devices/AC/mode/state/set"
mode_state_topic: "devices/AC/mode/state"
temperature_command_topic: "devices/AC/temperature/state/set"
temperature_state_topic: "devices/AC/temperature/state"
fan_mode_command_topic: "devices/AC/fan/state/set"
fan_mode_state_topic: "devices/AC/fan/state"
swing_mode_command_topic: "devices/AC/swing/state/set"
swing_mode_state_topic: "devices/AC/swing/state"iFeel is exposed as a dedicated MQTT switch (cleaner than the old away_mode hack which showed "Preset: Home/Away"):
switch:
name: "AC iFeel"
unique_id: main_ac_ifeel
device: *main_ac_device
icon: mdi:home-thermometer-outline
command_topic: "devices/AC/ifeel/state/set"
state_topic: "devices/AC/ifeel/state"
payload_on: "on"
payload_off: "off" button:
name: "AC Controller Reboot"
unique_id: ac_esp_reboot
device: *main_ac_device
icon: mdi:restart
command_topic: "devices/AC/reboot/trigger/set"
payload_press: "true"Note: The
mqtt:key must appear only once inconfiguration.yaml. Placeclimate:,switch:, andbutton:as siblings under it. The YAML anchor&main_ac_devicemust be defined before it is referenced with*main_ac_device, so theclimate:block (where the anchor is declared) must come first.
Lovelace UI example:
Home Assistant's MQTT HVAC component can be used with the following configuration (note the use if simple-thermostat custom component):
cards:
- type: custom:simple-thermostat
entity: climate.ac
name: false
step_size: 1
control:
_headings: false
hvac:
'off':
icon: mdi:power
name: 'כבוי'
cool:
icon: mdi:snowflake
name: 'קור'
heat:
icon: mdi:fire
name: 'חימום'
dry: false
fan:
'low':
icon: mdi:network-strength-1
name: 'נמוך'
'med':
icon: mdi:network-strength-3
name: 'בינוני'
'high':
icon: mdi:network-strength-4
name: 'גבוהה'
'Auto':
icon: mdi:autorenew
name: 'אוטו'
swing:
'on':
icon: mdi:home-thermometer
name: 'iFeel פעיל'
'off':
icon: mdi:home-thermometer-outline
name: 'iFeel כבוי'
sensors:
- entity: sensor.<external-hunidity-sensor>
name: 'לחות'
- entity: sensor.<external-temperature-sensor>
name: 'טמפרטורה'
hide:
mode: false
temperature: trueTo Inject external temperature (from any tempureture sensor) to iFeel every minute, add the following automation:
automation:
- alias: Update ifeel temperature
initial_state: 'on'
trigger:
platform: time_pattern
minutes: "/1"
action:
service: mqtt.publish
data:
topic: "devices/AC/ifeel-temperature/state/set"
payload: "{{ states('sensor.<tempereture-sensor>') }}"Note: The protocol only supports integer values, so the temperature will be rounded down.
Many thanks to @barakwei and IRelectra for analyzing the IR protocol.