Giter Site home page Giter Site logo

Comments (11)

krlaframboise avatar krlaframboise commented on July 21, 2024

The manual I received with the device was wrong, but Neo sent me the latest PDF manual and that manual matched the functionality of the device.

Are you waking up the device with the action button after making changes to the settings?

from smartthings.

roelante avatar roelante commented on July 21, 2024

from smartthings.

krlaframboise avatar krlaframboise commented on July 21, 2024

When did you purchase the devices that aren't working?

I originally wrote the handler based on the manual's specs so if you PM me on the SmartThings forum I can send you the original version.

Manually waking up the device isn't necessary if you're willing to wait about 4 hours for it to wake up on its own.

from smartthings.

roelante avatar roelante commented on July 21, 2024

I received the 2 new motions sensors this week and the previous one about 2 weeks ago.
Can you post the correct manual? I will copy your device handler and change the parameter 10 and remove 11 and 12 for one of the 2 PIRs and see if it syncs then correctly.

from smartthings.

roelante avatar roelante commented on July 21, 2024

I had the model numbers wrong. The device that works (received weeks ago) has model 108D.
Both ones that do not work have model 1083.
Here is the raw description of model 1083 - which does not sync:
zw:S type:0701 mfr:0258 prod:0003 model:1083 ver:3.97 zwv:4.05 lib:06 cc:5E,86,72,5A,73,80,31,71,30,70,85,59,84 role:06 ff:8C07 ui:8C07

from smartthings.

krlaframboise avatar krlaframboise commented on July 21, 2024

This version should work with the 1083 model without requiring you to make any changes.


/**
 *  Neo Coolcam Motion Sensor v0.0
 *  (Model: NAS-PD01ZU-T)
 *
 *  Author: 
 *    Kevin LaFramboise (krlaframboise)
 *
 *  URL to documentation:  
 *
 *  Changelog:
 *
 *    0.0 (11/10/2018)
 *      - Beta Release
 *
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License. You may obtain a copy of the License at:
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
 *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
 *  for the specific language governing permissions and limitations under the License.
 *
 */
metadata {
	definition (
		name: "Neo Coolcam Motion Sensor-OLD", 
		namespace: "krlaframboise", 
		author: "Kevin LaFramboise",
		vid: "generic-motion-4"
	) {
		capability "Sensor"
		capability "Motion Sensor"
		capability "Temperature Measurement"
		capability "Illuminance Measurement"
		capability "Battery"
		capability "Configuration"
		capability "Refresh"
		capability "Health Check"
		
		attribute "lastCheckIn", "string"
		attribute "syncStatus", "string"
		
		fingerprint mfr:"0258", prod:"0003", model:"008D", deviceJoinName: "Neo Coolcam Motion Sensor" //US Version		
		fingerprint mfr: "0258", prod: "0003", model: "108D", deviceJoinName: "NEO Coolcam Motion Sensor" //EU Version
	}
	
	tiles(scale: 2) {
		multiAttributeTile(name:"motion", type: "generic", width: 6, height: 4){
			tileAttribute("device.motion", key: "PRIMARY_CONTROL") {
				attributeState("active", label:'MOTION', icon:"st.motion.motion.active", backgroundColor:"#00A0DC")
				attributeState("inactive", label:'NO MOTION', icon:"st.motion.motion.inactive", backgroundColor:"#CCCCCC")
			}
		}
		
		valueTile("temperature", "device.temperature", inactiveLabel: false, width: 2, height: 2) {
			state "temperature", label:'${currentValue}°',
				backgroundColors:[
					[value: 31, color: "#153591"],
					[value: 44, color: "#1e9cbb"],
					[value: 59, color: "#90d2a7"],
					[value: 74, color: "#44b621"],
					[value: 84, color: "#f1d801"],
					[value: 95, color: "#d04e00"],
					[value: 96, color: "#bc2323"]
				]
		}
		
		valueTile("illuminance", "device.illuminance", inactiveLabel: false, width: 2, height: 2) {
			state "illuminance", label:'${currentValue} lux'
		}
		
		valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
			state "battery", label:'${currentValue}% Battery', unit:"%"
		}
		
		valueTile("syncStatus", "device.syncStatus", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
			state "syncStatus", label:'${currentValue}'
		}

		standardTile("refresh", "device.refresh", width: 2, height: 2, decoration: "flat") {
			state "default", label: "Refresh", action: "refresh", icon:"st.secondary.refresh-icon"
		}		
		
		main(["motion", "temperature", "illuminance"])
		details(["motion", "temperature", "illuminance", "battery", "refresh", "syncStatus"])
	}
	
	simulator { }
	
	preferences {
		getParamInput(motionEnabledParam)
		getParamInput(motionSensitivityParam)
		getParamInput(motionClearIntervalParam)
		getParamInput(motionRetriggerIntervalParam)
		getParamInput(ledEnabledParam)
		getParamInput(luxReportingIntervalParam)
		getParamInput(luxReportingThresholdParam)		
		getParamInput(ambientLightIntensityCalibrationParam)
		getParamInput(basicSetLevelParam)
		getParamInput(basicSetMotionLuxThresholdParam)
		getParamInput(basicSetMotionLuxEnabledParam)
				
		input "wakeUpInterval", "enum",
			title: "Wake Up Interval:",
			required: false,
			defaultValue: "${wakeUpIntervalSetting}",
			options:  setDefaultOption(wakeUpIntervalOptions, wakeUpIntervalSetting)
		
		input "debugOutput", "bool", 
			title: "Enable debug logging?", 
			defaultValue: true, 
			required: false
	}
}

