ZOOZ ZSE40 4-in-1 Sensor Device Handler

dth_motionsensor
dth_humiditysensor
dth_luxsensor
dth_sensors

(www.rboyapps.com - Make your home your butler!) #14

This one didn't work for me, got fed up of trying. For someone I wasn't even getting any debug messages. I had to switch to an alternative one on the ZooZ website to get it to start working.


#15

Which???

I have my 2 “working” but not all that well. Seems to stick on “motion” forever even though I have set the time to 1 minute. Worst yet was when I first added it. One of the sensors stuck on “Motion” for over 1 hour. I gave up and went out for dinner. Later that night it switched to “No motion” but once it detected motion again it stayed there for well over 4 minutes even though the time was set to 1 minute and there was no way any motion was present (placed inside a closed box).


(www.rboyapps.com - Make your home your butler!) #16

Yep I'm facing similar issues, I think the device packets are getting lost on the network. I'm working on a potential new DH for it. There are two DH's available for this on GitHub, one of them is just plain wrong, that just isn't the way sleepy devices work. The second one is written much better but there are a few bugs in it. Let me see if I can crack this puzzle.


#17

So, I do have both my sensors working albeit very slow. With a sensor pointing right at the door and less than 6 feet away, I can walk down the length of my foyer before a "motion detected" event occurs. This compared to a wemo motion sensor (which is notoriously slow) placed directly next to ZooZ, the wemo wins every time by as much as 3-4 seconds.


(Simon) #18

I had a lot of trouble with my sensors at first, I fixed my issues by adding more devices closer to the Zooz, I think it had trouble sending signals through the walls in 2 of the rooms I have them in, they were also 30-40 ft from the nearest device as well as having to go through the walls.

When I installed some GE zwave light switches (that also act as repeaters) between the Zooz and the Hub things improved a lot and now I don’t have any issues. The Zooz is about 6ft from the light switch.

I’d also tried an enerwave motion sensor and it didn’t do any better than the Zooz, it also had trouble reliably reporting events 40ft away from the hub.


(www.rboyapps.com - Make your home your butler!) #19

Thanks for the tips.

We just decided to create a brand new DH from scratch based on my experience with other sensors and the specifications. Also decided to add some additional features. If anyone's interested they can check it out here, those who already have access to RBoy apps can download it right away.

Also as @cdikland pointed out, I've found the motion sensor to be very "slow" compared to the Ecolink and Monoprice (both new and old) sensors. However the temperature updates and humidity updates are fantastic and are better than those found on Monoprice (temp only).


(Jorden) #20

I assume that the slowness can't be fixed by a DH then?


(Simon) #21

I don’t see how a new DH would help, this sounds like an issue with the way the motion sensor works. There are no parameter on the device I know of to improve responsiveness.

I use it to turn off lights after no activity is detected and turn on an alarm so a few seconds slowness doesn’t impact my usage but I can see he slowness would be a pain for some uses.


(tkreidl) #22

Will any of these device handlers allow you to change the parameters interactively? From all your experience, which is the most reliable version to currently use? I currently only can see the temperature and detect motion, which is another issue, but would like to be able to adjust a number of the parameters, like sesitivity, humidity granularity, etc. and see no other way than via an app like this. Many thanks in advance.


(Ben) #23

Can anyone tell me how quickly the humidity reports? I'd like to try to use this as a trigger to turn on a bathroom exhaust fan whilst showering if the humidity reaches a specific level.


#24

Hi @Zoey, it depends on what you set the reporting threshold for. It's set to report any change by 10% in humidity by default, so new value will report once humidity drops or goes up by 10% but you can set it to as low as 1%. Lower settings will decrease battery life though. Let us know if you have any other questions!


(Ben) #25

@TheSmartestHouse

Thanks for the info!


(Scott) #26

I have 2 of these and they go through batteries about every 2.5 months. I'd like to use rechargeable batteries instead. Can the DTH be updated to show rechargeable battery life accurately?


(Simon) #27

I’ll take a look this w/e and do a new release.

I get the same battery life, 2-3 months, it switches to 255% when it get low and doesn’t give out an low battery alarm, is that the problem you have been seeing too?


(Simon) #28

Updated device handler, fixed the battery value shown.

Previously it used to show 255% when it was about to die, now it shows 1%, it now updates the battery level once a day.

