Help Using Webcore Pistons & Hue Motion IDE

Hi,

I’m new to SmartThings and still very much in the learning stages. I have installed webCoRE as it seems to be the way forward with what i want to achieve but clearly I am doing a few things wrong and kindly ask that people have a look through my pistons and tell me what i am doing wrong.

A bit of background information, I am using Philips Hue bulbs and a couple of Hue Motion sensors with the custom IDE that i got from the blog post on here. It seems to be working well:
/**

  • Copyright 2015 SmartThings
  • Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except
  • in compliance with the License. You may obtain a copy of the License at:
  •  http://www.apache.org/licenses/LICENSE-2.0
    
  • Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
  • on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
  • for the specific language governing permissions and limitations under the License.

*/

metadata {
definition (name: “Hue Motion Sensor”, namespace: “digitalgecko”, author: “digitalgecko”) {

	capability "Motion Sensor"
	capability "Configuration"
	capability "Battery"
	capability "Refresh"
    capability "Temperature Measurement"
    capability "Sensor"
    capability "Illuminance Measurement" //0x0400

    fingerprint profileId: "0104", inClusters: "0000,0001,0003,0406,0400,0402", outClusters: "0019", manufacturer: "Philips", model: "SML001", deviceJoinName: "Hue Motion Sensor"
}

preferences {
		section {
		input title: "Temperature Offset", description: "This feature allows you to correct any temperature variations by selecting an offset. Ex: If your sensor consistently reports a temp that's 5 degrees too warm, you'd enter '-5'. If 3 degrees too cold, enter '+3'.", displayDuringSetup: false, type: "paragraph", element: "paragraph"
		input "tempOffset", "number", title: "Degrees", description: "Adjust temperature by this many degrees", range: "*..*", displayDuringSetup: false
	}
}

tiles(scale: 2) {
	multiAttributeTile(name:"motion", type: "generic", width: 6, height: 4){
		tileAttribute ("device.motion", key: "PRIMARY_CONTROL") {
			attributeState "active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#53a7c0"
			attributeState "inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff"
		}
	}
   
    
	valueTile("temperature", "device.temperature", width: 2, height: 2) {
		state("temperature", label:'${currentValue}°',
			backgroundColors:[
				[value: 31, color: "#153591"],
				[value: 44, color: "#1e9cbb"],
				[value: 59, color: "#90d2a7"],
				[value: 74, color: "#44b621"],
				[value: 84, color: "#f1d801"],
				[value: 95, color: "#d04e00"],
				[value: 96, color: "#bc2323"]
			]
		)
	}
    
    valueTile("battery", "device.battery", decoration: "flat", inactiveLabel: false, width: 2, height: 2) {
		state "battery", label:'${currentValue}% battery', unit:""
	}
	valueTile("illuminance", "device.illuminance", width: 2, height: 2) {
		state("illuminance", label:'${currentValue}', unit:"lux",
			backgroundColors:[
				[value: 9, color: "#767676"],
				[value: 315, color: "#ffa81e"],
				[value: 1000, color: "#fbd41b"]
			]
		)
	}
    standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
        state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
    }
    standardTile("configure", "device.configure", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
        state "default", label:"configure", action:"configure"
    }
    main "motion"
    details(["motion","temperature","battery", "refresh","illuminance",'configure'])
}

}

// Parse incoming device messages to generate events
def parse(String description) {
def msg = zigbee.parse(description)

//log.warn "--"
//log.trace description
//log.debug msg
//def x = zigbee.parseDescriptionAsMap( description )
//log.error x

Map map = [:]
if (description?.startsWith('catchall:')) {
	map = parseCatchAllMessage(description)
}
else if (description?.startsWith('temperature: ')) {
	map = parseCustomMessage(description)
}
else if (description?.startsWith('illuminance: ')) {
	map = parseCustomMessage(description)
}

// else if (description?.startsWith(‘zone status’)) {
// //map = parseIasMessage(description)
// log.trace “zone status”
// }

def result = map ? createEvent(map) : null

if (description?.startsWith('enroll request')) {
	List cmds = enrollResponse()
	result = cmds?.collect { new physicalgraph.device.HubAction(it) }
}
else if (description?.startsWith('read attr -')) {
	result = parseReportAttributeMessage(description).each { createEvent(it) }
}
return result

}