private getParamInput(param) {
	input "configParam${param.num}", "enum",
		title: "${param.name}:",
		required: false,
		defaultValue: "${param.value}",
		options: param.options
}

private getWakeUpIntervalSetting() {
	return safeToInt(settings?.wakeUpInterval, 1440)
}


def installed() {
	state.refreshConfig = true
}

def updated() {	
	if (!isDuplicateCommand(state.lastUpdated, 3000)) {		
		state.lastUpdated = new Date().time
		logTrace "updated()"

		refreshSyncStatus()
		
		logForceWakeupMessage "Configuration changes will be sent to the device the next time it wakes up."	
	}		
}


def configure() {
	logTrace "configure()"
	
	runIn(8, executeConfigure)	
}

def executeConfigure() {
	def cmds = [
		wakeUpIntervalGetCmd(),
		sensorBinaryGetCmd(),
		batteryGetCmd(),
		sensorMultilevelGetCmd(tempSensorType),
		sensorMultilevelGetCmd(lightSensorType)
	]
	
	cmds += getConfigCmds()
	
	sendCommands(delayBetween(cmds, 500))
}

private getConfigCmds() {
	def cmds = []
	configParams.each { param ->
		def storedVal = getParamStoredValue(param.num)
		if (state.refreshConfig) {
			cmds << configGetCmd(param)
		}
		else if ("${storedVal}" != "${param.value}") {
			logDebug "Changing ${param.name}(#${param.num}) from ${storedVal} to ${param.value}"
			cmds << configSetCmd(param)
			cmds << configGetCmd(param)
		}
	}
	state.refreshConfig = false
	return cmds
}

private sendCommands(cmds) {
	def actions = []
	cmds?.each {
		actions << new physicalgraph.device.HubAction(it)
	}
	sendHubCommand(actions, 100)
	return []
}


// Required for HealthCheck Capability, but doesn't actually do anything because this device sleeps.
def ping() {
	logDebug "ping()"	
}


// Forces the configuration to be resent to the device the next time it wakes up.
def refresh() {	
	logForceWakeupMessage "The sensor data will be refreshed the next time the device wakes up."
	state.lastBattery = null
	if (!state.refreshSensors) {	
		state.refreshSensors = true
	}
	else {
		state.refreshConfig = true		
	}
	refreshSyncStatus()
	return []
}

private logForceWakeupMessage(msg) {
	logDebug "${msg}  You can force the device to wake up immediately by pressing the z-button."
}


def parse(String description) {
	def result = []
	try {
		def cmd = zwave.parse(description, commandClassVersions)
		if (cmd) {
			result += zwaveEvent(cmd)
		}
		else {
			logDebug "Unable to parse description: $description"
		}
		
		sendEvent(name: "lastCheckIn", value: convertToLocalTimeString(new Date()), displayed: false)
	}
	catch (e) {
		log.error "$e"
	}
	return result
}


