[SOLVED] Rules Syntax : Select into Select

Hi Guys,

almost several hours on this but i do not see it clear

i am getting those errors all the time :weary:

2018-05-21 21:09:31.931 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'Clim1.rules' has errors, therefore ignoring it: [10,17]: missing '{' at 'case'
[30,5]: missing '}' at 'case'
[33,10]: missing '{' at 'case'
[49,6]: missing '}' at 'case'
[51,8]: missing '{' at 'case'

The rules below

var clim1str

rule "Clim 1"
when
   Item Clim_1 received command
then 
   	clim1str=Clim_1.previousState().state.toString
   	logInfo("previousState",clim1str )	
       switch (receivedCommand) 
               case "off" :{
   							switch (clim1str) 
   								case "off":{
   										logInfo("Rule File: mqtt.rules", "ALREADY OFF")
   								}

   								case "heat" :{
   									publish("mosquitto", "broadlink/mqtt_RM_1/ac/heat", "replay") 
   									logInfo("Rule File: mqtt.rules", "Rule:Clim 1")
   									logInfo("MQTT", "broadlink/mqtt_RM_1/ac/heat")
   								}
   								
   								case "cold" :{		
   									publish("mosquitto", "broadlink/mqtt_RM_1/ac/power", "replay") 
   									logInfo("Rule File: mqtt.rules", "Rule:Clim 1")
   									logInfo("MQTT", "broadlink/mqtt_RM_1/ac/power")
   								}		
   						}		
   					
   			case "heat" :{
   					
   							switch (clim1str ) 
   								case "off" :{
   									publish("mosquitto", "broadlink/mqtt_RM_1/ac/heat", "replay") 
   									logInfo("Rule File: mqtt.rules", "Rule:Clim 1")
   									logInfo("MQTT", "broadlink/mqtt_RM_1/ac/heat")
   								}
   								case "heat" :{
   									logInfo("Rule File: mqtt.rules", "ALREADY heat")
   								}
   								case "cold" :{		
   									publish("mosquitto", "broadlink/mqtt_RM_1/ac/power", "replay") 
   									publish("mosquitto", "broadlink/mqtt_RM_1/ac/power", "replay") 
   									logInfo("Rule File: mqtt.rules", "Rule:Clim 1")
   									logInfo("MQTT", "broadlink/mqtt_RM_1/ac/power")
   								}    
   						}				
   						
   				case "cold" :{
   					switch (clim1str ) 
   						case "off" :{
   							publish("mosquitto", "broadlink/mqtt_RM_1/ac/power", "replay") 
   							logInfo("Rule File: mqtt.rules", "Rule:Clim 1")
   							logInfo("MQTT", "broadlink/mqtt_RM_1/ac/power")
   						}
   						case "heat" :{
   							publish("mosquitto", "broadlink/mqtt_RM_1/ac/power", "replay") 
   							publish("mosquitto", "broadlink/mqtt_RM_1/ac/power", "replay") 
   							logInfo("Rule File: mqtt.rules", "Rule:Clim 1")
   							logInfo("MQTT", "broadlink/mqtt_RM_1/ac/power")
   						}
   						case "cold" :{		
   							logInfo("Rule File: mqtt.rules", "ALREADY cold")
   						}
   					}
   				}				
   							
   	
               case "plus" :
   			 {
                       publish("mosquitto", "broadlink/mqtt_RM_1/ac/plus", "replay") 
   					logInfo("Rule File: mqtt.rules", "Rule:Clim 1")
   					logInfo("MQTT", "broadlink/mqtt_RM_1/ac/plus")
   			}	
   			
               case "minus" :
   			{
                       publish("mosquitto", "broadlink/mqtt_RM_1/ac/minus", "replay") 
   					logInfo("Rule File: mqtt.rules", "Rule:Clim 1")
   					logInfo("MQTT", "broadlink/mqtt_RM_1/ac/minus")			
   			}		
   		}


