Mitsubishi AC with Wemos D1 Mini Pro

I cant believe it!
My cables arrived today (finally) and I cant believe it but mine are wrong pitch…the pitch on the CN105 appears to be 2.00mm while the cables that arrived are 2.54mm pitch.

Where did you order yours from skip?

UPDATE: I did manage to get hold of a plug (with a short tails) salvaged from a electronics repair place here in Beenleigh.
Installed that but having troubles with the code atm.

Traceback (most recent call last):
  File "/usr/src/app/homeassistant/helpers/entity_platform.py", line 352, in _async_add_entity
    await entity.async_update_ha_state()
  File "/usr/src/app/homeassistant/helpers/entity.py", line 231, in async_update_ha_state
    state = self.state
  File "/usr/src/app/homeassistant/components/climate/__init__.py", line 197, in state
    if self.current_operation:
  File "/config/custom_components/mitsubishi_mqtt/climate.py", line 172, in current_operation
    return me_to_ha[self._current_operation]
KeyError: None
2019-03-26 07:11:56 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/src/app/homeassistant/helpers/entity.py", line 231, in async_update_ha_state
    state = self.state
  File "/usr/src/app/homeassistant/components/climate/__init__.py", line 197, in state
    if self.current_operation:
  File "/config/custom_components/mitsubishi_mqtt/climate.py", line 172, in current_operation
    return me_to_ha[self._current_operation]
KeyError: None
2019-03-26 07:12:21 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/src/app/homeassistant/helpers/entity.py", line 231, in async_update_ha_state
    state = self.state
  File "/usr/src/app/homeassistant/components/climate/__init__.py", line 197, in state
    if self.current_operation:
  File "/config/custom_components/mitsubishi_mqtt/climate.py", line 172, in current_operation
    return me_to_ha[self._current_operation]
KeyError: None
2019-03-26 07:13:21 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/src/app/homeassistant/helpers/entity.py", line 231, in async_update_ha_state
    state = self.state
  File "/usr/src/app/homeassistant/components/climate/__init__.py", line 197, in state
    if self.current_operation:
  File "/config/custom_components/mitsubishi_mqtt/climate.py", line 172, in current_operation
    return me_to_ha[self._current_operation]
KeyError: None

What version of HA are you running?
Are you using the Master branch which is sorted for 0.89 (Breaking Changes)?
Trying it with 0.89.2 and the above Traceback is in the log.
My usual version is 0.81.6 and it had major errors so I tried it in 0.89.2 and 0.90.0 both show less errors but refuse to show a climate entity id. Had enough for today.

Revolectrix

http://www.store.revolectrix.com/Products/Cellpro-4s-Charge-Adapters/Cellpro-Battery-Pigtail-10-5-Position

Cheers! How much did they charge you to send them?
I found mine on Bangood and they were free shipping…false economy…should have followed the advice!

I’ll answer. They sent four to me in NZ (because I am bound to bugger up two of them), Cost was

Subtotal 7.96
Shipping Cost (Int’l First Class (10-14 days)) 3.02
Total $10.98

It took a lot less than 10-14 days too!

Cheers mate! Best I order a couple from there then!

Progress has been made! I received my new leads and tried the Wemos D1 devices with no success…very disappointing! So I thought it best to retry the ESP01 devices now that I had the new leads. Flashed them successfully using Arduino IDE, made up the leads to suit, checked all wiring, fitted to the AC and success! VERY Happy! Next step was to try integrate with HA.
All went smoothly and the unit is controllable via the Thermostat Control.

Rumpus%20AC

I have a ‘however’ though. It seems something is amiss (even though it is working?) as I have errors telling me:

2019-04-12 03:51:21 WARNING (MainThread) [homeassistant.helpers.service] Not passing an entity ID to a service to target all entities is deprecated. Update your call to climate.turn_on to be instead: entity_id: all                                                              
2019-04-12 03:51:21 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection.139656101561456]                                                                                                                                                                     
Traceback (most recent call last):                                                                                                                                                                                                                                                  
  File "/usr/src/app/homeassistant/components/websocket_api/commands.py", line 122, in handle_call_service                                                                                                                                                                          
    connection.context(msg))                                                                                                                                                                                                                                                        
  File "/usr/src/app/homeassistant/core.py", line 1138, in async_call                                                                                                                                                                                                               
    self._execute_service(handler, service_call))                                                                                                                                                                                                                                   
  File "/usr/src/app/homeassistant/core.py", line 1160, in _execute_service                                                                                                                                                                                                         
    await handler.func(service_call)                                                                                                                                                                                                                                                
  File "/usr/src/app/homeassistant/helpers/entity_component.py", line 188, in handle_service                                                                                                                                                                                        
    self._platforms.values(), func, call, service_name                                                                                                                                                                                                                              
  File "/usr/src/app/homeassistant/helpers/service.py", line 314, in entity_service_call                                                                                                                                                                                            
    future.result()  # pop exception if have                                                                                                                                                                                                                                        
  File "/usr/src/app/homeassistant/helpers/service.py", line 328, in _handle_service_platform_call                                                                                                                                                                                  
    await getattr(entity, func)(**data)                                                                                                                                                                                                                                             
  File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run                                                                                                                                                                                                     
    result = self.fn(*self.args, **self.kwargs)                                                                                                                                                                                                                                     
  File "/usr/src/app/homeassistant/components/climate/__init__.py", line 485, in turn_on                                                                                                                                                                                            
    raise NotImplementedError()                                                                                                                                                                                                                                                     
NotImplementedError                                                                                                                                                                                                                                                                 
2019-04-12 03:54:16 INFO (MainThread) [homeassistant.loader] Loaded hassio from homeassistant.components.hassio                                                                                                                                                                     
2019-04-12 03:58:33 WARNING (MainThread) [homeassistant.helpers.service] Not passing an entity ID to a service to target all entities is deprecated. Update your call to climate.turn_on to be instead: entity_id: all                                                              
2019-04-12 03:58:33 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection.139656101561456]                                                                                                                                                                     
Traceback (most recent call last):                                                                                                                                                                                                                                                  
  File "/usr/src/app/homeassistant/components/websocket_api/commands.py", line 122, in handle_call_service                                                                                                                                                                          
    connection.context(msg))                                                                                                                                                                                                                                                        
  File "/usr/src/app/homeassistant/core.py", line 1138, in async_call                                                                                                                                                                                                               
    self._execute_service(handler, service_call))                                                                                                                                                                                                                                   
  File "/usr/src/app/homeassistant/core.py", line 1160, in _execute_service                                                                                                                                                                                                         
    await handler.func(service_call)                                                                                                                                                                                                                                                
  File "/usr/src/app/homeassistant/helpers/entity_component.py", line 188, in handle_service                                                                                                                                                                                        
    self._platforms.values(), func, call, service_name                                                                                                                                                                                                                              
  File "/usr/src/app/homeassistant/helpers/service.py", line 314, in entity_service_call                                                                                                                                                                                            
    future.result()  # pop exception if have                                                                                                                                                                                                                                        
  File "/usr/src/app/homeassistant/helpers/service.py", line 328, in _handle_service_platform_call                                                                                                                                                                                  
    await getattr(entity, func)(**data)                                                                                                                                                                                                                                             
  File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run                                                                                                                                                                                                     
    result = self.fn(*self.args, **self.kwargs)                                                                                                                                                                                                                                     
  File "/usr/src/app/homeassistant/components/climate/__init__.py", line 485, in turn_on                                                                                                                                                                                            
    raise NotImplementedError()                                                                                                                                                                                                                                                     
NotImplementedError

Any ideas whats going wrong there? I noticed in the my new /custom_components/mitsubishi_mqtt/ folder there is now another folder /pycache/ and inside is the file ‘climate.cpython-37’

I’m a little lost where to look to diagnose further but I will read the error further for some clues.

Cheers all!