def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityMessageEncapsulation cmd) {
	def encapCmd = cmd.encapsulatedCommand(commandClassVersions)
		
	def result = []
	if (encapCmd) {
		result += zwaveEvent(encapCmd)
	}
	else {
		log.warn "Unable to extract encapsulated cmd from $cmd"
	}
	return result
}


def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpIntervalReport cmd) {
	state.wakeUpInterval = cmd.seconds

	logDebug "Wake Up Interval = ${cmd.seconds} Seconds"
	
	updateSyncingStatus()
	runIn(4, refreshSyncStatus)
	
	// Set the Health Check interval so that it reports offline 5 minutes after it's missed 3 checkins.
	def val = ((cmd.seconds * 3) + (5 * 60))
	
	def eventMap = getEventMap("checkInterval", val, false)

	eventMap.data = [protocol: "zwave", hubHardwareId: device.hub.hardwareID]
	
	sendEvent(eventMap)
	
	return [ ]
}


def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd) {
	logDebug "Device Woke Up"
	
	def cmds = []	
	if (state.refreshConfig || pendingChanges > 0) {
		cmds += getConfigCmds()
	}
	
	if (canReportBattery()) {
		cmds << batteryGetCmd()
	}
		
	if (state.refreshSensors) {
		cmds += [
			sensorBinaryGetCmd()
			// ,
			// sensorMultilevelGetCmd(tempSensorType),
			// sensorMultilevelGetCmd(lightSensorType)
		]
		state.refreshSensors = false
	}
	
	if (wakeUpIntervalSetting != state.wakeUpInterval) {
		logDebug "Changing Wake Up Interval to ${wakeUpIntervalSetting} Seconds"
		cmds << wakeUpIntervalSetCmd(wakeUpIntervalSetting)
		cmds << wakeUpIntervalGetCmd()
	}
		
	if (cmds) {
		cmds = delayBetween(cmds, 1000)
		cmds << "delay 3000"
	}
	cmds << wakeUpNoMoreInfoCmd()	
	return response(cmds)
}


def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
	def val = (cmd.batteryLevel == 0xFF ? 1 : cmd.batteryLevel)
	if (val > 100) {
		val = 100
	}
	else if (val < 1) {
		val = 1
	}
	state.lastBattery = new Date().time
	
	logDebug "Battery ${val}%"
	sendEvent(getEventMap("battery", val, null, null, "%"))
	return []
}


def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv5.SensorMultilevelReport cmd) {
	logTrace "SensorMultilevelReport: ${cmd}"
	
	switch (cmd.sensorType) {
		case tempSensorType:
				def unit = cmd.scale ? "F" : "C"
				def temp = convertTemperatureIfNeeded(cmd.scaledSensorValue, unit, cmd.precision)
				
				sendEvent(getEventMap("temperature", temp, true, null, getTemperatureScale()))
				break		
				
		case lightSensorType:			
			sendEvent(getEventMap("illuminance", cmd.scaledSensorValue, true, null, "lux"))
			break		

		default:
			logDebug "Unknown Sensor Type: ${cmd.sensorType}"
	}
	return []
}


def zwaveEvent(physicalgraph.zwave.commands.configurationv1.ConfigurationReport cmd) {	
	logTrace "ConfigurationReport ${cmd}"
	
	updateSyncingStatus()
	runIn(4, refreshSyncStatus)
	
	def param = configParams.find { it.num == cmd.parameterNumber }
	if (param) {	
		def val = hexBytesToInt(cmd.configurationValue,cmd.size)
		
		logDebug "${param.name}(#${param.num}) = ${val}"
		setParamStoredValue(param.num, val)
	}
	else {
		logDebug "Parameter #${cmd.parameterNumber} = ${cmd.configurationValue}"
	}		
	return []
}

private updateSyncingStatus() {
	if (device.currentValue("syncStatus") != "Syncing...") {
		sendEvent(getEventMap("syncStatus", "Syncing...", false))
	}
}

def refreshSyncStatus() {
	def changes = pendingChanges	
	sendEvent(name: "syncStatus", value: (changes ?  "${changes} Pending Changes" : "Synced"), displayed: false)
}


def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cmd) {
	logTrace "NotificationReport: $cmd"
		
	return []
}