end```

I am not a 100% sure, but I think your use of block expressions ({}) is not correct.

Take a look at the description of Xtend Switch Expression on this link:
http://www.eclipse.org/xtend/documentation/203_xtend_expressions.html

   						}
   					}
   				}				
   						

isn’t that one “}” too much?
If i’m correct you have 12 times “{” and 13 times “}” from the beginning of the rule up to the end of “Cold Case” :wink:

1 Like

Thanks

the code fixed below

var clim1str


rule "Clim 1"
when
    Item Clim_1 received command
then 
		clim1str=Clim_1.previousState().state.toString
    	logInfo("previousState",clim1str )	
        switch (receivedCommand){
			case "off" :{
					
						switch (clim1str){
								case "off":
								{
										logInfo("Rule File: mqtt.rules", "ALREADY OFF")
								}

								case "heat":
								{
										publish("mosquitto", "broadlink/mqtt_RM_1/ac/heat", "replay") 
										logInfo("Rule File: mqtt.rules", "Rule:Clim 1")
										logInfo("MQTT", "broadlink/mqtt_RM_1/ac/heat")
								}	
								case "cold":
								{		
										publish("mosquitto", "broadlink/mqtt_RM_1/ac/cold", "replay") 
										logInfo("Rule File: mqtt.rules", "Rule:Clim 1")
										logInfo("MQTT", "broadlink/mqtt_RM_1/ac/cold")
								}				
						}
			}


			case "cold" :{
					
						switch (clim1str){
								case "off":
								{
										publish("mosquitto", "broadlink/mqtt_RM_1/ac/cold", "replay") 
										logInfo("Rule File: mqtt.rules", "Rule:Clim 1")
										logInfo("MQTT", "broadlink/mqtt_RM_1/ac/cold")
								}

								case "heat":
								{
										publish("mosquitto", "broadlink/mqtt_RM_1/ac/cold", "replay") 
										publish("mosquitto", "broadlink/mqtt_RM_1/ac/cold", "replay") 
										logInfo("Rule File: mqtt.rules", "Rule:Clim 1")
										logInfo("MQTT", "broadlink/mqtt_RM_1/ac/cold")
								}	
								case "cold":
								{		
										logInfo("Rule File: mqtt.rules", "ALREADY cold")
										//publish("mosquitto", "broadlink/mqtt_RM_1/ac/power", "replay") 
										//logInfo("Rule File: mqtt.rules", "Rule:Clim 1")
										//logInfo("MQTT", "broadlink/mqtt_RM_1/ac/power")
								}				
						}
			}




			case "heat" :{
					
						switch (clim1str){
								case "off":
								{
										publish("mosquitto", "broadlink/mqtt_RM_1/ac/heat", "replay") 
										logInfo("Rule File: mqtt.rules", "Rule:Clim 1")
										logInfo("MQTT", "broadlink/mqtt_RM_1/ac/heat")		
								}

								case "heat":
								{

										logInfo("Rule File: mqtt.rules", "ALREADY heat")
								}	
								case "cold":
								{		
										publish("mosquitto", "broadlink/mqtt_RM_1/ac/heat", "replay") 
										publish("mosquitto", "broadlink/mqtt_RM_1/ac/heat", "replay") 
										logInfo("Rule File: mqtt.rules", "Rule:Clim 1")
										logInfo("MQTT", "broadlink/mqtt_RM_1/ac/heat")
								}				
						}
			}
		}
end

You should use VScode with the openHAB extension which will tell you immediately where you have syntax problems like this.

Also, this rule is way more complex than it needs to be.
If you apply the following rule structure it will reduce the code quite a bit:

  • Determine if there rule needs to run at all and exit if not.
  • Calculate what needs to be done
  • do it

So first, look to see if the receivedCommand is the same as the previous state. If so, log and exit. That eliminates three of your case statements with one line of code.

Next set a String with the topic to publish to and a boolean to indicate if you need to publish twice populated appropriately based on the receivedCommand and previous state. Remember, we don’t have to check if they after the same as we already did that.

Finally, publish the message, twice if necessary.

Something like the following (typing on my phone so there will be errors)

rule "Clim1"
when
    Item Clim_1 received command
then
    val clim1str = Clim_1.previousState().state.toString
    if(receivedCommand.toString == clim1str) {
        logInfo("Rule File: mqtt.rules", "ALREADY " + clim1str)
        return;
    }

    var topic = if(receivedCommand == "off") clim1str else receivedCommand.toString
    var doubleSend = if(receivedCommand.toString == "off") false else true
									 
   publish("mosquitto", "broadlink/mqtt_RM_1/ac/"+topic, "replay")
    if(doubleSend) publish("mosquitto", "broadlink/mqtt_RM_1/ac/"+topic, "replay")
end

How it works is I looked for the patterns. The first pattern is if the receivedCommand and the previous state are the same we do nothing so exit the rule.

Next the topic ends with either the value of receivedCommand or if receivedCommand is “off” it ends with the value of the previous state.

Next, the message is only sent twice if neither or receivedCommand nor previous state are “off”.

Once we calculated the topic to publish to and whether or not to publish twice it is a simple matter of doing the publishes.

1 Like

Thanks a lot for taking time for such clear explanations

really useful and kind !

Thanks again

Thanks again

i would be glad to get your advice to well build my code.

i have a main list of scenario that i want to call from Telegram, or voicecommand or IFTTT or others.

i want to build my code with a reusable function Launch scenario.

is it a good design?

any remarks?

A smart thinking!

really interesting! thank you

i have seen in this past this article . you match the question and the answer and now i have understood!

i have another simple syntax question. is it possible to have several options in a case like

switch (Item.state.ToString){
								case "eteindre", || "éteindre :


Thanks again

http://www.eclipse.org/xtend/documentation/203_xtend_expressions.html#switch-expression

Go down to the Fall Through section.

1 Like

Thanks

the format for other :slight_smile:

 switch salutation {
    case "Mr.", 
    case "Sir" : true
    default : false

i have another issue after the restart openhab service

Before restart openhab service,it’s ok

2018-05-31 08:56:40.679 [ome.event.ItemCommandEvent] - Item 'Clim_1' received command cold
2018-05-31 08:56:40.700 [vent.ItemStateChangedEvent] - Clim_1 changed from OFF to cold

==> /var/log/openhab2/openhab.log <==
2018-05-31 08:56:40.753 [INFO ] [smarthome.model.script.previousState] - off
2018-05-31 08:56:40.764 [INFO ] [odel.script.receivedCommand.toString] - cold
2018-05-31 08:56:40.789 [INFO ] [e.model.script.Rule File: mqtt.rules] - Rule:Clim 1
2018-05-31 08:56:40.800 [INFO ] [.eclipse.smarthome.model.script.MQTT] - broadlink/mqtt_RM_1/ac/cold

after restart, when opening openhab, the state cold is saved thanks to influxdb persistence

but when i am trying to turn off the AC.

==> /var/log/openhab2/events.log <==
2018-05-31 09:02:35.817 [ome.event.ItemCommandEvent] - Item 'Clim_1' received command OFF
2018-05-31 09:02:35.846 [vent.ItemStateChangedEvent] - Clim_1 changed from cold to OFF
==> /var/log/openhab2/openhab.log <==
2018-05-31 09:02:36.425 [INFO ] [smarthome.model.script.previousState] - off
2018-05-31 09:02:36.430 [INFO ] [odel.script.receivedCommand.toString] - off
2018-05-31 09:02:36.435 [INFO ] [e.model.script.Rule File: mqtt.rules] - ALREADY OFF

The previous state should be cold. the previous state is not saved after restart service.

an issue, after my AC status in openhab is not aligned anymore with the AC

what am i missing?

It is probably a timing issue. previousState only returns the most recent entry in the database. Apparently it is managing to save the new state before your Rule executes. That’s unusual but not unheard of.

I think you need to live without that check at the start of the Rule and live with some unnecessary duplicated commands sent to the device.

thanks

bad news :slight_smile:

if the raspberry restart, i need to turn off manually all the AC

Why?

The device is set to “cold”.

OH turns off

OH turns back on

The Item is restored to “cold”.

The problem is in the above Rule the following is happening:

Clim_1 is receiving command “off”
The new state “off” is being saved into InfluxDB
The “Clim1” Rule runs
The Rule doesn’t do anything because previousState and receivedCommand are the same, because for some reason your InfluxDB is really fast and is saving the command state faster than the Rule can run.

This has nothing to do with restoreOnStartup.

So there might be another way but I’m not sure it will work in this context because I don’t remember all the nuanaces to what you are trying to accomplish. But if you can use changed instead of received command then the previousState implicit variable will be whatever the Item was previously independent of what is in the database.