Afgelopen zomer ben ik verhuisd naar een andere woning waarin al airco’s geplaatst zijn. Het zijn airco’s van Mitsubishi Heavy Industries en hebben besturing door middel van een infrarood afstandsbediening. Natuurlijk wil ik deze airco’s kunnen bedienen met Home Assistant via WiFi. Ik stuitte in mijn zoektocht op het MHI-AC-Ctrl project. Nodo-Shop bleek complete kitjes te verkopen en er is een ESPhome versie van het MHI-AC-Ctrl project. Top, ik heb voor beide airco’s een kitje besteld en ben aan de slag gegaan.
Stappenplan voor het toevoegen van je airco aan Home Assistant
Benodigde tijd: 1 uur
Om je Mitsubishi airco te voorzien van WiFi besturing met Home Assistant doorloop je de volgende stappen. Onder het stappenplan lees je een uitgebreide toelichting.
- Controleer compatibiliteit van het MHI-AC-CTRL project met jouw Airco.
Bekijk de lijst van ondersteunde apparaten van MHI-AC-CTRL en zoek het typenummer van je airco op. Het typenummer van je airco staat op de binnenkant van de klep. In mijn geval een SRK50ZS-W.
- Soldeer de componenten op de printplaat
Bestel de ESPAC Wifi interface MHI-AC-Ctrl via Nodo-Shop. Vergeet niet een Wemos D1 mini mee te bestellen als je er geen meer hebt liggen.
- Demonteer de behuizing van de airco
Klik de behuizing van de airco af en zoek de printplaat.
- Plug de MHI-AC-CTRL in de airco
Via het meegeleverde stekkertje kun je de MHI-AC-CTRL verbinden met de Mitsubishi airco.
- Sluit de behuizing van de airco en test
Monteer de behuizing terug op het apparaat en test de werking.
Controleer compatibiliteit van het MHI-AC-CTRL project met jouw Airco
Bekijk de lijst van ondersteunde apparaten van MHI-AC-CTRL en zoek het typenummer van je airco op. De meeste airco’s met een aparte binnen- en buitenunit van Mitsubishi Heavy Industries zijn ondersteund. Het typenummer van je airco staat op de binnenkant van de klep. In mijn geval een SRK50ZS-W. De airco’s bevatten een CNS aansluitheader waarop je met een kabel de officiĆ«le WiFi module kunt aansluiten. Wij maken daar mooi gebruik van om op een nette manier onze MHI-AC-CTRL aan te sluiten.
Soldeer de componenten op de printplaat
Bestel de ESPAC Wifi interface MHI-AC-Ctrl via Nodo-Shop. Vergeet niet een Wemos D1 mini mee te bestellen als je er geen meer hebt liggen. Op de Wemos flashen we de ESPHome versie van de MHI-AC-CTRL firmware.
Het kitje bevat 2 componenten, een kabeltje en een printplaat. De twee componenten dienen te worden gesoldeerd op het printje. Het is even goed opletten op de polariteit, maar er staan duidelijke vormen op het printje afgedrukt. De vormen komen overeen met hoe de componenten geplaatst dienen te worden. De headers welke meegeleverd worden met de Wemos dien je ook te solderen op het bordje. Let goed op aan welke kant van de print je het allemaal soldeert.
De Wemos kun je dan voorzien van headers. Als dat gereed is, kunnen we gaan flashen. Steek hiervoor de USB kabel in de Wemos (zonder dat hij aangesloten is op de MHI-AC-CTRL print).
Flashen van ESPHome versie van MHI-AC-CTRL
Maak in ESPHome een nieuw device aan van het type d1_mini. Plak onderstaande code in het scherm waarbij je wel je eigen secrets en encryption keys gebruikt natuurlijk. Het originele voorbeeld bestand staat hier. Pas in de onderstaande code twee keer de waarden van <<< AIRCO NAAM >>> aan.
esphome: name: <<< AIRCO NAAM >>> friendly_name: ${devicename} min_version: 2024.6.0 platformio_options: # Run CPU at 160Mhz to fix mhi_ac_ctrl_core.loop error: -2 board_build.f_cpu: 160000000L esp8266: board: d1_mini # Enable logging logger: level: INFO baud_rate: 0 # logs: # component: ERROR ota: password: !secret ota_password platform: esphome wifi: ssid: !secret wifi_ssid password: !secret wifi_password # Enable fallback hotspot (captive portal) in case wifi connection fails ap: ssid: ${devicename} captive_portal: # Version 3.0 substitutions: # Unique device ID in HA deviceid: "<<< AIRCO NAAM >>>" # Unique MHI device ID used for climate class mhi_device_id: "mhi_${deviceid}" # Unique device name in HA (sensor names will be prefixed by this name) devicename: ${deviceid} # If you encounter mhi_ac_ctrl_core.loop error: -2 errors, change the frame_size to 20 frame_size: "33" # Optionally enables the ESP web server web_server: port: 80 external_components: - source: github://ginkage/MHI-AC-Ctrl-ESPHome@master components: [ MhiAcCtrl ] MhiAcCtrl: id: ${mhi_device_id} frame_size: ${frame_size} button: - platform: restart name: Restart entity_category: diagnostic api: encryption: key: "<<< ENCRYPTION KEY >>>" reboot_timeout: 0s services: # Call the set_api_room_temperature service from HA to override the room temperature # If a new value has not been received after room_temp_api_timeout seconds, it will fall back to internal sensor - service: set_api_room_temperature variables: value: float then: - lambda: |- return ((MhiAcCtrl*)id(${deviceid}))->set_room_temperature(value); # Call the set_vanes service from HA to set the vane position # Needed because the ESPHome Climate class does not support this natively # Possible values: 1-4: static positions, 5: swing, 0: unknown - service: set_vanes variables: value: int then: - lambda: |- return ((MhiAcCtrl*)id(${deviceid}))->set_vanes(value); globals: - id: room_temp_api_timeout type: int restore_value: no initial_value: "120" - id: frame_size type: byte restore_value: no initial_value: ${frame_size} climate: - platform: MhiAcCtrl mhi_ac_ctrl_id: ${mhi_device_id} id: ${deviceid} name: "${devicename}" binary_sensor: - platform: custom lambda: |- return ((MhiAcCtrl*)id(${deviceid}))->get_binary_sensors(); binary_sensors: - name: Defrost sensor: - platform: template name: "Frame Size" id: frame_size_sensor lambda: |- return ${frame_size}; - platform: uptime name: Uptime - platform: wifi_signal name: WiFi Signal update_interval: 60s - platform: custom lambda: |- return ((MhiAcCtrl*)id(${deviceid}))->get_sensors(); # Sensor names in HA, you can change these if you want # Don't delete them or change their position in the list sensors: - name: Error code - name: Outdoor temperature - name: Return air temperature - name: Outdoor unit fan speed - name: Indoor unit fan speed - name: Current power - name: Compressor frequency - name: Indoor unit total run time - name: Compressor total run time - name: Vanes id: vanes_UD_received on_value: then: - lambda: |- float received_value = id(vanes_UD_received).state; if (received_value == 1.0) { id(fan_control_ud).publish_state("Up"); } else if (received_value == 2.0) { id(fan_control_ud).publish_state("Up/Center"); } else if (received_value == 3.0) { id(fan_control_ud).publish_state("Center/Down"); } else if (received_value == 4.0) { id(fan_control_ud).publish_state("Down"); } else if (received_value == 5.0) { id(fan_control_ud).publish_state("Swing"); } - name: Energy used - name: Indoor (U-bend) HE temp 1 - name: Indoor (capillary) HE temp 2 - name: Indoor (suction header) HE temp 3 - name: Outdoor HE temp - name: Outdoor unit exp. valve - name: Outdoor unit discharge pipe - name: Outdoor unit discharge pipe super heat - name: Compressor protection code - name: Vanes Left Right id: vanes_LR_received on_value: then: - lambda: |- if (id(frame_size_sensor).state != 33) { return; } float received_value = id(vanes_LR_received).state; if (received_value == 1.0) { id(fan_control_lr).publish_state("Left"); } else if (received_value == 2.0) { id(fan_control_lr).publish_state("Left/Center"); } else if (received_value == 3.0) { id(fan_control_lr).publish_state("Center"); } else if (received_value == 4.0) { id(fan_control_lr).publish_state("Center/Right"); } else if (received_value == 5.0) { id(fan_control_lr).publish_state("Right"); } else if (received_value == 6.0) { id(fan_control_lr).publish_state("Wide"); } else if (received_value == 7.0) { id(fan_control_lr).publish_state("Spot"); } else if (received_value == 8.0) { id(fan_control_lr).publish_state("Swing"); } - name: 3D Auto id: Dauto_received on_value: then: - lambda: |- if (id(frame_size_sensor).state != 33) { return; } bool received_value = id(Dauto_received).state; if (received_value) { ESP_LOGD("main", "received 3DAuto from AC"); id(fan_control_3Dauto).publish_state(true); } else { ESP_LOGD("main", "received 3DAuto off from AC"); id(fan_control_3Dauto).publish_state(false); } text_sensor: - platform: version name: ESPHome Version - platform: wifi_info ip_address: name: IP ssid: name: SSID bssid: name: BSSID - platform: custom lambda: |- return ((MhiAcCtrl*)id(${deviceid}))->get_text_sensors(); text_sensors: - name: Compressor protection status select: - platform: template name: Fan Control Left Right id: fan_control_lr icon: mdi:arrow-left-right optimistic: true options: # - "3D Auto" - "Left" - "Left/Center" - "Center" - "Center/Right" - "Right" - "Wide" - "Spot" - "Swing" on_value: - lambda: |- if (id(frame_size_sensor).state == 33) { auto state = id(fan_control_lr).state.c_str(); ESP_LOGD("main", "Option of my select: %s", state); uint8_t vanesLR = 0; // Initialize the vanesLR variable if (id(fan_control_lr).state == "3D Auto") { id(fan_control_3Dauto).publish_state(true); } else if (id(fan_control_lr).state == "Left") { vanesLR = 1; } else if (id(fan_control_lr).state == "Left/Center") { vanesLR = 2; } else if (id(fan_control_lr).state == "Center") { vanesLR = 3; } else if (id(fan_control_lr).state == "Center/Right") { vanesLR = 4; } else if (id(fan_control_lr).state == "Right") { vanesLR = 5; } else if (id(fan_control_lr).state == "Wide") { vanesLR = 6; } else if (id(fan_control_lr).state == "Spot") { vanesLR = 7; } else if (id(fan_control_lr).state == "Swing") { vanesLR = 8; } if ((vanesLR > 0) & (vanesLR < 9) & (vanesLR != id(vanes_LR_received).state)){ ESP_LOGD("main", "setting vanesLR to: %i", vanesLR); return ((MhiAcCtrl*)id(${deviceid}))->set_vanesLR(vanesLR); } else { ESP_LOGD("main", "Not setting vanesLR: %i", vanesLR); } } - platform: template name: Fan Control Up Down id: fan_control_ud icon: mdi:arrow-up-down optimistic: true options: # - "3D Auto" - "Up" - "Up/Center" - "Center/Down" - "Down" - "Swing" on_value: - lambda: |- auto state = id(fan_control_ud).state.c_str(); ESP_LOGD("main", "Option of my select: %s", state); uint8_t vanesUD = 0; // Initialize the vanesUD variable if (id(fan_control_ud).state == "3D Auto") { id(fan_control_3Dauto).publish_state(true); } else if (id(fan_control_ud).state == "Up") { vanesUD = 1; } else if (id(fan_control_ud).state == "Up/Center") { vanesUD = 2; } else if (id(fan_control_ud).state == "Center/Down") { vanesUD = 3; } else if (id(fan_control_ud).state == "Down") { vanesUD = 4; } else if (id(fan_control_ud).state == "Swing") { vanesUD = 5; } if ((vanesUD > 0) & (vanesUD < 6) & (vanesUD != id(vanes_UD_received).state)){ ESP_LOGD("main", "setting vanesUD to: %i", vanesUD); return ((MhiAcCtrl*)id(${deviceid}))->set_vanes(vanesUD); } else { ESP_LOGD("main", "Not setting vanesUD: %i", vanesUD); } switch: - platform: template name: 3D Auto id: fan_control_3Dauto icon: mdi:video-3d optimistic: true turn_on_action: - lambda: |- if (id(frame_size_sensor).state == 33) { if (id(Dauto_received).state != 1) { ESP_LOGD("main", "Turn on 3DAuto"); return ((MhiAcCtrl*)id(${deviceid}))->set_3Dauto(1); } } else { ESP_LOGD("main", "Frame size is not 33, cannot turn on 3DAuto"); } turn_off_action: - lambda: |- if (id(frame_size_sensor).state == 33) { if (id(Dauto_received).state != 0) { ESP_LOGD("main", "Turn off 3DAuto"); return ((MhiAcCtrl*)id(${deviceid}))->set_3Dauto(0); } } else { ESP_LOGD("main", "Frame size is not 33, cannot turn off 3DAuto"); }
Flash nu de code naar de aangesloten Wemos D1 mini.
Demonteer de behuizing van de airco
Voordat je begint sluit je natuurlijk de stroom af. Klik de behuizing van de airco af. Dit gaat door een aantal schroeven los te maken aan de voorkant. Deze zitten verstopt onder de klep, welke je er ook uit moet klikken, en tussen de onderste kleppen. Aan de achterzijde aan de bovenkant kun je een aantal lippen indrukken om zo de kap los te halen. Je houdt dan de volgende situatie over:
Let op dat er water kan lekken door het gerommel aan de behuizing. Bij de onderste kleppen zat in een opvangbakje bij mijn airco nog wat water.
Aan de zijkant bevind zich een zwarte afdekkap die je er makkelijk af kunt schroeven. Je komt dan bij de besturingsprint terecht die we zoeken.
Plug de MHI-AC-CTRL in de airco
Lokaliseer de CNS header op het moederbord en steek met het meegeleverde stekkertje je MHI-AC-CTRL op de printplaat van de airco. De stekker past maar op 1 manier. Isoleer de Wemos D1 mini door middel van de behuizing die Nodoshop kan leveren of zoals ik met een goed stuk tape (alles op eigen risico!). Verstop de Wemos in de zwarte behuizing van de printplaat en schroef de kap terug op de airco. Plaats de andere behuizingen terug op de airco en schroef alles weer vast. Schakel de stroom in en check of de airco werkt zoals normaal met de afstandsbediening.
Mitsubishi Heavy Industries airco toevoegen aan Home Assistant
Home Assistant zal het nieuwe ESPHome apparaat nu zelf ontdekken en de entiteiten toevoegen.
Besparen op je energierekening
Onderstaand twee screenshots van het verschil tussen verwarmen met de CV vs verwarmen met de airco. Het eerste screenshot laat goed zien dat er hoge kosten voor gas betaald moeten worden om het huis te verwarmen (tussen 04:00-08:00), het tweede laat zien dat dat met een airco veel goedkoper kan (tussen 05:00-08:00). Het scheelt in dit voorbeeld gauw een euro, maar er zijn ook ochtenden geweest dat het verwarmen met gas al ā¬3,50 kostte terwijl de elektriciteitsprijs toen laag was en verwarmen met een airco me dan ā¬ 0,60 zou kosten.
Het werkt!
Het werkt! Je kunt nu je Mitsubishi Heavy Industries airco bedienen via wifi met Home Assistant terwijl je ook nog de normale afstandsbediening kan blijven gebruiken. Is het jou ook gelukt of heb je een vraag? Laat een reactie achter!
Je kunt je airco nu ook gebruiken in combinatie met automatische verwarming automations. Verwarm je ruimte met de airco op basis van je aanwezigheid, de ruimte temperatuur, een schema… Het is allemaal mogelijk met de Advanced Heating Control blueprint.
Heb hem ook weer even gedeeld op mijn Discord groep over home assistant en veel meer.