Mitsubishi Wifi Module WF-RAC (Smart M-Air)

You are synocommunity.com for the homeassistant package I see?
If I look that up it does have a very outdated homeassistant.

Can you look up your version?

image

yes, it is the outdated version, unfortunatly there is no newer version for a synology without docker and i do not have any other hardware where HA can run 24/7 :frowning: guess i’ll have to wait untill WF-RAC is supported by Homey… thanks for your work and effort though!

Hi…
I’m trying to code your great project in Javascript.
But I don’t understand the encoding of the airconstat string.

Could someone perhaps explain to me how the string is decoded?

Hi guys, great job done. The integration works fine. Is somebody werking on additional commands like vertical swinging modes?

Regards

Why I can’t send Data to my climate ?
The response is the same as before…

My Code :

#!/usr/bin/python3
# -*- coding: iso-8859-1 -*-

from sys import argv
from aenum import StrEnum
from wfrac.repository import Repository
from wfrac.rac_parser import RacParser
from wfrac.models.aircon import AirconStat
from datetime import datetime
import os


# KLIMAANLAGE
KLIMA_HOSTNAME = "192.168.5.184"
KLIMA_PORT = 51443

operator_id = "1"
device_id = "2"
    
r = Repository(hostname=KLIMA_HOSTNAME, port=KLIMA_PORT, operator_id=str(operator_id), device_id=str(device_id))
details = r.get_details()


date = datetime.now()


stats = r.get_aircon_stats()
par = RacParser()
aircon = par.translate_bytes(stats["airconStat"])

device_id = str(stats["airconId"])
operator_id = stats["remoteList"][0]
print (stats["remoteList"])

if str(aircon.Operation) == "True": klima_status = 1
if str(aircon.Operation) == "False": klima_status = 0
klima_status_bool = str(aircon.Operation).lower()
klima_presettemp = str(aircon.PresetTemp)
    
if str(stats["ledStat"]) == "0": klima_led_bool = "false"
if str(stats["ledStat"]) == "1": klima_led_bool = "true"
klima_led = int(str(stats["ledStat"]))
klima_autoheat = str(stats["autoHeating"])
klima_indoortemp = str(aircon.IndoorTemp)
klima_outdoortemp = str(aircon.OutdoorTemp)
    
klima_airflow = str(aircon.AirFlow)
if str(aircon.AirFlow) == "0": klima_fanspeed = "Auto"
if str(aircon.AirFlow) == "1": klima_fanspeed = "Niedrigste Stufe"
if str(aircon.AirFlow) == "2": klima_fanspeed = "Mittlere Stufe"
if str(aircon.AirFlow) == "3": klima_fanspeed = "Hohe Stufe"
if str(aircon.AirFlow) == "4": klima_fanspeed = "Höchste Stufe"
    
klima_modus = str(aircon.OperationMode)
if str(aircon.OperationMode) == "0": klima_modus_txt = "Auto"
if str(aircon.OperationMode) == "1": klima_modus_txt = "Kühlen"
if str(aircon.OperationMode) == "2": klima_modus_txt = "Heizen"
if str(aircon.OperationMode) == "3": klima_modus_txt = "Lüften"
if str(aircon.OperationMode) == "4": klima_modus_txt = "Trocknen"
    
klima_windUD = str(aircon.WindDirectionUD)
if str(aircon.WindDirectionUD) == "0": klima_dirud = "Hoch/Runter Auto"
if str(aircon.WindDirectionUD) == "1": klima_dirud = "Hoch"
if str(aircon.WindDirectionUD) == "2": klima_dirud = "Mittel"
if str(aircon.WindDirectionUD) == "3": klima_dirud = "Tief"
if str(aircon.WindDirectionUD) == "4": klima_dirud = "sehr Tief"
    