I’ve been getting about 2-3 months life out of the batteries on my 3 devices, my Enerwave motion sensors (which don’t have temp, humidity or illumination are still running on their first set 8 months after install.
To help with this I’ve changed the wakeup interval default to 60 mins (from 30) and dialed back the temp alerts to only happen when the temp changes a whole degree C rather than 0.1 degrees C. Hopefully this will improve the battery life. If you already installed this device handler you’ll need to goto the setting and change the values yourself in the device settings.

The updated device handler code is in the 1st post of this thread.


Need help pairing a monoprice 4 in 1 sensor to smart things hub
Monoprice Multi-Sensor Pairing Issue
#29

hey simon - trying out your latest code and getting an error....

Org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: script14793481754691795643373.groovy: 217: expecting anything but ''\n''; got it anyway @ line 217, column 70. name:"tamper", value: "clear”) ^ 1 error


(Simon) #30

Hmm, I think I had a cut and paste error.

I’ve updated my post with a fixed version, you shouldn’t see the error any more.


#31

awesome thx!


#32

Awesome stuff! Works great. Temperature is most important to me. Is there a way to show the temperature on the main screen instead of the motion state?


(Simon) #33

This is an updated device handler which lets you choose the primary display sensor to be Motion or Temperature.
By default it is Motion. To change to Temperature goto the device setting (the little gear in the top right corner in the device display window) and choose Temperature from the “Primary Display” setting.

/**
 *  ZOOZ 4-in-1 sensor
 *
 *  Copyright 2016 Simon Capper
 *
 *  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.
 *
 */
 
/* change history

Initial version : may 2016
Update 1 : november 12th 2016
- battery low warning fixed, previous the battery level would show 255% when it was low, now
  it shows the battery is low
- read the battery level every day, previously it would only update when the config was changed
- fix descriptions on sensor levels
- changed some default values to improve battery life
Update 2&3 : december 31st 2016
- add primary display option to allow temperature or motion to be the primary display
- fix help text on LED Mode
Update 4: january 1st 2017
- re-read battery level after tamper, causes battery level to be updated more quickly 
  after batteries are replaced
- re-send config to Zooz after tamper as sometimes config parameters get reset after battery
  change
- Use BasicSet for motion notification as the burglar events can be unreliable
Update 5: january 24th 2017
- add "Illumination Sensor Update" setting to turn off illumination update events, 
previously if you set the illumination change level to 0 to disable this
- min value for luminosity changed to 5
- Fixed bug in motion sensor introduced in Update 4. This could cause the device handler to fail to
  report motion events
- Add signature for newer version of the device so it is recognized by this device handler

/*
Device handler for ZOOZ ZSE40 4-in-1 sensor.
 
To add the zooz to a smart things network do the following:

1) Add this device handler to your "My Device Handlers" in the developer IDE.

2) Make sure you save *and* publish the new device in "My Device Handlers" in the IDE.

3) Find the "Z Wave Button" on the zooz. It is shown on the instructions that come with the Zoos,
it is a small hole on one edge of the Zooz next to a row of slightly larger holes, find something
that you can press it with, pin or something

4) Put the batteries into the zooz, close the case.

5) Get really close to the Smart Things hub, the zooz is a secure device and needs to talk directly 
to the hub, you can move it later once it is pared.

6) In the smart things app on you phone "add a new thing" and select Connect New Device, your phone 
will say it is looking for a new thing.

7) Press the z wave button twice quickly, the zooz will flash 6 times, about 30 seconds later
your phone will say it found a "ZOOZ ZSE40 4-in-1 Sensor"

NOTE: If something goes wrong with the secure pairing the device might show up as a "z-wave door/window sensor".
If you are not close to the hub when you pair it can cause it to show up like this.
You can fix this by deleting the device and re-adding or by going to the IDE and changing the device type 
to "ZOOZ ZSE40 4-in-1 sensor".

The device "raw description" in the IDE should start with this:
zw:Ss type:0701 
If it starts with "zw:S" (i.e. no little s) then the secure join has failed, you should
delete the device and try again (if you care about secure mode).

8) Name your device and select your configuration options. (You can come back and change these later at any time)

Biggest thing to think of when choosing the settings is battery life, you can set the settings in
a way that will drain the battery quickly if you are not careful.

- Primary Display: Select Motion or Temperature, (default Motion). This tells the device handler whether to
display the temperature or the motion in the main menu on your phone.

- Motion Sensor Idle Time (minutes) (default 3 mins): this tells the zooz how long it has to detect no
motion before sending a "no motion detected" event back to the ST hub. Min 1 min, max 255 mins.
If you set this too low the zooz will send lots of motion/no-motion events and this drains the battery.

- Motion Sensor Sensitivity (1 high - 7 low) (default 4): sets how sensitive the zooz is, 1 is most sensitive
7 is least sensitive. Experimaent to see what works for you.

- Sensort updates: enable/disable. When enabled the Zooz will send temperature, humidity and lumination events to the hub
at the levels configured. When disabled the hub will read the temperature, humidity and luminosity value once every 
"Wake interval" (see below for wake interval).

- Temperature change level (1/10th °C) (default 10): (0.1°C - 5°C) The zooz only sends temperature info to the hub when the 
temp changes by at least this value.
If you set this too low the zooz will send lots of temp change events and this drains the battery.

- Humidity change level (default 50): The zooz only sends humidity info to the hub when the 
humidity changes by at least this vale.
If you set this too low the zooz will send lots of humidity change events and this drains the battery.

- Illumination change level (default 50): The zooz only sends illumination info to the hub when the 
illumination changes by at least this value.
If you set this too low the zooz will send lots of illumination change events which will drain the battery.

- Wake Interval (minutes) (default: 60 mins). The zooz is a sleepy device because it runs off a battery, this
setting tells it how often to wake up to see if you've changed its configuration. 
When the zooz wakes up this driver reads the Temperature, Humidy and Illumination value from the Zooz, 
so unless sensors are at alert levels this interval is also controls how often the sensor values get updated.
If you make a configuration change to the Zooz, you have to wait up to the "Wake Interval" before it takes 
effect. (you can speed this up by pressing the z wave button on the zooz once, this forces the Zooz to 
wake up early).
The lower you set this value the faster the battery will drain.

- Led mode (1, 2 or 3) (default: 3)
Option 1 - LED off
Option 2 - LED is has a different color depending on the temperature, "breadth mode"
Option 3 - LED will blink when motion is detected or the temp goes below the alert level

Option 1 is best for the battery life, option 2 is the worst.

*/

metadata {
    definition (name: "ZOOZ ZSE40 4-in-1 sensor", namespace: "skyjunky", author: "Simon Capper") {
        capability "Battery"
        capability "Motion Sensor"
        capability "Tamper Alert"
        capability "Temperature Measurement"
        capability "Configuration"
        capability "Relative Humidity Measurement"
        capability "Illuminance Measurement"
        
        attribute "sensorlevels", "string"
        attribute "primaryDisplay", "string"
        
        fingerprint deviceId: "0x0701", inClusters: "0x5E,0x98,0x72,0x5A,0x85,0x59,0x73,0x80,0x71,0x31,0x70,0x84,0x7A"
        fingerprint deviceId: "0x0701", inClusters: "0x5E,0x98,0x86,0x72,0x5A,0x85,0x59,0x73,0x80,0x71,0x31,0x70,0x84,0x7A"
    }

    tiles(scale:2) {
        multiAttributeTile(name:"motion", type: "generic", width: 6, height: 4){
            tileAttribute ("device.primaryDisplay", key: "PRIMARY_CONTROL") {
                attributeState "",  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"]
                ]
                attributeState "active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#53a7c0"
                attributeState "inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff"
            }
            tileAttribute ("device.sensorlevels", key: "SECONDARY_CONTROL") {
                attributeState "sensorlevels", label: '${currentValue}'
            }
        }
        standardTile("tamper", "device.tamper", decoration: "flat", width: 2, height: 2)
        {
            state("clear", label:'Secure', defaultState: true, icon:"", backgroundColor: "#ffffff"  )
            state("detected", label:'Tamper', icon:"st.alarm.alarm.alarm", backgroundColor: "#ffffff" )
        }
        valueTile("battery", "device.battery", decoration: "flat", width: 2, height: 2) 
        {
            state("battery", label:'${currentValue}% battery')
        }
        main "motion"
        details(["motion", "tamper", "battery"])
    }
    
    preferences {
        input "primaryDisplayType", "enum", options: ["Motion", "Temperature"], title: "Primary Display", defaultValue: "Motion",
              description: "Sensor to show in primary display",
              required: false, displayDuringSetup: true
        input "pirTimeout", "number", title: "Motion Sensor Idle Time (minutes)", defaultValue: 3,
              description: "Inactivity time before reporting no motion",
              required: false, displayDuringSetup: true, range: "1..255"
        input "pirSensitivity", "number", title: "Motion Sensor Sensitivity (1 high - 7 low)", defaultValue: 3,
              description: "1 is most sensitive, 7 is least sensitive",
              required: false, displayDuringSetup: true, range: "1..7"
        input "tempAlert", "number", title: "Temperature reporting level (1/10th °C)", defaultValue: 10,
              description: "Minimum temperature change to trigger temp updates",
              required: false, displayDuringSetup: true, range: "1..50"
        input "humidityAlert", "number", title: "Humidity reporting level", defaultValue: 50,
              description: "Minimum humidity level change to trigger updates",
              required: false, displayDuringSetup: true, range: "1..50"
        input "illumSensorAlerts", "enum", options: ["Enabled", "Disabled"], title: "Enable Illumination Sensor Updates", defaultValue: "Disabled",
              description: "Enables illumination update events",
              required: false, displayDuringSetup: true
        input "illumAlert", "number", title: "Illumination reporting level", defaultValue: 50,
              description: "Minumum illumination level change to trigger updates",
              required: false, displayDuringSetup: true, range: "5..50"
        input "ledMode", "number", title: "LED Mode", defaultValue: 3,
              description: "1 LED Off, 2 - Always on (drains battery), 3 - Blink LED",
              required: false, displayDuringSetup: true, range: "1..3"
        input "wakeInterval", "number", title: "Wake Interval (minutes)", defaultValue: 60,
              description: "Interval (in minutes) for polling configuration and sensor values, shorter interval reduces battery life.",
              required: false, displayDuringSetup: true, range: "10..10080"
    }
}

