Aeon Labs Multisensor Gen5 - Need to change data report interval

Hi,
Has anyone tried to change the reporting interval for the Aeon Labs Multisensor Gen5? I bought one to track humidity in my bathroom and it reports new values every 30 minutes. I need it to report every minute for it to manage my bathroom fan properly. (I know that’s a battery drain… that’s why it’s plugged in.)
The manual indicates it can be changed with a z-wave parameter field but I don’t think the out-of-the-box device type supports this. Has anyone built a custom device type that allows dynamic config? I would hate to re-invent the wheel on this.
I’m a programmer and can make one if I need to… but I’d rather get code from someone else if its out there.

Yup… Not sure which device type you are using but it will likely have a function called config. I repalced it with

def configure() {
delayBetween([
// send binary sensor report instead of basic set for motion
zwave.configurationV1.configurationSet(parameterNumber: 5, size: 1, scaledConfigurationValue: 2).format(),

// send no-motion report 1 minute after motion stops
zwave.configurationV1.configurationSet(parameterNumber: 3, size: 2, scaledConfigurationValue: 60).format(),

// send illuminance data periodically. The actual period is set below
zwave.configurationV1.configurationSet(parameterNumber: 101, size: 4, scaledConfigurationValue: 128).format(),

    // send humidity & temperature data periodically. The actual period is set below
  zwave.configurationV1.configurationSet(parameterNumber: 102, size: 4, scaledConfigurationValue: 96).format(),  
    // send battery periodically. The actual period is set below
  zwave.configurationV1.configurationSet(parameterNumber: 103, size: 4, scaledConfigurationValue: 1).format(),
    // Set the period in seconds. send illuminance data every 4 minutes
  zwave.configurationV1.configurationSet(parameterNumber: 111, size: 4, scaledConfigurationValue: 240).format(),
    // Set the period in seconds. send humidity & temperature data every 2 minutes
  zwave.configurationV1.configurationSet(parameterNumber: 112, size: 4, scaledConfigurationValue: 120).format(),

// Set the period in seconds. send battery every 1 hour
zwave.configurationV1.configurationSet(parameterNumber: 113, size: 4, scaledConfigurationValue: 3590).format()
])
}

I forgot to mention. For this to take you must…
Press the config button on the sensor.
Press the config icon for the Motion Thing
Press the config button on the Sensor once again.

Thanks @cdikland ! That got me started but nothing I do seems to be taking. Here is my code so far. The template has the commands enveloped as secured so I did that… but it still isn’t taking… :confused:
Anyone see what I am doing wrong???

/**
 *  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.
 *
 *  Modified by john.fullman@gmail.com
 */
metadata {
	definition (name: "Aeon Multisensor Gen5 (Wired Bathroom)", namespace: "", author: "john.fullman@gmail.com") {
		capability "Motion Sensor"
		capability "Temperature Measurement"
		capability "Relative Humidity Measurement"
		capability "Illuminance Measurement"
		capability "Configuration"
		capability "Sensor"
		capability "Battery"

		fingerprint deviceId: "0x0701", inClusters: "0x5E,0x86,0x72,0x59,0x85,0x73,0x71,0x84,0x80,0x30,0x31,0x70,0x98,0x7A", outClusters:"0x5A"
	}

	simulator {
		status "no motion" : "command: 9881, payload: 00300300"
		status "motion"    : "command: 9881, payload: 003003FF"

		for (int i = 0; i <= 100; i += 20) {
			status "temperature ${i}F": new physicalgraph.zwave.Zwave().securityV1.securityMessageEncapsulation().encapsulate(
				new physicalgraph.zwave.Zwave().sensorMultilevelV2.sensorMultilevelReport(
					scaledSensorValue: i, precision: 1, sensorType: 1, scale: 1)
				).incomingMessage()
		}

		for (int i = 0; i <= 100; i += 20) {
			status "humidity ${i}%":  new physicalgraph.zwave.Zwave().securityV1.securityMessageEncapsulation().encapsulate(
				new physicalgraph.zwave.Zwave().sensorMultilevelV2.sensorMultilevelReport(scaledSensorValue: i, sensorType: 5)
			).incomingMessage()
		}

		for (int i in [0, 20, 89, 100, 200, 500, 1000]) {
			status "illuminance ${i} lux":  new physicalgraph.zwave.Zwave().securityV1.securityMessageEncapsulation().encapsulate(
				new physicalgraph.zwave.Zwave().sensorMultilevelV2.sensorMultilevelReport(scaledSensorValue: i, sensorType: 3)
			).incomingMessage()
		}

		for (int i in [0, 5, 10, 15, 50, 99, 100]) {
			status "battery ${i}%":  new physicalgraph.zwave.Zwave().securityV1.securityMessageEncapsulation().encapsulate(
				new physicalgraph.zwave.Zwave().batteryV1.batteryReport(batteryLevel: i)
			).incomingMessage()
		}
		status "low battery alert":  new physicalgraph.zwave.Zwave().securityV1.securityMessageEncapsulation().encapsulate(
			new physicalgraph.zwave.Zwave().batteryV1.batteryReport(batteryLevel: 255)
		).incomingMessage()

		status "wake up" : "command: 8407, payload: "
	}

	tiles {
		standardTile("motion", "device.motion") {
			state "active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#53a7c0"
			state "inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff"
		}
		valueTile("temperature", "device.temperature", inactiveLabel: false) {
			state "temperature", label:'${currentValue}°',
			backgroundColors:[
				[value: 32, color: "#153591"],
				[value: 44, color: "#1e9cbb"],
				[value: 59, color: "#90d2a7"],
				[value: 74, color: "#44b621"],
				[value: 84, color: "#f1d801"],
				[value: 92, color: "#d04e00"],
				[value: 98, color: "#bc2323"]
			]
		}
		valueTile("humidity", "device.humidity", inactiveLabel: false) {
			state "humidity", label:'${currentValue}% humidity', unit:""
		}
		valueTile("illuminance", "device.illuminance", inactiveLabel: false) {
			state "luminosity", label:'${currentValue} lux', unit:"lux"
		}
		valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat") {
			state "battery", label:'${currentValue}% battery', unit:""
		}
        standardTile("configureAfterSecure", "device.configure", inactiveLabel: false, decoration: "flat") {
			state "configure", label:'', action:"configureAfterSecure", icon:"st.secondary.configure"
		}

		main(["motion", "temperature", "humidity", "illuminance"])
		details(["motion", "temperature", "humidity", "illuminance", "battery", "configureAfterSecure"])
	}
}