klima_windLR = str(aircon.WindDirectionLR)
if str(aircon.WindDirectionLR) == "0": klima_dirlr = "Links/Rechts Auto"
if str(aircon.WindDirectionLR) == "1": klima_dirlr = "Links / Links"
if str(aircon.WindDirectionLR) == "2": klima_dirlr = "Links / Mitte"
if str(aircon.WindDirectionLR) == "3": klima_dirlr = "Mitte / Mitte"
if str(aircon.WindDirectionLR) == "4": klima_dirlr = "Mitte / Rechts"
if str(aircon.WindDirectionLR) == "5": klima_dirlr = "Rechts / Rechts"
if str(aircon.WindDirectionLR) == "6": klima_dirlr = "Links / Rechts"
if str(aircon.WindDirectionLR) == "7": klima_dirlr = "Rechts / Links"
    
klima_3dauto_bool = str(aircon.Entrust).lower()
if str(aircon.Entrust) == "True": klima_3dauto = 1
if str(aircon.Entrust) == "False": klima_3dauto = 0
    
klima_vacant = str(aircon.Vacant)
klima_coolhotjudge = str(aircon.CoolHotJudge).lower()
klima_strom = str(aircon.Electric)
klima_error = str(aircon.ErrorCode)
    
    
    

#clear = lambda: os.system('clear')
#clear()
print ("-------------------- " + date.time().strftime("%H:%M:%S") + " ---------------------")
print (" IP : " + KLIMA_HOSTNAME + " | PORT : " + str(KLIMA_PORT) )
print (" Device ID : " + device_id)
print (" Operator ID : " + operator_id)
print ("---------------------------------------------------")
print (" Status : " + klima_status_bool + "(" + str(klima_status) + ") | Preset Temp. : " + klima_presettemp + "°C")
print (" Indoor Temp : " + klima_indoortemp + "°C  | Outdoor Temp. : " + klima_outdoortemp + "°C")
print (" Modus : " + klima_modus_txt + "(" + klima_modus + ")")
print ("---------------------------------------------------")
print (" Ventilator : " + klima_fanspeed + "(" + klima_airflow + ")")
print (" Vert. Lamelle : " + klima_dirud + "(" + klima_windUD + ")")
print (" Hor. Lamelle : " + klima_dirlr + "(" + klima_windLR + ")")
print (" 3D Auto : " + klima_3dauto_bool + "(" + str(klima_3dauto) + ")")
print ("---------------------------------------------------")    
print (" LED Status : " + klima_led_bool + "(" + str(klima_led) + ")" )
print (" ??autoHeating : " + klima_autoheat)
print (" ??Vacant : " + klima_vacant)
print (" ??CoolHotJudge : "  + klima_coolhotjudge)
print (" Stromverbrauch : " + klima_strom)
print (" Fehlercode : " + klima_error)

count = 0
anzahl_att = len(argv)-1
print ("---------------------------------------------------") 
   

for x in range(1, anzahl_att+1):
    if argv[x].find("-status=") == 0:
        aircon.Operation = argv[x][8 : ].capitalize()
        print("Status wird auf " + argv[x][8 : ].capitalize() + " geschaltet.")
        count+=1

    if argv[x].find("-preset=") == 0:
        aircon.PresetTemp = float(argv[x][8 : ])
        print("PresetTemp wird auf " + argv[x][8 : ] + "°C geschaltet.")
        count+=1

    if argv[x].find("-airflow=") == 0:
        aircon.AirFlow = int(argv[x][9 : ])
        print("AirFlow wird auf " + argv[x][9 : ] + " geschaltet.")
        count+=1
        
    if argv[x].find("-dirud=") == 0:
        aircon.WindDirectionUD = int(argv[x][7 : ])
        print("WindDirectionUD wird auf " + argv[x][7 : ] + " geschaltet.")
        count+=1
        
    if argv[x].find("-dirlr=") == 0:
        aircon.WindDirectionLR = int(argv[x][7 : ])
        print("WindDirectionLR wird auf " + argv[x][7 : ] + " geschaltet.")
        count+=1
        
    if argv[x].find("-3dauto=") == 0:
        aircon.Entrust = argv[x][8 : ].capitalize()
        print("3D Auto wird auf " + argv[x][8 : ].capitalize() + " geschaltet.")
        count+=1

    if argv[x].find("-mode=") == 0:
        aircon.OperationMode = int(argv[x][6 : ])
        print("OperationMode wird auf " + argv[x][6 : ] + " geschaltet.")
        count+=1
        