def zwaveEvent(physicalgraph.zwave.commands.sensorbinaryv2.SensorBinaryReport cmd) {
	logTrace "SensorBinaryReport: $cmd"
	
	sendEvent(getEventMap("motion", cmd.sensorValue ? "active" : "inactive", true))
	
	return []
}


def zwaveEvent(physicalgraph.zwave.Command cmd) {
	logDebug "Ignored Command: $cmd"
	return []
}


private getEventMap(name, value, displayed=null, desc=null, unit=null) {	
	def isStateChange = (device.currentValue(name) != value)
	displayed = (displayed == null ? isStateChange : displayed)
	def eventMap = [
		name: name,
		value: value,
		displayed: displayed,
		isStateChange: isStateChange,
		descriptionText: desc ?: "${device.displayName} ${name} is ${value}"
	]
	
	if (unit) {
		eventMap.unit = unit
		eventMap.descriptionText = "${eventMap.descriptionText}${unit}"
	}		
	if (displayed) {
		logDebug "${eventMap.descriptionText}"
	}
	return eventMap
}


private wakeUpNoMoreInfoCmd() {
	return secureCmd(zwave.wakeUpV1.wakeUpNoMoreInformation())
}

private wakeUpIntervalSetCmd(value) {		
	return secureCmd(zwave.wakeUpV2.wakeUpIntervalSet(seconds:value, nodeid:zwaveHubNodeId))
}

private wakeUpIntervalGetCmd() {
	return secureCmd(zwave.wakeUpV1.wakeUpIntervalGet())
}

private batteryGetCmd() {	
	return secureCmd(zwave.batteryV1.batteryGet())
}

private sensorBinaryGetCmd() {
	return secureCmd(zwave.sensorBinaryV2.sensorBinaryGet())
}

private sensorMultilevelGetCmd(sensorType) {
	def scale = (sensorType == tempSensorType ? 0 : 1)
	return secureCmd(zwave.sensorMultilevelV5.sensorMultilevelGet(scale: scale, sensorType: sensorType))
}

private configGetCmd(param) {
	return secureCmd(zwave.configurationV1.configurationGet(parameterNumber: param.num))
}

private configSetCmd(param) {
	return secureCmd(zwave.configurationV1.configurationSet(parameterNumber: param.num, size: param.size, configurationValue: intToHexBytes(param.value, param.size)))	
}

private secureCmd(cmd) {
	if (zwaveInfo?.zw?.contains("s") || ("0x98" in device.rawDescription?.split(" "))) {
		return zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format()
	}
	else {
		return cmd.format()
	}	
}


private getCommandClassVersions() {
	[
		0x30: 2,	// SensorBinary
		0x31: 5,	// SensorMultilevel (7)
		0x59: 1,  // AssociationGrpInfo
		0x5A: 1,  // DeviceResetLocally
		0x5E: 2,  // ZwaveplusInfo
		0x70: 1,  // Configuration
		0x71: 3,  // Notification (4)
		0x72: 2,  // ManufacturerSpecific
		0x73: 1,  // Powerlevel
		0x80: 1,  // Battery
		0x84: 1,  // WakeUp
		0x85: 2,  // Association
		0x86: 1,	// Version
	]
}


private canReportBattery() {
	return state.refreshSensors || (!isDuplicateCommand(state.lastBattery, (12 * 60 * 60 * 1000)))
}

private getPendingChanges() {	
	return configParams.count { "${it.value}" != "${getParamStoredValue(it.num)}" } + (wakeUpIntervalSetting != state.wakeUpInterval ? 1 : 0)
}

private getParamStoredValue(paramNum) {
	return safeToInt(state["configVal${paramNum}"] , null)
}

private setParamStoredValue(paramNum, value) {
	state["configVal${paramNum}"] = value
}


// Sensor Types
private getTempSensorType() { return 1 }
private getLightSensorType() { return 3 }


// Configuration Parameters
private getConfigParams() {
	[
		motionSensitivityParam,
		motionClearIntervalParam,
		basicSetLevelParam,
		motionEnabledParam,
		basicSetMotionLuxThresholdParam,
		motionRetriggerIntervalParam,
		luxReportingIntervalParam,
		basicSetMotionLuxEnabledParam,
		luxReportingThresholdParam,
		ledEnabledParam,
		ambientLightIntensityCalibrationParam
	]
}

