Aeon WallMote Quad: how to detect second time the same scene button was tapped

I have an item called WallMoteQuad1_SceneNumber which is linked to the SceneNumber channel.

When I tap button 1 on the controller, the item state goes to 1.0. When I tap it a second time, nothing happens. What would be the optimum way of detecting this second tap? I would like to use the buttons of the controller as simple pushbutton, and have OH react to each tap.

I have now done it with below rule, but I would hope there would be a way to have a trigger attached to the incoming zwave message.

var Timer ResetScene = null
rule "emulate pushbutton"
when
	Item WallMoteQuad1_SceneNumber  changed
then
	if (WallMoteQuad1_SceneNumber.state as Number == 1.0 || WallMoteQuad1_SceneNumber.state as Number == 2.0 || WallMoteQuad1_SceneNumber.state as Number == 3.0 || WallMoteQuad1_SceneNumber.state as Number == 4.0 ){
		logDebug("hvd","create scene reset timer")
		ResetScene = createTimer(now.plusMillis(100)) [|
			WallMoteQuad1_SceneNumber.postUpdate(0.0)
			ResetScene = null
			]
		
		//add code here to deal with the button that was tapped
	}
end

I see no logic in your rule to increment the number

I use this, maybe to compley and anyone can make it more easy.

Is also covers a replay of the same command. I see that if the wall mount is far away from z-wave stick, the command received more times.

Sorry for the german namings and comments.

Items:

// Funkschalter 01
// Z-Wave me WALLC-S
Number WallSwitch01_Scene				"Wandschalter [%.1f °C]"  									        <temperature> (gMAPDB) { channel="zwave:device:xxxx:node26:scene_number" }

Switch swFunktaster1_Taste1_Klick			(gMAPDB)
String stFunktaster1_Taste1_Klick_Helper    (gMAPDB)
DateTime dtFunktaster1_LastUpdate           "Funktaster1_LastUpdate [%1$tH:%1$tM]"  (gMAPDB)
DateTime dtFunktaster1_LangKlick_LastUpdate "Funktaster1_Langklick_LastUpdate [%1$tH:%1$tM]"  (gMAPDB)
String swFunktaster1_OldState               "Funktaster1_OldState [%s]"             (gMAPDB)
Switch swFunktaster1_Taste1_Doppelklick	    (gMAPDB)
Switch swFunktaster1_Taste1_Langklick	    (gMAPDB)

Switch swFunktaster1_Taste2_Klick			(gMAPDB)
Switch swFunktaster1_Taste2_Doppelklick	    (gMAPDB)
Switch swFunktaster1_Taste2_Langklick	    (gMAPDB)

Switch swFunktaster1_Taste3_Klick			(gMAPDB)
Switch swFunktaster1_Taste3_Doppelklick	    (gMAPDB)
Switch swFunktaster1_Taste3_Langklick	    (gMAPDB)

Switch swFunktaster1_Taste4_Klick			(gMAPDB)
Switch swFunktaster1_Taste4_Doppelklick	    (gMAPDB)
Switch swFunktaster1_Taste4_Langklick	    (gMAPDB)

The rule changes the above switch items. They can be used to trigger rules regarding the needed scene.