print ("---------------------------------------------------")    
       
if count >> 0:
    print ("Schreibe Werte...")
    airconstat = AirconStat(aircon=aircon)
    print (airconstat.PresetTemp)
    command = par.to_base64(aircon_stat=airconstat)
    response = r.send_airco_command(airco_id=operator_id, command=command)
    aircon_changed = par.translate_bytes(input_string=response)
    print(aircon_changed.PresetTemp)
    print(operator_id)


print ("---------------------------------------------------")    

The Output :

 python3 klima_write.py -status=true -preset=20 -airflow=1 -dirud=2 -dirlr=3 -3dauto=false -mode=1
['xxxxxxxx-xxxx-xxxx-xxxx-xxxxfxxxxxxx', '', '', '']
-------------------- 20:15:20 ---------------------
 IP : 192.168.5.184 | PORT : 51443
 Device ID : a043b05ada82dAADjj6b/AAAIAAAUDgAAAAAAAf////9bpoAEQQcmigAQiAIABAQAAAAAAAOAIIr/gBDY/5QQEwAw9w==
 Operator ID : 14338eb6-xxxx-xxxx-xxxx-xxxxxxxx
---------------------------------------------------
 Status : true(1) | Preset Temp. : 19.0°C
 Indoor Temp : 19.7°C  | Outdoor Temp. : 31.3°C
 Modus : Auto(0)
---------------------------------------------------
 Ventilator : Auto(0)
 Vert. Lamelle : Hoch/Runter Auto(0)
 Hor. Lamelle : Rechts / Rechts(5)
 3D Auto : true(1)
---------------------------------------------------
 LED Status : false(0)
 ??autoHeating : 0
 ??Vacant : 0
 ??CoolHotJudge : false
 Stromverbrauch : 4.75
 Fehlercode : 00
---------------------------------------------------
Status wird auf True geschaltet.
PresetTemp wird auf 20°C geschaltet.
AirFlow wird auf 1 geschaltet.
WindDirectionUD wird auf 2 geschaltet.
WindDirectionLR wird auf 3 geschaltet.
3D Auto wird auf False geschaltet.
OperationMode wird auf 1 geschaltet.
---------------------------------------------------
Schreibe Werte...
20.0
19.0
14338eb6-xxxx-xxxx-xxxx-xxxxxxxx
---------------------------------------------------

I read the operatorID from remotelist[0]
my remotelist is :
[‘14338eb6-xxxx-xxxx-xxxx-xxxxxxxx’, ‘’, ‘’, ‘’]

Awesome integration, thank you!
It works great also with HomeKit.

Realy great functionality, even the powerusage is shown! Unfortunatly I experience a problem which I can’t identify the source off . Sometimes I can’t connect to the wifi module froms HASS. Rebooting HASS seems to work everytime. Not sure what causes this. Any thoughts?

Hey,

This is a known issue and we are working/finding on a solution for this.
See Github - Issue 15

For known the only solution is indeed rebooting Hass

Hi, Thanks, apparently I missed that and your comment. Good to hear I wasn’t doing anything wrong. I’ll be patient, the functionality I already have is incredible.

Still very happy with this integration. Great work!

Do you guys also see a big difference between your inside temp and the actual temp in the room? It’s not uncommon the AC shows 31°C when it’s only 15°C in the room. This is not an integration issue, it shows the same temps in the smart m-air app. I was wondering if there is some way to recalibrate the temp sensor.

Yes, I find it’s often wrong, I’ve raised a feature request to “solve” it

Thanks for the great integration! Now I’m looking at the energy usage cycle it gives me. During the day it increments as it seems. And it seems to reset the next day when I turn the ac on again.

The smart m-air just shows me the monthly energy usage and not for each day. Is there any way I could get the full day usage in HA as a seperate number? I’m looking at the utility sensor integration but not sure if that’s the right way to go.

Hi guys, I was reading this discussion about the Mitsubishi WiFi Module WF-RAC integration with big interest and was at first very exited to get this up and running in no time with my 4 Mitsubishi aircons. Unfortunately, my excitement got slowed down quite quick.

