I have an Amcrest IP4M-956E dome camera I am using to monitor the front of my house. The camera does not have a builtin feature to allow HTTP calls when motion is detected, but I found a different way to get openHab to respond to motion events. I thought I would share the details with the community.
Item
String Amcrest_Motion "Motion detected [%S]" <camera> (Group) { http="<[http://user:pass@x.x.x.x/cgi-bin/eventManager.cgi?action=getEventIndexes&code=VideoMotion:2000:JS(motiondetect.js)]" }
I am using the http binding with the Amcrest API to query the events info from the camera. After motion is detected, the camera will report the motion for as long as it is occurring and for up to 60 seconds after the motion stops. If no motion is detected, the camera returns “Error: No Events”. If motion is detected, it simply returns “channels[0]=0”. I am using motiondetect.js to translate the results into string TRUE or FALSE.
motiondetect.js
// Wrap everything in a function
(function(i) {
var response = i.replace(/(\r\n|\n|\r)/gm,"");
if(response == 'channels[0]=0'){return "TRUE"}else{return "FALSE"};
})(input)
// input variable contains data passed by openhab
Rule
var Timer tOutdoorMotionLightsOff = null
var DateTime dtOutdoorMotionTriggerTime = new DateTime(now)
var DateTime motionSunset = null
rule "Driveway Motion"
when
Item Amcrest_Motion changed
then
logInfo("Timer", "Motion Detected!")
motionSunset = new DateTime(parse(now.getYear()+"-"+now.getMonthOfYear()+"-"+now.getDayOfMonth()+"T"+strSunset.state))
if ((Amcrest_Motion.state == "TRUE")
&& ((motionSunset.isBeforeNow()) || (now.getHourOfDay() < 7))
&& (Light_Outdoor_Front.state == OFF)
&& (dtOutdoorMotionTriggerTime.plusMinutes(6).isBeforeNow())) {
logInfo("Timer","Driveway motion detected. Turning on light and creating off timer")
sendCommand(Light_Outdoor_Front, ON)
if(tOutdoorMotionLightsOff!=null) {
logInfo("Timer","Timer tOutdoorMotionLightsOff cancelled")
tOutdoorMotionLightsOff.cancel()
}
tOutdoorMotionLightsOff = createTimer(now.plusMinutes(5)) [|
logInfo("Timer","Timer tOutdoorMotionLightsOff executed")
dtOutdoorMotionTriggerTime = new DateTime(now)
sendCommand(Light_Outdoor_Front, OFF)
]
}
end
I am using the rule to turn the front light on for 5 minutes, but only if the current time is after sunset or before 7am and it has been at least 6 minutes since the last motion detection. This is because the act of turning off the light causes a motion trigger in the camera. If this check wasn’t there, the light would turn off and on all night. The only other if clause is to check if the light isn’t already on. I wouldn’t want motion to turn off the light if i already had it turned on for some reason.