rule "Z-Wave WALLC-S 01 events changed"
	when
		Item WallSwitch01_Scene changed
	then
		// Der Taste wird gerade lang gedrückt und wurde noch nicht losgelassen
		if(WallSwitch01_Scene.state.toString == "1.2" || WallSwitch01_Scene.state.toString == "2.2"  || WallSwitch01_Scene.state.toString == "5.2" || WallSwitch01_Scene.state.toString == "4.2")
		{
			// Zeit des Drückens merken
			dtFunktaster1_LangKlick_LastUpdate.postUpdate(new DateTimeType)
			return;
		}

		// Der Taster wurde nach einem Langklick wieder losgelassen
		if(WallSwitch01_Scene.state.toString == "1.1" || WallSwitch01_Scene.state.toString == "2.1"  || WallSwitch01_Scene.state.toString == "5.1" || WallSwitch01_Scene.state.toString == "4.1")
		{
			// Ist der Unterschied kleiner als diese Zeit, dann nur als Shortklick interpretieren
			// und ein Statusupdate mit .0 schicken
			// Hier wird die Zeit für Langklick eingestellt, ist diese unterschritten, ist es nur ein Shortklick
			val long current_state  = now.millis
			val long previous_state = (dtFunktaster1_LangKlick_LastUpdate.state as DateTimeType).getZonedDateTime.toInstant.toEpochMilli
			//logInfo("Logger", "portable switch 01 - Status: " + WallSwitch01_Scene.state.toString.mid(0,2) + "0")

			if((current_state - previous_state) < 500)
			{
				WallSwitch01_Scene.postUpdate(WallSwitch01_Scene.state.toString.mid(0,2) + "0")
				logInfo("Logger", "portable switch 01 - lange gedrueckt als kurz gedruckt veraendert")
				return;
			}
		}

		if (WallSwitch01_Scene.state.toString == "1.1")
		{
			// Dieses Kommando wird jede sec. so oft gesendet, bis die Taste wieder losgelassen wird
			// kann dadurch zum dimmen benutzt werden
			logInfo("Logger","portable switch 01 - Taste 1 lange gedrueckt")
			if(swFunktaster1_Taste1_Langklick.state != ON)
			{
				swFunktaster1_Taste1_Langklick.postUpdate(ON)
				Thread::sleep(100)
				swFunktaster1_Taste1_Langklick.postUpdate(OFF)				
			}
		}

		else if (WallSwitch01_Scene.state.toString == "2.1")
		{
			// Dieses Kommando wird jede sec. so oft gesendet, bis die Taste wieder losgelassen wird
			// kann dadurch zum dimmen benutzt werden
			logInfo("Logger","portable switch 01 - Taste 2 lange gedrueckt")
			if(swFunktaster1_Taste2_Langklick.state != ON)
			{
				swFunktaster1_Taste2_Langklick.postUpdate(ON)
				Thread::sleep(100)
				swFunktaster1_Taste2_Langklick.postUpdate(OFF)				
			}
		}		

		else if (WallSwitch01_Scene.state.toString == "5.1")
		{
			// Dieses Kommando wird jede sec. so oft gesendet, bis die Taste wieder losgelassen wird
			// kann dadurch zum dimmen benutzt werden aber nicht zum kippen eines Schaltzustandes, da dieser permanent kippt
			logInfo("Logger","portable switch 01 - Taste 3 lange gedrueckt")
			if(swFunktaster1_Taste3_Langklick.state != ON)
			{
				swFunktaster1_Taste3_Langklick.postUpdate(ON)
				Thread::sleep(100)
				swFunktaster1_Taste3_Langklick.postUpdate(OFF)
			}
		}

		else if (WallSwitch01_Scene.state.toString == "4.1")
		{
			// Dieses Kommando wird jede sec. so oft gesendet, bis die Taste wieder losgelassen wird
			// kann dadurch zum dimmen benutzt werden
			logInfo("Logger","portable switch 01 - Taste 4 lange gedrueckt")
			if(swFunktaster1_Taste4_Langklick.state != ON)
			{
				swFunktaster1_Taste4_Langklick.postUpdate(ON)
				Thread::sleep(100)
				swFunktaster1_Taste4_Langklick.postUpdate(OFF)				
			}
		}			
end