Update I read here and here but it seems to me the way it is setup now is correct? The errors seem to be saying not though?

Update 2 I realised that there was a problem with how I intrepreted the new way custom components should be setup.
So after setting it all up as described here

And in particular:

And now after completing that task using the files from here , I have errors somewhat reduced to:

2019-04-12 13:11:22 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
File “/usr/src/app/homeassistant/helpers/entity.py”, line 215, in async_update_ha_state
“No entity id specified for entity {}”.format(self.name))
homeassistant.exceptions.NoEntitySpecifiedError: No entity id specified for entity Rumpus AC

Plus:

2019-04-12 13:14:04 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection.139820874127792]                                                                                                                                                                     
Traceback (most recent call last):                                                                                                                                                                                                                                                  
  File "/usr/src/app/homeassistant/components/websocket_api/commands.py", line 122, in handle_call_service                                                                                                                                                                          
    connection.context(msg))                                                                                                                                                                                                                                                        
  File "/usr/src/app/homeassistant/core.py", line 1138, in async_call                                                                                                                                                                                                               
    self._execute_service(handler, service_call))                                                                                                                                                                                                                                   
  File "/usr/src/app/homeassistant/core.py", line 1160, in _execute_service                                                                                                                                                                                                         
    await handler.func(service_call)                                                                                                                                                                                                                                                
  File "/usr/src/app/homeassistant/helpers/entity_component.py", line 188, in handle_service                                                                                                                                                                                        
    self._platforms.values(), func, call, service_name                                                                                                                                                                                                                              
  File "/usr/src/app/homeassistant/helpers/service.py", line 314, in entity_service_call                                                                                                                                                                                            
    future.result()  # pop exception if have                                                                                                                                                                                                                                        
  File "/usr/src/app/homeassistant/helpers/service.py", line 328, in _handle_service_platform_call                                                                                                                                                                                  
    await getattr(entity, func)(**data)                                                                                                                                                                                                                                             
  File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run                                                                                                                                                                                                     
    result = self.fn(*self.args, **self.kwargs)                                                                                                                                                                                                                                     
  File "/usr/src/app/homeassistant/components/climate/__init__.py", line 485, in turn_on                                                                                                                                                                                            
    raise NotImplementedError()                                                                                                                                                                                                                                                     
NotImplementedError

I’ll leave it here for now…The Component is actually working for now anyway.
PS there is also these two new entries now:

11:14 PM components/climate/__init__.py (ERROR)

Not passing an entity ID to a service to target all entities is deprecated. Update your call to climate.turn_on to be instead: entity_id: all

11:14 PM helpers/service.py (WARNING)

Updated 5/29/2019


A big thanks to @hernanjc, @mktbs, @nickrout, @wellsy for their support in getting my own project working, and then improving these instructions.


These instructions show how to integrate a Mitsubishi air conditioner into Home Assistant, using a WeMos D1 Min PRO. They have been validated to work with Home Assistant 0.93.2.

The D1 mini PRO connects to the CN105 port on the circuit board of the air conditioner using a wiring pigtail. The D1 mini PRO will send commands, receive state information, and be powered by the CN105.

Hardware you will need

  • A WeMos D1 mini PRO. There are different models and form-factors of Mitsubishi air conditioners, and the circuit boards are in different places such that some will get better WiFi reception than others. For example, for the in-ceiling cassette model, the circuit board is located within a sheet-metal box that will degrades WiFi reception. In these types of situations, you may want to consider using an external antennae for the D1 mini PRO (instead of the on-board antenna) to improve the reception. I have found that “WeMos® D1 Mini Pro-16 Module + ESP8266 Series WiFi Wireless Antenna” from www.banggood.com works well.

  • A Wiring Pigtail that connects the D1 mini PRO to the CN105 port on the air conditioner. I used the "Cellpro (JST PA) Battery Pigtail, 10”, 5 Position” from www.store.revolectrix.com.