def parse(String description)
{
	def result = null
	if (description == "updated") {
		result = null
	} else {
		def cmd = zwave.parse(description, [0x31: 5, 0x30: 2, 0x84: 1])
		if (cmd) {
			result = zwaveEvent(cmd)
		}
	}
	log.debug "Parsed '${description}' to ${result.inspect()}"
	return result
}

def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd)
{
	def result = [createEvent(descriptionText: "${device.displayName} woke up", isStateChange: false)]

	if (!isConfigured()) {
		// we're still in the process of configuring a newly joined device
		log.debug("not sending wakeUpNoMoreInformation yet")
        result += response(configureAfterSecure())
	} else {
		result += response(zwave.wakeUpV1.wakeUpNoMoreInformation())
	}
	result
}

def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityMessageEncapsulation cmd) {
	def encapsulatedCommand = cmd.encapsulatedCommand([0x31: 5, 0x30: 2, 0x84: 1])
	// log.debug "encapsulated: ${encapsulatedCommand}"
	if (encapsulatedCommand) {
		zwaveEvent(encapsulatedCommand)
	} else {
		log.warn "Unable to extract encapsulated cmd from $cmd"
		createEvent(descriptionText: cmd.toString())
	}
}

def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityCommandsSupportedReport cmd) {
    // log.debug "Received SecurityCommandsSupportedReport"
	response(configureAfterSecure())
}

def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
	def map = [ name: "battery", unit: "%" ]
	if (cmd.batteryLevel == 0xFF) {
		map.value = 1
		map.descriptionText = "${device.displayName} battery is low"
		map.isStateChange = true
	} else {
		map.value = cmd.batteryLevel
	}
	state.lastbatt = new Date().time
	createEvent(map)
}

def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv5.SensorMultilevelReport cmd)
{
	def map = [:]
	switch (cmd.sensorType) {
		case 1:
			map.name = "temperature"
			def cmdScale = cmd.scale == 1 ? "F" : "C"
			map.value = convertTemperatureIfNeeded(cmd.scaledSensorValue, cmdScale, cmd.precision)
			map.unit = getTemperatureScale()
			break;
		case 3:
			map.name = "illuminance"
			map.value = cmd.scaledSensorValue.toInteger()
			map.unit = "lux"
			break;
		case 5:
			map.name = "humidity"
			map.value = cmd.scaledSensorValue.toInteger()
			map.unit = "%"
			break;
		default:
			map.descriptionText = cmd.toString()
	}
	createEvent(map)
}

def motionEvent(value) {
	def map = [name: "motion"]
	if (value) {
		map.value = "active"
		map.descriptionText = "$device.displayName detected motion"
	} else {
		map.value = "inactive"
		map.descriptionText = "$device.displayName motion has stopped"
	}
	createEvent(map)
}

def zwaveEvent(physicalgraph.zwave.commands.sensorbinaryv2.SensorBinaryReport cmd) {
	motionEvent(cmd.sensorValue)
}

def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd) {
	motionEvent(cmd.value)
}

def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cmd) {
	if (cmd.notificationType == 7 && cmd.event == 7) {
		motionEvent(cmd.notificationStatus)
	} else {
		createEvent(descriptionText: cmd.toString(), isStateChange: false)
	}
}

def zwaveEvent(physicalgraph.zwave.Command cmd) {
	createEvent(descriptionText: cmd.toString(), isStateChange: false)
}

