New Product! Homeseer outdoor motion

Having looked at the logs for motion events, I'm very surprised to see that the IR sensor seems fairly immune to false triggering during daylight hours. I'd have to say 'completely immune' based on what I've observed so far but we've only had one sunny afternoon in the last several days, so I'll reserve final judgement. But it certainly exceeds my expectations.

We've had a lot of rain/clouds lately, but when the afternoon sun broke through this afternoon, my Iris motion sensor, sheltered but oriented to the southwest to detect in front of the garage doors, generated a half dozen false triggers. The motion sensor on the FLS100+ positioned to cover the same general area, didn't triggered once. In fact, until I just went out and walked into its activation zone, I assumed it was disabled by the lux sensor (still haven't been able to disable that even with modified driver settings, btw). But it triggered on me properly, in spite of the sensor being in full sun.

In spite of (or perhaps, because of) its sharply defined detection zone in the vertical, this looks to be a reliable sensor for triggering during daylight hours as well as night. It doesn't have great range because of how I have it aimed from its high mounting point, but in combination with the Iris it will make for a pretty nice annunciator for somebody pulling up to the garage.

1 Like

Can someone post a working HE DH for this?

This is the Homeseer DH with the basic conversion to HE. Seems to works well. I installed these around two weeks ago.

/**
 *  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.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"
        
        
        
        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\nOn Time: Duration (8-720 seconds) [default: 15]", defaultValue: 15,range: "8..720", required: false)
       input ( "luxDisableValue", "number", title: "Lux Value to Disable Sensor: (30-200 lux) [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)
    }
    
	tiles(scale: 2) {
		multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
			tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
				attributeState "on", label:'${name}', action:"switch.off", icon:"st.Home.home30", backgroundColor:"#79b821", nextState:"turningOff"
				attributeState "off", label:'${name}', action:"switch.on", icon:"st.Home.home30", backgroundColor:"#ffffff", nextState:"turningOn"
				attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.Home.home30", backgroundColor:"#79b821", nextState:"turningOff"
				attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.Home.home30", backgroundColor:"#ffffff", nextState:"turningOn"
			}			
            tileAttribute("device.status", key: "SECONDARY_CONTROL") {
                attributeState("default", label:'${currentValue}', unit:"")
            }
		}
        /*
        multiAttributeTile(name:"motion", type: "generic", width: 6, height: 4, canChangeIcon: false){
			tileAttribute ("device.motion", key: "PRIMARY_CONTROL") {
				attributeState "inactive", 
					label:'No Motion', 
					icon:"st.motion.motion.inactive", 
					backgroundColor:"#cccccc"
				attributeState "active", 
					label:'Motion', 
					icon:"st.motion.motion.active", 
					backgroundColor:"#00a0dc"
			}			
		}
        */
		/*
		valueTile("motion", "device.motion", inactiveLabel: false, width: 2, height: 2) {
			state "motion", label:'${currentValue}'	
		}	
        */
        
        standardTile("motion", "device.motion", inactiveLabel: true, decoration: "flat", width: 2, height: 2) {
			state "inactive",  icon: "st.motion.motion.inactive", label: 'No Motion'
			state "active",  icon: "st.motion.motion.active", label: 'Motion'		
		}
        
        
		valueTile("illuminance", "device.illuminance", inactiveLabel: false, width: 2, height: 2) {
			state "illuminance", label:'${currentValue} lux',unit:"lux"
				
		}	
        
		standardTile("refresh", "device.switch", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
			state "default", label:'', action:"refresh.refresh", icon:"st.secondary.configure"
		}
        
        valueTile("firmwareVersion", "device.firmwareVersion", width:2, height: 2, decoration: "flat", inactiveLabel: false) {
			state "default", label: '${currentValue}'
		}       

		main(["switch"])
        
		details(["switch","motion","illuminance","firmwareVersion", "refresh"])
	}
}

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


// Creates motion events.
def zwaveEvent(hubitat.zwave.commands.notificationv3.NotificationReport cmd) {
	log.debug "NotificationReport: ${cmd}"
	
	if (cmd.notificationType == 0x07) {
		switch (cmd.event) {
			case 0:
				log.debug "NO MOTION"	
                createEvent(name:"motion", value: "inactive", isStateChange: true)
				break
			case 8:
				log.debug "MOTION"
				createEvent(name:"motion", value: "active", isStateChange: true)
				break
			default:
				logDebug "Sensor is ${cmd.event}"
		}
	}	
}

def zwaveEvent(hubitat.zwave.commands.sensormultilevelv5.SensorMultilevelReport cmd) {
	//log.debug("sensor multilevel report")
    //log.debug "cmd:  ${cmd}"
    
    def lval = cmd.scaledSensorValue
    
    createEvent(name:"illuminance", value: lval)
}

def zwaveEvent(hubitat.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
	log.debug "manufacturerId:   ${cmd.manufacturerId}"
	log.debug "manufacturerName: ${cmd.manufacturerName}"
    state.manufacturer=cmd.manufacturerName
	log.debug "productId:        ${cmd.productId}"
	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}")
    log.debug ("received Version Report")
    log.debug "applicationVersion:      ${cmd.applicationVersion}"
    log.debug "applicationSubVersion:   ${cmd.applicationSubVersion}"
    state.firmwareVersion=cmd.applicationVersion+'.'+cmd.applicationSubVersion
    log.debug "zWaveLibraryType:        ${cmd.zWaveLibraryType}"
    log.debug "zWaveProtocolVersion:    ${cmd.zWaveProtocolVersion}"
    log.debug "zWaveProtocolSubVersion: ${cmd.zWaveProtocolSubVersion}"
    setFirmwareVersion()
    createEvent([descriptionText: "Firmware V"+state.firmwareVersion, isStateChange: false])
}

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

