Foscam - easily add motion sensor and other control

I used the Foscam motion detection piece from the Cookbook and made a few, what I feel, improvements/simplifications. Some of the code below has been taken from that Cookbook entry and modified with the small changes I made, many of which are for readability and future feature expansion. Might be neat to have these features built into the Foscam Camera component in the future - I might take a look if I get some time.

Most of those simplifications come from the following file that I’ve added to my home-assistant directory (foscam.py) - which is /config for me since I am using Docker:


import requests, xmltodict, sys

## Set Motion Config:
## http://192.168.2.50:88/cgi-bin/CGIProxy.fcgi?cmd=setMotionDetectConfig&isEnable=1&usr=admin&pwd=PASSWORD&linkage=0&snapInterval=3&&sensitivity=1&triggerInterval=0&schedule0=281474976710655&schedule1=281474976710655&schedule2=281474976710655&schedule3=281474976710655&schedule4=281474976710655&schedule5=281474976710655&schedule6=281474976710655&area0=1023&area1=1023&area2=1023&area3=1023&area4=1023&area5=1023&area6=1023&area7=1023&area8=1023&area9=1023
## Get Motion Status:
## http://192.168.2.50:88/cgi-bin/CGIProxy.fcgi?cmd=getMotionDetectConfig&isEnable=1&usr=admin&pwd=PASSWORD
## Get Motion Alert:
## Example URL: http://192.168.2.52:88/cgi-bin/CGIProxy.fcgi?cmd=getDevState&isEnable=1&usr=admin&pwd=PASSWORD

def getMotionAlert(ip, usr, pwd):
	url = "http://%s:88/cgi-bin/CGIProxy.fcgi?cmd=getDevState&usr=%s&pwd=%s" % (ip,usr,pwd)
	response = requests.get(url)
	doc = xmltodict.parse(response.content)
	result = doc['CGI_Result']['motionDetectAlarm'][0]
	
	# 0-Disabled, 1-No Alarm, 2-Detect Alarm
	print(result)
	
def getMotionStatus(ip, usr, pwd):
	url = "http://%s:88/cgi-bin/CGIProxy.fcgi?cmd=getMotionDetectConfig&usr=%s&pwd=%s" %(ip,usr,pwd)
	response = requests.get(url)
	doc = xmltodict.parse(response.content)
	result = doc['CGI_Result']['isEnable'][0]
	print(result)

def setMotionStatus(ip, usr, pwd, enabled):
	url = "http://%s:88/cgi-bin/CGIProxy.fcgi?cmd=setMotionDetectConfig&usr=%s&pwd=%s&isEnable=%s" %(ip,usr,pwd,enabled)
	url = url + "&linkage=0&snapInterval=3&&sensitivity=1&triggerInterval=0&schedule0=281474976710655&schedule1=281474976710655&schedule2=281474976710655&schedule3=281474976710655&schedule4=281474976710655&schedule5=281474976710655&schedule6=281474976710655&area0=1023&area1=1023&area2=1023&area3=1023&area4=1023&area5=1023&area6=1023&area7=1023&area8=1023&area9=1023"
	response = requests.get(url)
	doc = xmltodict.parse(response.content)
	result = doc['CGI_Result']['result'][0]
	print(result)
	
def ptzGotoPresetPoint(ip, usr, pwd, preset):
	url = "http://%s:88/cgi-bin/CGIProxy.fcgi?cmd=ptzGotoPresetPoint&usr=%s&pwd=%s&name=%s" %(ip,usr,pwd,preset)
	response = requests.get(url)
	doc = xmltodict.parse(response.content)
	result = doc['CGI_Result']['runResult'][0]
	# 0-Success, 1-Error
	print(result)


if __name__ == "__main__":
	func = sys.argv[1]
	
	if func == "getMotionAlert":
		getMotionAlert(sys.argv[2], sys.argv[3], sys.argv[4])
	elif func == "getMotionStatus":
		getMotionStatus(sys.argv[2], sys.argv[3], sys.argv[4])
	elif func == "setMotionStatus":
		setMotionStatus(sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5])
	elif func == "ptzGotoPresetPoint":
		ptzGotoPresetPoint(sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5])
	else:
		print("Add Function to Main!!!!")

Sensors can then be setup by doing:

  - platform: command_line
    name: Living Room Motion
    command: "python3 /path/to/foscam.py 'getMotionAlert' '192.168.2.50' 'username' 'password'"
    value_template: '{{ value == "2" }}'
    scan_interval: 2

