Prevent roller shutter rule from firing more than once + inconsistent Z-Wave state reported

That’s the problem I have with Z-Wave. I find it rather cumbersome to properly configure.

I know, but then I get duplicate notifications.

Not really. For the most part it’s more a matter of lack of proper documentation of the devices and their behavior. Particularly with those vendors who rather treat this to be an addon to “their” system and not a core smart home technology.

Many ways of getting around that:
Use a variable to track if you’ve already sent a message.
Use a separate rule to send notifications to trigger on shutter state changes

I was first sending the commands directly to the roller shutter proxy items and then I wanted to do the same through the gShutterProxy group. It didn’t work, probably due to the mess in the roller shutter states.

The items are defined as follows:

Group:Rollershutter:OR(UP, DOWN)	gShutter			"Roller Shutter"		<rollershutter>		(Home)				["Rollershutter"]

Group:Rollershutter:OR(UP, DOWN) AT_Shutters "All roof roller shutters" <rollershutter> (Home) ["Rollershutter"]

Rollershutter	AT_Shutter_N	"Roller Shutter North (direct)"				<rollershutter>   (AT_GuestRoom, gShutter, AT_Shutters)		["Rollershutter"]            {
    channel="zwave:device:88a05a4f:node2:blinds_control"
}
Rollershutter	AT_Shutter_SE	"Roller Shutter South East (direct)"		<rollershutter>   (AT_GuestRoom, gShutter, AT_Shutters)		["Rollershutter"]            {
    channel="zwave:device:88a05a4f:node3:blinds_control"
}
Rollershutter	AT_Shutter_SW	"Roller Shutter South West (direct)"		<rollershutter>   (AT_Office, gShutter, AT_Shutters)		["Rollershutter"]            {
    channel="zwave:device:88a05a4f:node4:blinds_control"
}

// Automation should only use the proxy items - rules will take care of controlling the actual items
Group:Rollershutter:OR(UP, DOWN)	gShutterProxy			"Roller Shutter"		<rollershutter>		(Home)				["Rollershutter"]

Rollershutter   Proxy_AT_Shutter_N      "Roller Shutter North"          <rollershutter>     (gShutterProxy)
Rollershutter   Proxy_AT_Shutter_SE     "Roller Shutter South East"     <rollershutter>     (gShutterProxy)
Rollershutter   Proxy_AT_Shutter_SW     "Roller Shutter South West"     <rollershutter>     (gShutterProxy)