def configureAfterSecure() {
    // log.debug "configureAfterSecure()"

    def request = [
		// send temperature and illuminance every 5 minutes
		zwave.configurationV1.configurationSet(parameterNumber: 101, size: 4, scaledConfigurationValue: 128|32),
		zwave.configurationV1.configurationSet(parameterNumber: 111, size: 4, scaledConfigurationValue: 5*60),

		// send humidity every minute
		zwave.configurationV1.configurationSet(parameterNumber: 102, size: 4, scaledConfigurationValue: 64),
		zwave.configurationV1.configurationSet(parameterNumber: 112, size: 4, scaledConfigurationValue: 1*60),

		// send battery every 20 hours
		zwave.configurationV1.configurationSet(parameterNumber: 103, size: 4, scaledConfigurationValue: 1),
		zwave.configurationV1.configurationSet(parameterNumber: 113, size: 4, scaledConfigurationValue: 20*60*60),

		// send no-motion report 60 seconds after motion stops
		zwave.configurationV1.configurationSet(parameterNumber: 3, size: 2, scaledConfigurationValue: 60),

		// send binary sensor report instead of basic set for motion
		zwave.configurationV1.configurationSet(parameterNumber: 5, size: 1, scaledConfigurationValue: 2),

		// disable notification-style motion events
		zwave.notificationV3.notificationSet(notificationType: 7, notificationStatus: 0),

		zwave.batteryV1.batteryGet(),
		zwave.sensorBinaryV2.sensorBinaryGet()
    ]
	
    setConfigured()
	
    secureSequence(request) + ["delay 20000", zwave.wakeUpV1.wakeUpNoMoreInformation().format()]
}


def configure()
{
    ["delay 5000"] + secureSequence([
		// send temperature and illuminance every 5 minutes
		zwave.configurationV1.configurationSet(parameterNumber: 101, size: 4, scaledConfigurationValue: 128|32),
		zwave.configurationV1.configurationSet(parameterNumber: 111, size: 4, scaledConfigurationValue: 5*60),

		// send humidity every minute
		zwave.configurationV1.configurationSet(parameterNumber: 102, size: 4, scaledConfigurationValue: 64),
		zwave.configurationV1.configurationSet(parameterNumber: 112, size: 4, scaledConfigurationValue: 1*60),

		// send battery every 20 hours
		zwave.configurationV1.configurationSet(parameterNumber: 103, size: 4, scaledConfigurationValue: 1),
		zwave.configurationV1.configurationSet(parameterNumber: 113, size: 4, scaledConfigurationValue: 20*60*60),

		// send no-motion report 60 seconds after motion stops
		zwave.configurationV1.configurationSet(parameterNumber: 3, size: 2, scaledConfigurationValue: 60),

		// send binary sensor report instead of basic set for motion
		zwave.configurationV1.configurationSet(parameterNumber: 5, size: 1, scaledConfigurationValue: 2),

		// disable notification-style motion events
		zwave.notificationV3.notificationSet(notificationType: 7, notificationStatus: 0)
    ], 200) + ["delay 20000", zwave.wakeUpV1.wakeUpNoMoreInformation().format()]
}

def setConfigured() {
	device.updateDataValue("configured", "true")
}

def isConfigured() {
	Boolean configured = device.getDataValue(["configured"]) as Boolean
	
	return configured
}

private secure(physicalgraph.zwave.Command cmd) {
	zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format()
}

private secureSequence(commands, delay=200) {
	delayBetween(commands.collect{ secure(it) }, delay)
}

I added log.debug statements to my configureAfterSecure and configure functions and published.
When I press the “Configure” button on the device on my phone no debug entries appear in my log as if they are not getting hit. Could I be doing something wrong that would prevent the config from firing???

Are you pressing the Config button inside the sensor + the config icon for the sensor device under “Things” and lastly press the Config button inside the sensor?

The Z-Wave button is the only button in the sensor. Is that the one you are referring to? I’ve tried every combo I could think of. The directions say to hold for 3 seconds and then the LED should go solid… but I can’t get it to do that. The LED blinks while I hold it down but goes out when I let go.

What steps did you take to get yours configured? Battery or plugged in? Hold in the z-wave button for 3 seconds or click it several times?

I’m starting to wonder if my sensor is defective…

Mine is plugged in. The button I am referring to is the black button to the right of the sensitivity dial. There appear to be several opinions on how to (re)configure the sensor. Some say, hold the black button down. The log will then spit out a message indicating new command received. I never used this so no idea if this is correct.
Other say, press the black button immediately followed by the config tile icon.
I have always done Black button, Tile icon, black button. I am positive that works for mine as I have changed the reporting interval several times none of which would “take” if I did not reconfig as I described.

One thing I did though was to update the Aeon FW (1,18) for this device but I have no proof (dont even know what the previous version was) this changed anything. It was a suggestion made somewhere on this forum and I just decided to update it. Just connect the sensor to your pc and run the .exe file you can download from http://aeotec.com/z-wave-sensor/1270-multisensor-firmware.html

Hmm… I can confirm looking at the live logging that my sensor was sending a “wake up” message (though not anymore… weird). I tried the button/config/button combo… but still no luck. Heck… I tried every combo I could think of.
I’m trying to update firmware hoping that is the answer but it says it can’t find my sensor when plugged into the computer. What OS did you run when you did your firmware upgrade? You have any trouble with it not finding the sensor via USB?

These things seem flaky… Now it’s stuck on motion and I’m not getting any no-motion reports. :confused:

Windows 7… No problem updating as I recall.
It sounds like your is a bit flaky to be sure.

UPDATE: Got it working!
-The motion sensor was not working because the parameter to enabled was set to zero.

  • Not sure why, but the response() function was not pushing the z-wave ConfigurationSet commands back to the device so I made the config action a standalone action.
    -I also extended the delay between transactions… that seemed to help the device take the configs.

I have built a much-improved device type of the Gen5 if anyone wants to use it. It is fully configurable and let’s you “beep” it to have it report config values back to the log so you can check if they took or not. Sharing this code so no one has to go through what I did with their gen5.