/*
Refresh Function
*/
def refresh() {
log.debug “Refreshing Values”

def refreshCmds = []
refreshCmds +=zigbee.readAttribute(0x0001, 0x0020) // Read battery?
refreshCmds += zigbee.readAttribute(0x0402, 0x0000) // Read temp?
refreshCmds += zigbee.readAttribute(0x0400, 0x0000) // Read luminance?
refreshCmds += zigbee.readAttribute(0x0406, 0x0000) // Read motion?

return refreshCmds + enrollResponse()

}

/*
Configure Function
*/
def configure() {

// TODO : device watch?

String zigbeeId = swapEndianHex(device.hub.zigbeeId)
log.debug "Confuguring Reporting and Bindings."


def configCmds = []
configCmds += zigbee.batteryConfig()
configCmds += zigbee.temperatureConfig(30, 600) // Set temp reporting times // Confirmed

configCmds += zigbee.configureReporting(0x406,0x0000, 0x18, 30, 600, null) // motion // confirmed


// Data type is not 0x20 = 0x8D invalid data type Unsigned 8-bit integer

configCmds += zigbee.configureReporting(0x400,0x0000, 0x21, 60, 600, 0x20) // Set luminance reporting times?? maybe    
return refresh() + configCmds 

}

/*
getMotionResult
*/

private Map getMotionResult(value) {
//log.trace "Motion : " + value

def descriptionText = value == "01" ? '{{ device.displayName }} detected motion':
		'{{ device.displayName }} stopped detecting motion'

return [
	name: 'motion',
	value: value == "01" ? "active" : "inactive",
	descriptionText: descriptionText,
	translatable: true,
]

}

/*
getTemperatureResult
*/
private Map getTemperatureResult(value) {

//log.trace "Temperature : " + value
if (tempOffset) {
	def offset = tempOffset as int
	def v = value as int
	value = v + offset
}
def descriptionText = temperatureScale == 'C' ? '{{ device.displayName }} was {{ value }}°C':
		'{{ device.displayName }} was {{ value }}°F'

return [
	name: 'temperature',
	value: value,
	descriptionText: descriptionText,
	translatable: true,
	unit: temperatureScale
]

}

def getTemperature(value) {
def celsius = Integer.parseInt(value, 16).shortValue() / 100
if(getTemperatureScale() == “C”){
return Math.round(celsius)
} else {
return Math.round(celsiusToFahrenheit(celsius))
}
}

private Map getLuminanceResult(rawValue) {
log.debug “Luminance rawValue = ${rawValue}”

def result = [
	name: 'illuminance',
	value: '--',
	translatable: true,
	unit: 'lux'
]

result.value = rawValue as Integer
return result

}

/*
getBatteryResult
*/
//TODO: needs calibration
private Map getBatteryResult(rawValue) {
//log.debug “Battery rawValue = ${rawValue}”

def result = [
	name: 'battery',
	value: '--',
	translatable: true
]

def volts = rawValue / 10

if (rawValue == 0 || rawValue == 255) {}
else {
	if (volts > 3.5) {
		result.descriptionText = "{{ device.displayName }} battery has too much power: (> 3.5) volts."
	}
	else {
		if (device.getDataValue("manufacturer") == "SmartThings") {
			volts = rawValue // For the batteryMap to work the key needs to be an int
			def batteryMap = [28:100, 27:100, 26:100, 25:90, 24:90, 23:70,
							  22:70, 21:50, 20:50, 19:30, 18:30, 17:15, 16:1, 15:0]
			def minVolts = 15
			def maxVolts = 28

			if (volts < minVolts)
				volts = minVolts
			else if (volts > maxVolts)
				volts = maxVolts
			def pct = batteryMap[volts]
			if (pct != null) {
				result.value = pct
				result.descriptionText = "{{ device.displayName }} battery was {{ value }}%"
			}
		}
		else {
			def minVolts = 2.1
			def maxVolts = 3.0
			def pct = (volts - minVolts) / (maxVolts - minVolts)
			def roundedPct = Math.round(pct * 100)
			if (roundedPct <= 0)
				roundedPct = 1
			result.value = Math.min(100, roundedPct)
			result.descriptionText = "{{ device.displayName }} battery was {{ value }}%"
		}
	}
}

return result

}
/*
parseCustomMessage
*/
private Map parseCustomMessage(String description) {
Map resultMap = [:]
if (description?.startsWith('temperature: ')) {
def value = zigbee.parseHATemperatureValue(description, "temperature: ", getTemperatureScale())
resultMap = getTemperatureResult(value)
}

if (description?.startsWith('illuminance: ')) {
log.warn "value: " + description.split(": ")[1]
        log.warn "proc: " + value

	def value = zigbee.lux( description.split(": ")[1] as Integer ) //zigbee.parseHAIlluminanceValue(description, "illuminance: ", getTemperatureScale())
	resultMap = getLuminanceResult(value)
}
return resultMap

}

