Hs-fls100+

@mike.maxwell

Did a native driver ever get written?

No, not a big fan of this device, so its not on the radar.

Any recommendations?

I messed around with the driver created for ST with limited success last year when it first came out. It was a little buggy, as such it has been collecting dust in my to do pile. Someone with a little more know how might have better luck porting over the driver.

I have a porting from HomeSeer. I was just trying to be a good Hubitatizen and limit the amount of custom code I have running. I was worth a try.

What driver are you using? I was just planning to buy this.

/**

  • HomeSeer HS-FLS100+
  • Copyright 2018 HomeSeer
  • 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.
  • Author: HomeSeer
  • Date: 7/24/2018
  • Changelog:
  • 1.2 Modified for Hubitat and Lux to 0 - jrf
  • 1.0 Initial Version

*/

metadata {
definition (name: "FLS100+ Motion Sensor", namespace: "homeseer", author: "support@homeseer.com") {
capability "Switch"
capability "Motion Sensor"
capability "Sensor"
capability "Polling"
capability "Refresh"
capability "Configuration"
capability "Illuminance Measurement"

  command "manual"
    command "auto"
    
  attribute "operatingMode", "enum", ["Manual", "Auto"]
    attribute "defaultLevel", "number"        
    
    fingerprint mfr: "000C", prod: "0201", model: "000B"

}

// simulator {
// status "on": "command: 2003, payload: FF"
// status "off": "command: 2003, payload: 00"
//
// // reply messages
// reply "2001FF,delay 5000,2602": "command: 2603, payload: FF"
// reply "200100,delay 5000,2602": "command: 2603, payload: 00"
// }

preferences {            
   input ( "onTime", "number", title: "Press Configuration button after changing preferences\n\n   On Time: Duration (8-720 seconds) [default: 15]", defaultValue: 15,range: "8..720", required: false)
   input ( "luxDisableValue", "number", title: "Lux Value to Disable Sensor: (0-200 lux)(0 Disables lux from motion) [default: 50]", defaultValue: 50, range: "0..200", required: false)       
   input ( "luxReportInterval", "number", title: "Lux Report Interval: (0-1440 minutes) [default 10]", defaultValue: 10, range: "0..1440", required: false)
   input name: "logEnable", type: "bool", title: "Enable debug logging", defaultValue: true
   input name: "txtEnable", type: "bool", title: "Enable descriptionText logging", defaultValue: true
}

}

def parse(String description) {
def result = null
if (logEnable) log.debug (description)
if (description != "updated") {
def cmd = zwave.parse(description, [0x20: 1, 0x26: 1, 0x70: 1])
if (cmd) {
result = zwaveEvent(cmd)
}
}
if (!result){
if (logEnable) log.debug "Parse returned ${result} for command ${cmd}"
}
else {
if (logEnable) log.debug "Parse returned ${result}"
}
return result
}

// Creates motion events.
def zwaveEvent(hubitat.zwave.commands.notificationv3.NotificationReport cmd) {
if (logEnable) log.debug "NotificationReport: ${cmd}"

if (cmd.notificationType == 0x07) {
switch (cmd.event) {
case 0:
if (txtEnable) log.info "Motion Inactive"
createEvent(name:"motion", value: "inactive", isStateChange: true)
break
case 8:
if (txtEnable) log.info "Motion Active"
createEvent(name:"motion", value: "active", isStateChange: true)
break
default:
if (txtEnable) logDebug "Sensor is ${cmd.event}"
}
}
}

def zwaveEvent(hubitat.zwave.commands.sensormultilevelv5.SensorMultilevelReport cmd) {
if (logEnable) log.debug("sensor multilevel report")
if (logEnable) log.debug "cmd: ${cmd}"
if (txtEnable) log.info "Illuminance: ${cmd.scaledSensorValue}"

def lval = cmd.scaledSensorValue

createEvent(name:"illuminance", value: lval)

}

def zwaveEvent(hubitat.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
if (logEnable) log.debug "manufacturerId: ${cmd.manufacturerId}"
if (logEnable) log.debug "manufacturerName: ${cmd.manufacturerName}"
state.manufacturer=cmd.manufacturerName
if (logEnable) log.debug "productId: ${cmd.productId}"
if (logEnable) log.debug "productTypeId: ${cmd.productTypeId}"
def msr = String.format("%04X-%04X-%04X", cmd.manufacturerId, cmd.productTypeId, cmd.productId)
updateDataValue("MSR", msr)
setFirmwareVersion()
createEvent([descriptionText: "$device.displayName MSR: $msr", isStateChange: false])
}