To configure using this Device Type:

  1. Plug sensor into USB so it’s always listening (in range of hub of course)

  2. Save the device preferences with all the settings how you want them

  3. Press the “configure” device tile and what about a minute

  4. Open the log viewer and Press the “get config” device tile to see that your settings took

    /**

    • 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.

    • Modified by john.fullman@gmail.com
      */
      metadata
      {
      definition (name: “Aeon Multisensor Gen5 (Configurable)”, namespace: “”, author: "john.fullman@gmail.com")
      {
      capability "Motion Sensor"
      capability "Temperature Measurement"
      capability "Relative Humidity Measurement"
      capability "Illuminance Measurement"
      capability "Configuration"
      capability "Sensor"
      capability "Battery"
      capability "Refresh"
      capability “Tone” //used for LOG CONFIG button

      fingerprint deviceId: "0x0701", inClusters: "0x5E,0x86,0x72,0x59,0x85,0x73,0x71,0x84,0x80,0x30,0x31,0x70,0x98,0x7A", outClusters:"0x5A"
      

      }

      preferences
      {
      //realtime reporting
      input “ReportRealTime”, “bool”, title: “Should values be reported in realtime as they move past thresholds?”, required: true, displayDuringSetup: true, defaultValue: false
      input “ReportTemperatureRT”, “decimal”, title: “Report threshold temperature (degrees):”, required: true, displayDuringSetup: true, defaultValue: 1.8
      input “ReportHumidityRT”, “decimal”, title: “Report threshold for humidity (%):”, required: true, displayDuringSetup: true, defaultValue: 1.0
      input “ReportIlluminanceRT”, “decimal”, title: “Report threshold for illuminance (LUX):”, required: true, displayDuringSetup: true, defaultValue: 100.0
      input “ReportBatteryRT”, “decimal”, title: “Report threshold for battery (%):”, required: true, displayDuringSetup: true, defaultValue: 5.0

      //motion
      input "MotionStopMinutes", "number", title: "Minutes until no-motion is reported:", required: true, displayDuringSetup: true, defaultValue: 4
      input "MotionStopSeconds", "number", title: "Seconds until no-motion is reported:", required: true, displayDuringSetup: true, defaultValue: 0
      
      //group 1
      input "ReportInterval1", "number", title: "Report Group 1 items every x minutes:", required: true, displayDuringSetup: true, defaultValue: 30
      input "ReportTemperature1", "bool", title: "Report temperature in Group 1?", required: true, displayDuringSetup: true, defaultValue: true
      input "ReportHumidity1", "bool", title: "Report humidity in Group 1?", required: true, displayDuringSetup: true, defaultValue: true
      input "ReportIlluminance1", "bool", title: "Report illuminance in Group 1?", required: true, displayDuringSetup: true, defaultValue: true
      input "ReportBattery1", "bool", title: "Report battery level in Group 1?", required: true, displayDuringSetup: true, defaultValue: true
      
      //group 2
      input "ReportInterval2", "number", title: "Report Group 2 items every x minutes:", required: true, displayDuringSetup: true, defaultValue: 30
      input "ReportTemperature2", "bool", title: "Report temperature in Group 2?", required: true, displayDuringSetup: true, defaultValue: false
      input "ReportHumidity2", "bool", title: "Report humidity in Group 2?", required: true, displayDuringSetup: true, defaultValue: false
      input "ReportIlluminance2", "bool", title: "Report illuminance in Group 2?", required: true, displayDuringSetup: true, defaultValue: false
      input "ReportBattery2", "bool", title: "Report battery level in Group 2?", required: true, displayDuringSetup: true, defaultValue: false
      
      //group 3
      input "ReportInterval3", "number", title: "Report Group 3 items every x minutes:", required: true, displayDuringSetup: true, defaultValue: 30
      input "ReportTemperature3", "bool", title: "Report temperature in Group 3?", required: true, displayDuringSetup: true, defaultValue: false
      input "ReportHumidity3", "bool", title: "Report humidity in Group 3?", required: true, displayDuringSetup: true, defaultValue: false
      input "ReportIlluminance3", "bool", title: "Report illuminance in Group 3?", required: true, displayDuringSetup: true, defaultValue: false
      input "ReportBattery3", "bool", title: "Report battery level in Group 3?", required: true, displayDuringSetup: true, defaultValue: false
      

      }

      simulator
      {
      status “no motion” : "command: 9881, payload: 00300300"
      status “motion” : “command: 9881, payload: 003003FF”

      for (int i = 0; i <= 100; i += 20) {
      	status "temperature ${i}F": new physicalgraph.zwave.Zwave().securityV1.securityMessageEncapsulation().encapsulate(
      		new physicalgraph.zwave.Zwave().sensorMultilevelV2.sensorMultilevelReport(
      			scaledSensorValue: i, precision: 1, sensorType: 1, scale: 1)
      		).incomingMessage()
      }
      
      for (int i = 0; i <= 100; i += 20) {
      	status "humidity ${i}%":  new physicalgraph.zwave.Zwave().securityV1.securityMessageEncapsulation().encapsulate(
      		new physicalgraph.zwave.Zwave().sensorMultilevelV2.sensorMultilevelReport(scaledSensorValue: i, sensorType: 5)
      	).incomingMessage()
      }
      
      for (int i in [0, 20, 89, 100, 200, 500, 1000]) {
      	status "illuminance ${i} lux":  new physicalgraph.zwave.Zwave().securityV1.securityMessageEncapsulation().encapsulate(
      		new physicalgraph.zwave.Zwave().sensorMultilevelV2.sensorMultilevelReport(scaledSensorValue: i, sensorType: 3)
      	).incomingMessage()
      }
      
      for (int i in [0, 5, 10, 15, 50, 99, 100]) {
      	status "battery ${i}%":  new physicalgraph.zwave.Zwave().securityV1.securityMessageEncapsulation().encapsulate(
      		new physicalgraph.zwave.Zwave().batteryV1.batteryReport(batteryLevel: i)
      	).incomingMessage()
      }
      status "low battery alert":  new physicalgraph.zwave.Zwave().securityV1.securityMessageEncapsulation().encapsulate(
      	new physicalgraph.zwave.Zwave().batteryV1.batteryReport(batteryLevel: 255)
      ).incomingMessage()
      
      status "wake up" : "command: 8407, payload: "
      

      }

      tiles
      {
      standardTile(“motion”, “device.motion”) {
      state “active”, label:‘motion’, icon:“st.motion.motion.active”, backgroundColor:"#53a7c0"
      state “inactive”, label:‘no motion’, icon:“st.motion.motion.inactive”, backgroundColor:"#ffffff"
      }
      valueTile(“temperature”, “device.temperature”, inactiveLabel: false) {
      state “temperature”, label:’${currentValue}°’,
      backgroundColors:[
      [value: 32, color: “#153591”],
      [value: 44, color: “#1e9cbb”],
      [value: 59, color: “#90d2a7”],
      [value: 74, color: “#44b621”],
      [value: 84, color: “#f1d801”],
      [value: 92, color: “#d04e00”],
      [value: 98, color: “#bc2323”]
      ]
      }
      valueTile(“humidity”, “device.humidity”, inactiveLabel: false) {
      state “humidity”, label:’${currentValue}% humidity’, unit:""
      }
      valueTile(“illuminance”, “device.illuminance”, inactiveLabel: false) {
      state “luminosity”, label:’${currentValue} lux’, unit:“lux”
      }
      valueTile(“battery”, “device.battery”, inactiveLabel: false, decoration: “flat”) {
      state “battery”, label:’${currentValue}% battery’, unit:""
      }
      standardTile(“configure”, “device.configure”, inactiveLabel: false, decoration: “flat”) {
      state “configure”, label:’’, action:“configure”, icon:“st.secondary.configure”
      }
      standardTile(“currentconfig”, “tone.beep”)
      {
      state “default”, label: “log config”, action: “tone.beep” //, inactiveLabel: true
      }
      standardTile(“refresh”, “device.refresh”, inactiveLabel: false, decoration: “flat”) {
      state “default”, label:’’, action:“refresh.refresh”, icon:“st.secondary.refresh”
      }

      main(["motion", "temperature", "humidity", "illuminance"])
      details(["motion", "temperature", "humidity", "illuminance", "battery", "configure", "currentconfig", "refresh"])
      

      }
      }

    def parse(String description)
    {
    def result = null
    if (description == “updated”) {
    result = null
    } else {
    def cmd = zwave.parse(description, [0x31: 5, 0x30: 2, 0x70: 1, 0x84: 2])
    if (cmd) {
    result = zwaveEvent(cmd)
    }
    }
    //log.debug "Parsed ‘${description}’ to ${result.inspect()}"
    return result
    }

    def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd)
    {
    def result = [createEvent(descriptionText: “${device.displayName} woke up”, isStateChange: false)]

    if (!isConfigured()) {
    	// we're still in the process of configuring a newly joined device
    	log.debug("not sending wakeUpNoMoreInformation yet")
        //result += response(["delay 20000"] + configure())
    } else {
    	result += response(zwave.wakeUpV1.wakeUpNoMoreInformation())
    }
    return result
    

    }

    def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityMessageEncapsulation cmd) {
    def encapsulatedCommand = cmd.encapsulatedCommand([0x31: 5, 0x30: 2, 0x70: 1, 0x84: 2])
    // log.debug "encapsulated: ${encapsulatedCommand}"
    if (encapsulatedCommand) {
    zwaveEvent(encapsulatedCommand)
    } else {
    log.warn "Unable to extract encapsulated cmd from $cmd"
    createEvent(descriptionText: cmd.toString())
    }
    }

    def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityCommandsSupportedReport cmd) {
    // log.debug "Received SecurityCommandsSupportedReport"
    response([“delay 10000”] + configure())
    }

    def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
    def map = [ name: “battery”, unit: “%” ]
    if (cmd.batteryLevel == 0xFF) {
    map.value = 1
    map.descriptionText = "${device.displayName} battery is low"
    map.isStateChange = true
    } else {
    map.value = cmd.batteryLevel
    }
    state.lastbatt = new Date().time
    createEvent(map)
    }

    def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv5.SensorMultilevelReport cmd)
    {
    def map = [:]
    switch (cmd.sensorType) {
    case 1:
    map.name = "temperature"
    def cmdScale = cmd.scale == 1 ? “F” : "C"
    map.value = convertTemperatureIfNeeded(cmd.scaledSensorValue, cmdScale, cmd.precision)
    map.unit = getTemperatureScale()
    break;
    case 3:
    map.name = "illuminance"
    map.value = cmd.scaledSensorValue.toInteger()
    map.unit = "lux"
    break;
    case 5:
    map.name = "humidity"
    map.value = cmd.scaledSensorValue.toInteger()
    map.unit = "%"
    break;
    default:
    map.descriptionText = cmd.toString()
    }
    createEvent(map)
    }

    def motionEvent(value) {
    def map = [name: “motion”]
    if (value) {
    map.value = "active"
    map.descriptionText = “$device.displayName detected motion”
    } else {
    map.value = "inactive"
    map.descriptionText = “$device.displayName motion has stopped”
    }
    createEvent(map)
    }

    def zwaveEvent(physicalgraph.zwave.commands.sensorbinaryv2.SensorBinaryReport cmd) {
    motionEvent(cmd.sensorValue)
    }

    def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd) {
    motionEvent(cmd.value)
    }

    def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cmd) {
    if (cmd.notificationType == 7 && cmd.event == 7) {
    motionEvent(cmd.notificationStatus)
    } else {
    createEvent(descriptionText: cmd.toString(), isStateChange: false)
    }
    }

    def zwaveEvent(physicalgraph.zwave.commands.configurationv1.ConfigurationReport cmd) {
    def hexval = cmd.configurationValue.collect { String.format( ‘%02x’, it.toInteger() ) }.join()
    def decval = Integer.parseInt(hexval,16)
    def precval = decval / 256.0
    def minval = (decval / 60).toInteger()
    def secval = decval - (minval * 60)
    switch(cmd.parameterNumber)
    {
    case 3: //motion stop seconds
    log.info "Will transmit no-motion report after ${minval} miuntes and ${secval} seconds of no motion."
    break
    case 4: //motion enabled
    if(decval == 1)
    {
    log.info “Motion sensor is enabled.”
    }
    else
    {
    log.info “Motion sensor is disabled.”
    }
    break
    case 5: //motion commandset
    if(deval == 1)
    {
    log.info “Sending ‘basic set’ commands for motion.”
    }
    else if(decval == 2)
    {
    log.info “Sending ‘sensor binary report’ commands for motion.”
    }
    else
    {
    log.info “Unxpected value for motion commandset. Currently 0x${hexval}”
    }
    break
    case 40: //realtime threshold reporting enabled
    if(decval == 1)
    {
    log.info “Realtime (threshold) reporting is enabled.”
    }
    else
    {
    log.info “Realtime (threshold) reporting is disabled.”
    }
    break
    case 41: //temperature threshold
    def fer_thresh = precval * 1.8
    log.info "Temperature threshold is ${precval}C or ${fer_thresh}F."
    break
    case 42: //humidity threshold
    log.info "Humidity threshold is ${precval}%."
    break
    case 43: //luminance threshold
    log.info "Luminance threshold is ${precval} LUX."
    break
    case 44: //battery threshold
    log.info "Battery threshold is ${precval}%."
    break
    case 101: //group 1 interval
    log.info "Group 1 will report every ${minval} miuntes and ${secval} seconds."
    break
    case 102: //group 2 interval
    log.info "Group 2 will report every ${minval} miuntes and ${secval} seconds."
    break
    case 103: //group 3 interval
    log.info "Group 3 will report every ${minval} miuntes and ${secval} seconds."
    break
    case 111: //group 1 members
    log.info "Group 1 report members are ${ReportItemsToString(decval)}"
    break
    case 112: //group 2 members
    log.info "Group 2 report members are ${ReportItemsToString(decval)}"
    break
    case 113: //group 3 members
    log.info "Group 3 report members are ${ReportItemsToString(decval)}"
    break
    case 252: //config lock
    if(decval == 1)
    {
    log.info “Configuration settings are locked.”
    }
    else
    {
    log.info “Configuration settings are unlocked.”
    }
    break
    default:
    log.info "Parameter #${cmd.parameterNumber} = 0x${hexval}"
    break
    }
    //log.debug “Parameter #${cmd.parameterNumber} = 0x${hexval} = ${cmd.configurationValue.toString()}”
    }

    def zwaveEvent(physicalgraph.zwave.Command cmd) {
    createEvent(descriptionText: cmd.toString(), isStateChange: false)
    }

    def ReportItemsToString(int report_items)
    {
    def ret = ""
    if((report_items & 128) > 0)
    {
    def item_name = "Luminance"
    if(ret == “”)
    {
    ret = item_name
    }
    else
    {
    ret = “${ret}, ${item_name}”
    }
    }
    if((report_items & 64) > 0)
    {
    def item_name = "Humidity"
    if(ret == “”)
    {
    ret = item_name
    }
    else
    {
    ret = “${ret}, ${item_name}”
    }
    }
    if((report_items & 32) > 0)
    {
    def item_name = "Temperature"
    if(ret == “”)
    {
    ret = item_name
    }
    else
    {
    ret = “${ret}, ${item_name}”
    }
    }
    if((report_items & 1) > 0)
    {
    def item_name = "Battery"
    if(ret == “”)
    {
    ret = item_name
    }
    else
    {
    ret = “${ret}, ${item_name}”
    }
    }
    return ret
    }

    def BuildReportGroupConfig(i)
    {
    int report_interval = 0
    int report_items = 0

    switch(i)
    {
        case 1:
        	report_interval = ReportInterval1
            if(ReportTemperature1)
            {
                report_items = report_items|128
            }
            if(ReportHumidity1)
            {
                report_items = report_items|64
            }
            if(ReportIlluminance1)
            {
                report_items = report_items|32
            }
            if(ReportBattery1)
            {
                report_items = report_items|1
            }
            break;
        case 2:
        	report_interval = ReportInterval2
            if(ReportTemperature2)
            {
                report_items = report_items|128
            }
            if(ReportHumidity2)
            {
                report_items = report_items|64
            }
            if(ReportIlluminance2)
            {
                report_items = report_items|32
            }
            if(ReportBattery2)
            {
                report_items = report_items|1
            }
            break;
        case 3:
        	report_interval = ReportInterval3
            if(ReportTemperature3)
            {
                report_items = report_items|128
            }
            if(ReportHumidity3)
            {
                report_items = report_items|64
            }
            if(ReportIlluminance3)
            {
                report_items = report_items|32
            }
            if(ReportBattery3)
            {
                report_items = report_items|1
            }
            break;
    }
    
    if(report_interval == 0 || report_items == 0)
    {
    	log.debug "Report Group ${i} - No Report"
        return [
            zwave.configurationV1.configurationSet(parameterNumber: 100 + i, size: 4, scaledConfigurationValue: 0),
            zwave.configurationV1.configurationSet(parameterNumber: 110 + i, size: 4, scaledConfigurationValue: 30 * 60)
        ]
    }
    
    log.debug "Report Group ${i} - Report ${report_items} every ${report_interval} minutes"
    return [
    	zwave.configurationV1.configurationSet(parameterNumber: 100 + i, size: 4, scaledConfigurationValue: report_items),
        zwave.configurationV1.configurationSet(parameterNumber: 110 + i, size: 4, scaledConfigurationValue: report_interval * 60)
    ]
    

    }

    def configure()
    {
    log.debug “configure()”

    //calculate parameter values
    int motion_stop_value = MotionStopMinutes * 60 + MotionStopSeconds
    int iReportRealTime = ReportRealTime ? 1 : 0
    int temp_th = (256.0 * ReportTemperatureRT / 1.8).toInteger()
    int hum_th = (256.0 * ReportHumidityRT).toInteger()
    int ill_th = (256.0 * ReportIlluminanceRT).toInteger()
    int batt_th = (256.0 * ReportBatteryRT).toInteger()
    
    //show values being sent
    log.debug "Report no motion after ${motion_stop_value} seconds"
    if(iReportRealTime == 1)
    {
    	log.debug "Realtime reporting enabled with values (P41=${temp_th}; P42=${hum_th}; P43=${ill_th}; P44=${batt_th})"
    }
    else
    {
    	log.debug "Realtime reporting disabled"
    }
    
    def request = GetSensorUpdates() + [
    
    	//unlock config in case it is locked
    	zwave.configurationV1.configurationSet(parameterNumber: 252, size: 1, scaledConfigurationValue: 0)
        
    //configure report intervals
    ] + BuildReportGroupConfig(1) + BuildReportGroupConfig(2) + BuildReportGroupConfig(3) + [
    
    	//configure realtime reporting
    	zwave.configurationV1.configurationSet(parameterNumber: 40, size: 1, scaledConfigurationValue: iReportRealTime),
    	zwave.configurationV1.configurationSet(parameterNumber: 41, size: 2, scaledConfigurationValue: temp_th),
    	zwave.configurationV1.configurationSet(parameterNumber: 42, size: 2, scaledConfigurationValue: hum_th),
    	zwave.configurationV1.configurationSet(parameterNumber: 43, size: 2, scaledConfigurationValue: ill_th),
    	zwave.configurationV1.configurationSet(parameterNumber: 44, size: 2, scaledConfigurationValue: batt_th),
        
    	// enable motion reporting
    	zwave.configurationV1.configurationSet(parameterNumber: 4, size: 1, scaledConfigurationValue: 1),
        
    	// send no-motion report x seconds after motion stops
    	zwave.configurationV1.configurationSet(parameterNumber: 3, size: 2, scaledConfigurationValue: motion_stop_value),
    
    	// send binary sensor report instead of basic set for motion
    	zwave.configurationV1.configurationSet(parameterNumber: 5, size: 1, scaledConfigurationValue: 2),
    
    	// disable notification-style motion events
    	zwave.notificationV3.notificationSet(notificationType: 7, notificationStatus: 0),
    ]
    
    setConfigured()
    
    //return secureSequence(request) //+ ["delay 20000", zwave.wakeUpV1.wakeUpNoMoreInformation().format()]
    return secureSequence(request, 2000)
    

    }

    def setConfigured()
    {
    device.updateDataValue(“configured”, “true”)
    }

    def isConfigured()
    {
    Boolean configured = device.getDataValue([“configured”]) as Boolean
    return configured
    }

    private secure(physicalgraph.zwave.Command cmd) {
    return zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format()
    }

    private secureSequence(commands, delay=200)
    {
    return delayBetween(commands.collect{ secure(it) }, delay)
    }

    def GetSensorUpdates()
    {
    return [
    //sensor updates
    zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 1), //temperature
    zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 3), //light
    zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 5), //humidity
    zwave.sensorBinaryV2.sensorBinaryGet(sensorType: 12), //motion
    zwave.batteryV1.batteryGet() //battery
    ]
    }

    def GetCurrentConfig()
    {
    return [
    zwave.configurationV1.configurationGet(parameterNumber: 3),
    zwave.configurationV1.configurationGet(parameterNumber: 4),
    zwave.configurationV1.configurationGet(parameterNumber: 5),
    zwave.configurationV1.configurationGet(parameterNumber: 40),
    zwave.configurationV1.configurationGet(parameterNumber: 41),
    zwave.configurationV1.configurationGet(parameterNumber: 42),
    zwave.configurationV1.configurationGet(parameterNumber: 43),
    zwave.configurationV1.configurationGet(parameterNumber: 44),
    zwave.configurationV1.configurationGet(parameterNumber: 101),
    zwave.configurationV1.configurationGet(parameterNumber: 102),
    zwave.configurationV1.configurationGet(parameterNumber: 103),
    zwave.configurationV1.configurationGet(parameterNumber: 111),
    zwave.configurationV1.configurationGet(parameterNumber: 112),
    zwave.configurationV1.configurationGet(parameterNumber: 113),
    zwave.configurationV1.configurationGet(parameterNumber: 252)
    ]
    }

    def refresh()
    {
    log.debug "Sensor data refresh initiated"
    return secureSequence(GetSensorUpdates(), 1000)
    }

    def currentconfig()
    {
    log.debug "Getting current configuration"
    return secureSequence(GetCurrentConfig(), 2000)
    }

    def beep()
    {
    return currentconfig()
    }