// parse events into attributes
def parse(String description) {
    def result = null
    // supported classes
    // 0x20 - BasicSet, reports when motion detected (alarm provides same info)
    // 0x70 - configuration V1
    // 0x72 - manufacturer specific V2
    // 0x80 - Battery V1
    // 0x84 - Wakeup V2
    // 0x85 - association V2
    // 0x86 - version V2
    // 0x5E - zwave plus info V2 (not supported by ST)
    // 0x98 - Security V1
    // 0x5A - Device Reset Locally V1
    // 0x59 - Association Grp Info V1
    // 0x73 - Powerlevel (RF power) V1
    // 0x71 - Notification V4
    // 0x31 - Sensor Multilevel V7
    // 0x7A - Firmware Update Md V2
    log.debug "raw: ${description}"
    state.sec = 0
    if (description.contains("command: 5E02")) {
        // for some reason this causes a crash in parse(), so skip it
        return null
    }
    def cmd = zwave.parse(description, 
                        [ 0x86:1, 0x70:1, 0x72:1, 0x80:1, 0x84:2, 0x85:1, 0x86:2, 
                          0x98:1, 0x5a:1, 0x59:1, 0x73:1, 0x71:3, 0x31:5, 0x7a:1 ])
    if (cmd) {
        result = zwaveEvent(cmd)
        if (result) {
            log.debug "Parsed command: ${result} raw: ${description}"
        } else {
            log.debug "Unhandled command: ${description}"
        }
    } else {
        log.debug "Unparsed command: ${description}"
    }
    return result
}

