[SOLVED] Make Switch item to show status of another Switch item independetly

I have a physical light switch and a virtual switch for a light bulb. They are connected to the output using XOR argument (Logo soft comfort configuration for LOGO 8 plc) - so the light bulb only works when there are one signal present, if both are present light bulb is in OFF state.


.sitemap

Switch item=VirtualSwitch
Switch item=LightBulb

The problem is that my switch in sitemap shows the state of the virtual switch and sometimes if I have signal from physical and virtual switches together light bulb is off but the switch in the sitemap shows that it is on.


I want the virtual switch toggle icon to be dependant from lightbulb state, but the value of the virtual switch independent of it.
So if I have physical light bulb in ON state I would have virtual switch icon in ON state independent of virtual switch value. And if I toggle it, I want it to change virtual switch value.
I did one tricky solution using rules and visibility tags:
.sitemap

        Switch item=VirtualSwitch icon="switch-on" mappings=[OFF="TURN ON"] visibility=[DATAITEM==ON]  
    	Switch item=VirtualSwitch icon="switch-off" mappings=[ON="TURN ON"] visibility=[DATAITEM1==ON]
        Switch item=VirtualSwitch icon="switch-on" mappings=[ON="TURN OFF"] visibility=[DATAITEM2==ON]  
    	Switch item=VirtualSwitch icon="switch-off" mappings=[OFF="TURN OFF"] visibility=[DATAITEM3==ON]  

.rules

rule "light change"
	when 
 		Item LightBulb received update
 	then
 			DATAITEM.sendCommand(OFF)
 			DATAITEM1.sendCommand(OFF)
 			DATAITEM2.sendCommand(OFF)
 			DATAITEM3.sendCommand(OFF) 	
 		if (LightBulb.state==OFF && VirtualSwitch.state==ON){
 			DATAITEM.sendCommand(ON)
 			DATAITEM1.sendCommand(OFF)
 			DATAITEM2.sendCommand(OFF)
 			DATAITEM3.sendCommand(OFF) 		
 		}
 		else if (LightBulb.state==OFF && VirtualSwitch.state==OFF){
  			DATAITEM.sendCommand(OFF)
 			DATAITEM1.sendCommand(ON)
 			DATAITEM2.sendCommand(OFF)
 			DATAITEM3.sendCommand(OFF)
 		}	 
 		else if (LightBulb.state==ON && VirtualSwitch.state==OFF){
  			DATAITEM.sendCommand(OFF)
 			DATAITEM1.sendCommand(OFF)
 			DATAITEM2.sendCommand(ON)
 			DATAITEM3.sendCommand(OFF)
 		}
 		else if (LightBulb.state==ON && VirtualSwitch.state==ON){
 			DATAITEM.sendCommand(OFF)
 			DATAITEM1.sendCommand(OFF)
 			DATAITEM2.sendCommand(OFF)
 			DATAITEM3.sendCommand(ON)
 		}
end

Which does the trick, but I thought it is not the best solution. And my icon tag did not work as expected, the icon did not changed accordingly. I tried another approach bu using postUpdate:
.sitemap

Switch item=VirtualSwitch

.rules

rule "Postupdate TEST"
	when 
 		Item LightBulb received update
 	then
 		if (LightBulb.state==OFF){
 			VirtualSwitch.postUpdate(OFF)
 		} 
 		else{
 			VirtualSwitch.postUpdate(ON)
 		}

BUT the problem is that when using the switch I have to press it twice to change the real state, although the switch shows correct position.

Is there any workaround to make it lightweight and working? Thank you!

UPDATE:

I managed to make switch with .postUpdate that works correctly:

.rules

// Number variable holds information about previous change. If the virtualswitch was .postUpdated it will hold - 1, if not - 0.

var Number test

rule "PostUpdating status of VirtualSwitch"
	when 
 		Item LightBulb changed
 	then
	 	Thread::sleep(100)
 		if (LightBulb.state!=VirtualSwitch.state){		
 			VirtualSwitch.postUpdate(LightBulb.state)
 			test=1

// I also added another switch item that holds the real status of virtual switch (not the .postUpdated
//version) - real status of virtual switch (VSRealStatus) I did it because when switching alternating
//statuses I do not want my toggle to jiggle

            if  (LightBulb.state==VSRealStatus.state){
                test=0
            }	
 		}
 		else{
 			test=0
		}	      	
end
  
rule "Changing the real status of VirtualSwitch"
	when 
 		Item VirtualSwitch changed
 	then
 		if (LightBulb.state!=VirtualSwitch.state && test==1){
                        if (LightBulb.state!=VSRealStatus.state){
			               VirtualSwitch.sendCommand(LightBulb.state)
                        }
                        else {
                           Thread::sleep(100)
			               VirtualSwitch.sendCommand(LightBulb.state)
                         }
                        Thread::sleep(100)
          }
 end

.sitemap

Switch item=VirtualSwitch

I added delay because without it the light bulb goes crazy from time to time.

Use a number Item instead:
items:

Number dataItem

rules:

rule "light change"
when
    Item LightBulb received update
then
    var Number data = 0
    if(LightBulb.state == ON) data = data + 1
    if(VirtualSwitch == ON) data = data + 2
    dataItem.postUpdate(data)
end

sitemap:

Switch item=VirtualSwitch icon="switch-on"  mappings=[OFF="TURN ON"]  visibility=[dataItem==0]  
Switch item=VirtualSwitch icon="switch-off" mappings=[ON="TURN ON"]   visibility=[dataItem==1]
Switch item=VirtualSwitch icon="switch-on"  mappings=[ON="TURN OFF"]  visibility=[dataItem==2]
Switch item=VirtualSwitch icon="switch-off" mappings=[OFF="TURN OFF"] visibility=[dataItem==3]
1 Like

Thank you for elegant solution. But I will probably stay with the more complicated solution with switch .postUpdate because it shows the true status of the physical bulb and changes virtual switch status at the same time.
Your solution will fit most of the users.