Hi, I have a Mitsubishi heavy industry air conditioner with the WF-Rac wifi module (Smart M-Air)
And it would be nice if it could be added to Home Assistant as an integration so that I can control and automate it with Home Assistant.
By the way, The Smart M-Air is different from the Mel cloud app from Mitsubishi Electric (is a different company)
Ah yes, this would be great indeed. I just installed the WF-Rac wifi module and agreed, the Smart M-Air app is quite good, but I’d really love to see this integrated in HA. Had I known this, I’d have gone for the simpeler am-mhi-01 wifi module which works with Airconwithme that can be integrated in HA.
I also have 3 of these units. Still trying to find out how to interpret the response I get from those modules.
You can request data from those units by sending a request via port 51443.
http://:51443/beaver/command/getAirconStat
Send json: ‘{“apiVer”:“1.0”,“command”:“getAirconStat”,“deviceId”:“1234567890ABCDEF”,“operatorId”:“d2bc4571-1cea-4858-b0f2-34c18bef1901”,“timestamp”:1649703587}’
But airconStat is encoded. I tried to decompile the apk, but I cannot seem to find the translation.
App is finding the units by sending a multicast _beaver._tcp.
And the APK does have a mapper class, but I cannot read it correctly: ResponseAirconMApper.class and ResponseArconStartMapper.class contain mappings
I just got a new airco unit this week with a smart m-air wifi adaptor. So it would be nice to also connect it wit homeassistant.
As far as I can see there is no open api yet.
Hi All,
I have just received this airco, together with the WF-RAC module, and would also like to control this device from Home Asssitant.
Using “mitmproxy” I have setup a detour for my iPhone to capture the app’s traffic.
I have discovered the following commands:
/beaver/command/updateAccountInfo
/beaver/command/getDeviceInfo
/beaver/command/getAirconStat
/beaver/command/setAirconStat
Regarding the AirconStat string, I have captured the request and response for several commands. I do not have the idea that this string has any kind of encryption. After changing the temperature with halve a degree, I can see the string move 5 characters (see the end of the next block). This would also suggest that the(set) temperature is encoded as an integer. (perhaps offset from 18-30 degrees?)
AirconStat request and response after action in App
AAfij7L/AAAAAAAQCwAAAAAAAf////9ZuYAEQAcylwAAiAAAAAEAAAAAAAOAIJf/gBCl/5QQAADucw==
AAfij7L/AAAAAAAQCwAAAAAAAf////9ZuYAEQAcylwAAiAAAAAEAAAAAAAOAIJf/gBCl/5QQAADucw==
AAfij7L/AAAAAAAQCwAAAAAAAf////9ZuYAEQAcylwAAiAAAAAEAAAAAAAOAIJf/gBCl/5QQAADucw==
AAfij7L/AAAAAAAQCwAAAAAAAf////9ZuYAEQAcylwAAiAAAAAEAAAAAAAOAIJf/gBCl/5QQAADucw==
set airco on Auto mode, vent auto, 25.0
AAfjj7L/AAAAAAAQCwAAAAAAAf////+vbAAAQQcy/wAAAAAAAAEAAAAAAAH/////+o0=
AAfjj7L/AAAAAAAQCwAAAAAAAf////+vbIAEQQcylwAAiAAAAAEAAAAAAAOAIJf/gBCl/5QQAABCcA==
set to cooling
AAfrj7L/AAAAAAAQCwAAAAAAAf/////ZowAASQcy/wAAAAAAAAEAAAAAAAH/////jEI=
AAfrj7L/AAAAAAAQCwAAAAAAAf/////Zo4AESQcylQAAiAIAAAEAAAAAAAOAIJX/gBCl/5QQAADroA==
set to heating
AAfzj7L/AAAAAAAQCwAAAAAAAf////9i4gAAUQcy/wAAAAAAAAEAAAAAAAH/////NwM=
AAfzj7L/AAAAAAAQCwAAAAAAAf////9i4oAEUQcylAAAgQIAAAEAAAAAAAOAIJT/gBCl/5QQAADKcg==
AAfzj7L/AAAAAAAQCwAAAAAAAf////9i4oAEUQcykwAAgQAAAAEAAAAAAAOAIJP/gBCk/5QQAAAJLQ==
AAfzj7L/AAAAAAAQCwAAAAAAAf////9i4oAEUQcykwAAgQAAAAEAAAAAAAOAIJP/gBCk/5QQAAAJLQ==
set to vent
AAfvj7L/AAAAAAAQCwAAAAAAAf////9ixAAATQcy/wAAAAAAAAEAAAAAAAH/////NyU=
AAfvj7L/AAAAAAAQCwAAAAAAAf////9ixIAETQcykwAAiAAAAAEAAAAAAAOAIJP/gBCk/5QQAADjig==
set to dry
AAfnj7L/AAAAAAAQCwAAAAAAAf////8UCwAARQcy/wAAAAAAAAEAAAAAAAH/////Qeo=
AAfnj7L/AAAAAAAQCwAAAAAAAf////8UC4AERQcykwAAiAAAAAEAAAAAAAOAIJP/gBCk/5QQAACM0A==
set to auto
AAfjj7L/AAAAAAAQCwAAAAAAAf////+vbAAAQQcy/wAAAAAAAAEAAAAAAAH/////+o0=
AAfjj7L/AAAAAAAQCwAAAAAAAf////+vbIAEQQcykgAAiAAAAAEAAAAAAAOAIJL/gBCk/5QQAABHpQ==
change temp to 20.0
AAfjj6j/AAAAAAAQCwAAAAAAAf/////TYAAAQQco/wAAAAAAAAEAAAAAAAH/////hoE=
AAfjj6j/AAAAAAAQCwAAAAAAAf/////TYIAEQQcokQAAiAAAAAEAAAAAAAOAIJH/gBCj/5QQAAAThw==
vent auto -> 1
AAfjiKj/AAAAAAAQCwAAAAAAAf/////K6AAAQQAo/wAAAAAAAAEAAAAAAAH/////nwk=
AAfjiKj/AAAAAAAQCwAAAAAAAf/////K6IAEQQAokQAAiAAAAAEAAAAAAAOAIJH/gBCj/5QQAADWqQ==
vent 1->2
AAfjiaj/AAAAAAAQCwAAAAAAAf////953QAAQQEo/wAAAAAAAAEAAAAAAAH/////LDw=
AAfjiaj/AAAAAAAQCwAAAAAAAf////953YAEQQEokQAAiAIAAAEAAAAAAAOAIJH/gBCj/5QQAADS6w==
vent 2->3
AAfjiqj/AAAAAAAQCwAAAAAAAf////+sgwAAQQIo/wAAAAAAAAEAAAAAAAH/////+WI=
AAfjiqj/AAAAAAAQCwAAAAAAAf////+sg4AEQQIokQAAiAIAAAEAAAAAAAOAIJH/gBCj/5QQAAAtwA==
vent 3->4
AAfjjqj/AAAAAAAQCwAAAAAAAf////9gVQAAQQYo/wAAAAAAAAEAAAAAAAH/////NbQ=
AAfjjqj/AAAAAAAQCwAAAAAAAf////9gVYAEQQYojwAAiAIAAAEAAAAAAAOAII//gBCj/5QQAADSPA==
vent 4-> auto
AAfjj6j/AAAAAAAQCwAAAAAAAf/////TYAAAQQco/wAAAAAAAAEAAAAAAAH/////hoE=
AAfjj6j/AAAAAAAQCwAAAAAAAf/////TYIAEQQcojgAAiAIAAAEAAAAAAAOAII7/gBCj/5QQAABgZQ==
3d auto on
AAfjj6j/AAAAAAAQDwAAAAAAAf////+UMQAAQQco/wAAAAAAAAUAAAAAAAH/////wdA=
AAfjj6j/AAAAAAAQDwAAAAAAAf////+UMYAEQQcojAAAiAIAAAUAAAAAAAOAIIz/gBCi/5QQAABsSg==
3d auto off
AAfjj6j/AAAAAAAQCwAAAAAAAf/////TYAAAQQco/wAAAAAAAAEAAAAAAAH/////hoE=
AAfjj6j/AAAAAAAQCwAAAAAAAf/////TYIAEQQcojAAAiAIAAAUAAAAAAAOAIIz/gBCj/5QQAABIxw==
vertical all -> up
AAejj6j/AAAAAAAQCwAAAAAAAf////+lewAAAQco/wAAAAAAAAEAAAAAAAH/////8Jo=
AAejj6j/AAAAAAAQCwAAAAAAAf////+le4AEAQcoigAAiAIAAAEAAAAAAAOAIIr/gBCj/5QQAABxUw==
vertical up -> up-1
AAejn6j/AAAAAAAQCwAAAAAAAf/////2EAAAARco/wAAAAAAAAEAAAAAAAH/////o/E=
AAejn6j/AAAAAAAQCwAAAAAAAf/////2EIAEARcoigAAiAIAAAEAAAAAAAOAIIr/gBCj/5QQAAAyTA==
vertical up-1 -> up-2
AAejr6j/AAAAAAAQCwAAAAAAAf////8DrQAAASco/wAAAAAAAAEAAAAAAAH/////Vkw=
AAejr6j/AAAAAAAQCwAAAAAAAf////8DrYAEAScoiQAAiAIAAAEAAAAAAAOAIIn/gBCj/5QQAACH/A==
vertical up-2 -> up-3
AAejv6j/AAAAAAAQCwAAAAAAAf////9QxgAAATco/wAAAAAAAAEAAAAAAAH/////BSc=
AAejv6j/AAAAAAAQCwAAAAAAAf////9QxoAEATcoigAAiAIAAAEAAAAAAAOAIIn/gBCj/5QQAADBug==
vertical back to all
AAejv6j/AAAAAAAQCwAAAAAAAf////9QxgAAATco/wAAAAAAAAEAAAAAAAH/////BSc=
AAejv6j/AAAAAAAQCwAAAAAAAf////9QxoAEATcoigAAiAIAAAEAAAAAAAOAIIn/gBCj/5QQAADBug==
temp increase from 20.0 with 0.5 increments
AAfjj6j/AAAAAAAQCwAAAAAAAf/////TYAAAQQco/wAAAAAAAAEAAAAAAAH/////hoE=
AAfjj6n/AAAAAAAQCwAAAAAAAf/////MvgAAQQcp/wAAAAAAAAEAAAAAAAH/////mV8=
AAfjj6r/AAAAAAAQCwAAAAAAAf/////MzAAAQQcq/wAAAAAAAAEAAAAAAAH/////mS0=
AAfjj6v/AAAAAAAQCwAAAAAAAf/////TEgAAQQcr/wAAAAAAAAEAAAAAAAH/////hvM=
AAfjj6z/AAAAAAAQCwAAAAAAAf/////MKAAAQQcs/wAAAAAAAAEAAAAAAAH/////mck=
AAfjj63/AAAAAAAQCwAAAAAAAf/////T9gAAQQct/wAAAAAAAAEAAAAAAAH/////hhc=
AAfjj67/AAAAAAAQCwAAAAAAAf/////ThAAAQQcu/wAAAAAAAAEAAAAAAAH/////hmU=
end at 23
airco off:
AAfij67/AAAAAAAQCwAAAAAAAf////8lUQAAQAcu/wAAAAAAAAEAAAAAAAH/////cLA=
Hopefully my findings can help others in the reverse engineering of this protocol. I will post new findings when they occur, but am limited in my time .
Edit:
I have also just tried to decompile the APK (from https://m.apkpure.com/nl/smart-m-air/jp.co.mhi_mth.smartmair) using http://www.javadecompilers.com/.
The decompiled file “p008jp.p009co.mhi_mth.smartmair.util.AirconStatCoder.java” seems to contain the function that encodes this string. It contains a lot of bitwise operation, which is somewhat out of my league as a mechanical engineer.
I have transferred the decoding function from the Android App into Python. “ParseAirconStat.py” contains a function to decode the AirconStat string to the correct data. This data is structured into an “AirconStat” module.
Please bear in mind, that much of the structure of the code is transferred from the Android App, which is basically one large set of if statements. I have not had the time yet to clean this up.
My next step will be to implement the encoding function.
This is great news! If I can help in some way, let me know. I can program a bit in Python, but I’m not fluent in it. More for a hobby then profesionally (I’m a network engineer).
But if I can do some testing or other stuff, let me know!
I will also try to take a look when I have time, I’m a software developer so should be able to help (time is the only issue). Would be very interested to see this working.
The newest code has just been pushed to Github.
I think the decoding now can be done quite reliably.
The encoding of the AirconStat string still has some problems. To test the decoding, I have created a basic interface to the WF-RAC’s API interface. The routine “JSON.py” can request the state of the WF-RAC and display it.
Temperature is probably a bit off, because of the change in method to convert from integer value to temperature. This used to be a lookup table with 256 entries, which I have replaced by a fitted function.
The next steps should be the following:
Fix the encoding
Create a function to automatically locate the WF-RAC on the network
Integrate the code in Home-Assistant
Map the controls/sensors to applicable objects
Code that allows for periodic polling of the WF-RAC’s state
Bundle as integration?
The integration part is the part that seems the most difficult at this moment. Does anyone have experience with this part?
A few weeks back I also did some research and testen with the java apk.
Now I have written a simple decoder and encoder for the WF-RAC module.
(the encoder is based on yours)
The above wf-rac responses and encoded code of yours did help me create a simple python method for receiving and sending successfully data to the Airco.
Now i’m trying to make a integration for it but have little time at the moment.
This is great! Awesome!
I really like your structured approach of the program. And I like your elegant solution of setting the correct bits in the encoder.
When I have time I will try to have a look at the discovery method of the WF-RAC.