rule "Z-Wave WALLC-S 01 events update"
	when
		Item WallSwitch01_Scene received update
	then
		// Falls es einen Reboot gab, diese Aktion nicht ausführen, da diese nicht gewollt ist
		if(swAfterReboot.state == ON)
			return;
	
		// Taster 1: 1.0, 1.1, 1.2, 3.0, 3.1, 3.2
		// Tester 2: 2.0, 2.1, 2.2, 6.0, 6.1, 6.2
		// Taster 3: 5.0, 5.1, 5.2, 7.0, 7.1, 7.2
		// Taster 4: 4.0, 4.1, 4.2, 8.0, 8.1, 8.2

		//logInfo("Logger","Scene Update received " + WallSwitch01_Scene.state.toString)

		// Caluclate now and last time of the item is updates as milli sec.
		val long current_state  = now.millis
		val long previous_state = (dtFunktaster1_LastUpdate.state as DateTimeType).getZonedDateTime.toInstant.toEpochMilli

		// if prev status equal new status
		// check if update is more then 1 sec. from previous update
		if(WallSwitch01_Scene.state.toString == swFunktaster1_OldState.state.toString)
		{
			if((current_state - previous_state) < 1500)
			{
				return;
			}
		}

		// remember new time of update and old state 
		dtFunktaster1_LastUpdate.postUpdate(new DateTimeType)
		swFunktaster1_OldState.postUpdate(WallSwitch01_Scene.state.toString)		
		
		// Taste1
		if(WallSwitch01_Scene.state.toString == "1.0")
		{
			logInfo("Logger","portable switch 01 - Taste 1 gedrueckt")
			swFunktaster1_Taste1_Klick.postUpdate(ON)
			Thread::sleep(100)
			swFunktaster1_Taste1_Klick.postUpdate(OFF)
		}
		
		else if (WallSwitch01_Scene.state.toString == "3.0")
		{
			logInfo("Logger","portable switch 01 - Taste 1 doppelklick")
			swFunktaster1_Taste1_Doppelklick.postUpdate(ON)
			Thread::sleep(100)
			swFunktaster1_Taste1_Doppelklick.postUpdate(OFF)
		}

		// Taste2
		else if(WallSwitch01_Scene.state.toString == "2.0")
		{
			logInfo("Logger","portable switch 01 - Taste 2 gedrueckt")
			swFunktaster1_Taste2_Klick.postUpdate(ON)
			Thread::sleep(100)
			swFunktaster1_Taste2_Klick.postUpdate(OFF)
		}

		else if (WallSwitch01_Scene.state.toString == "6.0")
		{
			logInfo("Logger","portable switch 01 - Taste 2 doppelklick")
			swFunktaster1_Taste2_Doppelklick.postUpdate(ON)
			Thread::sleep(100)
			swFunktaster1_Taste2_Doppelklick.postUpdate(OFF)
		}

		// Taste3
		else if(WallSwitch01_Scene.state.toString == "5.0")
		{
			logInfo("Logger","portable switch 01 - Taste 3 gedrueckt")
			swFunktaster1_Taste3_Klick.postUpdate(ON)
			Thread::sleep(100)
			swFunktaster1_Taste3_Klick.postUpdate(OFF)
		}
		
		else if (WallSwitch01_Scene.state.toString == "7.0")
		{
			logInfo("Logger","portable switch 01 - Taste 3 doppelklick")
			swFunktaster1_Taste3_Doppelklick.postUpdate(ON)
			Thread::sleep(100)
			swFunktaster1_Taste3_Doppelklick.postUpdate(OFF)			
		}

		// Taste4
		else if(WallSwitch01_Scene.state.toString == "4.0")
		{
			logInfo("Logger","portable switch 01 - Taste 4 gedrueckt")
			swFunktaster1_Taste4_Klick.postUpdate(ON)
			Thread::sleep(100)
			swFunktaster1_Taste4_Klick.postUpdate(OFF)
		}
		
		else if (WallSwitch01_Scene.state.toString == "8.0")
		{
			logInfo("Logger","portable switch 01 - Taste 4 doppelklick")
			swFunktaster1_Taste4_Doppelklick.postUpdate(ON)
			Thread::sleep(100)
			swFunktaster1_Taste4_Doppelklick.postUpdate(OFF)		
		}
end 

In your rule, change changed to received update?

Item WallMoteQuad1_SceneNumber received update

Which is what I have been using for my scene switches, too.

1 Like

@luckymallari: my wording should have been better. I didn’t mean to capture exactly the second button click, but just find a way to see whether the same scene button was pressed again.

Thank you Mark. That did the trick.

I didn’t see anything recorded in the event log, so I was (wrongly) assuming that no event reached the item.

1 Like

The above suggestions are correct, but I would change your rule’s postUpdate to sendCommand since with sendCommand you can use the receivedCommand iplicit variable and check if it’s the same value.


rule "Z-Wave WALLC-S 01 events changed"
when
	Item WallSwitch01_Scene received command
then
        if (WallSwitch01_Scene.receivedCommand.toString == WallSwitch01_Scene.previousState.toString)
        {
               // same as before.. must be multiple clicks
        }
end

Those events are filtered by default in the logging config.

log4j2.logger.smarthomeItemStateEvent.name = smarthome.event.ItemStateEvent
log4j2.logger.smarthomeItemStateEvent.level = ERROR

very good hint: I will update my code and give feedback.