Attach the pigtail cables to the D1 mini PRO (TX, RX, GND and 5V pins). The CN105 connector has a fifth pin that is not used in this project, and I cut this off at the connector to reduce the clutter inside the air conditioner. In the picture below, a pin header has been soldered to the D1 mini PRO, and the cables were soldered to the pin headers. You may find that a better setup is to solder your wires to a male-to-female connector row that sits on top of those headers, allowing you to remove / swap out the D1 mini PRO as needed (thanks for the suggestion, @mktbs!)

D1

Configure the D1 mini PRO

  • Your computer will need a USB to UART Bridge Virtual COM Port (VCP) driver to communicate with the D1 mini PRO. If you don’t already have one installed, you can use the CP210x driver from https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers.

  • We now need to setup the Arduino IDE to configure the D1 mini PRO. In IDE, select “File”, then “Preferences”. In the “Additional Boards Manager URLs:” field, type “http://arduino.esp8266.com/stable/package_esp8266com_index.json” and click “Ok”.

  • We now need to install the libraries needed by the Arduino sketch. Select “Tools”, then “Board: “Arduino/Genuino Uno”, and then “Boards Manager …”, and then:

    1. Search for “esp8266”. Select “esp8266 by ESP8266 Community”, and “Install”.
    1. Search for “json”. Select “ArduinoJson by Benoit Blanchon”, and “Install”.
    1. Search for “pubsub”. Select “PubSubClient by Nick O”Leary”, and “Install”.
  • Select “Tools”, then “Board: “Arduino/Genuino Uno”. Scroll to the bottom of the list. Additional boards will appear that were not shown earlier. Select “LOLIN(WEMOS) D1 mini PRO”.

  • Open Device Manger (or your computer’s equivalent). Connect the D1 Mini PRO to your computer using the appropriate cable (in my case it is a USB to Micro USB), and take note of the new COM port number that will appear.

  • Use a browser to navigate to the SwiCago/Heatpump page (https://github.com/SwiCago/HeatPump) on GitHub. Click on the green “Clone or Download” button, and then Download the ZIP File.

  • In the Arduino IDE, select “Sketch”, then “Include Library”, then “Add .ZIP Library”, and select the .ZIP file you just downloaded.

  • Select “File”, then “Examples”, and under the “Examples from Custom Libraries” section, select “HeatPump”, and then “mitsubishi_heatpump_mqtt_esp8266_esp32”. You should now have two tabs in your Arduino sketch - one named “Mitsubishi_heatpump_mqtt_esp8266_esp32”, and the other named “Mitsubishi_heatpump_mqtt_esp8266_esp32.h”.

  • Make the following changes in the “Mitsubishi_heatpump_mqtt_esp8266_esp32.h” tab:

    • In “// wifi settings” section, input your network’s ssid and password.
    • In “// mqtt server settings” section, update the IP address of your mqtt server. In my case, this is the same IP address as my home assistant server, as i am using the mqtt plug-in from the add-ons page.
    • In “// mqtt client settings” section, choose a unique client_id (name) for the air conditioning Unit in which the D1 mini Pro will be installed. Amend the back of the word "heatpump” with this name so that you can keep track of multiple units (if you have more than one units in your house). In this example, the air conditioning unit is in the Study, and so we’re going to use “heatpump-Study”. Make this change for all of the other heatpump fields in this section.
  • Select “Tools”, then “Port”, then the COM port name that you saw in device manager earlier. On the main IDE toolbar, select the circle with the tick to verify your code, and then the circle with the right-facing arrow to upload the code the D1 Mini PRO.

After the upload, unplug the D1 mini PRO from the computer. Wait a few seconds, and then plug it back in. Wait a minute for the D1 mini PRO to boot up and associate with the network, and then check your router’s admin page or other network tool to confirm that the D1 Mini PRO successfully joined your WiFi network. Open a command prompt (or your operating system’s equivalent), and confirm that the D1 mini PRO is passing traffic over the network (by sending it a ping, etc). If for example you mis-typed the WiFi password in the Arduino sketch, the LED on the D1 mini PRO will flash blue. Knowing this can be handy when you are troubleshoot the device in the future. In my case, for the wall-mounted units I can easily see the flashing blue light through the plastic casing of the air conditioner when the room is dark.

Open Home Assistant

  • In your custom components folder, create a folder called mitsubishi_mqtt (“custom_components/mitsubishi_mqtt”) and into this folder copy the climate.py and manifest.json files from the SwiCago/Heatpump page on GitHub (https://github.com/SwiCago/HeatPump/blob/master/integrations/home-assistant.io/custom_components/mitsubishi_mqtt/climate.py and manifest.json).

  • If you already have your own MQTT broker installed, great! In my case I use the embedded broker in Home Assistant. To do that, select “Hass.io” in the main panel, then “Add-ons”, and “Mosquitto broker”. Install the add-on, and then create a username and password. Note - these need to match the mqtt settings from your Arduino sketch. Start the service.

  • Select “Configuration”. In the “Users” section, add a user named “MQTT_User”, and again add the same username and password.

  • Select "Configurator”. Open your configuration.yaml file, and add the following, remembering that in this example, the air conditioner is located in the Study.

Config

  • The “name” field will be the title of the card in Lovelace.

At the air conditioning unit

Open up the air conditioner so that you can access the circuit board. If you’re not familiar with your unit, you may want to look at the service manual (available on-line), which will provide you with a step-by-step guide. Connect the wiring pigtail (with D1 Mini PRO attached) to the CN105 port. Note: Don’t try and update the config on the D1 Mini Pro while it is connected to the air conditioner. Not only is this likely to be dangerous (because you’re standing on a ladder with a laptop, etc), but it won’t flash correctly to the board and will give you an error. If you need to update the config, unplug it first.

Back in Home Assistant

Restart Home Assistant. With some luck, you should see the following card in Lovelace:

Card

Congrats - you should now be able to control your air conditioner from Home Assistant.

10 Likes

A word of warning about the CN105 interface.
The RX and TX signals are 5V and are not strictly compatible with the ESP8266.
(5V from the CN105 output may damage the RX 3.3 volt max input and the TX output voltage may not be high enough for the CN105 input.)
I plan to use the NodeMCU unit with a bi-directional level translator similar to BangGood 1033749 or SparkFun BOB-12009.

1 Like

For those of you that have done this successfully, did you tie the tx and rx to 5v with 2 resistors? The SwiCago github page suggests this is necessary, but from the pictures above doesn’t look to have been done.

I did not do it and have not had any issues.

Great job @Skipjack. Thanks!

In the “Mtsubishi_heatpump_mqtt_esp8266_esp32.h” I can’t find “// wifi settings”, “// mqtt server settings” and “// mqtt client settings” sections. At least under those names.

Should I input data directly in the Setup()? The client_id is the one inside Wifi.hostname()? Should I change the ota_password and client_id in the OTA section?

void setup() {
pinMode(redLedPin, OUTPUT);
digitalWrite(redLedPin, HIGH);
pinMode(blueLedPin, OUTPUT);
digitalWrite(blueLedPin, HIGH);

WiFi.hostname(client_id);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
// wait 500ms, flashing the blue LED to indicate WiFi connecting…
digitalWrite(blueLedPin, LOW);
delay(250);
digitalWrite(blueLedPin, HIGH);
delay(250);
}

// startup mqtt connection
mqtt_client.setServer(mqtt_server, mqtt_port);
mqtt_client.setCallback(mqttCallback);
mqttConnect();

// connect to the heatpump. Callbacks first so that the hpPacketDebug callback is available for connect()
hp.setSettingsChangedCallback(hpSettingsChanged);
hp.setStatusChangedCallback(hpStatusChanged);
hp.setPacketCallback(hpPacketDebug);

#ifdef OTA
ArduinoOTA.setHostname(client_id);
ArduinoOTA.setPassword(ota_password);
ArduinoOTA.begin();
#endif

hp.connect(&Serial);

lastTempSend = millis();
}

Thank you!!!

That is not Mtsubishi_heatpump_mqtt_esp8266_esp32.h. it is mtsubishi_heatpump_mqtt_esp8266_esp32.ino. mtsubishi_heatpump_mqtt_esp8266_esp32.h is in the same directory.

Done. Thanks!

Hey guys.

I’ve been updating the how-to post to make things a bit clearer. Has anyone used it to get this to work for them (and if so, did I miss any steps?).

Question for you - can anyone guide me on what needs to be done so that I can update the configs on the D1 Minis over the air? I’m still very new to this, and want to be able to update WiFi passwords (etc) without having to open up the unit and connect a cable.

Skip

I’ll you know about the how-to when I complete it…

For the moment when you open “mitsubishi_heatpump_mqtt_esp8266_esp32” example ir Arduio IDE in my case two tabs are open “mitsubishi_heatpump_mqtt_esp8266_esp32” and “mitsubishi_heatpump_mqtt_esp8266_esp32.h”. No “Heatpump_Master” tab.

Already finished the process

Some comments:

1- The link to configure de D1 is not correct. In the first 8266 number 2 has been changed for a 1. The correct one:
http://arduino.esp8266.com/stable/package_esp8266com_index.json

2- Libraries

We now need to install the libraries needed by the Arduino sketch. Select “Tools”, then “Board: “Arduino/Genuino Uno”, and then “Boards Manager …”, and then:

Search for “esp8266”. Select “esp8266 by ESP8266 Community”, and “Install”.

Search for “json”. Select “ArduinoJson by Benoit Blanchon”, and “Install”.

Search for “pubsub”. Select “PubSubClient by Nick O”Leary”, and “Install”.

I found “esp8266” in “Boards Manager…” as it is written but not “json” and “pubsub”. I found them in “Tools” - “Library Admin” (or similar, I use the spanish version and don’t know the exact translation).

3- Files have to be placed under “custom_components/mitsubishi_mqtt/” folder

4- For platform I used

  - platform: mitsubishi_mqtt

as the SwiCago/Heatpump page on git explains. Maybe “platform: mqtt” works, I haven’t tried.

Everything works great! Great job @Skipjack. Thanks again.

1 Like

In the example header file SwiCago/HeatPump/examples/mitsubishi_heatpump_mqtt_esp8266_esp32/mitsubishi_heatpump_mqtt_esp8266_esp32.h near the top uncomment the #define and password for over-the-air (OTA) updates:

#define OTA
const char* ota_password = "<YOUR OTA PASSWORD GOES HERE>";

After you flash the firmware, you’ll see the port in Arduino IDE based on the IP address of the unit.

I have 6 Mitsubishi units controlled in HA using this firmware. It’s great. I created a different header file for each unit and uncomment the one I’m flashing in the .ino file.

Hey Skipjack,

Works for me! I wound up using the same board and pigtail that you did. Instead of soldering directly to the pin headers like you did (since my soldering skills suck). I did solder the pin header onto the board like you did but then I soldered to one of the pin header connectors? that come with the D1 mini to the pig tail cables. I can then just plug the D1 mini into the soldered board thing. https://imgur.com/ip5HMKR is a picture. Followed all of your writeup, which is awesome and things still weren’t working for me. The issue was mosquitto on HA for some reason. I just spun up another VM at home, installed mosquitto, configured it, and suddenly everything worked. I did need to add the following to my configuration.yaml file though.

mqtt:
    broker: local mqtt ip address
    port: 1883
    username: mqtt username here
    password: mqtt password here
    client_id: some unique client id

NOTE! Below text is inaccurate at this time. Leaving in case someone else runs into these issues.

This has been really helpful, thank you! I think I've got everything in place. In testing with the current HA version, 0.93.2, I'm seeing some issues with setting up the mitsubiti_mqtt platform, looks to be python errors. I know I have the custom components in the right place, can you confirm what version of HA you are on and if any of the recent updates might have broken this integration?

Thanks kindly @mktbs. I think the pin header is a great idea, and updated the instructions.

Thanks @shampeon!

Skip