Need a bit of advice... Getting OH to figure out which command to send


(l1t7l3ph0o7) #1

Hey Guys, I just got a Broadlink RMpro as a pre Christmas present. and one of the things I want to do with it is control my Fujitsu Halcyon mini-split system.
I’ve been following this thread and I have to say the binding is fantastic:

I got it up and running out of the box without a single issue, which is very rare for me.
The problem is The remote for my mini-split system. When it transmits an ir code, it sends ON + system mode + fan mode + temp set point, All as one IR code. I basically have an IR code for each temp set-point, In each mode, in each fan mode eg a sample of ir commands:
ON,Heat,Temp60,FanAuto
On,Cool,Temp60,FanAuto
ON,Heat,Temp60,FanLow
On,Cool,Temp60,FanLow
ON,Heat,Temp60,FanMed
On,Cool,Temp60,FanMed
ON,Heat,Temp60,FanHigh
On,Cool,Temp60,FanHigh

So that’s 8 different IR codes that could be sent if I change the temp to 60, all of which make the mini-split do a different function.

So I guess what I’m trying to figure out is, what is the best way to have OH figure out which command it should send whenever a change is made?


(Udo Hartmann) #2

I do not have a complete recipe, but a guess:
Use some items for the different functions

Switch halSystemMode "Halcyon is [MAP(sysmode.map):%s]"
Number halFanMode "Halcyon Fan [MAP(fanmode.map):%s]"
Number halTemp "Halcyon Temp [%.1 °F]"
String halSend {...}

sysmode.map

ON=heating
OFF=cooling
NULL=-
-=-

fanmode.map

0=Auto
1=Low
2=Med
3=High
NULL=-

and now a rule to build the string to send to:

rule "send to halcyon"
when
    Item halSystemMode changed or
    Item halFanMode changed or
    Item halTemp changed
then
    var string MyString = "ON," +
    if(halSystemMode.state == ON) "Heat" else "Cool" +
    ",Temp" + (halTemp.state as Number).intValue.toString + ",Fan" +
    switch (halFanMode.state as Number) {
        case 1: "Low"
        case 2: "Med"
        case 3: "High"
        default: "Auto" // all other numbers (and NULL) are treated as Auto mode
    }
    halSend.sendCommand(MyString)
end

I’m pretty sure this code will not really work, but I think you got the idea :wink:
You will have to ensure that all items always have a correct state, or you will have to build default parameters in the rule (like the last part).


(l1t7l3ph0o7) #3

Thanks for the food for thought, definitly helps. I think I can figure it out from here.
I dont think keeping track of the current item states should be a problem once I have this working, OH will be the only thing sending commands to the mini-split. I actually have 3 of these units, they came with the house. They dont have any controls on the actual unit and I have always only had 1 remote (previous home owner lost the other 2 remotes), So after I figure this out OH will be the only thing controlling them.


(Udo Hartmann) #4

To narrow this down:

If openHAB does a restart, all states are lost, then the states of the items are NULL. Now, if building the command string, because one of the three items was set to a new state, the rule will trigger, but two of the items have no allowed state ant the command string will be wrong.


(l1t7l3ph0o7) #5

If openHAB does a restart, all states are lost, then the states of the items are NULL.

I’ve implemented MySQL persistence, so this really isn’t an issue for me. All of my items update to their Previous states before any rules are loaded.

I am having trouble figuring out how to make this rule work now though, I have spent a bit of time and effort but I’m afraid I’m not very good when it comes to strings (I’m not sure how to start the string) Or case switches for that matter.

I modified your example to use two case switches for system mode and fan mode, I don’t really know if this is the best way to do it, but I’d prefer it because there are so many different modes.

Here is my rule as it currently stands, it doesn’t work at all but I think I’m on the right track:

rule "Update Upstairs Halcyon"
when 
	Item HalUpstairsSystemMode changed or
	Item HalUpstairsFanMode changed or
	Item HalUpstairsSetPoint changed 