def updateDisplay(String source) {
    def evt = []
    switch (primaryDisplayType) {
       default: // motion is the default
           if(source == "motion") {
               evt += createEvent([name:"primaryDisplay", value: "${state.motion}", displayed:false])
           } else {
               evt += createEvent([name: "sensorlevels", value: "Temp:${state.temp}°F   Humidity:${state.humidity}%   Light:${state.illuminance}"])
           }
           break
       case "Temperature": 
           if(source == "multi") {
               evt += createEvent([name:"primaryDisplay", value: state.temp, displayed:false])
           }
           evt += createEvent([name: "sensorlevels", value: "${state.motionText}   Humidity:${state.humidity}%   Light:${state.illuminance}"])
           break
    }
    return evt
}

def handleMotion(boolean motion) {
	def evt = []

	if(motion && state.motion != "active") {
        state.motion = "active"
        state.motionText = "Motion"
        evt += updateDisplay("motion")
        evt += createEvent([name:"motion", value: "active"])
    } else if (!motion && state.motion != "inactive") {
        state.motion = "inactive"
        state.motionText = "No Motion"
        evt += updateDisplay("motion")
        evt += createEvent([name:"motion", value: "inactive"])
    }
    return evt
}	

def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd) {
	log.debug "BasicSet ${cmd}"
    // Zooz usually reports a burglar and a basic set event when motion is detected/cleared
    // sometimes the burglar event is missing so we use on the 
    // BasicSet to detect motion
    def evt = []
    if(cmd.value) { // motion detected
    	evt += handleMotion(true)
    } else { // no motion 
    	evt += handleMotion(false)
    }
    return evt
}

