Building a string with values from 4 switches to post to a String item

Hi all - I have an MQTT topic that expects a string of 4 ones or zeroes to work. These are actually 4 individual switches.

I have configured a String item with the MQTT binding and created 4 seperate switches to be able to hopefully build a string to post to the String item but I am stumped on how to proceed.

I tried a few different rules but barely anything would work.

Basically, when one of the 4 switches change, I need to take the ON/OFF values of all 4 switches, convert them to 0 or 1 and then join them all together and post to the main String item. Additionally, Ideally at least one switch should always be on, so if the result is "0000’ then effectively put the switch back (but this is not essential)

Can someone give me some pointers on this? I’ve only done some basic tasks with Rules but not manipulating strings etc. I seem to really struggle with the Xtend language yet am very comfortable with many other programming languages.

I might be able to mangle some other code to replay the switches elsewhere but ideally I want to do this within openhab to keep it simple.

That seems straightforward. How about showing us your attempt, it may be easily fixable. Its a funny thing about forum behaviour that generally gets more results than “write code for me”.

In the meantime, I might restructure as
when any of the 4 switches change,
I need to take the ON/OFF values first switch, convert to “0” or “1”, create a temp string
take the ON/OFF values second switch, convert to “0” or “1”, add to temp string
… etc
finally look at whole string and if it some special value do something else
otherwise post it to String Item

This is the code I was trying to work with but now I sort of see a way to do it differently.

This handles the incoming MQTT messages and should update the switches. The bottom IF statement was to handle a switch change and would be repeated for each switch. However, it an probably be one statement with ORs between them but basically, none of the code works at all.

Where can I see actual errors generated by the scripts? I could not find anything. If I knew where to look (logging wise) for errors generated by the script i’d probably be able to nut it out.

import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*

rule "Aircon Zone Control"
var zoneBit0
var zoneBit1
var zoneBit2
var zoneBit3

when Item AC_Zone received update
then
  logInfo("Aircon","AC_Zone got update")
  if(AC_Zone.state != "0000"){  //Probably from the AC going in to idle mode
if(AC_Zone.state.substring(0,1) == "1") {
  postUpdate(AC_Zone0, "ON")
}else{
 postUpdate(AC_Zone0, "OFF")
}
if(AC_Zone.state.substring(0,2) == "1") {
  postUpdate(AC_Zone1, "ON")
}else{
  postUpdate(AC_Zone1, "OFF")
}
if(AC_Zone.state.substring(0,3) == "1") {
  postUpdate(AC_Zone2, "ON")
}else{
  postUpdate(AC_Zone2, "OFF")
}
if(AC_Zone.state.substring(0,4) == "1") {
  postUpdate(AC_Zone3, "ON")
}else{
  postUpdate(AC_Zone3, "OFF")
}
  }
end


when Item AC_Zone0 received update
then
  if(receivedCommand=="ON"){
zoneBit0 = "1"
  }else{
zoneBit0 = "0"
  }
  sendCommand(AC_Zone, zoneBit0 + zoneBit1 + zoneBit2 + zoneBit3)
end

You mean from the rule(s) ?
http://docs.openhab.org/administration/logging.html

Using the ‘designer’ tool to write rules can be helpful. It has limitations, but picks up many typos and syntax issues.

This is bad syntax. Put those declarations after the then if you want them local to the rule, or at the head of the file (outside of any rule-when-then-end) if you want them global to that rules file.

This is bad syntax. You must begin with a rule “some unique name” before ‘when’

Well it took some time but this is what I ended up with. I find it very frustrating that errors do not indicate a line number or be at least a little more descriptive but here it is:

rule "Aircon Zone Control input"
when Item AC_Zone received update
then
  logInfo("Aircon","AC_Zone got update")
  val String zoneState = AC_Zone.state.toString
  val String zoneState0 = zoneState.substring(0,1)
  val String zoneState1 = zoneState.substring(1,2)
  val String zoneState2 = zoneState.substring(2,3)
  val String zoneState3 = zoneState.substring(3,4)

  if(zoneState != "0000"){
    if(zoneState0 == "1") {
      postUpdate(AC_Zone0, "ON")
    }else{
     postUpdate(AC_Zone0, "OFF")
    }
    if(zoneState1 == "1") {
      postUpdate(AC_Zone1, "ON")
    }else{
      postUpdate(AC_Zone1, "OFF")
    }
    if(zoneState2 == "1") {
      postUpdate(AC_Zone2, "ON")
    }else{
      postUpdate(AC_Zone2, "OFF")
    }
    if(zoneState3 == "1") {
      postUpdate(AC_Zone3, "ON")
    }else{
      postUpdate(AC_Zone3, "OFF")
    }
  }
end

rule "Aircon Zone Control output"
when Item AC_Zone0 received command or
     Item AC_Zone1 received command or
     Item AC_Zone2 received command or
     Item AC_Zone3 received command
then
     val String zoneSwitchState = "0000"
     if (AC_Zone0.state == ON){
       logInfo("Aircon","AC_ZoneX read state")
       zoneSwitchState = '1'
     }else{
       zoneSwitchState = '0'
     }
     if (AC_Zone1.state == ON){
       zoneSwitchState = zoneSwitchState + '1'
     }else{
       zoneSwitchState = zoneSwitchState + '0'
     }
     if (AC_Zone2.state == ON){
       zoneSwitchState = zoneSwitchState + '1'
     }else{
       zoneSwitchState = zoneSwitchState + '0'
     }
     if (AC_Zone3.state == ON){
       zoneSwitchState = zoneSwitchState + '1'
     }else{
       zoneSwitchState = zoneSwitchState + '0'
     }
     if (zoneSwitchState != "0000") {
       AC_Zone.sendCommand(zoneSwitchState)
     }
end