I am living in Thailand and Mitsubishi Thailand seems to equip their aircons with a different WiFi module. Instead of the Module WF-RAC (with the app Smart M-Air) they are using here he WiFi module IFU-WF (with the app M-HomeControl)

Anybody has any idea on this or how I could proceed to get this WiFi module addresses in Home Assistant as well? It looks like all of these WiFi modules are getting connected to the very same CN105 port on the main PCB board. Would it be the easiest to buy these WiFi adapters new. Or is there any easy way to integrate my WiFi adaptor?CN105 Connector


Appreciate any feedback highly!

Roland

I seem to remember the CN105 port being a Mitsubishi Electric thing, and not on Mitsubishi Heavy Industries HVAC units. Even though the names are confusingly similar, they are two different companies with two different product lines, and are not compatible in any way, shape or form. This integration is for the Mitsubishi Heavy Industries Wifi unit, and it won’t work for Mitsubishi Electric units.

For Mitsubishi Electric, I would take a look at this: cn105 – isaiahchia

Thanks for your hint!

@jeatheak, based on your project I just ordered the WF-RAC module! I’m very curious to see how the integration works! Are most features working now, or are you still working on things? Thank you for all your effort!

First of all let me say what a great integration, great work. But I have one question, is it possible to use an external temperature sensor. What I have now done is that I use the thermostat that I have programmed in my PLC, here I use a PID controller. This controls the set point of the air conditioning (in the past I used this to control my central heating, but I went off the gas last summer), it would be nice if this was all possible in an integration. I could also solve this in node red but because I’ve been using this for over 8 years via the PLC this was the easiest way for me. And to make this run completely smoothly, such as automatically switching on the air conditioning, etc., I actually have to reprogram the entire controller and thought I’d ask here first before I start this

Hello everybody:
I’m not sure if this is an bug and I should open an issue.
the last time i opened an issue it was wrong, so I try it this time here :slight_smile:

I get three types of messegaes from the integration ( Version 0.3.0)
And it seems that some times the Aircons do not respond, as far as I can see, it is related to this messages:

This error originated from a custom integration.

Logger: custom_components.mitsubishi_wf_rac.wfrac.device
Source: custom_components/mitsubishi_wf_rac/wfrac/repository.py:81
Integration: Mitsubishi WF-RAC (documentation)
First occurred: February 12, 2023 at 22:05:06 (15 occurrences)
Last logged: 14:30:06

Could not send airco data
Traceback (most recent call last):
  File "/config/custom_components/mitsubishi_wf_rac/wfrac/device.py", line 99, in set_airco
    response = await self._api.send_airco_command(self._airco_id, command)
  File "/config/custom_components/mitsubishi_wf_rac/wfrac/repository.py", line 116, in send_airco_command
    result = await self._post("setAirconStat", contents)
  File "/config/custom_components/mitsubishi_wf_rac/wfrac/repository.py", line 81, in _post
    response.raise_for_status()
  File "/usr/local/lib/python3.10/site-packages/requests/models.py", line 1021, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 501 Server Error: Method Not Implemented for url: http://192.168.100.59:51443/beaver/command/setAirconStat

This error originated from a custom integration.

Logger: custom_components.mitsubishi_wf_rac.wfrac.device
Source: custom_components/mitsubishi_wf_rac/wfrac/repository.py:66
Integration: Mitsubishi WF-RAC (documentation)
First occurred: February 11, 2023 at 12:13:46 (145 occurrences)
Last logged: 14:26:53