def zwaveEvent(hubitat.zwave.commands.versionv1.VersionReport cmd) {
//updateDataValue("applicationVersion", "${cmd.applicationVersion}")
if (logEnable) log.debug ("received Version Report")
if (logEnable) log.debug "applicationVersion: ${cmd.applicationVersion}"
if (logEnable) log.debug "applicationSubVersion: ${cmd.applicationSubVersion}"
state.firmwareVersion=cmd.applicationVersion+'.'+cmd.applicationSubVersion
if (logEnable) log.debug "zWaveLibraryType: ${cmd.zWaveLibraryType}"
if (logEnable) log.debug "zWaveProtocolVersion: ${cmd.zWaveProtocolVersion}"
if (logEnable) log.debug "zWaveProtocolSubVersion: ${cmd.zWaveProtocolSubVersion}"
setFirmwareVersion()
createEvent([descriptionText: "Firmware V"+state.firmwareVersion, isStateChange: false])
}

def zwaveEvent(hubitat.zwave.commands.firmwareupdatemdv2.FirmwareMdReport cmd) {
if (logEnable) log.debug ("received Firmware Report")
if (logEnable) log.debug "checksum: ${cmd.checksum}"
if (logEnable) log.debug "firmwareId: ${cmd.firmwareId}"
if (logEnable) log.debug "manufacturerId: ${cmd.manufacturerId}"
[:]
}

def zwaveEvent(hubitat.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd) {
if (logEnable) log.debug ("received switch binary Report")
createEvent(name:"switch", value: cmd.value ? "on" : "off")
}

def zwaveEvent(hubitat.zwave.Command cmd) {
// Handles all Z-Wave commands we aren't interested in
[:]
}

def on() {
if (txtEnable) log.info "On"
delayBetween([
zwave.basicV1.basicSet(value: 0xFF).format(),
zwave.switchMultilevelV1.switchMultilevelGet().format()
],5000)
}

def off() {
if (txtEnable) log.info "Off"
delayBetween([
zwave.basicV1.basicSet(value: 0x00).format(),
zwave.switchMultilevelV1.switchMultilevelGet().format()
],5000)
}

def poll() {
/*
zwave.commands.switchbinaryv1.SwitchBinaryGet
zwave.switchMultilevelV1.switchMultilevelGet().format()
*/
}

def refresh() {
log.info "refresh() called"
configure()
}

//
//THIS IS NOT WORKING PROPERLY YET
//
//def zwaveEvent(hubitat.zwave.commands.associationv2.AssociationReport cmd) {
// if (logEnable) log.debug "---CONFIGURATION REPORT V1--- ${device.displayName} sent ${cmd}"
// //def config = cmd.scaledConfigurationValue
// config = zwave.configurationV1.configurationGet(parameterNumber: 2)
// def result = []
// if (cmd.parameterNumber == 1) {
// def value = config
// result << sendEvent([name:"TimeoutDuration", value: value, displayed:true])
// } else if (cmd.parameterNumber == 2) {
// if (config == 0 ) {
// result << sendEvent([name:"operatingMode", value: "Manual", displayed:true])
// } else {
// result << sendEvent([name:"operatingMode", value: "Auto", displayed:true])
// }
// return result
// }
//}

def setFirmwareVersion() {
def versionInfo = ''
if (state.manufacturer)
{
versionInfo=state.manufacturer+' '
}
if (state.firmwareVersion)
{
versionInfo=versionInfo+"Firmware V"+state.firmwareVersion
}
else
{
versionInfo=versionInfo+"Firmware unknown"
}
sendEvent(name: "firmwareVersion", value: versionInfo, isStateChange: true, displayed: false)
}

def configure() {
if (logEnable) log.info "On"
if (logEnable) log.debug ("configure() called")

//sendEvent(name: "numberOfButtons", value: 12, displayed: false)
def cmds = []
//cmds << setPrefs()
cmds = setPrefs()
cmds << zwave.manufacturerSpecificV1.manufacturerSpecificGet().format()
cmds << zwave.versionV1.versionGet().format()
if (logEnable) log.info "On"
if (logEnable) log.debug ("cmds: " + cmds)
delayBetween(cmds,500)
}

