So I have a controller that has 8 outputs it can only send the status of all ports
combined together, Example if it sends 255 it means All 8 ports are ON just
convert the number to binary and can see the status of the ports,
My question is this, how would a rule look like to update switches status in openhab from that number? if it is possible to do.
Thanks for your reply, I think is DSL ( the default language ) , the controller sends MQTT message like PA=255 cos it has 4 ports PA,PB,PC,PD what i have done till now is a string item that displays this data
now what i need to do is some string manipulation in the rules for example:
when string change , check if string contains “PA=” if yes extract the number after "PA= "
then example i have a value of 255 convert that in to a binary string of 8 characters , then
pic the character i am interested in check if 1 or 0 , if 1 then the switch is ON if 0 put it off
, but as i said i am new to dsl i know some cpp and php but never dsl ,
also what programming languages are accepted in the rules files ?
val checkKthBit = [ Integer num, Integer bit |
val n = num.intValue
val k = bit.intValue
if ((n & (1 << (k - 1))) == 1) True else False // shift to the kth bit and check if it's 1
]
if(checkKthBit.apply(MyItem.state, 0)) // device from first bit is ON
if(checkKthBit.apply(MyItem.state, 1)) // device from second bit is ON
...
I am not at all certain that the above will work. I think Xtend will let us use the Java binary shift operators. If not I’m not sure how to do this.
Hi , I have started to experiment some code with regex , when i test the regex on simulator it
it works but in rules file dose not , what am i doing wrong ?
I want to extract only whats after “PA=” in item PORTA
val str1 = transform(“REGEX”, “(?<=PA=).*”, PORTA.state.toString)
it seems that in my case regex is useless cos if I know the whole string i wouldn’t be needing it.
but I am a beginner maybe I am missing something.
Python seems to be popular and a lot of help is available on the web will try to see how I can use it
to create rules.
also, I know you suggested a number item but because the controller sends all data in the same topic
inspecting the string is the only way I have to distinguish the data.
but it’s a long way to victory i have to convert str1 to int and figure out how checkKthBit is going to work
is checkKthBit part of the standard DSL or i have to install it? like transform Regex
That’s Rule code that you will need to copy and paste into a Rule and very likely debug it as I have no way to really test that it works as written above.
Yes, it seems that your approach Jim is more suitable for a beginner I can clearly understand what’s happening and will surely implement that.
Once I feel more fluent in this language will also try checkKthBit which really looks elegant.
searching the forum was not able to find a simple syntax to convert a string to int.
Hi Rosko, yes it worked regex converted it into an integer
NumberOutput = new Integer(transform(“REGEX”, “([0-9]+)”, StringInput))
var String X_Topic = "uart_rx"
var String Broker = "mqtt:systemBroker:embedded-mqtt-broker"
var String str1 = ""
var int AllBits = 0
rule XC1_PA_UPD
when
Item PORTA received update
then
str1 = transform("REGEX", ".*(?<=PA=)(.*)", PORTA.state.toString) // remove PA= & put value in to str1
AllBits = new Integer(transform("REGEX", "([0-9]+)", str1)) // Convert String to int
PAVAL.sendCommand(AllBits) // Update PAVAL
val mqttActions = getActions("mqtt", Broker) mqttActions.publishMQTT(X_Topic, "|ssd0clr|SSD0:X1,Y1,F0,T1,S[" + str1 + "]|") // Print received data on LCD.
// Update Switches Status //
if (AllBits >= 128 ) { PA8.sendCommand(ON) AllBits = AllBits - 128 } else { PA8.sendCommand(OFF) }
if (AllBits >= 64 ) { PA7.sendCommand(ON) AllBits = AllBits - 64 } else { PA7.sendCommand(OFF) }
if (AllBits >= 32 ) { PA6.sendCommand(ON) AllBits = AllBits - 32 } else { PA6.sendCommand(OFF) }
if (AllBits >= 16 ) { PA5.sendCommand(ON) AllBits = AllBits - 16 } else { PA5.sendCommand(OFF) }
if (AllBits >= 8 ) { PA4.sendCommand(ON) AllBits = AllBits - 8 } else { PA4.sendCommand(OFF) }
if (AllBits >= 4 ) { PA3.sendCommand(ON) AllBits = AllBits - 4 } else { PA3.sendCommand(OFF) }
if (AllBits >= 2 ) { PA2.sendCommand(ON) AllBits = AllBits - 2 } else { PA2.sendCommand(OFF) }
if (AllBits >= 1 ) { PA1.sendCommand(ON) AllBits = AllBits - 1 } else { PA1.sendCommand(OFF) }
end
This DSL language … lest just say I don’t like it at all, there must be a better way.
Without your help guys, I would have given up so thanks very much.
You can call external scripts using the Exec binding or from Rules DSL Rules using the executecommandLine Action, but that’s not what I’m referring to. I’m referring to writing openHAB Rules using these other languages instead of Rules DSL.
Just for completeness I was able to get the checkKthBit routine working in a .rules file.
// The variable "num" must be between 0 and 255.
// The variable "bit" must be between 1 (the rightmost bit) and 8 (the leftmost bit)
val checkKthBit = [ Integer num, Integer bit |
var n = num
var s = 1 << (bit - 1)
if (n.bitwiseAnd(s) > 0) {
true
}
else {
false
}
]
Assuming AllBits is a number item
if (checkKthBit.apply(AllBits.state,8)) {
Port8.postUpdate(ON)
}
else {
Port8.postUpdate(OFF)
}
if (checkKthBit.apply(AllBits.state,7)) {
Port7.postUpdate(ON)
}
else {
Port7.postUpdate(OFF)
}
....
....