def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cmd) {
    log.debug "NotificationReport ${cmd}"
    def evt = []
    // zooz reports 2 "burgler" event types, motion (8) and tamper (3)
    if (cmd.notificationType == 7) {
        switch (cmd.event) {
            case 0:
                if (cmd.eventParameter == [8]) {
                	// probably obsolete as BasicSet reports motion
                    evt += handleMotion(false)
                    return evt
                } else if (cmd.eventParameter == [3]) {
                    // clear the batterytime to force a battery read
                    state.batteryReadTime = 0
                    // force a parameter update, if the batteries are changed
                    // some parameters get set back to default
                    state.configRequired = true
                    return createEvent(name:"tamper", value: "clear")
                }
                break
            case 3:
                return createEvent(name:"tamper", value: "detected")
                break
            case 8:
                // probably obsolete as BasicSet reports motion
                evt += handleMotion(true)
                return evt
                break
        }
    }
    return null
}

def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv5.SensorMultilevelReport cmd) {
    log.debug "SensorMultilevelReport ${cmd}"
    def evt = []
    switch (cmd.sensorType) {
        case 1: //temp
            if (cmd.scale == 0) {
                // Celcius, convert to Fahrenheit
                def temp = ((cmd.scaledSensorValue * 9) / 5) + 32
                state.temp = Math.round(temp * 100)/100
            } else {
                state.temp = cmd.scaledSensorValue
            }
            evt += createEvent([name: "temperature", value: state.temp, unit: "fahrenheit"]) 
            break
        case 3: // light
            state.illuminance = cmd.scaledSensorValue 
            evt += createEvent([name: "illuminance", value: state.illuminance]) 
            break
        case 5: // humidity
            state.humidity = cmd.scaledSensorValue
            evt += createEvent([name: "humidity", value: state.humidity]) 
            break
    }
    evt += updateDisplay("multi")
}

def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityMessageEncapsulation cmd) {
    def secCmd = cmd.encapsulatedCommand([ 0x86:1, 0x70:1, 0x72:1, 0x80:1, 0x84:2, 0x85:1, 0x86:1,
                                           0x98:1, 0x5a:1, 0x59:1, 0x73:1, 0x71:3, 0x31:5, 0x7a:1 ])
    if (secCmd) {
        state.sec = 1
        return zwaveEvent(secCmd)
    } else {
        log.debug "SecurityMessageEncapsulation cannot decode ${cmd}"
    }
}

def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
   def level = cmd.batteryLevel
    def desc = ""
    if (level > 100) {
        level = 1
        desc = "${device.displayName}, Battery level low"
    }
    state.batteryReadTime = new Date().time    
    return createEvent(name:"battery", value: level, description: desc)
}

def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd) {
    log.debug "WakeUpNotification v2 ${cmd}"

    def cmds = readSensors()
    // read the battery level every day
    log.debug "battery ${state.batteryReadTime} ${new Date().time}"
    if (!state.batteryReadTime || (new Date().time) - state.batteryReadTime > 24*60*60*1000) {
        cmds += secure(zwave.batteryV1.batteryGet())
    }
    if (state.configRequired) {
        // send pending configure commands
        cmds += configCmds()
        state.configRequired = false
    }
    cmds += zwave.wakeUpV2.wakeUpNoMoreInformation().format()
    cmds = delayBetween(cmds, 600)
    return [response(cmds)]
}

def zwaveEvent(physicalgraph.zwave.Command cmd) {
	log.debug "Unhandled ${cmd}"
    // Handles all Z-Wave commands we aren't interested in
    return null
}

def updated() {
    def evt = []
    log.debug "updated"
    // called when the device is updated or perferences changed
    state.configRequired = true
    state.batteryReadTime = 0
    if(!state.primaryDisplayType) state.primaryDisplayType = "Motion"
    if(!state.illumSensorAlerts) state.illumSensorAlerts = "Disabled"
    // set default values so the display isn't messed up
    if(state.motion == null || state.motionText == null) {
        state.motion = "inactive"
        state.motionText = "No Motion"
    }
    evt += updateDisplay("multi")
    evt += updateDisplay("motion")
    for(Map e : evt ) {
        sendEvent(e)
    }
}