/*
parseReportAttributeMessage
*/
private List parseReportAttributeMessage(String description) {
Map descMap = (description - “read attr - “).split(”,”).inject([:]) { map, param ->
def nameAndValue = param.split(":")
map += [(nameAndValue[0].trim()):nameAndValue[1].trim()]
}

List result = []

// Temperature
if (descMap.cluster == "0402" && descMap.attrId == "0000") {
	def value = getTemperature(descMap.value)
	result << getTemperatureResult(value)
}

// Motion
else if (descMap.cluster == "0406" && descMap.attrId == "0000") {
	result << getMotionResult(descMap.value)
}

// Battery
else if (descMap.cluster == "0001" && descMap.attrId == "0020") {
	result << getBatteryResult(Integer.parseInt(descMap.value, 16))
}

// Luminance
else if (descMap.cluster == "0402" ) { //&& descMap.attrId == "0020") {
	log.error "Luminance Response " + description
    //result << getBatteryResult(Integer.parseInt(descMap.value, 16))
}

return result

}

/*
parseCatchAllMessage
*/
private Map parseCatchAllMessage(String description) {
Map resultMap = [:]
def cluster = zigbee.parse(description)
// log.debug cluster
if (shouldProcessMessage(cluster)) {
switch(cluster.clusterId) {
case 0x0001:
// 0x07 - configure reporting
if (cluster.command != 0x07) {
resultMap = getBatteryResult(cluster.data.last())
}
break

		case 0x0400:
        	if (cluster.command == 0x07) { // Ignore Configure Reporting Response
            	if(cluster.data[0] == 0x00) {
					log.trace "Luminance Reporting Configured"
					sendEvent(name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
				}
				else {
					log.warn "Luminance REPORTING CONFIG FAILED- error code:${cluster.data[0]}"
				}
			}
			else {
        		log.debug "catchall : luminance" + cluster
            	resultMap = getLuminanceResult(cluster.data.last());
            }

		break
        
		
        
		case 0x0402:
			if (cluster.command == 0x07) {
				if(cluster.data[0] == 0x00) {
					log.trace "Temperature Reporting Configured"
					sendEvent(name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
				}
				else {
					log.warn "TEMP REPORTING CONFIG FAILED- error code:${cluster.data[0]}"
				}
			}
			else {
				// temp is last 2 data values. reverse to swap endian
				String temp = cluster.data[-2..-1].reverse().collect { cluster.hex1(it) }.join()
				def value = getTemperature(temp)
				resultMap = getTemperatureResult(value)
			}
		break
	}
}

return resultMap

}

private boolean shouldProcessMessage(cluster) {
// 0x0B is default response indicating message got through
boolean ignoredMessage = cluster.profileId != 0x0104 ||
cluster.command == 0x0B ||
(cluster.data.size() > 0 && cluster.data.first() == 0x3e)
return !ignoredMessage
}

// This seems to be IAS Specific and not needed we are not really a motion sensor
def enrollResponse() {
// log.debug “Sending enroll response”
// String zigbeeEui = swapEndianHex(device.hub.zigbeeEui)
// [
// //Resending the CIE in case the enroll request is sent before CIE is written
// “zcl global write 0x500 0x10 0xf0 {{zigbeeEui}}", "delay 200", // "send 0x{device.deviceNetworkId} 1 {endpointId}", "delay 500", // //Enroll Response // "raw 0x500 {01 23 00 00 00}", "delay 200", // "send 0x{device.deviceNetworkId} 1 1”, “delay 200”
// ]
}

def configureHealthCheck() {
Integer hcIntervalMinutes = 12
refresh()
sendEvent(name: “checkInterval”, value: hcIntervalMinutes * 60, displayed: false, data: [protocol: “zigbee”, hubHardwareId: device.hub.hardwareID])
}

def updated() {
log.debug “in updated()”
configureHealthCheck()
}

def ping() {
return zigbee.onOffRefresh()
}

private getEndpointId() {
new BigInteger(device.endpointId, 16).toString()
}

private String swapEndianHex(String hex) {
reverseArray(hex.decodeHex()).encodeHex()
}

private byte reverseArray(byte array) {
int i = 0;
int j = array.length - 1;
byte tmp;
while (j > i) {
tmp = array[j];
array[j] = array[i];
array[i] = tmp;
j–;
i++;
}
return array
}

Kitchen:
Aim: I want to configure my lights to turn on when motion is detected but only when the room is dark enough. I also want them to turn off when i leave the room.
Piston:


Problem: Whilst it is working roughly correctly, the lights turn off when i am still in the room (presumably because the motion sensor isn’t detecting motion) and sometimes they turn back on instantly, as they should, when i move again but sometimes they don’t turn back on at all which is rather annoying! What am i doing wrong?

Living Room:
Aim: The room clearly used to be 2 rooms and when creating one larger room, the electrics were not altered so there are 2 separate switches for the 2 ceiling lights. I want to configure the lights so both turn on when i turn on the switch next to the door (leaving the far switch permanently turned on).
Piston:


Problem: This piston is not working at all. WHat have i got wrong here?

Hallway:
Aim: For the lights to turn on only when dark enough and when either motion is detected or when i open the front door.
Piston:


Problem: It seems to work fairly well but sometimes the lights do not turn off at all. What am i doing wrong?

Thanks in advance for your help.

The best place to post your webCoRE questions are in the WC community forum :slight_smile:

Yes but for that i need my account verified and over a week later, i still haven’t received the verification email (yes, i have sent a chaser already) so for now i have to ask on here. Plus, i want to know whether i have done something wrong in the IDE too.

If you’re using an outlook or any microsoft email address, there might be an issue with the verification emails. If you have an alternate, I’d suggest you use that for now.

Tagging @anon36505037

Do you have a log from WebCore of when you think the bulb should be turning off? You do realize your else will only fire if the first part is totally false, correct? Typically, I don’t set up any of my off functions as "eles"s just because they are harder to predict. I would set up this piston by saying CHANGES TO ACTIVE in the first part and then a separate off function with CHANGES TO INACTIVE to turn them off. That seems to be more reliable and more straightforward.

Sorry Robin, i missed this. I just have sent you a PM with an alternative email address.

Hi @Ryan780 Here is the log taken a few minutes ago:

03/09/2018, 19:10:07 +975ms
+1ms ╔Received event [Hue Motion Sensor - Kitchen].motion = active with a delay of 167ms
+118ms ║RunTime Analysis CS > 15ms > PS > 39ms > PE > 64ms > CE
+121ms ║Runtime (38289 bytes) successfully initialized in 39ms (v0.3.107.20180806) (119ms)
+122ms ║╔Execution stage started
+130ms ║║Comparison (enum) active is (string) active = true (1ms)
+132ms ║║Cancelling condition #8’s schedules…
+132ms ║║Condition #8 evaluated true (6ms)
+133ms ║║Cancelling condition #1’s schedules…
+134ms ║║Condition group #1 evaluated true (state changed) (8ms)
+143ms ║║Comparison (integer) 22 is_less_than_or_equal_to (integer) 15 = false (1ms)
+145ms ║║Cancelling condition #10’s schedules…
+146ms ║║Condition #10 evaluated false (9ms)
+146ms ║║Cancelling condition #6’s schedules…
+147ms ║║Condition group #6 evaluated false (state changed) (11ms)
+149ms ║╚Execution stage complete. (28ms)
+150ms ╚Event processed successfully (150ms)
03/09/2018, 19:10:06 +67ms
+1ms ╔Received event [Home].time = 1535998207952 with a delay of -1885ms
+140ms ║RunTime Analysis CS > 22ms > PS > 39ms > PE > 78ms > CE
+142ms ║Runtime (38273 bytes) successfully initialized in 39ms (v0.3.107.20180806) (138ms)
+144ms ║╔Execution stage started
+180ms ║║Executed physical command [Kitchen - Back Hue color spot 1].off() (12ms)
+181ms ║║Executed [Kitchen - Back Hue color spot 1].off (14ms)
+197ms ║║Executed physical command [Kitchen - Back Hue color spot 2].off() (14ms)
+198ms ║║Executed [Kitchen - Back Hue color spot 2].off (15ms)
+213ms ║║Executed physical command [Kitchen - Back Hue color spot 3].off() (12ms)
+214ms ║║Executed [Kitchen - Back Hue color spot 3].off (14ms)
+229ms ║║Executed physical command [Kitchen - Forward Hue color spot 1].off() (12ms)
+230ms ║║Executed [Kitchen - Forward Hue color spot 1].off (14ms)
+244ms ║║Executed physical command [Kitchen - Forward Hue color spot 1].off() (12ms)
+245ms ║║Executed [Kitchen - Forward Hue color spot 1].off (13ms)
+259ms ║║Executed physical command [Kitchen - Forward Hue color spot 2].off() (11ms)
+260ms ║║Executed [Kitchen - Forward Hue color spot 2].off (13ms)
+273ms ║║Executed physical command [Kitchen - Under cabinet lights].off() (11ms)
+274ms ║║Executed [Kitchen - Under cabinet lights].off (13ms)
+277ms ║╚Execution stage complete. (134ms)
+278ms ╚Event processed successfully (278ms)
03/09/2018, 19:09:37 +820ms
+2ms ╔Received event [Hue Motion Sensor - Kitchen].motion = inactive with a delay of 81ms
+108ms ║RunTime Analysis CS > 15ms > PS > 37ms > PE > 56ms > CE
+110ms ║Runtime (38283 bytes) successfully initialized in 37ms (v0.3.107.20180806) (108ms)
+111ms ║╔Execution stage started
+119ms ║║Comparison (enum) inactive is (string) active = false (1ms)
+120ms ║║Cancelling condition #8’s schedules…
+121ms ║║Condition #8 evaluated false (5ms)
+122ms ║║Cancelling condition #1’s schedules…
+123ms ║║Condition group #1 evaluated false (state changed) (7ms)
+124ms ║║Cancelling statement #3’s schedules…
+130ms ║║Executed virtual command [Kitchen - Back Hue color spot 1, Kitchen - Back Hue color spot 2, Kitchen - Back Hue color spot 3, Kitchen - Forward Hue color spot 1, Kitchen - Forward Hue color spot 1, Kitchen - Forward Hue color spot 2, Kitchen - Under cabinet lights].wait (0ms)
+131ms ║║Requesting a wake up for Mon, Sep 3 2018 @ 7:10:07 PM BST (in 30.0s)
+135ms ║╚Execution stage complete. (24ms)
+137ms ║Setting up scheduled job for Mon, Sep 3 2018 @ 7:10:07 PM BST (in 29.996s)
+146ms ╚Event processed successfully (146ms)

I’m new to webcoRE so my knowledge is minimal. Is this what you mean? image

No. Go to the WebCore community and look at the example pistons. You can view them without being verified or logged in. There are a ton up there.

That’s not overly helpful! I have already done this…

I will try and find an example of when it doesn’t work.

But you didn’t follow any of them obviously since you have the off function nested inside the on function which won’t work. You have to separate them.

1 Like

If it was obvious, i wouldn’t be asking. I didn’t understand what you meant and changed it to what i thought you meant. So far you have just picked holes in things and when i ask for help you simply say “look at the examples” which i “obviously” have already done.

How is this different to what I started with?

Ah, I see. Ryan said originally that else statements were unreliable. Do you use them and if not, how do you configure it?

Great, thanks. I will revert to the original script and upload a log tomorrow when i have one of it misbehaving. Thanks again for your help.

I said, I find them unreliable. Because I’m not one of the people who wrote WebCore (like @anon36505037). So, I find it easier as a beginner to use two separate functions. One for on and one for off. And if you’re a newbie, you might want to learn to crawl first and not try to keep up with a marathoner like Robin. Start off simple and then when you get the hang of it move up to more complicated things. But hey, you wanna run first, then have at it dude.

Here is a log from them not working. They were working perfectly and coming back on instantly when they went off from lack of movement, then simply would not come back on despite waving my hand in front of the motion sensor.

04/09/2018, 19:29:26 +77ms
+1ms ╔Received event [Hue Motion Sensor - Kitchen].motion = active with a delay of 78ms
+157ms ║RunTime Analysis CS > 12ms > PS > 29ms > PE > 115ms > CE
+159ms ║Runtime (38726 bytes) successfully initialized in 29ms (v0.3.107.20180806) (157ms)
+160ms ║╔Execution stage started
+169ms ║║Comparison (enum) active is (string) active = true (1ms)
+171ms ║║Cancelling condition #8’s schedules…
+171ms ║║Condition #8 evaluated true (6ms)
+172ms ║║Cancelling condition #1’s schedules…
+173ms ║║Condition group #1 evaluated true (state changed) (8ms)
+183ms ║║Comparison (integer) 0 is_less_than_or_equal_to (integer) 15 = true (1ms)
+184ms ║║Condition #10 evaluated true (9ms)
+185ms ║║Condition group #6 evaluated true (state did not change) (10ms)
+186ms ║║Cancelling statement #6’s schedules…
+206ms ║║Executed physical command [Kitchen - Back Hue color spot 1].on() (16ms)
+207ms ║║Executed [Kitchen - Back Hue color spot 1].on (16ms)
+221ms ║║Executed physical command [Kitchen - Back Hue color spot 2].on() (12ms)
+222ms ║║Executed [Kitchen - Back Hue color spot 2].on (14ms)
+235ms ║║Executed physical command [Kitchen - Back Hue color spot 3].on() (11ms)
+236ms ║║Executed [Kitchen - Back Hue color spot 3].on (13ms)
+250ms ║║Executed physical command [Kitchen - Forward Hue color spot 1].on() (12ms)
+251ms ║║Executed [Kitchen - Forward Hue color spot 1].on (14ms)
+266ms ║║Executed physical command [Kitchen - Forward Hue color spot 1].on() (13ms)
+267ms ║║Executed [Kitchen - Forward Hue color spot 1].on (13ms)
+280ms ║║Executed physical command [Kitchen - Forward Hue color spot 2].on() (11ms)
+281ms ║║Executed [Kitchen - Forward Hue color spot 2].on (13ms)
+296ms ║║Executed physical command [Kitchen - Under cabinet lights].on() (13ms)
+297ms ║║Executed [Kitchen - Under cabinet lights].on (14ms)
+299ms ║╚Execution stage complete. (139ms)
+300ms ╚Event processed successfully (300ms)
04/09/2018, 19:27:47 +176ms
+1ms ╔Received event [Home].time = 1536085668157 with a delay of -981ms
+315ms ║RunTime Analysis CS > 147ms > PS > 38ms > PE > 129ms > CE
+318ms ║Runtime (38711 bytes) successfully initialized in 38ms (v0.3.107.20180806) (316ms)
+320ms ║╔Execution stage started
+358ms ║║Executed physical command [Kitchen - Back Hue color spot 1].off() (12ms)
+359ms ║║Executed [Kitchen - Back Hue color spot 1].off (13ms)
+374ms ║║Executed physical command [Kitchen - Back Hue color spot 2].off() (13ms)
+375ms ║║Executed [Kitchen - Back Hue color spot 2].off (15ms)
+389ms ║║Executed physical command [Kitchen - Back Hue color spot 3].off() (12ms)
+390ms ║║Executed [Kitchen - Back Hue color spot 3].off (14ms)
+403ms ║║Executed physical command [Kitchen - Forward Hue color spot 1].off() (11ms)
+404ms ║║Executed [Kitchen - Forward Hue color spot 1].off (13ms)
+418ms ║║Executed physical command [Kitchen - Forward Hue color spot 1].off() (12ms)
+419ms ║║Executed [Kitchen - Forward Hue color spot 1].off (13ms)
+434ms ║║Executed physical command [Kitchen - Forward Hue color spot 2].off() (12ms)
+435ms ║║Executed [Kitchen - Forward Hue color spot 2].off (15ms)
+449ms ║║Executed physical command [Kitchen - Under cabinet lights].off() (12ms)
+450ms ║║Executed [Kitchen - Under cabinet lights].off (13ms)
+452ms ║╚Execution stage complete. (133ms)
+454ms ╚Event processed successfully (453ms)
04/09/2018, 19:27:17 +976ms
+1ms ╔Received event [Hue Motion Sensor - Kitchen].motion = inactive with a delay of 224ms
+149ms ║RunTime Analysis CS > 15ms > PS > 26ms > PE > 108ms > CE
+151ms ║Runtime (38722 bytes) successfully initialized in 26ms (v0.3.107.20180806) (149ms)
+152ms ║╔Execution stage started
+161ms ║║Comparison (enum) inactive is (string) active = false (2ms)
+162ms ║║Cancelling condition #8’s schedules…
+163ms ║║Condition #8 evaluated false (6ms)
+164ms ║║Cancelling condition #1’s schedules…
+164ms ║║Condition group #1 evaluated false (state changed) (7ms)
+170ms ║║Comparison (enum) inactive is (string) inactive = true (2ms)
+171ms ║║Condition #15 evaluated true (5ms)
+172ms ║║Condition group #11 evaluated true (state did not change) (6ms)
+174ms ║║Cancelling statement #12’s schedules…
+180ms ║║Executed virtual command [Kitchen - Back Hue color spot 1, Kitchen - Back Hue color spot 2, Kitchen - Back Hue color spot 3, Kitchen - Forward Hue color spot 1, Kitchen - Forward Hue color spot 1, Kitchen - Forward Hue color spot 2, Kitchen - Under cabinet lights].wait (0ms)
+181ms ║║Requesting a wake up for Tue, Sep 4 2018 @ 7:27:48 PM BST (in 30.0s)
+185ms ║╚Execution stage complete. (33ms)
+186ms ║Setting up scheduled job for Tue, Sep 4 2018 @ 7:27:48 PM BST (in 29.995s)
+197ms ╚Event processed successfully (197ms)
04/09/2018, 19:27:16 +268ms
+2ms ╔Received event [Hue Motion Sensor - Kitchen].motion = active with a delay of 114ms
+191ms ║RunTime Analysis CS > 18ms > PS > 36ms > PE > 136ms > CE
+195ms ║Runtime (38727 bytes) successfully initialized in 36ms (v0.3.107.20180806) (193ms)
+196ms ║╔Execution stage started
+217ms ║║Comparison (enum) active is (string) active = true (2ms)
+218ms ║║Cancelling condition #8’s schedules…
+219ms ║║Condition #8 evaluated true (6ms)
+220ms ║║Cancelling condition #1’s schedules…
+221ms ║║Condition group #1 evaluated true (state changed) (8ms)
+230ms ║║Comparison (integer) 3 is_less_than_or_equal_to (integer) 15 = true (1ms)
+232ms ║║Condition #10 evaluated true (9ms)
+233ms ║║Condition group #6 evaluated true (state did not change) (9ms)
+234ms ║║Cancelling statement #6’s schedules…
+257ms ║║Executed physical command [Kitchen - Back Hue color spot 1].on() (18ms)
+258ms ║║Executed [Kitchen - Back Hue color spot 1].on (20ms)
+277ms ║║Executed physical command [Kitchen - Back Hue color spot 2].on() (16ms)
+278ms ║║Executed [Kitchen - Back Hue color spot 2].on (16ms)
+295ms ║║Executed physical command [Kitchen - Back Hue color spot 3].on() (15ms)
+296ms ║║Executed [Kitchen - Back Hue color spot 3].on (16ms)
+314ms ║║Executed physical command [Kitchen - Forward Hue color spot 1].on() (15ms)
+314ms ║║Executed [Kitchen - Forward Hue color spot 1].on (16ms)
+331ms ║║Executed physical command [Kitchen - Forward Hue color spot 1].on() (14ms)
+332ms ║║Executed [Kitchen - Forward Hue color spot 1].on (16ms)
+350ms ║║Executed physical command [Kitchen - Forward Hue color spot 2].on() (15ms)
+351ms ║║Executed [Kitchen - Forward Hue color spot 2].on (17ms)
+368ms ║║Executed physical command [Kitchen - Under cabinet lights].on() (15ms)
+369ms ║║Executed [Kitchen - Under cabinet lights].on (16ms)
+371ms ║╚Execution stage complete. (175ms)
+372ms ╚Event processed successfully (372ms)

Also it is not restarting the 30 second clock despite walking past the motion sensor within that time (i have tried walking past after 15 seconds and the lights go off after another 15 seconds rather than 30 seconds after the last motion was detected).

Good idea. I wonder if it is the If statement in the Else that’s the issue - once it is inactive, it waits 30 seconds and then turns off regardless of whether it becomes active before the 30 seconds has completed. What do you think?

Sorry for the late reply, i have been adjusting the piston but i still can’t get it right. I am wondering whether the problem is with using a Hue motion sensor. Do you have a similar piston that uses a Hue motion sensor?