def setPrefs()
{
if (logEnable) log.debug ("set prefs")
def cmds = []

if (onTime)
{
def onTime = Math.max(Math.min(onTime, 720), 8)
cmds << zwave.configurationV1.configurationSet(parameterNumber:1, size:2, scaledConfigurationValue: onTime ).format()
}
if (luxDisableValue)
{
def luxDisableValue = Math.max(Math.min(luxDisableValue, 200), 0)
cmds << zwave.configurationV1.configurationSet(parameterNumber:2, size:2, scaledConfigurationValue: luxDisableValue ).format()
}
if (luxReportInterval)
{
def luxReportInterval = Math.max(Math.min(luxReportInterval, 1440), 0)
cmds << zwave.configurationV1.configurationSet(parameterNumber:3, size:2, scaledConfigurationValue: luxReportInterval).format()
}

//Enable the following configuration gets to verify configuration in the logs
//cmds << zwave.configurationV1.configurationGet(parameterNumber: 7).format()
//cmds << zwave.configurationV1.configurationGet(parameterNumber: 8).format()
//cmds << zwave.configurationV1.configurationGet(parameterNumber: 9).format()
//cmds << zwave.configurationV1.configurationGet(parameterNumber: 10).format()

return cmds
}

def updated()
{
def cmds= []
cmds = setPrefs()
cmds << zwave.manufacturerSpecificV1.manufacturerSpecificGet().format()
cmds << zwave.versionV1.versionGet().format()

delayBetween(cmds, 500)

}

def manual() {
if (logEnable) log.debug "Setting operating mode to: Manual"
def cmds = []
cmds << zwave.configurationV1.configurationSet(parameterNumber:2, size:2, scaledConfigurationValue: 0 ).format()
sendEvent(name:"operatingMode", value: "manual")
return cmds
}

def auto() {
if (logEnable) log.debug "Setting operating mode to: Auto"
def cmds = []
def luxDisableValue = Math.max(Math.min(luxDisableValue, 200), 0)
cmds << zwave.configurationV1.configurationSet(parameterNumber:2, size:2, scaledConfigurationValue: luxDisableValue ).format()
sendEvent(name:"operatingMode", value: "auto")
return cmds
}

2 Likes

I have yet to find a better outdoor motion detection / light combo. What bothers you about the device? I have had 5 of them running solidly under HE for a year now.

Aesthetically, I don't like the white, nor the plastic, but the device works well for me with my outdoor floods.

The limited scale of the illuminance sensor readings.

I haven't found any other outdoor lux meters. Do you have a better recommendation? I want to use a lux meter to turn on my various outdoor lighting

Philips Hue outdoor motion has Lux.

1 Like

I can't argue the limited scale of the readings, but that isn't why I use them, thats what I use the outside Hue motion illuminance for. I have not, however, found a better outside floodlight with motion detection that works nearly as well as this does with Hubitat. Do you know of another z-wave or zigbee off the shelf alternative for house floodlights?

1 Like

Has anyone else noticed a high-pitched frequency being constantly emitted from their HS-FLS100? I have to be within 4-5 yards of the device to hear it, but it's clearly audible.

A bit of google searching discovered this:

I was/am on the verge of buying this device because it gives me AC power on a Lux/ Light sensor. Investigating.

@mike.maxwell, do you have a recommendation for a light sensor that is AC powered? Thanks!

Depending on your needs, the scale of the lux sensor may be adequate. For my use (turning on lights in the house earlier than their scheduled time in heavy overcast weather) it works well enough. I would think it would do fine for controlling outside lighting. On the other hand, it's not suitable as a trigger for opening/closing shades in response to different levels of moderately strong daylight.

1 Like

Very helpful description -- sounds like it would work for me.

Oh, nice parrot too.

1 Like

I'm not aware of any that are mains powered directly, Aeotecs multi can be usb powered.

Thanks for this. I'm using these on my security lights and I like them. Seem to work fine and provide independent sensors as well as an automatic mode. I didn't have any luck changing the ON time in auto mode though. Not sure I was using the driver correctly and was too lazy to debug, so I just changed the default to my desired value which worked.

I have this device hooked up with 2.1.8 and I set the driver but I'm not getting any lux readings. Is it working for everyone else?

Little late now... but yes, I hear it with all 3 of mine.