then
        //the string should start with the system mode
	var string TransmitMSG = select (HalUpstairsSystemMode.state as Number){
		case 0: "HalcyonOFF"  //this should be the complete string when this case is selected
		case 1: "Fan" +
		case 2: "Dry" +
		case 3: "Heat" +
		case 4: "Cool" +
	}
//then the fan mode should be added to the string (without any spaces or characters)
	select (HalUpstairsFanMode.state as Number){
		case 0: "Auto" +
		case 1: "High" +
		case 2: "Med" +
		case 3: "Low" +
		case 4: "Quiet" +
	}
//after that I need to add the current temperature set point, but only if the system is in heat or cool mode....
	if (HalUpstairsSystemMode.state>=3)(HalUpstairsSetPoint.state as Number).intValue.toString
	RMProTransmit.sendCommand(TransmitMSG)
end

Any Ideas?


(l1t7l3ph0o7) #6

Nevermind, a little persistance and I have acheived what I set out to do


(Udo Hartmann) #7

I think you will get errors because you build the string in parts, but need sometimes no additional part.

rule "Update Upstairs Halcyon"
when
    Item HalUpstairsSystemMode changed or
    Item HalUpstairsFanMode changed or
    Item HalUpstairsSetPoint changed 
then
    var string TransmitMSG
    //the string should start with the system mode
    if (HalUpstairsSystemMode.state as Number == 0)
        TransmitMSG = "HalcyonOFF"  //this should be the complete string when this case is selected
    else {
        TransmitMSG = switch (HalUpstairsSystemMode.state as Number) {
            case 1: "Fan" +
            case 2: "Dry" +
            case 3: "Heat" +
            case 4: "Cool" +
        }
        //then the fan mode should be added to the string (without any spaces or characters)
        switch (HalUpstairsFanMode.state as Number) {
            case 0: "Auto" +
            case 1: "High" +
            case 2: "Med" +
            case 3: "Low" +
            case 4: "Quiet" +
        }
        //after that I need to add the current temperature set point, but only if the system is in heat or cool mode....
        if (HalUpstairsSystemMode.state>=3)(HalUpstairsSetPoint.state as Number).intValue.toString else ""
    }
    RMProTransmit.sendCommand(TransmitMSG)
end

(l1t7l3ph0o7) #8

I Suppose I should have posted my code, I went in a completely different direction. I gave up on making case switches work(I’ts just over my head). It’s dirty code and it’s probably buggy, but it works. feel free to take a look if you like:

rule "Update Upstairs Halcyon"
when 
	Item HalUpstairsSystemMode changed or
	Item HalUpstairsFanMode changed or
	Item HalUpstairsSetPoint changed or
	Item HalUpstairsForceUpdate changed from ON to OFF	
then
	var String TransmitMSG
	var String FanModeMSG	
	if(HalUpstairsFanMode.state==0)FanModeMSG = "Auto"
	else if(HalUpstairsFanMode.state==1)FanModeMSG = "High"
	else if(HalUpstairsFanMode.state==2)FanModeMSG = "Med"
	else if(HalUpstairsFanMode.state==3)FanModeMSG = "Low"
	else if(HalUpstairsFanMode.state==4)FanModeMSG = "Quiet"	
	if(HalUpstairsSystemMode.state==0){
		TransmitMSG = "HalcyonOFF"
		HalUpstairsUpdateFlag.sendCommand(ON)
		}
	//State 1 Dry		
	else if(HalUpstairsSystemMode.state==1){
		if (HalUpstairsUpdateFlag.state==ON){
			TransmitMSG = "ONDry"  
			HalUpstairsForceUpdate.sendCommand(ON)
			HalUpstairsUpdateFlag.sendCommand(OFF)
			}
		else TransmitMSG = "DryAuto"
	}
	//state2 Fan
	else if(HalUpstairsSystemMode.state==2){
		if (HalUpstairsUpdateFlag.state==ON){
			TransmitMSG = "ONFan"
			HalUpstairsForceUpdate.sendCommand(ON)
			HalUpstairsUpdateFlag.sendCommand(OFF)
			}
		else TransmitMSG = "Fan"+(FanModeMSG)
	}	
	//state 3 Heat
	else if(HalUpstairsSystemMode.state==3){
		if (HalUpstairsUpdateFlag.state==ON){
			TransmitMSG = "ONHeat"
			HalUpstairsForceUpdate.sendCommand(ON)
			HalUpstairsUpdateFlag.sendCommand(OFF)
			}
		else TransmitMSG = "Heat"+(FanModeMSG)+(HalUpstairsSetPoint.state as Number)	
	}
	//state 4 Cool
	else if(HalUpstairsSystemMode.state==4){
		if (HalUpstairsUpdateFlag.state==ON){
			TransmitMSG = "ONCool"
			HalUpstairsForceUpdate.sendCommand(ON)
			HalUpstairsUpdateFlag.sendCommand(OFF)
			}			
		else TransmitMSG = "Cool"+(FanModeMSG)+(HalUpstairsSetPoint.state as Number)
		}	
	RM3Transmit.sendCommand(TransmitMSG)