A switch can be setup to turn motion detection on/off using:

  - platform: command_line
    switches:
     #Switch for Foscam Motion Detection
      foscam_motion_livingroom:
        command_on: "python3 /path/to/foscam.py 'setMotionStatus' '192.168.2.50' 'username' 'password' '1'"
        command_off: "python3 /path/to/foscam.py 'setMotionStatus' '192.168.2.50' 'username' 'password' '0'"
        command_state: "python3 /path/to/foscam.py 'getMotionStatus' '192.168.2.50' 'username' 'password'"
        value_template: '{{ value == "1" }}'
        friendly_name: Living Room Detection Status

additional commands can be built, for instance the ability to move to a Preset Point:

shell_command:
  top_most: "python3 /path/to/foscam.py 'ptzGotoPresetPoint' '192.168.2.50' 'username' 'password' 'TopMost'"

Script to easily turn off motion detection and point camera away:

  foscam_on_livingroom:
   sequence:
    - service: switch.turn_off
      data:
        entity_id: switch.foscam_motion_livingroom
    - service: shell_command.top_most

Automation to turn on motion detection and point camera away when I am not home:

  - alias: Set Foscam to Away Mode when I leave home
    trigger:
      platform: state
      entity_id: group.family
      from: 'home'
    action:
      service: script.foscam_on_livingroom

Using this, the ability to control the PTZ could be added along with other capabilities available within the Foscam CGI Documentation --> http://www.camarasip.es/descarga/IP_Camera_CGI_(SDK).pdf.

8 Likes

I am not sure if you have had chance to look at this python library. https://github.com/quatanium/foscam-python-lib … I’ve been hacking together a ‘foscmd’ script that would read in python config style commands and processing them. (Example https://github.com/texnofobix/foscam-python-lib/blob/foscmd/foscmd.py )

Hopefully my plan is to reduce command down to
foscmd [command_switch] [camera]

ptz shouldn’t be too much of a stretch to add

Very cool, had not seen that but that’s much more robust version of what I was going for. Would love to see this support built in to HA for the foscam component.

This looks cool, I’m hoping to get some webcams employed in a similar way.

What model(s) do you have this working with? I have a couple Foscams now, and one issue I have is they both seem to use completely different control methods/APIs. What works with one does not work with the other, and looking through their forums Foscam seems to be incredibly inconsistent about what interface standards they support and don’t from model to model.

FI9821W and C1 both have similar CGI interfaces.

I’m able to run this from the command line and it works, but I can’t get the sensor working on HA. It seems to have a problem with the value template but I can’t figure out what, and I’m using the same as you. Started a thread.

Is the link same for foscam fi8910w or fi8918w as i am not able to get any data if i try manually. I wanted to get an notification and turn on outside light when motion is detected on camera. I have setup the same thing on vera and is working fine but cannot get it working on HA. Can anyone guide through it.

Hi there. Was this ever fixed? I’m interested in doing automations in HASS based on motion form the Foscam.

Hello,

This thread looks really interesting. I would love to leverage the Motion Detection capabilities of my Foscam C1 versus a standalone ZWave motion detector (considering I already have the camera).

Wondering if anymore work was done on this. Thanks

hi, its a nice post indeed. I followed your python script for the cleanup and ease of the alerting. However, recently my Foscam Camera component giving a lot of error. Interestingly when I tried your script manually, it worked. and I checked the permission of the python file as well and its owned by homeassistant so permission issue can be omitted.

Do you have any advise regarding this ? By the way this error particularly started from version 0.40 I believe.

17-03-18 03:56:32 ERROR (Thread-7) [homeassistant.components.sensor.command_line] Command failed: python3 /home/homeassistant/.homeassistant/custom_py/foscam.py 'getMotionAlert' '192.168.254.150' 'username' 'pass

While the actual output from manual running of the script…

pi@homeassistant:/home/homeassistant/.homeassistant/custom_py$ python3 foscam.py 'getMotionAlert' '192.168.x.x' 'user' 'pass'
1
pi@homeassistant:/home/homeassistant/.homeassistant/custom_py$ python3 foscam.py 'getMotionAlert' '192.168.x.x' 'user' 'pass'
2

And the config is here:

- platform: command_line
  switches:
    foscam_motion:
      command_on: "python3 /home/homeassistant/.homeassistant/custom_py/foscam.py 'setMotionStatus' '192.168.x.x' 'usr' 'pass' '1'"
      command_off: "python3 /home/homeassistant/.homeassistant/custom_py/foscam.py 'setMotionStatus' '192.168.x.x' 'usr' 'pass' '0'"
      command_state: "python3 /home/homeassistant/.homeassistant/custom_py/foscam.py 'getMotionStatus' '192.168.x.x' 'usr' 'pass'"
      value_template: '{{ value == "1" }}'

Any idea anyone ?

first of all @kylerw ! your script worked perfectly man. thanks.

I figured out my issue, it was a silly one though :frowning: The python module “xmltodict” wasn’t installed in venv but same was installed in the machine. That’s why the manual command was running well while from HA it was failing. I just created a soft link by this command:

ln -s /usr/local/lib/python3.4/dist-packages/xmltodict-10.2.egg /srv/homeassistant/lib/site-package

And then changed the ownership of the package to homeassistant user. I am not sure if this step was required at all. All good so far except the alert component.

Well, if I set the motion sensor scan interval very low, then it can detect and report movement but I would be wary of running a python program every 2s from my poor pi. This would be the last option to choose. I was wondering if anyone got any other idea of alerting from foscam when motion detection in on. May be foscam will trigger a binary sensor in HA which can be used for automation later. I am not sure if it is something technically impossible or not ? Any one playing with this?

Hi everyone,

Now all the motion sensor switch/alert are working fine. But I was just wondering, is it possible to start probing the getAlert component working after an event fires ?

The idea is like this. Foscam motion sensor will be on after HA detect all_devices are out of home. This part works fine, then I would like to add the getAlert component to activate and hence I can set the aggressive timer(2s) for that window. If the motion sensor is not enabled then no point of trying to get the motion alert!

Anyone got any idea regarding this ? This would be a great way to get alerted at the same time HA host doesn’t have to deal with CPU intensive task all the time.

Hi everyone,

I am new to home-assistant, but not to the automation world…

how don’t understand how can I poll the motion sensor and send a notification, can you help me?

I just wanted to say thank you for this. It took me the better part of a week, but I finally got my Foscam R2 set up as a baby monitor with iOS notifications. In case anyone else is trying to do something similar with the R2, there are a few changes you need to make.

The major item is that you need to add a 1 to the end of getMotionDetectConfig and setMotionDetectConfig in foscam.py, so they become getMotionDetectConfig1 and setMotionDetectConfig1.

In addition, the CGI for setMotionStatus is a little bit different:

def setMotionStatus(ip, usr, pwd, enabled):
  url = "http://%s:88/cgi-bin/CGIProxy.fcgi?cmd=setMotionDetectConfig1&usr=%s&pwd=%s&isEnable=%s" %(ip,usr,pwd,enabled)
  url = url + "&linkage=0&snapInterval=3&triggerInterval=0&schedule0=281474976710655&schedule1=281474976710655&schedule2=281474976710655&schedule3=281474976710655&schedule4=281474976710655&schedule5=281474976710655&schedule6=281474976710655&x1=3042&y1=1604&width1=5185&height1=6229&threshold1=0&sensitivity1=2&valid1=1"
  response = requests.get(url)
  doc = xmltodict.parse(response.content)
  result = doc['CGI_Result']['result'][0]
  print(result)

These are the updated values to set the motion detection zone (you can also set 2 additional zones): &x1=3042&y1=1604&width1=5185&height1=6229&threshold1=0&sensitivity1=2&valid1=1

Finally, I also had issues getting automations working with the command line sensor. The using sensor.living_room_motion (which is what shows on the states page) wouldn’t work. I switched the name to underscores and then the automation started firing.

  - platform: command_line
    name: living_room_motion
    command: "python3 /path/to/foscam.py 'getMotionAlert' '192.168.2.50' 'username' 'password'"
    value_template: '{{ value == "2" }}'
    scan_interval: 2

I’m playing around with a few other options, but for now this is a great start. Specific updates I’m playing with are:

  1. Adjust the sensitivity settings
  2. Only send a notification if both motion and sound are detected
  3. Include a snapshot in the notification
  4. Send a TTS notification to LMS to play in various speakers in the house
3 Likes

Good day running the sensor from command line and get the following:

Traceback (most recent call last):
File “/home/homeassistant/.homeassistant/python_scripts/foscam.py”, line 1, in
import requests, xmltodict, sys
ImportError: No module named ‘xmltodict’

Running Hassbian on Pi3. Thank you

for those who come accross this and didnt know, i created an complete app for appdaemon with controls for PTZ, infared, motion detection, snapshot, etc.

it can be found here:

1 Like

Wonderful script I will, I have HASSIO and a Foscam FI9900P external camera.
It is compatbel to works with my camera?
What I have to do to use it?

Hi,
after hours i found out that if you use the Foscam C2 the Motion Detection Link needs to add a 1

Example:
Code in foscam documentation (works for my C1-Lite and my C1)

/cgi-bin/CGIProxy.fcgi?cmd=getMotionDetectConfig&usr=admin&pwd=

Code for the C2 Camera:

/cgi-bin/CGIProxy.fcgi?cmd=getMotionDetectConfig1&usr=admin&pwd=

1 Like

Hi Andy,

the getMotionDetectConfig doesn’t work on the R4 Foscam IP Camera. Does any know of a fix?

Regards,
John

does getMotionDetectConfig1 also not work?
is the cam a bit older then you probably have a foscam camera that uses the old cgi structure.

1 Like