Error: something went wrong updating the airco [Klima-WoZi] values
Error: something went wrong updating the airco [Klima-Kueche] values
Error: something went wrong updating the airco [Klima-DG] values
Error: something went wrong updating the airco [Klima-Bad] values
Error: something went wrong updating the airco [Klima-Kind1] values
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/urllib3/connection.py", line 174, in _new_conn
    conn = connection.create_connection(
  File "/usr/local/lib/python3.10/site-packages/urllib3/util/connection.py", line 95, in create_connection
    raise err
  File "/usr/local/lib/python3.10/site-packages/urllib3/util/connection.py", line 85, in create_connection
    sock.connect(sa)
ConnectionRefusedError: [Errno 111] Connection refused

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/urllib3/connectionpool.py", line 703, in urlopen
    httplib_response = self._make_request(
  File "/usr/local/lib/python3.10/site-packages/urllib3/connectionpool.py", line 398, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/usr/local/lib/python3.10/site-packages/urllib3/connection.py", line 239, in request
    super(HTTPConnection, self).request(method, url, body=body, headers=headers)
  File "/usr/local/lib/python3.10/http/client.py", line 1282, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/usr/local/lib/python3.10/http/client.py", line 1328, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/usr/local/lib/python3.10/http/client.py", line 1277, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/usr/local/lib/python3.10/http/client.py", line 1037, in _send_output
    self.send(msg)
  File "/usr/local/lib/python3.10/http/client.py", line 975, in send
    self.connect()
  File "/usr/local/lib/python3.10/site-packages/urllib3/connection.py", line 205, in connect
    conn = self._new_conn()
  File "/usr/local/lib/python3.10/site-packages/urllib3/connection.py", line 186, in _new_conn
    raise NewConnectionError(
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0x7f3faf3c3820>: Failed to establish a new connection: [Errno 111] Connection refused

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/requests/adapters.py", line 489, in send
    resp = conn.urlopen(
  File "/usr/local/lib/python3.10/site-packages/urllib3/connectionpool.py", line 787, in urlopen
    retries = retries.increment(
  File "/usr/local/lib/python3.10/site-packages/urllib3/util/retry.py", line 592, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='192.168.100.61', port=51443): Max retries exceeded with url: /beaver/command/getAirconStat (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f3faf3c3820>: Failed to establish a new connection: [Errno 111] Connection refused'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/config/custom_components/mitsubishi_wf_rac/wfrac/device.py", line 53, in update
    response = await self._api.get_aircon_stats()
  File "/config/custom_components/mitsubishi_wf_rac/wfrac/repository.py", line 110, in get_aircon_stats
    result = await self._post("getAirconStat")
  File "/config/custom_components/mitsubishi_wf_rac/wfrac/repository.py", line 66, in _post
    response = await self._hass.async_add_executor_job(
  File "/usr/local/lib/python3.10/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/local/lib/python3.10/site-packages/requests/api.py", line 115, in post
    return request("post", url, data=data, json=json, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/requests/api.py", line 59, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/requests/sessions.py", line 587, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python3.10/site-packages/requests/sessions.py", line 701, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/requests/adapters.py", line 565, in send
    raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='192.168.100.61', port=51443): Max retries exceeded with url: /beaver/command/getAirconStat (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f3faf3c3820>: Failed to establish a new connection: [Errno 111] Connection refused'))

Sometimes I get only:

Logger: homeassistant.helpers.entity
Source: helpers/entity.py:548
First occurred: February 11, 2023 at 11:48:56 (91 occurrences)
Last logged: 10:12:00

Update of climate.klima_schlafzimmer is taking over 10 seconds
Update of climate.klima_kind1 is taking over 10 seconds
Update of climate.klima_kueche is taking over 10 seconds
Update of climate.klima_bad is taking over 10 seconds

I think it is also related …should we/can we increase the timeout?
Anybody any other suggestions for this? Thank you :slight_smile:

I have a SRK-5–ZMX-S Mitsubishi airco (floormodel). And a Smart M-Air app. Everything works in de app, only the option Grafic Electricity Bill/ Account does not work.
In the manual of the Smart M-Air app on page 37: Depending on the type airco you connect, it can be that this function/ option (grafic electricity account) is not available.
Question: is there a list where you can see, for which airco’s this option is available?
Where can I check if this option is available for my airco?

Maybe you can see it in the catalogue on the Mitsubishi HI Site …you can download pdf file with all devices as far as I know.
but if the app does not show it, then your device should not have the necessary sensor.

But you can measure the consumed electricity power with another sensor…I use a shelly 3em for this for example

1 Like