[OBSOLETE] ZOOZ ZSE40 4-in-1 Sensor Device Handler

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.

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!

@TheSmartestHouse

Thanks for the info!

1 Like

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?

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?

1 Like

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.

1 Like

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

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.

awesome thx!

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?

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()
    }
}

Simon, thank you for cranking this one out so quickly. The options in the settings is great. One problem. I don’t want to switch the tiles. For instance, in your new DH, when you switch to “Temperature”, the temperature is displayed in the main Things menu (great!), but the tiles within the device change so that motion and temperature swap places (meaning temperature takes up the large tile and motion becomes a secondary attribute to the large tile). Is there a way to keep the tiles the same (motion on the large tile; temperature, humidity, light at the bottom of the large tile)?

As a bonus, would it be possible in the main things menu to not only show temperature but to change the color of the font based on temperature (like my Ecobee DH does)?

I know I’m asking a lot, but I think others would find it useful…perhaps…

Thanks for this. I’m using it as a starting point to customize my own - mainly because I want humidity as the primary display value.

croger, the value shown in the main menu is the same as the main value displayed in the detailed device view.

The way that smart things have defined the Tiles in their software does not allow you to separately control what appears in these two screens, so unfortunately what you ask is impossible to do. (Why do you want to do this ?)

The second request, the color of the temp value, is already implemented. There are 7 different colors for different temperature ranges, I got them from a sample device handler, if you can give me the colors your ecobee device handler uses I can use those instead. Can you send me the device handler you are using for that?

Hi Simon,

Thanks for the code. I’m using your code on Monoprice multisensor.
zw:Ss type:0701 mfr:0109 prod:2021 model:2101 ver:5.01 zwv:4.05 lib:03 cc:5E,98 sec:86,72,5A,85,59,73,80,71,31,70,84,7A role:06 ff:8C07 ui:8C07

Most of the options work, but I can’t seem to get the illumination to update whenever the brightness changes above the threshold by changing illumalert to 1.
Do you need the actual sensor to tweak it?
BTW, for people using this on Monoprice sensor, Ledmode 1 actually turns off the blinking on this sensor.

What you want should be fairly easy to do now that the temp/motion option is there.
I think all you’ll need to do make 2 changes.

  1. add “Humidy” as an option to the input “primaryDisplayType” on line 155.
  2. add a “humidy” case to the “updateDisplay()” function, it can be cut and paste from “Temperature” one and then modified to switch state.temp and state.humidity.

The one thing that will be odd is that the colors for the primary display will be the same as for the temperature, I don’t think there is a way to have 2 different color ranges for the main tile in the device handler.

To test the code easily I do need a real device, but it sounds like the luminosity setting is just not working
Have you tried values other than 1, the zooz suggests 5-50 is the valid range and the device Handler will convert anything less than 5 to off (0).

Note: the luminosity setting will take up to an hour to take effect when you change it, this is because the zooz is a battery operated device and is sleepy, it only wakes up once an hour to see if the configuration has changed to save battery.

Do you see any errors in the logs for the device, you can get this from the logging tab on the developers page, you’ll need to leave the logging on for an hour or so go see any message from the update handler telling the device the new parameters.

Btw, regarding the LED mode, the zooz is the same, it turns off with LED mode 1, I have a typo on the message displayed in the settings/setup, I’ll fix that soon.

I already got the humidity set as the primary display. You’re right, it was pretty easy except for the fact I’m still messing with the color logic. There were also a couple minor changes to switch between a degree symbol and percent symbol depending on which primary display option is chosen.
I was thinking about doing variables for the color ranges. Is that possible.

I’ve never gotten variables to work in a tile other than ${currentValue} and %{name}.

How did you fix the degree vs. % so that it changes automatically, I could not get “unit” to work in the Tiles.