1 Like

I installed your device type and tried to update the reporting times for all parameters to 10 minutes, but it seems that they are still updating every ~30 minutes and then only if the parameter has changed.

I’m running on batteries at the moment.

Any suggestions?

If you are on batteries you have to make sure your device is listening. Press and hold the black z-wave button inside the battery compartment of the sensor for about 3 seconds the red LED comes on and stays on. If you can’t get the LED to stay on, use USB power.

Once you have the LED on or USB power, then push the configure button on your phone.

Also, I have an updated device type code here:
https://github.com/johnathan398/SmartThings/blob/master/DeviceTypes/aeon_multisensor_gen5.groovy

1 Like

When i hit the button in the battery compartment it will stay lit for 2-3 second, then turn off. If i hold the button it starts flashing faster and faster. If i continue to hold the button it will increase flashing speed until its a solid light and then turn off, this unpaired it from the network.

Same exact thing happens when it is running on AC.

I had the same issue with my sensor. Still do. I was never able to get it to listen reliably on battery. That’s why I used USB power. I recommend switching to that. That way, there is no need to press the z-wave button at all.
You should bring up the live logging console while you are trying a config update with USB power and post what you saw if you are still having issues.

Plugged sensor into AC
Under Preference tile in app, set my parameters
hit replace button
hit done button
tapped Configure Button
Waited
tapped Log Config Button
waited
copy pasted log for you

