Mitsubishi Heavy Industries MHI air conditioning with WF-RAC binding development

@bartsnijder if you’re still interested I can prepare a jar for whatever version OH you’re using. Plenty of stuff works, all read-only for now, so it’s safe to test.

1 Like

Sorry for the complete lack of response. With a cold summer (airco switched on this week for the first time), my focus was somewhere else. I’m on OH 4.1.3 and I’m always happy to try stuff. Still quite busy with other projects so I’m not sure if I can contribute a lot other than being a debug user for now.

1 Like

No problem! :grinning: It’s not yet ready for the real world usage. And I’m perfectly fine on my own (+ forum help, thank you!!).
I’m not sure what are the typical ways of sending jar file… You can get the 4.1.3 version from here. I install it from the OH console. There is no dedicated wodget yet, but it’s planned. No control functions, all read only. It should be safe, but I give no warranty :innocent:

HI @PrzemoF

I’ve finally got a coding setup backup but looks like you’ve made a lot of progress.

I continued with my generic java “library” for MHI aircon’s. I can receive data and update my aircon object but for some reason my setAirconStat isn’t updating the unit. I’ll keep debugging but just in case it’s useful I’ve got a full Parser porting the python HA addon here:

matt1309/mhiJava

If you spot why the sending command isn’t working please let me know.

1 Like

Can you write a 3 line manual how to run it please? My code seems to be fairly stable, but it’s still read only.

I’ll get the github repo readme updated this evening. I’m in a similar situation where I can read the data but not write to the aircon unit. I’ll need to debug with wireshark this evening to see how my commands differ from the app.

In short though:

  // Create aircon object
        AirCon aircon = new AirCon();

        // Set hostname and port.
        aircon.sethostname("192.168.0.12");
        aircon.setport("51443");
        aircon.setDeviceID("e8165615c7d6"); 
        aircon.setOperatorID("openhab");

Then to get aircon data you would send:

 try {
            // Get initial stats from aircon unit and parse into the aircon object.
            aircon.getAirconStats(false);
            aircon.printDeviceData(); //for debugging to see aircon data has updated

        } catch (Exception e) {

            System.out.println(e.toString());
        }

See Aircon.java for a full list of attributes you can get/set. I’ve used methods to get/set the attributes just in case the library is ever used in a multithread environment the methods make it somewhat threadsafe.

To write change to the aircon unit you first change the attributes like so:

 aircon.setPresetTemp(21); 

Then finally the part that’s not working and needs debugging is encoding the command and sending it to the aircon unit. I suspect I’m missing something from the “send” command that’s needed. As the aircon unit replies but it doesnt update the values. So my guess is I’m missing something from the command.

EDIT: I’m not handling the account adding side of things set so that might be it thinking about it

String command = aircon.parser.toBase64();

        try {
            // sending command to the aircon unit itself
            String response = aircon.sendAircoCommand(command);

           aircon.parser.translateBytes(response); //eventually this will be hidden in sendAircoCommand function, this just writes the response to the attributes in Aircon Object, for debugging I've done in manually but eventually this will be "automatic" ie handled in sendAircoCommand method. 

            aircon.printDeviceData(); //to print response from aircon unit

        } catch (Exception e) {

            System.out.println(e.toString());
        }

1 Like

@PrzemoF

It was the account not being added. I can update the aircon unit now. I’ll type up how to use the library/tidy up tonight and send over a useful readme once I’m done

1 Like

Sounds great! :heart_eyes:

I’m really lost with openhab addon layouts, feels like a maze.

If I can wrap my head around it or if you can translate my library commands/methods then I’m happy to help as much as I can with the addon.

I’ve used:
apache http client
and org.json libraries.

The rest is from java.time and java.util so nothing fancy.

1 Like

Hi @PrzemoF

I’ve updated the readme now. I’ve had a look at what you’ve done already, slowly getting me head around it. I’m half tempted to just use my java to make a mqtt bridge to save me learning the openhab addon structure. Or see how much gpt can generate for me.

mhiJava/README.md at master · matt1309/mhiJava

1 Like

You can have a look at my Intesis Binding, which works very well for Intesis/AirconWithMe adaptors in MHI devices,

@Matt_Jayne I still have no idea how to use it :blush:
How do you compile and run it?
Feel free to ignore this question - I’ll be analysing your code soon to get my code fully functional :roll_eyes:

Hi @PrzemoF

I’ll try add some more detail this evening. I’ve started adding MQTT bridge.
Essentially clone the repo, then build using maven. (I used VS code to code, so I clone the repo then just run and build). I’ll write out detailed explanation.