def installed() {
   log.debug "installed"
    // called when the device is installed
    state.configRequired = true
    state.batteryReadTime = 0
    if(!state.primaryDisplayType) state.primaryDisplayType = "Motion"
    if(!state.illumSensorAlerts) state.illumSensorAlerts = "Disabled"
}

def configure() {
    state.sec = 1
    delayBetween( configCmds() + readSensors(), 600)
}

def readSensors() {
    [
        secure(zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType:3)), // light
        secure(zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType:5)), // humidity
        secure(zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType:1)), // temp
    ]
}

def getWakeIntervalPref() {
    (wakeInterval < 10 || wakeInterval > 10080) ? 3600 : (wakeInterval * 60).toInteger()
}

def getLedModePref() {
    (ledMode < 1 || ledMode > 3) ? 3 : ledMode.toInteger()
}

def getIllumAlertPref() {
    if(illumSensorAlerts == "Disabled") {
        return 0
    } else { // alerts enabled
        return (illumAlert >= 5 && illumAlert <= 50) ? illumAlert.toInteger() : 50
    }
}

def getHumidityAlertPref() {
    (humidityAlert < 1 || humidityAlert > 50) ? 50 : humidityAlert.toInteger()
}

def getTempAlertPref() {
    (tempAlert < 1 || tempAlert > 50 ) ? 10 : tempAlert.toInteger()
}

def getPirTimeoutPref() {
    (pirTimeout < 1 || pirTimeout > 255 ) ? 3 : pirTimeout.toInteger()
}

def getPirSensitivityPref() {
    (pirSensitivity < 1 || pirSensitivity > 7) ? 3 : pirSensitivity.toInteger()
}

def configCmds() {
    log.debug "configure, tempAlertPref:${tempAlertPref} humidityAlertPref:${humidityAlertPref}"
    log.debug "configure, illumAlertPref:${illumAlertPref} pirTimeoutPref:${pirTimeoutPref}"
    log.debug "configure, pirSensitivityPref:${pirSensitivityPref} ledModePref:${ledModePref}" 
    log.debug "configure, wakeIntervalPref:${wakeIntervalPref}"
    def cmds = [
        secure(zwave.associationV2.associationSet(groupingIdentifier:1, nodeId:zwaveHubNodeId)),

        secure(zwave.configurationV1.configurationSet(scaledConfigurationValue: tempAlertPref, parameterNumber: 2)),
        secure(zwave.configurationV1.configurationSet(scaledConfigurationValue: humidityAlertPref, parameterNumber: 3)),
        secure(zwave.configurationV1.configurationSet(scaledConfigurationValue: illumAlertPref, parameterNumber: 4)),
        secure(zwave.configurationV1.configurationSet(scaledConfigurationValue: pirTimeoutPref, parameterNumber: 5)),
        secure(zwave.configurationV1.configurationSet(scaledConfigurationValue: pirSensitivityPref, parameterNumber: 6)),
        secure(zwave.configurationV1.configurationSet(scaledConfigurationValue: ledModePref, parameterNumber: 7)),

        secure(zwave.wakeUpV2.wakeUpIntervalSet(seconds: wakeIntervalPref, nodeid:zwaveHubNodeId)),
        


/*
        secure(zwave.configurationV1.configurationGet(parameterNumber: 1)), // Temp scale C(0) or F(1)
        secure(zwave.configurationV1.configurationGet(parameterNumber: 2)), // Temp trigger 0.1 - 5 (1-50)
        secure(zwave.configurationV1.configurationGet(parameterNumber: 4)), // Light trigger, None(0), 5%-50%
        secure(zwave.configurationV1.configurationGet(parameterNumber: 5)), // Motion Timeout 1-255 Mins
        secure(zwave.configurationV1.configurationGet(parameterNumber: 6)), // Motion Sensitivity 1-7 (1 is most sensitive)
        secure(zwave.configurationV1.configurationGet(parameterNumber: 7)), // LED Mode (1,2 or 3). 
                                                                            // - 1 is Off
                                                                            // - 2 is fancy temp color scheme that wastes battery 
                                                                            // - 3 is brief flash when temp/motion trigger fires
*/
        
    ]
    return cmds
}

def secure(cmd) {
    if (state.sec) {
        return zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format()
    } else {
        return cmd.format()
    }
}