def zwaveEvent(hubitat.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd) { 
	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() {
	
	delayBetween([
			zwave.basicV1.basicSet(value: 0xFF).format(),
			zwave.switchMultilevelV1.switchMultilevelGet().format()
	],5000)
}

def 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.debug "refresh() called"
    configure()
}


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() {
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()
log.debug ("cmds: " + cmds)
delayBetween(cmds,500)
}

def setPrefs() 
{
   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)

}
2 Likes

Question--the manual mentions "Conventional Floodlight Mode" and "Smart Floodlight Mode". But I didn't really see anything else mentioned, like how you set into those modes if indeed you have to do that. What I think would be great is for it to work in Conventional Floodlight Mode but also do Smart Floodlight Mode at the same time.

I guess mostly what I want to know is, if I use it with the hub, do I need to turn the lights on when a motion event comes in to the hub, or will the motion sensor turn the lights on itself?

I didn't read that part of the manual, but It works the way you are describing. If it senses motion, it turns itself on, and off again a few minutes later with no required interaction in Hubitat. That is as long as the Lux reading is within the set range. In the Hubitat driver you can see that the motion was triggered, and you can turn on / off the light from within the driver. I setup a two button pico to turn on and off the floodlights, and installed the pico into a switch plate by my back door.

One tip, Make sure that the manual knob controls on the back of the motion are not set to one extreme or the other or it wont respect the setting within the driver. I made sure my knobs were set in the middle somewhere and they are working well.

1 Like

Some more information, or a summary of what I have found.

I've combined all the enhancements above and added some debug logging/turn off to the code posted below.

The "On Time" or duration will also be the duration that the sensor shows "active" once triggered. So if you set it to 8, it will reset in 8 seconds to inactive. Etc.

If you additionally set the Lux Value to 0. This basically disables the sensor from turning the light on locally. AKA you now have a Illuminance sensor, a motion sensor and a switch that all report back to the hub. No local turn on of the light. See above for "On Time" as that still sets how long the motion sensor stays active.

Once you set the Lux value then that engages the local light turn on. So at that lux value and below with motion the light will turn on and stay on for the duration of "On Time" as listed above. The motion sensor will also show "active" for this same time period.

Hope that helps to sum up this sensor... that I'm super happy to finally have!

This DH now has two modes, "manual" and "auto". In manual mode all it does is set the lux to 0. In auto mode it sets the lux to whatever value you set it to on the DH page. You can now create a custom command to set the "auto" or "manual" mode.

3 Likes

New to Hubitat, Groovy, and home automation in general. Have installed FLS 100+ driver from jrfarrar GitHub, but only have partial functionality. With the exception of "On", the commands are not working for me and return a Groovy error.
e.g. "groovy.lang.MissingMethodException: No signature of method: dev15469698773661700417423.refresh() is applicable for argument types: () values: []
Possible solutions: every(), parse(java.lang.String), every(groovy.lang.Closure), grep() (refresh)".
Any pointers would be appreciated.
Thanks...

I've been using this driver for months without error. Did you use the import feature or copy/paste over the code? Also, did you hit 'Configure' after installing the driver?

Newbie error. I used copy / paste. I somehow managed to truncate the file so all items were not defined. I imported the complete file and all is well. Sorry for the bother. Thanks much for the quick response.

1 Like

No problem at all, you'll find this group is always willing to help.

Welcome to Hubitat. :grin:

I'm a newbie to Hubitat (Iris victim). I just paired a Homeseer Floodlight sensor to the Hubitat hub. Paired fine, but device type is just "device". Homeseer claims "we're not familiar with Hubitat to tell you what device type to call it. Contact them." Last Homeseer product I buy. The driver business in your post is Greek to me. I plan on learning Java and whatever else I will need, but, for the immediate need, which type of device in the dropdown list will make it work at least rudimentarily?.

See post #28 above for the Device Driver code for this HomeSeer product. I'm using it with success.

If you need instructions on how to add it to you Hubitat, that info is available here as well, just search for "add new Driver" documentation.

Thanks!

Got it working, used the "import" method, thanks again!

1 Like

Awesome, glad it’s working. I’ve got mine set to turn on to light the driveway when my Ring doorbell detects motion. The things you can do with this hub... very addictive!

2 Likes

Can I use the lux level as a trigger to turn off and on lights in the house?

Probably, but you're much better off using motion sensors and or other interior sensors for this task.
The Lux sensor in this device taps out at something like 250 Lux, which is only sufficient to tell you that it's night time, which you already have available via sunrise and sunset.

Honestly you're better off in the long run getting a sensor that can report motion and Lux values at a much higher scale...
The Hue outdoor motion sensor being a good cantidate.

1 Like

Yes, that's exactly what I use it for. Helps on stormy dark days. It does tap out at 250 but that pretty darn bright out. Somewhere between 100 and 200 would probably work.

Okay thanks.

I know it works directly with hubitat, but do all the features including lux work ?

I was referring to the hue outdoor