end

edit: I’m using item HalUpstairsForceUpdate with the expire binding, and item HalUpstairsUpdateFlag to send a separate “ON” message if the unit is witching from OFF to ON, and a different message when the unit switches from one mode to another. this also forces an update to the unit after it is turned on(just to make sure the unit is doing what OH thinks it’s doing).


(Udo Hartmann) #9

Quiet nice :slight_smile: and pardon me, wrote the wrong command. select-case (vba…) should be switch-case here:

rule "Update Upstairs Halcyon"
when
    Item HalUpstairsSystemMode changed or
    Item HalUpstairsFanMode changed or
    Item HalUpstairsSetPoint changed or
    Item HalUpstairsForceUpdate changed from ON to OFF	
then
    var String TransmitMSG
    var String FanModeMSG	
    switch (HalUpstairsFanMode.state as Number) { 
        case 0:FanModeMSG = "Auto"
        case 1:FanModeMSG = "High"
        case 2:FanModeMSG = "Med"
        case 3:FanModeMSG = "Low"
        case 4:FanModeMSG = "Quiet"
    }
    if(HalUpstairsUpdateFlag.state == ON) {
        switch (HalUpstairsSystemMode.state as Number) {
            case 1: TransmitMSG = "ONDry"
            case 2: TransmitMSG = "ONFan"
            case 3: TransmitMSG = "ONHeat"
            case 4: TransmitMSG = "ONCool"
        }
        HalUpstairsForceUpdate.sendCommand(ON)
        HalUpstairsUpdateFlag.sendCommand(OFF)
    } 
    else {
        switch (HalUpstairsSystemMode.state as Number) {
            case 0: {
                TransmitMSG = "HalcyonOFF"
                HalUpstairsUpdateFlag.sendCommand(ON)
            }
            case 1: TransmitMSG = "DryAuto"
            case 2: TransmitMSG = "Fan"+(FanModeMSG)
            case 3: TransmitMSG = "Heat"+(FanModeMSG)+(HalUpstairsSetPoint.state as Number)
            case 4: TransmitMSG = "Cool"+(FanModeMSG)+(HalUpstairsSetPoint.state as Number)
    }
    RM3Transmit.sendCommand(TransmitMSG)
end

You could setup persistence for HalUpstairsSystemMode and then use

if(HalUpstairsSystemMode.historicState(now.minusMillis(100)).state == 0) {

instead of

if(HalUpstairsUpdateFlag.state == ON) {

and avoid the HalUpstairsUpdateFlag completely. This is nice when you want persistence data to see uptime of FanModes, but the update flag is ok :slight_smile:


(l1t7l3ph0o7) #10

Oh WOW, Thank you so much. This looks really good. it’s exactly what I was trying to do I will give it a try!

Edit: I’ve tested it out, added a } at the bottom, and I am so Thankful, This is perfect. Thank you again, Have yourself a Merry Christmas!!!

Edit Edit:

Didn’t pick up on this bit the first time I read your post, That is really brilliant, I have a handful of use cases for this tidbit, Thanks