private getMotionSensitivityParam() {
	return getParam(1, "Motion Sensitivity", 1, 20, motionSensitivityOptions)
}

private getMotionClearIntervalParam() {
	return getParam(2, "Motion Clear Interval", 2, 30, motionClearIntervalOptions)
}

private getBasicSetLevelParam() {
	return getParam(3, "Basic Set Level", 1, 255, basicSetLevelOptions) 
}

private getMotionEnabledParam() {
	return getParam(4, "Motion Detection", 1, 255,["0":"Disabled", "255":"Enabled"])
}

private getBasicSetMotionLuxThresholdParam() {
	return getParam(5, "Basic Set Motion Light Threshold", 2, 100, luxLevelOptions)
}

private getMotionRetriggerIntervalParam() {
	return getParam(6, "Motion Retrigger Interval", 1, 8, motionRetriggerIntervalOptions)
}

private getLuxReportingIntervalParam() {
	return getParam(7, "Light Reporting Interval", 2, 180, luxReportingIntervalOptions)
}

private getBasicSetMotionLuxEnabledParam() {
	return getParam(8, "Basic Set Motion Light Level Enabled", 1, 0, enabledDisabledOptions)
}

private getLuxReportingThresholdParam() {
	return getParam(9, "Light Reporting Threshold", 1, 100, luxThresholdOptions)
}

private getLedEnabledParam() {
	return getParam(10, "LED Enabled", 1, 1, enabledDisabledOptions)
}

private getAmbientLightIntensityCalibrationParam() {
	return getParam(99, "Ambient Light Intensity Calibration", 2, 1000, ambientLightIntensityCalibrationOptions)
}

private getParam(num, name, size, defaultVal, options=null, range=null) {
	def val = safeToInt((settings ? settings["configParam${num}"] : null), defaultVal) 
	
	def map = [num: num, name: name, size: size, value: val]
	if (options) {
		map.valueName = options?.find { k, v -> "${k}" == "${val}" }?.value
		map.options = setDefaultOption(options, defaultVal)
	}
	if (range) map.range = range
	
	return map
}

private setDefaultOption(options, defaultVal) {
	return options?.collect { k, v ->
		if ("${k}" == "${defaultVal}") {
			v = "${v} [DEFAULT]"		
		}
		["$k": "$v"]
	}
}


// Setting Options

private getWakeUpIntervalOptions() {
	def options = [:]
	
	[5,10,15,20,25,30,45].each {
		options["${it * 60}"] = "${it} Minutes"
	}
	
	options["${60 * 60}"] = "1 Hour"
	[2,3,4,5,6,9,12,15,18].each {
		options["${it * 60 * 60}"] = "${it} Hour"
	}
	
	options["${60 * 60 * 24}"] = "1 Day"
	[2,3,4,5,6].each {
		options["${it * 60 * 60 * 24}"] = "${it} Day"
	}
	
	options["${60 * 60 * 24 * 7}"] = "1 Week"
	[2,3,4].each {
	options["${it * 60 * 60 * 24 * 7}"] = "${it} Week"
	}	
	
	return options
}

private getEnabledDisabledOptions() {
	 return [
		"0":"Disabled", 
		"1":"Enabled"
	]
}

private getMotionSensitivityOptions() {
	def options = ["8":"Most Sensitive"]
	
	(2..24).each {
		options["${it * 10}"] = "${it}"		
	}

	options["255"] = "Least Sensitive"
	return options
}

private getLuxThresholdOptions() {
	def options = ["0":"Disabled"]
	
	(1..5).each {
		options["${it}"] = "${it}"
	}
	
	[10,15,20,25,50,75,100].each {
		options["${it}"] = "${it}"
	}
	return options
}

private getLuxLevelOptions() {
	def options = ["0":"Disabled"]
	
	(1..5).each {
		options["${it}"] = "${it}"
	}
	
	[10,15,20,25,50,75,100,150,200,250,300,350,400,450,500,550,600,650,700,750,800,850,900,950,1000].each {
		options["${it}"] = "${it}"
	}
	return options
}