946d3878-bc12-461d-b2ff-8e9576ed83ed 12:32:55 PM: debug Getting current configuration
946d3878-bc12-461d-b2ff-8e9576ed83ed 12:30:10 PM: debug Report Group 3 - No Report
946d3878-bc12-461d-b2ff-8e9576ed83ed 12:30:10 PM: debug Report Group 2 - No Report
946d3878-bc12-461d-b2ff-8e9576ed83ed 12:30:10 PM: debug Report Group 1 - Report 225 every 5 minutes
946d3878-bc12-461d-b2ff-8e9576ed83ed 12:30:10 PM: debug Realtime reporting disabled
946d3878-bc12-461d-b2ff-8e9576ed83ed 12:30:10 PM: debug Report no motion after 120 seconds
946d3878-bc12-461d-b2ff-8e9576ed83ed 12:30:10 PM: debug configure()

Looks like your parameters took. The sensor is reporting that it is set to report values every 5 minutes.
Keep in mind if the sensor reports every 5 minutes it will drain batteries very quickly. FYI.

@johnathan398 I just checked your code and it looks like you may be settings the wrong parameters.
original code

    // send temperature, humidity, and illuminance every 8 minutes
	zwave.configurationV1.configurationSet(parameterNumber: 101, size: 4, scaledConfigurationValue: 128|64|32),
	zwave.configurationV1.configurationSet(parameterNumber: 111, size: 4, scaledConfigurationValue: 8*60),
	// send battery every 20 hours
	zwave.configurationV1.configurationSet(parameterNumber: 102, size: 4, scaledConfigurationValue: 1),
	zwave.configurationV1.configurationSet(parameterNumber: 112, size: 4, scaledConfigurationValue: 20*60*60),

Your code:

zwave.configurationV1.configurationSet(parameterNumber: 40, size: 1, scaledConfigurationValue: iReportRealTime),
	zwave.configurationV1.configurationSet(parameterNumber: 41, size: 2, scaledConfigurationValue: temp_th),
	zwave.configurationV1.configurationSet(parameterNumber: 42, size: 2, scaledConfigurationValue: hum_th),
	zwave.configurationV1.configurationSet(parameterNumber: 43, size: 2, scaledConfigurationValue: ill_th),
	zwave.configurationV1.configurationSet(parameterNumber: 44, size: 2, scaledConfigurationValue: batt_th),

You’re setting different parameters, you sure it works

Yes, I am sure it works. log.debug injections will show that 101-103 and 111-113 are also being set. They are just getting built dynamically and connected to preference variables. There is more to the command array than just the hard coded values in the resultset. Notice i also concatenate with function calls.

Yes you’re right, I missed that. I guess those parameters above are for realtime reporting which are missing from the stock code right?