However you can also just copy the AirCon.java and create objects in java code as described in the readme. Everything (including parser) is included within the one class.

1 Like

Hi @PrzemoF

I’ve done my best to extend the readme file with some more detail. Hope this helps. I’m still working on it/adding the MQTT bridge so if you do need specific functionality shout i can slot it in.

matt1309/mhiJava

1 Like

Hi @PrzemoF

I’ve done my best to extend the readme file with some more detail. Hope this helps. I’m still working on it/adding the MQTT bridge so if you do need specific functionality shout i can slot it in.

matt1309/mhiJava

EDIT: This repo has pretty much turned into the place I’m writing a MQTT bridge for the aircon units (working but very messy/not tested for long period of time). I’ve got to add a settings file so you can add multiple aircon’s atm the IP etc is hard coded.
Once that’s done I’ll make a new repo that is just a java class file for controlling the aircon unit in java. The MQTT bridge does do this but it has the extra mqtt elements that you wont need/care about.

1 Like

I didn’t get into the code yet, but thank you for the efforts!
Edit: I read the code, looks like I understand enough to digest parts and add them to my code. :nerd_face: Or at least I will be able to deduct the steps needed to send commands. I see you use the lookup table for the temperatures - I decided to go for a function (analysed the data and used polynominal function that was a good fit to the lookup table.

What’s the story with the MQTT bridge - is it your plan for the integration of the MHI AC into openHAB?

Hi @PrzemoF

I copied most of the parsing from the home assistant python integration. They used a map so I followed suit. I like the function solution though, much cleaner.

Yes I’m pretty close to having it in beta at least, just need to work on the openhab side. ie setting up mapping transformations for the modes etc.

Once I’ve got that sorted I’ll leave the bridge running for a few days see if there’s any bugs then share my openhab (mainly the mqtt.things and mqtt.items) in case it’s useful for anyone.

At the moment the bridge literally just runs as a java service. It queries the aircon and sends to mqtt topics and vice versa, ie anything posted to the mqtt command topics are sent back to aircon. Each time a message is received in the mqtt commandtopics the data is sent back to aircon and the response from aircon is loaded into response topics. Each datapoint on the aircon has a commandtopic and statetopic on the mqtt instance.

The bridge atm takes an input of “interval” this is how long the bridge will wait before querying the aircon unit (assuming there’s no commands sent as it will also query the aircon unit whenever a command is sent). I think i’ve got logic to prevent overloading the ac unit with requests but that’s untested at the moment.

1 Like

Hi @PrzemoF and anyone else that stumbled upon this.

I imagine @PrzemoF solution will be far more polished once the remaining updates are made.
However in the mean time I’ve made a standalone mqtt bridge (written in java, the aircon coms is written in one class so if anyone wants to use it in other projects feel free to rip the AirCon.java from the repo). It lets me integrate the mhiAircon into openhab using the standard MQTT binding, and Map transform addons with a Mosquitto mqtt server running somewhere.

It’s very much in an alpha stage. At the moment I’m testing it on my single unit. I think I’ve written the code in a way that you can run one instance of the service for multiple aircon units to be bridged to mqtt however I dont have multi units to debug this on.

The repo is here:
https://github.com/matt1309/mhiJava

Just a few details on setup:
config.json looks like this:

{

"globalSettings" :{"AirconQueryinterval": 60000
                    },

"mqttSettings": {"hostname": "192.168.0.101",
                "username": "openhab",
                "password":"test123"},

"aircon": [{"hostname":"192.168.0.12",
            "port": "51443",
            "deviceID": "e8165615c7d6",
            "operatorID": "openhab"
            }
]

}

Interval is 60 seconds in milliseconds

Then you just run java -jar mhiJava.jar (or set it up as a service on your preferred operating system, I can share systemd.service file I’m using on a pi if it’s helpful).

In terms of openhab setup:
Things:

Bridge mqtt:broker:myMQTTBroker [ host="192.168.0.101", username="openhab", password="test123" ]


Thing mqtt:topic:mything "myMQTTthing" (mqtt:broker:myMQTTBroker) {
    Channels:
    Type number : ShedSetTemp "Shed Set temp" [ stateTopic="aircon/ec0baef63b5b/ReadOnly/presetTemp", commandTopic="aircon/ec0baef63b5b/ReadWrite/presetTemp" ]
    Type number : ShedIndoorTemp "Shed Temp" [ stateTopic="aircon/ec0baef63b5b/ReadOnly/indoorTemp"]
    Type number : ShedOutdoorTemp "Shed Outside Temp" [ stateTopic="aircon/ec0baef63b5b/ReadOnly/outdoorTemp"]




    Type string : AirConID "AirCon ID" [ stateTopic="aircon/ec0baef63b5b/ReadOnly/AirConID"]
    Type string : Hostname "Hostname" [ stateTopic="aircon/ec0baef63b5b/ReadOnly/hostname"]
    Type string : Port "Port" [ stateTopic="aircon/ec0baef63b5b/ReadOnly/port"]
    Type string : DeviceID "Device ID" [ stateTopic="aircon/ec0baef63b5b/ReadOnly/deviceID"]
    Type string : ErrorCode "Error Code" [ stateTopic="aircon/ec0baef63b5b/ReadOnly/errorCode"]





Type switch : Status "Status" [ stateTopic="aircon/ec0baef63b5b/ReadOnly/status", transformationPattern="MAP:boolswitch.map", commandTopic="aircon/ec0baef63b5b/ReadWrite/status", transformationPatternOut="MAP:boolswitch.map" ]
Type switch : Entrust "Entrust" [ stateTopic="aircon/ec0baef63b5b/ReadOnly/entrust", transformationPattern="MAP:boolswitch.map", commandTopic="aircon/ec0baef63b5b/ReadWrite/entrust", transformationPatternOut="MAP:boolswitch.map" ]
Type switch : Vacant "Vacant" [ stateTopic="aircon/ec0baef63b5b/ReadOnly/vacant", transformationPattern="MAP:boolswitch.map", commandTopic="aircon/ec0baef63b5b/ReadWrite/vacant", transformationPatternOut="MAP:boolswitch.map" ]
Type switch : CoolHotJudge "Cool/Hot Judge" [ stateTopic="aircon/ec0baef63b5b/ReadOnly/coolHotJudge", transformationPattern="MAP:boolswitch.map", commandTopic="aircon/ec0baef63b5b/ReadWrite/coolHotJudge", transformationPatternOut="MAP:boolswitch.map" ]
Type switch : SelfCleanOperation "Self-Clean Operation" [ stateTopic="aircon/ec0baef63b5b/ReadOnly/selfCleanOperation", transformationPattern="MAP:boolswitch.map", commandTopic="aircon/ec0baef63b5b/ReadWrite/selfCleanOperation", transformationPatternOut="MAP:boolswitch.map" ]
Type switch : SelfCleanReset "Self-Clean Reset" [ stateTopic="aircon/ec0baef63b5b/ReadOnly/selfCleanReset", transformationPattern="MAP:boolswitch.map", commandTopic="aircon/ec0baef63b5b/ReadWrite/selfCleanReset", transformationPatternOut="MAP:boolswitch.map" ]





    Type number : Electric "Electric" [ stateTopic="aircon/ec0baef63b5b/ReadOnly/electric"]

    Type string : AirFlow "Air Flow" [ stateTopic="aircon/ec0baef63b5b/ReadOnly/airFlow", transformationPattern="MAP:fanmode.map", commandTopic="aircon/ec0baef63b5b/ReadWrite/airFlow", transformationPatternOut="MAP:fanmode.map" ]
    Type string : WindDirectionUD "Wind Direction UD" [ stateTopic="aircon/ec0baef63b5b/ReadOnly/windDirectionUD", transformationPattern="MAP:swingmode.map", commandTopic="aircon/ec0baef63b5b/ReadWrite/windDirectionUD", transformationPatternOut="MAP:swingmode" ]
    Type string : WindDirectionLR "Wind Direction LR" [ stateTopic="aircon/ec0baef63b5b/ReadOnly/windDirectionLR", transformationPattern="MAP:swinghorizontalmode.map", commandTopic="aircon/ec0baef63b5b/ReadWrite/windDirectionLR",transformationPatternOut="MAP:swinghorizontalmode.map" ]


    Type switch : Operation "Operation" [ stateTopic="aircon/ec0baef63b5b/ReadOnly/operation", transformationPattern="MAP:boolswitch.map", commandTopic="aircon/ec0baef63b5b/ReadWrite/operation", transformationPatternOut="MAP:boolswitch.map" ]
    Type string : OperationMode "Operation Mode" [ stateTopic="aircon/ec0baef63b5b/ReadOnly/operationMode", transformationPattern="MAP:operationMode.map", commandTopic="aircon/ec0baef63b5b/ReadWrite/operationMode",transformationPatternOut="MAP:operationMode.map" ]

Then the items:

Group gAirCon "AirCon"

Number ShedSetTemp "Shed Set temp" (gAirCon) { channel="mqtt:topic:mything:ShedSetTemp" }
Number ShedIndoorTemp "Shed Temp" (gAirCon) { channel="mqtt:topic:mything:ShedIndoorTemp" }
Number ShedOutdoorTemp "Shed Outside Temp" (gAirCon) { channel="mqtt:topic:mything:ShedOutdoorTemp" }

String AirConID "AirCon ID" (gAirCon) { channel="mqtt:topic:mything:AirConID" }
String Hostname "Hostname" (gAirCon) { channel="mqtt:topic:mything:Hostname" }
String Port "Port" (gAirCon) { channel="mqtt:topic:mything:Port" }
String DeviceID "Device ID" (gAirCon) { channel="mqtt:topic:mything:DeviceID" }
String ErrorCode "Error Code" (gAirCon) { channel="mqtt:topic:mything:ErrorCode" }


Switch Status "AirCon Status" (gAirCon) { channel="mqtt:topic:mything:Status" }


DateTime LastUpdated "Last Updated [%1$tF %1$tT]" <time> (gAirCon)



Switch Entrust "Entrust" (gAirCon) { channel="mqtt:topic:mything:Entrust" }
Switch Vacant "Vacant" (gAirCon) { channel="mqtt:topic:mything:Vacant" }
Switch CoolHotJudge "Cool/Hot Judge" (gAirCon) { channel="mqtt:topic:mything:CoolHotJudge" }
Switch SelfCleanOperation "Self-Clean Operation" (gAirCon) { channel="mqtt:topic:mything:SelfCleanOperation" }
Switch SelfCleanReset "Self-Clean Reset" (gAirCon) { channel="mqtt:topic:mything:SelfCleanReset" }

Number Electric "Electric" (gAirCon) { channel="mqtt:topic:mything:Electric" }

String AirFlow "Air Flow" (gAirCon) { channel="mqtt:topic:mything:AirFlow" }
String WindDirectionUD "Wind Direction UD" (gAirCon) { channel="mqtt:topic:mything:WindDirectionUD" }
String WindDirectionLR "Wind Direction LR" (gAirCon) { channel="mqtt:topic:mything:WindDirectionLR" }

Switch Operation "Operation" (gAirCon) { channel="mqtt:topic:mything:Operation" }
String OperationMode "Operation Mode" (gAirCon) { channel="mqtt:topic:mything:OperationMode" }

Sitemap:

Text icon="switch" item=Status
Text item=LastUpdated label="Last updated [%1$tA, %1$tH:%1$tM, %1$td.%1$tm.%1$tY]" icon="temperature"
Switch icon="switch" item=Operation
Slider icon="heating" label="Set Temperature [%.1f]" item=ShedSetTemp maxValue=30 minValue=10 step=0.5
Text item=ShedIndoorTemp label="Shed Temperature"
Selection item=OperationMode label="Operation Mode" mappings=["Auto"="Auto", "Cool"="Cool", "Heat"="Heat", "Fan Only"="Fan Only", "Dry"="Dry"]
Selection item=WindDirectionUD label="Fan Up/Down" mappings=["Up/Down Auto"="Up/Down Auto", "Highest"="Highest", "Middle"="Middle", "Normal"="Normal", "Lowest"="Lowest"]
Selection item=WindDirectionLR label="Fan Left/Right" mappings=["Left/Right Auto"="Left/Right Auto", "Left-Left"="Left-Left", "Left-Center"="Left-Center", "Center-Center"="Center-Center", "Center-Right"="Center-Right", "Right-Right"="Right-Right", "Left-Right"="Left-Right", "Right-Left"="Right-Left"]

The lastUpdated item you might have spotted is going to be updated via rules to adjust the “status” item in the event the java service that’s forwarding data between mqtt and aircon (and back) goes down. I’ll have an openhab rule that will check when the aircon data was last sent, if it exceeds the expected interval then status will change to no.

Any additional features/requests or improvements feel free to let me know.
@PrzemoF shout if there’s anything I can lend a hand on on the main addon itself.

1 Like

Fantastic work - I’m trying right not go back to the development :innocent:

A side note for multisplits (2 indoor, 1 outdoor in my case) - if one indoor unit is working and the other indoor is switched off the temperature readings will not show skewed values. The reason is that the fluid is circulating through both indoor units. I consulted a professional and this is normal. I have 2 separate multisplit sets and they both work that way.

Hi @Matt_Jayne and @PrzemoF - I’ve just had an MHI AC installed with WF-RAC. I want to integrate it into my openHAB installation. Based on your experience, should I be going down the binding path or the MQTT path? Thanks.