private getMotionClearIntervalOptions() {
	def options = [:]
	
	[9,10,15,20,30,45].each {
		options["${it}"] = "${it} Seconds"
	}
	
	options["60"] = "1 Minute"	
	options["90"] = "1 Minute 30 Seconds"	
	options["120"] = "2 Minutes"
	options["150"] = "2 Minutes 30 Seconds"	
	
	(3..10).each {
		options["${it * 60}"] = "${it} Minutes"
	}
	
	return options
}

private getBasicSetLevelOptions() {
	def options = ["0":"Off"]
	
	(1..19).each {
		options["${it * 5}"] = "${it * 5}%"
	}
	
	options["99"] = "99%"
	options["255"] = "On"
	
	return options
}

private getMotionRetriggerIntervalOptions() {
	def options = ["1":"1 Second"]
	
	[2,3,4,5,6,7,8].each {
		options["${it}"] = "${it} Seconds"
	}
	
	return options
}

private getLuxReportingIntervalOptions() { 
	def options = ["60":"1 Minute"]
	
	options["90"] = "1 Minute 30 Seconds"
	// [2,3,4,5,10,15,20,25,30,45].each {
	[2,3,4,5,10,15].each {
		options["${it * 60}"] = "${it} Minutes"
	}
	
	options["3600"] = "1 Hour"
	[2,3,4,5,6,7,8,9,10].each {
		options["${it * 60 * 60}"] = "${it} Hours"
	}
	
	return options
}

private getAmbientLightIntensityCalibrationOptions() {
	def options = [:]
	
	[1,25,50,100,150,200,250,500,750,1000,1500,2000,2500,5000,7500,10000,15000,20000,25000,30000,35000,40000,45000,50000,55000,60000,65000].each {
		options["${it}"] = "${it}"
	}
		
	return options
}


private hexBytesToInt(val, size) {
	if (size == 2) {
		return val[1] + (val[0] * 0x100)
	}
	else {
		return val[0]
	}
}

private intToHexBytes(val, size) {
	if (size == 2) {
		if (val > 32767) val = (val - 65536)
		return [(byte) ((val >> 8) & 0xff),(byte) (val & 0xff)]
	}
	else {
		if (val > 127) val = (val - 256)
		return [val]
	}
}


private safeToInt(val, defaultVal=0) {
	return "${val}"?.isInteger() ? "${val}".toInteger() : defaultVal
}


private convertToLocalTimeString(dt) {
	def timeZoneId = location?.timeZone?.ID
	if (timeZoneId) {
		return dt.format("MM/dd/yyyy hh:mm:ss a", TimeZone.getTimeZone(timeZoneId))
	}
	else {
		return "$dt"
	}	
}

private isDuplicateCommand(lastExecuted, allowedMil) {
	!lastExecuted ? false : (lastExecuted + allowedMil > new Date().time) 
}

private logDebug(msg) {
	if (settings?.debugOutput || settings?.debugOutput == null) {
		log.debug "$msg"
	}
}

private logTrace(msg) {
	 log.trace "$msg"
}

from smartthings.

krlaframboise avatar krlaframboise commented on July 21, 2024

Can you post the 108D fingerprint?

from smartthings.

roelante avatar roelante commented on July 21, 2024

zw:S type:0701 mfr:0258 prod:0003 model:108D ver:3.80 zwv:4.38 lib:06 cc:5E,86,72,5A,73,80,31,71,30,70,85,59,84 role:06 ff:8C07 ui:8C07

from smartthings.

krlaframboise avatar krlaframboise commented on July 21, 2024

That's interesting, the 108D has an older firmware version, but according to the manufacturer it's the latest model and it has a higher zwave version so they must be right.

Both models will probably be sold until the 1083 runs out of stuck so in the meantime anyone that gets the older model will need to use the "-OLD" handler posted in this issue.

Please let me know if that handler solves your problem.

from smartthings.

roelante avatar roelante commented on July 21, 2024

The 'changed' device handler works and does set the 'led' on or off now. Thanks.
The temperature is no longer reported. Could you put that back, or do you think this is no longer reported (should be though).

from smartthings.

krlaframboise avatar krlaframboise commented on July 21, 2024

That handler supports temperature so it's possible that other model doesn't report it or the device needs to be removed and rejoined.

from smartthings.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.