And here’s what the log file is telling (I reverted back to sending the commands to the group item, and I temporarily commented out my state-checking attempt:

2019-03-11 17:08:56.726 [ome.event.ItemCommandEvent] - Item 'gShutterProxy' received command UP
2019-03-11 17:08:56.733 [ome.event.ItemCommandEvent] - Item 'Proxy_AT_Shutter_N' received command UP
2019-03-11 17:08:56.740 [ome.event.ItemCommandEvent] - Item 'Proxy_AT_Shutter_SE' received command UP
2019-03-11 17:08:56.755 [ome.event.ItemCommandEvent] - Item 'Proxy_AT_Shutter_SW' received command UP
2019-03-11 17:08:56.789 [vent.ItemStateChangedEvent] - Proxy_AT_Shutter_N changed from 100.0 to 0
2019-03-11 17:08:56.801 [vent.ItemStateChangedEvent] - Proxy_AT_Shutter_SE changed from 100.0 to 0
2019-03-11 17:08:56.805 [vent.ItemStateChangedEvent] - Proxy_AT_Shutter_SW changed from 100.0 to 0
2019-03-11 17:08:56.839 [ome.event.ItemCommandEvent] - Item 'AT_Shutter_SE' received command UP
2019-03-11 17:08:56.842 [ome.event.ItemCommandEvent] - Item 'AT_Shutter_N' received command UP
2019-03-11 17:08:56.856 [nt.ItemStatePredictedEvent] - AT_Shutter_SE predicted to become UP
2019-03-11 17:08:56.878 [ome.event.ItemCommandEvent] - Item 'AT_Shutter_SW' received command UP
2019-03-11 17:08:56.888 [nt.ItemStatePredictedEvent] - AT_Shutter_N predicted to become 100.0
2019-03-11 17:08:56.891 [GroupItemStateChangedEvent] - gShutter changed from 100 to 0 through AT_Shutter_SE
2019-03-11 17:08:56.893 [vent.ItemStateChangedEvent] - AT_Shutter_SE changed from 100 to 0
2019-03-11 17:08:56.897 [GroupItemStateChangedEvent] - AT_Shutters changed from 100 to 0 through AT_Shutter_SE
2019-03-11 17:08:56.901 [nt.ItemStatePredictedEvent] - AT_Shutter_SW predicted to become UP
2019-03-11 17:08:56.908 [vent.ItemStateChangedEvent] - AT_Shutter_SW changed from 100 to 0
2019-03-11 17:08:57.487 [hingStatusInfoChangedEvent] - 'zwave:device:88a05a4f:node2' changed from OFFLINE (COMMUNICATION_ERROR): Node is not communicating with controller to ONLINE
2019-03-11 17:08:58.504 [vent.ItemStateChangedEvent] - AT_Shutter_SE changed from 0 to 100
2019-03-11 17:08:58.603 [vent.ItemStateChangedEvent] - AT_Shutter_SW changed from 0 to 100
2019-03-11 17:08:58.606 [GroupItemStateChangedEvent] - AT_Shutters changed from 0 to 100 through AT_Shutter_SW
2019-03-11 17:08:58.608 [GroupItemStateChangedEvent] - gShutter changed from 0 to 100 through AT_Shutter_SW
2019-03-11 17:09:12.976 [ome.event.ItemCommandEvent] - Item 'Proxy_AT_Shutter_N' received command DOWN
2019-03-11 17:09:13.000 [vent.ItemStateChangedEvent] - Proxy_AT_Shutter_N changed from 0 to 100
2019-03-11 17:09:13.080 [ome.event.ItemCommandEvent] - Item 'AT_Shutter_N' received command DOWN
2019-03-11 17:09:13.088 [nt.ItemStatePredictedEvent] - AT_Shutter_N predicted to become DOWN

The command polling interval is set at the default values (1500ms), and the device minimum polling interval is also still the default 1 day.

Is this just from one flip of the gShutterProxy switch? The event logs are helpful, but not of much use without the rule logs to know what was happening in the rule to cause the events. If that doesn’t help, you’d need to combine them with the zwave log. Which is Node2? Everything seems to get sideways after it comes back online.

You’re using states in a received command triggered rule. This will mess things up, since the Item likely has not yet reached the state that was received in the command, but it could while the rule is running. There’s no way to tell.

Are you set on using the proxy Items? They seem to be more hassle than their worth. All three of these rules can be collapsed into one that accomplishes the same thing, and you coud include the temperature into the triggers as well, so that the shutters would close any time the temp was too low. Something like…

rule "Shutter rule"
when
    Channel "astro:sun:local:civilDawn#event" triggered START
    or Channel "astro:sun:local:rise#event" triggered// In case we missed the civil dawn due to temperature below automation threshold
    or Channel "astro:sun:local:noon#event" triggered// In case we missed the morning opening due to cold weather
    or Channel "astro:sun:local:civilDusk#event" triggered END
    or Item Wx_OWM_Current_Temperature changed
then
    val Number MIN_TEMP = 3.0|°C
    val String ruleTitle = "SunriseShutterRule"
    logInfo(ruleTitle, "Rule has been triggered")
    if (gShutter.state == DOWN && now.isBefore(new DateTime(INSERT_CIVILDUSK_ITEM_HERE.state.toString)) && Wx_OWM_Current_Temperature.state >= MIN_TEMP && Wx_OWM_Current_Temperature.minimumSince(now.minusMinutes(30)).state >= MIN_TEMP) {
        gShutter.sendCommand(UP)
        logInfo(ruleTitle, "Raised shutters")
    }
    else if (gShutter.state == UP) {
        gShutter.sendCommand(DOWN)
        logInfo(ruleTitle, "Lowered shutters")
    }
end

It is one group “UP” sequence followed with one single shutter “DOWN” event. Here’s the relevant openhab.log, where I separated both events with a blank line:

2019-03-11 17:08:56.774 [INFO ] [roller shutter item received command] - Proxy Item 'Proxy_AT_Shutter_N' (state = '100.0' or '100.0') received command 'UP' --> Proxy for Item 'AT_Shutter_N'
2019-03-11 17:08:56.778 [INFO ] [roller shutter item received command] - Proxy Item 'Proxy_AT_Shutter_SE' (state = '100.0' or '100.0') received command 'UP' --> Proxy for Item 'AT_Shutter_SE'
2019-03-11 17:08:56.789 [INFO ] [roller shutter item received command] - Proxy Item 'Proxy_AT_Shutter_N' - full details: [Proxy_AT_Shutter_N (Type=RollershutterItem, State=0, Label=Roller Shutter North, Category=rollershutter, Groups=[gShutterProxy])]
2019-03-11 17:08:56.797 [INFO ] [roller shutter item received command] - Proxy Item 'Proxy_AT_Shutter_SE' - full details: [Proxy_AT_Shutter_SE (Type=RollershutterItem, State=0, Label=Roller Shutter South East, Category=rollershutter, Groups=[gShutterProxy])]
2019-03-11 17:08:56.808 [INFO ] [roller shutter item received command] - Proxy Item 'Proxy_AT_Shutter_SW' (state = '0' or '0') received command 'UP' --> Proxy for Item 'AT_Shutter_SW'
2019-03-11 17:08:56.811 [INFO ] [roller shutter item received command] - Item 'AT_Shutter_N' (state = '100.0' or '100.0') - full details: [AT_Shutter_N (Type=RollershutterItem, State=100.0, Label=Roller Shutter North (direct), Category=rollershutter, Tags=[Rollershutter], Groups=[AT_GuestRoom, gShutter, AT_Shutters])]
2019-03-11 17:08:56.816 [INFO ] [roller shutter item received command] - Proxy Item 'Proxy_AT_Shutter_SW' - full details: [Proxy_AT_Shutter_SW (Type=RollershutterItem, State=0, Label=Roller Shutter South West, Category=rollershutter, Groups=[gShutterProxy])]
2019-03-11 17:08:56.816 [INFO ] [roller shutter item received command] - Item 'AT_Shutter_SE' (state = '100' or '100') - full details: [AT_Shutter_SE (Type=RollershutterItem, State=100, Label=Roller Shutter South East (direct), Category=rollershutter, Tags=[Rollershutter], Groups=[AT_GuestRoom, gShutter, AT_Shutters])]
2019-03-11 17:08:56.824 [INFO ] [roller shutter item received command] - Proxy Item 'Proxy_AT_Shutter_N' received command 'UP' --> Fowarding the command to Item 'AT_Shutter_N' as temperature ≥ 3.0 °C
2019-03-11 17:08:56.825 [INFO ] [roller shutter item received command] - Item 'AT_Shutter_SW' (state = '100' or '100') - full details: [AT_Shutter_SW (Type=RollershutterItem, State=100, Label=Roller Shutter South West (direct), Category=rollershutter, Tags=[Rollershutter], Groups=[AT_Office, gShutter, AT_Shutters])]
2019-03-11 17:08:56.825 [INFO ] [roller shutter item received command] - Proxy Item 'Proxy_AT_Shutter_SE' received command 'UP' --> Fowarding the command to Item 'AT_Shutter_SE' as temperature ≥ 3.0 °C
2019-03-11 17:08:56.838 [INFO ] [roller shutter item received command] - Proxy Item 'Proxy_AT_Shutter_SW' received command 'UP' --> Fowarding the command to Item 'AT_Shutter_SW' as temperature ≥ 3.0 °C

2019-03-11 17:09:13.029 [INFO ] [roller shutter item received command] - Proxy Item 'Proxy_AT_Shutter_N' (state = '100' or '100') received command 'DOWN' --> Proxy for Item 'AT_Shutter_N'
2019-03-11 17:09:13.037 [INFO ] [roller shutter item received command] - Proxy Item 'Proxy_AT_Shutter_N' - full details: [Proxy_AT_Shutter_N (Type=RollershutterItem, State=100, Label=Roller Shutter North, Category=rollershutter, Groups=[gShutterProxy])]
2019-03-11 17:09:13.046 [INFO ] [roller shutter item received command] - Item 'AT_Shutter_N' (state = '100.0' or '100.0') - full details: [AT_Shutter_N (Type=RollershutterItem, State=100.0, Label=Roller Shutter North (direct), Category=rollershutter, Tags=[Rollershutter], Groups=[AT_GuestRoom, gShutter, AT_Shutters])]
2019-03-11 17:09:13.058 [INFO ] [roller shutter item received command] - Proxy Item 'Proxy_AT_Shutter_N' received command 'DOWN' --> Fowarding the command to Item 'AT_Shutter_N' as temperature ≥ 3.0 °C

That is what I feared. It’s probably some event / state race condition at play.

That looks indeed much simpler than my approach.

I’ll give it a go and report.

Quick update.

I had to adapt your rule tom make it work on OH2.5M1 with my particular setup as I found out:

  1. The value of gShutter.state is never equal to DOWN or UP but always numeric (between 0 and 100). This is most definitely due to the incorrect detection of my Z-Wave roller shutters as being seen as window openers.
    → I fixed this by replacing DOWN with 100 and UP with 0 when checking state values (it works fine when sending commands with UP and DOWN).
  2. The OH1.x expression Wx_OWM_Current_Temperature.minimumSince(now.minusMinutes(30)).state >= MIN_TEMP clashes with the OH2 UoM Number<Temperature> constant (MIN_TEMP) and there’s no easy way to fix this (unless removing all UoM from the rule). There’s no simple type cast that will do the job, so the temperature check will always return false
    → I fixed this by removing the “30 minutes prior” temperature check.

I like the idea of following the temperature evolution in the rule to raise the roller shutters even after sunrise when the temperature remains low. The only drawback is that I can no longer manually override the shutters as whenever the temperature is updated, the shutters will open again during the day :sunglasses: (but that’s of course a different rule scenario)

Alas, the rule doesn’t work. Instead the shutters constantly toggle between open and close whenever the rule is triggered.

This is not an OH1.x expression, but a persistence extension. Unfortunately, persistence is still using compat1.x, so it currently has no understanding of QuantityType. Constructing QuanityType in the DSL is currently not working, we should get an issue logged for that, but you can work around this by comparing the persisted value to a number. Just make sure the persisted data is in the unit that you are comparing to. You could also manually persist the data, but that’s messy. Another option is to compare to a range, like…

(Wx_OWM_Current_Temperature.state >= MIN_TEMP.plus(5|°C) ||  Wx_OWM_Current_Temperature.state <= MIN_TEMP.minus(5|°C))

The point of this is to prevent flapping, but outside temperature readings are pretty stable, so may not be needed.

In my automations, I set dimmers to 99 and then don’t turn them off if 100. Let’s get it working first, then look into a manual override.

Opps… this was a silly mistake on my part… I’m a bit rusty with the DSL, and much prefer Jython. Try this one.

rule "Shutter rule"
when
    Channel "astro:sun:local:civilDawn#event" triggered START
    or Channel "astro:sun:local:rise#event" triggered// In case we missed the civil dawn due to temperature below automation threshold
    or Channel "astro:sun:local:noon#event" triggered// In case we missed the morning opening due to cold weather
    or Channel "astro:sun:local:civilDusk#event" triggered END
    or Item Wx_OWM_Current_Temperature changed
then
    val MIN_TEMP = 3.0|°C
    val ruleTitle = "SunriseShutterRule"
    logInfo(ruleTitle, "Rule has been triggered")
    if (now.isBefore(new DateTime(INSERT_CIVILDUSK_ITEM_HERE.state.toString)) && Wx_OWM_Current_Temperature.state >= MIN_TEMP && Wx_OWM_Current_Temperature.minimumSince(now.minusMinutes(30)).state >= MIN_TEMP.doubleValue) {
        if (gShutter.state == 100) {
            gShutter.sendCommand(UP)
            logInfo(ruleTitle, "Raised shutters")
        }
    }
    else if (gShutter.state == 0) {
        gShutter.sendCommand(DOWN)
        logInfo(ruleTitle, "Lowered shutters")
    }
end

I stand corrected. Thanks for the clarification.

It will be a great and welcome addition to the rules DSL.

Alas, here again, gShutter cannot reliably report its state.

I got the following (intentionally very verbose) rule now, which will fire every time the temperature is updated:

rule "Roof shutter rule"
when
	Channel "astro:sun:local:civilDawn#event" triggered START
	or Channel "astro:sun:local:rise#event" triggered// In case we missed the civil dawn due to temperature below automation threshold
	or Channel "astro:sun:local:noon#event" triggered// In case we missed the morning opening due to cold weather
	or Channel "astro:sun:local:civilDusk#event" triggered END
	// or Channel "astro:sun:local:nauticDusk#event" triggered END
	or Item Wx_OWM_Current_Temperature changed
then
	val String ruleTitle = "RoofShutterRule"

	val Number MIN_TEMP = 3.0|°C

	val boolean temperatureOk = if (
		(Wx_OWM_Current_Temperature.state >= MIN_TEMP)
		&& (Wx_OWM_Current_Temperature.minimumSince(now.minusMinutes(30)).state >= MIN_TEMP.doubleValue) ) { true } else { false }
	val String temperatureInfo = "(now: " + Wx_OWM_Current_Temperature.state.toString + (if (temperatureOk) {" ≥ "} else { " < " }) + MIN_TEMP +
		", lowest in the past 30 minutes: " + Wx_OWM_Current_Temperature.minimumSince(now.minusMinutes(30)).state + " °C"
		+ (if (temperatureOk) {" ≥ "} else { " < " }) + MIN_TEMP + ")"

	val String gShutterState = ( if ( gShutter.state == 100 ) { "DOWN" }
		else if ( gShutter.state == 0 ) { "UP" }
		else { gShutter.state.toString } )

	logInfo(ruleTitle, "Rule has been triggered - gShutter.state is '{}', Temperature is {} {}",
		gShutterState,
		( if ( temperatureOk === true ) { "OK" } else { "not OK" } ),
		temperatureInfo
	)

	if ( now.isBefore(new DateTime(Astro_Civil_Dusk_End.state.toString)) ) {
		// Anytime before the earliest 'shutters down' time: 'fire shutters UP' scenario
		logInfo(ruleTitle, "In Shutter Opening rule scenario - gShutter.state is " + gShutterState + " " + temperatureInfo)
		if ( temperatureOk === true ) {
			gShutter.sendCommand(UP)
			logInfo(ruleTitle, "Raised shutters " + temperatureInfo)
			sendNotification(notificationRecipient, "Raised shutters " + temperatureInfo)
		} else {
			logWarn(ruleTitle, "Shutters not raised, temperature condition not met " + temperatureInfo)
		}
	}
	else {
		// At or after the first 'shutters down' time: 'fire shutters DOWN' scenario
		logInfo(ruleTitle, "In Shutter Closing rule scenario - gShutter.state is " + gShutterState + " " + temperatureInfo)
		if ( temperatureOk === true ) {
			gShutter.sendCommand(DOWN)
			logInfo(ruleTitle, "Lowered shutters")
			sendNotification(notificationRecipient, "Lowered shutters " + temperatureInfo)
		} else {
			logWarn(ruleTitle, "Shutters not lowered, temperature condition not met " + temperatureInfo)
		}

	}
end```

I'm clueless about why it's not working.

Meanwhile I resorted on using a Switch to persist whether the up or down event fired. I also fixed the time check at the start of the rule since it would open the roller shutters at midnight.

The business logic of the rule now reads:

	if ( now.isBefore(new DateTime(Astro_Civil_Dusk_End.state.toString))
		&& now.isAfter(new DateTime(Astro_Civil_Dawn_Start.state.toString)) ) {
		// Anytime before the earliest 'shutters down' time and after the earliest 'shutters up' time:
		// 'fire shutters UP' scenario
		if (AT_Automation_RollerShutters_Opened.state == ON) {
			logDebug(ruleTitle, "Shutters already raised")
		} else {
			logInfo(ruleTitle, "In Shutter Opening rule scenario - gShutter.state is " + gShutterState + " " + temperatureInfo)
			if ( temperatureOk === true ) {
				gShutter.sendCommand(UP)
				logInfo(ruleTitle, "Raised shutters " + temperatureInfo)
				AT_Automation_RollerShutters_Opened.postUpdate(ON)
				sendNotification(notificationRecipient, "Raised shutters " + temperatureInfo)
			} else {
				logWarn(ruleTitle, "Shutters not raised, temperature condition not met " + temperatureInfo)
			}
		}
	}
	else {
		// At or after the first 'shutters down' time: 'fire shutters DOWN' scenario
		if (AT_Automation_RollerShutters_Opened.state == OFF) {
			logDebug(ruleTitle, "Shutters already lowered")
		} else {
			logInfo(ruleTitle, "In Shutter Closing rule scenario - gShutter.state is " + gShutterState + " " + temperatureInfo)
			if ( temperatureOk === true ) {
				gShutter.sendCommand(DOWN)
				logInfo(ruleTitle, "Lowered shutters")
				AT_Automation_RollerShutters_Opened.postUpdate(OFF)
				sendNotification(notificationRecipient, "Lowered shutters " + temperatureInfo)
			} else {
				logWarn(ruleTitle, "Shutters not lowered, temperature condition not met " + temperatureInfo)
			}
		}
	}

The Item I’m using:

Switch AT_Automation_RollerShutters_Opened "Roof shutters opened automatically"

When OpenHAB restarts, AT_Automation_RollerShutters_Opened is NULL which doesn’t adversely interfere with the rule. This is a workaround that seems to do the job.

As you can see from the log,

  • The rule works
  • State of gShutter remains bogus and unreliable (it reports DOWN where the shutters are all UP)
2019-03-13 15:15:24.338 [INFO ] [arthome.model.script.RoofShutterRule] - Rule has been triggered - gShutter.state is 'DOWN', Temperature is OK (now: 8.79 °C ≥ 3.0 °C, lowest in the past 30 minutes: 8.79 °C ≥ 3.0 °C)
2019-03-13 15:15:24.362 [WARN ] [arthome.model.script.RoofShutterRule] - Shutters already raised
2019-03-13 15:20:55.533 [INFO ] [arthome.model.script.RoofShutterRule] - Rule has been triggered - gShutter.state is 'DOWN', Temperature is OK (now: 8.79 °C ≥ 3.0 °C, lowest in the past 30 minutes: 8.79 °C ≥ 3.0 °C)
2019-03-13 15:20:55.641 [INFO ] [arthome.model.script.RoofShutterRule] - In Shutter Opening rule scenario - gShutter.state is DOWN (now: 8.79 °C ≥ 3.0 °C, lowest in the past 30 minutes: 8.79 °C ≥ 3.0 °C)
2019-03-13 15:20:55.648 [INFO ] [arthome.model.script.RoofShutterRule] - Raised shutters (now: 8.79 °C ≥ 3.0 °C, lowest in the past 30 minutes: 8.79 °C ≥ 3.0 °C)
2019-03-13 15:30:51.864 [INFO ] [arthome.model.script.RoofShutterRule] - Rule has been triggered - gShutter.state is 'DOWN', Temperature is OK (now: 8.62 °C ≥ 3.0 °C, lowest in the past 30 minutes: 8.62 °C ≥ 3.0 °C)
2019-03-13 15:30:51.879 [WARN ] [arthome.model.script.RoofShutterRule] - Shutters already raised
2019-03-13 15:40:51.025 [INFO ] [arthome.model.script.RoofShutterRule] - Rule has been triggered - gShutter.state is 'DOWN', Temperature is OK (now: 8.68 °C ≥ 3.0 °C, lowest in the past 30 minutes: 8.62 °C ≥ 3.0 °C)
2019-03-13 15:40:51.046 [WARN ] [arthome.model.script.RoofShutterRule] - Shutters already raised

Is your Command Polling Interval still set to the default? You would need zwave logs to determine exactly what it shiuld be set to, but you could just set it to the max and see if that fixes it.

I’m not at all surprised. Items of type Rollershutter have states 0-100, not UP/DOWN

Good to know. I replaced ‘UP’ with 0 and ‘DOWN’ with 100, but I still get inconsistent states.

You’ll probably have to elaborate on that, with event.log maybe

What exactly did you replace ? You cannot use OR in the group definition with values 0-100.
I didn’t follow your code but to rely on auto computed group state is an approach destined to fail for a number of reasons (value range being one of these, non-consistent behavior among devices being another one). You need to work on each member’s individual state instead.

Just FWIW, here’s a framework:

Granted it’s not elegant in terms of code, but as a matter of fact it is easier in the shutter use context to not use groups as there’s many “but what if” exceptions to apply to ever-differing groups of devices only.

Here’s what event.log told me this morning:

2019-03-14 06:28:01.070 [vent.ChannelTriggeredEvent] - astro:sun:local:nauticDawn#event triggered END
2019-03-14 06:28:01.074 [vent.ChannelTriggeredEvent] - astro:sun:local:civilDawn#event triggered START
2019-03-14 06:28:01.213 [ome.event.ItemCommandEvent] - Item 'gShutter' received command UP
2019-03-14 06:28:01.218 [ome.event.ItemCommandEvent] - Item 'AT_Shutter_N' received command UP
2019-03-14 06:28:01.247 [ome.event.ItemCommandEvent] - Item 'AT_Shutter_SE' received command UP
2019-03-14 06:28:01.264 [ome.event.ItemCommandEvent] - Item 'AT_Shutter_SW' received command UP
2019-03-14 06:28:01.268 [nt.ItemStatePredictedEvent] - AT_Shutter_N predicted to become UP
2019-03-14 06:28:01.273 [nt.ItemStatePredictedEvent] - AT_Shutter_SE predicted to become UP
2019-03-14 06:28:01.278 [vent.ItemStateChangedEvent] - AT_Automation_RollerShutters_Opened changed from OFF to ON
2019-03-14 06:28:01.280 [nt.ItemStatePredictedEvent] - AT_Shutter_SW predicted to become UP
2019-03-14 06:28:01.283 [vent.ItemStateChangedEvent] - AT_Shutter_SE changed from 100 to 0
2019-03-14 06:28:01.286 [vent.ItemStateChangedEvent] - AT_Shutter_SW changed from 100 to 0

As you can see, AT_Shutter_N apparently didn’t report its state change, although the closed shutter opened. But now the states are apparently more properly reported.

I replaced the OR(UP,DOWN) in the group definitions.

What I infer from your reply, is that it’s not reliable to infer group state with OR, so I’ll probably have to use a rule to set a group state proxy item whenever a member of gShutter changed state, in case I want to be able to assess the consolidated state.

You already said that but didn’t say what you’ve replaced it with.

Almost but not exactly. The point is that group state isn’t a meaningful value with range like data types such as a roller shutter (no matter if you use OR, SUM, AVG or whatever).
As I said I didn’t dive into your code to see how you use it and what you would need to change that into. No time for that sorry. But don’t use group state please, it’ll flaw your logic.
And before you hit that pitfall: mind that OPEN is not equivalent to (state == 0). Some shutters never reach 0 when driven up, even after calibration. YMMV as it depends on the devices but from experience, many people stumble across this sooner or later.

I’ll add that you could use MIN or MAX group functions if you are looking for all member shutters one way.

These messages come from autoupdate, having a pre-emptive guess at the outcome of a command. Where you’re expecting a timely update from a real device, it’s usually sensible to set autoupdate false for that Item.

That’s something worth looking into, on the zwave side (about which I know nothing but has already been discussed).

But - I don’t see the other shutters reporting either, in the events.log snip you’ve shown us. Maybe they do later, but the events shown look to me like they are results of autoupdate predictions.

Here you are:

Group:Rollershutter:OR(0, 100)  gShutter  "Roller Shutter"  <rollershutter>  (Home)				["Rollershutter"]

Good to know.

I keep learning :sunglasses:

So you would suggest that I set autoupdate="false" in the Rollershutter item bindings?

That’s up to you. But given the interest in the reported state, you probably don’t want autoupdate’s interference.

I don’t think the logic group functions work very well with non-bool member states.
The number based functions MIN/MAX/AVG are more appropriate here?

First step would be get your member shutters updating convincingly though.