motioneye-project / motioneyeos

A Video Surveillance OS For Single-board Computers
Other
7.79k stars 889 forks source link

Request: external trigger recording #842

Closed iceboatLen closed 2 years ago

iceboatLen commented 7 years ago

Hello, Would it be possible to add a feature where a camera will record when prompted by an external trigger on a GPIO of the Pi, such as a PIR sensor.

Thanks Ben.

m4rky-m4rk commented 7 years ago

I like this too. When using infra red illumination for night motion detection a big problem is the insects are attracted to IR lights causing so many false alerts outdoors IR motion detection is useless. Using PIR as a second trigger eliminates false alerts from insects... But just PIR can also cause false alerts from natural movement of leaves, wind etc. Combining both.... PIR + Motion = Recording with no false alerts :-)

hinkma commented 7 years ago

+1 this. I want use Piface2 board for trigger from PIR.

jasaw commented 7 years ago

A quick glance at motion source code suggests that USR1 signal is supposed to trigger a movie recording, and ALRM signal supposed to record a timelapsed image. I did a quick test by send both signals to motion, but didn't seem to make any difference. Will need time to delve into the source code to figure out why. The function is called sig_handler, in motion.c

ccrisan commented 7 years ago

I remember testing that stuff with signals and it sometimes crashed and sometimes didn't work at all. I don't recall it ever working :) Anyways this was for motion 3.x. I hoped things have changed with 4.x.

jasaw commented 7 years ago

I hacked motion and got external trigger to work. Motion has emulate_motion config flag and I'm abusing it to force a recording. When USR1 signal is received, emulate_motion flag is set to 1. When USR2 signal is received, emulate_motion is set to 0. What this allows me to do is when my PIR sensor triggers, I send USR1 to motion to start recording, otherwise I send USR2 periodically to make sure emulate_motion is not left on accidentally.

Patch file attached if anyone wants to use it, just remove the txt file extension.

motion_external_trigger_hack.patch.txt

htrdlicn commented 7 years ago

+1 on this request, I have 5 Pi Zero W with PIR's ready for testing.

jasaw commented 7 years ago

Do all PIRs output the same signal e.g. output pulse low when there is motion? The pulse duration is not the same as the detected motion duration? Someone who has worked with various PIR sensors please advise. Technically, it's really simple to implement once we know the PIRs behaviour.

htrdlicn commented 7 years ago

They Pulse high, The two popular and inexpensive models which I have used are linked below. I currently have the SR505's wired to GPIO15 on the Pi Zero's

The behaviour is simple enough, The output pin is pulled low when there is no motion and goes high (3.3v) when motion is detected. On the SR505's this is hard wired to ~8s although there are variants that have different but fixed times. If it continues to see motion it seems to stay high, although it may be going low momentarily and then re-triggering. The SR501 has a trim pot that allows for adjustment of the pulse duration (0.3-600s). But this model is quite big.

It seems the simplest would be to start the motion event when the pin goes high and pole it once a second after that, and continue that motion event until it's low for >1s. This would accommodate either of these PIR sensors as well as dry contacts on doors quite well.

Another use case I want to use this for is the output from a car alarm, this way installations in cars don't need to process all the motion on the street, but when the shock sensor senses something, then it can record.

HC-SR505 Mini-Body Sensor Switch eBay Listing 262130705424

HC-SR501 Adjust IR Pyroelectric Infrared PIR Motion eBay Listing 252153857716

jasaw commented 7 years ago

I'm not familiar with motioneye code, but after a quick glance at the code, I would do something like this:

GPIO.setmode(GPIO.BCM) PIR_PIN = 15 GPIO.setup(PIR_PIN, GPIO.IN)

def poll_pir():

to be called once per second

if not GPIO.input(PIR_PIN):
    motion_pid = motionctl._get_pid()
    if motion_pid is not None:
        os.kill(motion_pid, signal.SIGUSR2)

def pir_motion_detected(PIR_PIN): motion_pid = motionctl._get_pid() if motion_pid is not None: os.kill(motion_pid, signal.SIGUSR1)

GPIO.add_event_detect(PIR_PIN, GPIO.RISING, callback=pir_motion_detected)



- Call poll_pir() once per second from a timer. Motioneye already uses IOLoop, maybe piggyback it on checker() function in start_motion()? I'm not familiar with IOLoop.
- Call GPIO.cleanup() in the clean up section, maybe run() function in server.py.
- Also need to install RPi.GPIO python module.
- It would be nice be able to select the GPIO number from the web front end, so some addition to main.html and main.js.

@ccrisan can definitely tell us where's an appropriate place to add PIR handler code.
ccrisan commented 7 years ago

This can indeed be added somewhere in motionctl.py. However the reason why no such functionality exists yet is that controlling motion detection by killing the daemon is just bad. We'd need to somehow use the exposed web "API" to control that. Then, exposing a command via meyectl would help anyone build external motion controllers by simply calling it from bash scripts or whatever.

jasaw commented 7 years ago

@ccrisan After having a greater understanding of motion software, I have to agree with you that it's better done via the HTTP API.

There are 2 scenarios an external trigger can be used.

  1. External trigger OR image-based trigger = motion detected.
  2. External trigger AND image-based trigger = motion detected.

Both scenarios can be useful as pointed out by various users here.

OR scenario can be done by hitting http://127.0.0.1:7999/%(id)s/emulate_motion/%(enabled)s where "enabled" can be a string "on" or "off".

AND scenario can be done by hitting http://127.0.0.1:7999/%(id)s/detection/%(enabled)s similar to set_motion_detection function in motionctl.py to enable/disable motion detection when an external trigger is on/off respectively. The set_motion_detection function may have to be modified a bit.

ccrisan commented 7 years ago

Yeap, both scenarios are valid and useful, each for its own use case. The best way to go about it is to implement the HTTP requests in some functions in motionctl.py and expose them (1) via a meyectl command and (2) via web handlers to motionEye's UI. The former is probably the most useful for users that want to control motion themselves.

jasaw commented 7 years ago

@ccrisan Yes, your 2nd option would be really nice. I don't see a need for meyectl. If someone wants more complicated trigger control, they can hit motionEye's HTTP interface directly from their program.

William1Lam commented 7 years ago

Completely new to GIT/motioneyeos, very keen to understand the architecture and coding of the system. However, I have not even managed to locate the Python and C source code. Where to start?

jasaw commented 7 years ago

@William1Lam Front-end code is motioneye. Motion code here. Motioneyeos repo is the build system to compile all the required programs and libraries into disk images for various platforms. Motioneyeos repo does not contain the program source code.

William1Lam commented 7 years ago

Thank you very much for the info.

From: jasaw [mailto:notifications@github.com] Sent: 03 July 2017 00:56 To: ccrisan/motioneyeos Cc: William1Lam; Mention Subject: Re: [ccrisan/motioneyeos] Request: external trigger recording (#842)

@William1Lam https://github.com/william1lam Front-end code is motioneye https://github.com/ccrisan/motioneye . Motion code here https://github.com/Motion-Project/motion . Motioneyeos repo is the build system to compile all the required programs and libraries into disk images for various platforms. Motioneyeos repo does not contain the program source code.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ccrisan/motioneyeos/issues/842#issuecomment-312524644 , or mute the thread https://github.com/notifications/unsubscribe-auth/AcdUHyOMQ0yXhj6rw7iDE9UiE2D7R_S6ks5sKC3-gaJpZM4MkTYW .Image removed by sender.

lajo-osd commented 6 years ago

Hi!

Any updates on this and the web handlers?

Protarios commented 6 years ago

On implementing such a feature, it would be perfect, if notification (mail, etc..) can be set up for each trigger type. I want to integrate motioneyeos into a doorbell, having it save a picture on motion, but only notifying if doorbell button is pushed.

InfectedKernel commented 6 years ago

I'm also looking forward to have kind of feature on MotionEye OS. it will be very great and for multiple uses!

mixpc commented 6 years ago

+1 and thank you for labeling it as 'feature request'. Look foward to seeing that web handler in motioneye

I am more inclined to the External trigger OR image-based trigger = motion detected. approach so that image-based trigger may be turned off in motioneye but that is a matter of personal preference as I think it would put less workload on the cpu.

jorgekramer commented 6 years ago

I would like to trigger a snapshot via http-request (and then download the still-image to display it in my Home-Automation-System (FHEM)). Is there a way to do this?

ccrisan commented 6 years ago

@jorgekramer use the Snapshot URL (which includes the required authorization signature as well).

jorgekramer commented 6 years ago

Tanks, it works. Is there also a way to trigger a snapshot in motioneye (e.g. if PIR in the Home-Automation-System detects motion) - and then send this image to a ftp-server?

stefi01 commented 5 years ago

I have mine set to zero for motion sensitivaty and it detects everything but i want mine to be used at night only, the camera is raspberry pi noir v2 ir camera, also 36 x ir 940nm leds that all turn on, gives perfect night vision in zero light for around 30feet, detects nothing at night but sees everything, the settings are all good, need a pir motion sensor to be added but how, i see lots of interest has been shown for the past year or two but no one has added this yet, why? simple arduino/raspberry pi pir sensors are advertised everywhere and very cheap.

jasaw commented 5 years ago

@stefi01 If you want your PIR sensor to trigger motion detection and start recording, do this:

  1. Write some python code that reads the GPIO of your PIR output.
  2. On PIR trigger, run curl "http://localhost:7999/1/config/set?emulate_motion=1".
  3. When PIR stops triggering, run curl "http://localhost:7999/1/config/set?emulate_motion=0".
stefi01 commented 5 years ago

@jasaw ok thanks for explaining, sounds easy enougth, i use my camera for night vision to see what is roaming around, i live up in mountains in california so i never know what to expect but the camera alone does not detect at all using the ir and 36 940nm leds plus another 36 on an add on board, motion setting set to zero and 2 frames to detect so i am hoping the pir works better, if i get stuck i will ask again and show what i have done but if it works then i could post those results too as it may help others i wish i found this software sooner before i started experimenting with others that dont even come close to this awsome software :) thank you for sharring

schnabelnator commented 5 years ago

@jasaw could you point me into a direction for the python code? Im running a raspberry pi 3b+ using the motion distro, do i have to use another distro with motion on top of it to be able to use the gpio pins?

Thank you!

jasaw commented 5 years ago

Something like this that polls the GPIO pin (assuming active high PIR signal). You run this as a standalone program. If you are running motionEyeOS, you can run this program from /data/etc/userinit.sh. Change the PIR_GPIO_PIN to whichever pin you have connected to your PIR. Change the background flag to True (note the upper case T) if you want it to daemonize (needed if running from userinit.sh).

#!/usr/bin/python
""" Watches GPIO pin for external motion trigger """

import sys
import os
import signal
import time
import cStringIO
import pycurl
import RPi.GPIO as GPIO

terminate = False
PIR_GPIO_PIN = 17

def handle_signals(signum, stack):
    global terminate
    if signum == signal.SIGTERM or signum == signal.SIGINT:
        terminate = True

def createDaemon():
    UMASK = 0
    WORKDIR = "/"
    MAXFD = 1024
    REDIRECT_TO = "/dev/null"
    if (hasattr(os, "devnull")):
        REDIRECT_TO = os.devnull

    try:
        pid = os.fork()
    except OSError, e:
        raise Exception, "%s [%d]" % (e.strerror, e.errno)
    if (pid == 0):
        os.setsid()
        try:
            pid = os.fork()
        except OSError, e:
            raise Exception, "%s [%d]" % (e.strerror, e.errno)

        if (pid == 0):
            os.chdir(WORKDIR)
            os.umask(UMASK)
        else:
            os._exit(0)
    else:
        os._exit(0)

    import resource
    maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
    if (maxfd == resource.RLIM_INFINITY):
        maxfd = MAXFD
    for fd in range(0, maxfd):
        try:
            os.close(fd)
        except OSError:
            pass
    os.open(REDIRECT_TO, os.O_RDWR)
    os.dup2(0, 1)
    os.dup2(0, 2)
    return(0)

def http_req(url):
    curl = pycurl.Curl()
    curl.setopt(pycurl.URL, url)
    response = cStringIO.StringIO()
    curl.setopt(pycurl.WRITEFUNCTION, response.write)
    response_headers = []
    curl.setopt(pycurl.HEADERFUNCTION, response_headers.append)
    try:
        curl.perform()
    except pycurl.error, e:
        print str(e)
    response_code = curl.getinfo(pycurl.RESPONSE_CODE)
    response_type = curl.getinfo(pycurl.CONTENT_TYPE)
    curl.close()
    response_data = response.getvalue()
    response.close()
    return response_code

def run():
    global terminate
    background = False

    # TODO: look for 'daemonize' and 'pir gpio pin' options from command line arguments

    if background:
        createDaemon()

    signal.signal(signal.SIGTERM, handle_signals)
    signal.signal(signal.SIGINT, handle_signals)

    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)
    GPIO.setup(PIR_GPIO_PIN, GPIO.IN,pull_up_down = GPIO.PUD_UP)

    GPIO.input(PIR_GPIO_PIN)

    prev_state = None
    while not terminate:
        time.sleep(0.5)
        cur_state = GPIO.input(PIR_GPIO_PIN)
        if cur_state == False:
            url = 'http://localhost:7999/1/config/set?emulate_motion=0'
        elif cur_state == True:
            url = 'http://localhost:7999/1/config/set?emulate_motion=1'
        if prev_state != cur_state:
            rc = http_req(url)
            print rc
            prev_state = cur_state

if __name__ == "__main__":
    run()

DISCLAIMER: I haven't tested this code, use at your own risk.

stefi01 commented 5 years ago

@jasaw where would the code go if it is MotionEye installed along side Raspbian and I guess we would need the above code and some other code that reads the GPIO pin

jasaw commented 5 years ago

@stefi01 If you're running Raspbian with MotionEye, you can put this code anywhere you like, e.g. /opt, /home/pi, /usr/bin. Make sure you enable execute bit in the file permission. You can start it automatically at boot time by running the command in /etc/rc.local. The code that I posted above already does the GPIO reading and triggering motion.

stefi01 commented 5 years ago

@jasaw i forgot to ask, what do i name the file, i hate to ask but still fairly new to raspberry pi

jasaw commented 5 years ago

@stefi01 You can name the file anything you like. pir_reader comes to mind.

stefi01 commented 5 years ago

@jasaw I think I am nearly there, just 2 more things.

  1. I am not sure where to execute file permission, like where do I do that and with what code.

  2. I checked in rc.local but everything there is commented out so not sure what to put in that, apart from that I think I am all setup

stefi01 commented 5 years ago

might have worked out the rc.local part, here is my my file after i added the line, the rest was already there , i think it is right, just not sure now for the where to add the permission part

#
# By default this script does nothing.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

sudo python /home/pi/pir_reader 
exit 0
jasaw commented 5 years ago

@stefi01 To enable execute permission, run chmod +x pir_reader. Did you change the background flag to True in the code? Make sure runs in the background. You should be able just do this:

#
# By default this script does nothing.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

/home/pi/pir_reader
exit 0
stefi01 commented 5 years ago

i have the code how you have it above if thats what you mean but i am guessing the background flag enabled would be def run(): global terminate background = true

jasaw commented 5 years ago

@stefi01 Use upper case T, as in True.

stefi01 commented 5 years ago

ok gotcha, gona run the camera tonight outside as trying to find out what is trying to eat live wires and that, have it working in night mode with a raspberry pi noir and 2x 32 ir led ring's, detects pretty well up to about 12 feet but can see with out light for around 50feet, not bad but the pir should add an extra 8 to 9 feet, tommorow i will play around with the pir sensor, i redesigned someone elses camera file on thingiverse and printed a nice camera just for MotionEye :)

schnabelnator commented 5 years ago

Thank you very much for your help @jasaw! I have saved your code above under /data/etc/motionDetection.py and my /data/etc/userinit.sh only has those two lines:

/home/pi/motionDetection.py
exit 0

Is this correct? I used chmod to make the motionDetection.py executable and changed the backgroundflag to true. However the script does not seem to work! Is there any way to monitor it's output or see if it is running under MotionOS?

Thank you very much!

jasaw commented 5 years ago

@schnabelnator Use upper case for background flag True. To debug, change the background flag back to False (note the upper case), then run the script /home/pi/motionDetection.py from command line and it will run in the foreground. It should print "200" when there's a change in the PIR GPIO pin.

Your userinit.sh looks correct.

schnabelnator commented 5 years ago

@jasaw Thank you for your help! I have changed your suggested code to work with 3 diffrent input GPIOs, if one is high then all 3 cameras should start recording. A text ("motionDetected") is supposed to be displayed on the camera that corresponds to the alarm. My Code does work but only once, the while loop is immediately stopped and I can't figure out why. If I use your code it works but with my changes it does not. Could you take a glance at my code? This is my first python script... Thank you!

#!/usr/bin/python
""" Watches GPIO pin for external motion trigger """

import sys
import os
import signal
import time
import cStringIO
import pycurl
import RPi.GPIO as GPIO

terminate = False
ALARM_GPIO_PIN_1 = 7
ALARM_GPIO_PIN_2 = 11
ALARM_GPIO_PIN_3 = 13

def handle_signals(signum, stack):
    global terminate
    if signum == signal.SIGTERM or signum == signal.SIGINT:
        terminate = True

def createDaemon():
    UMASK = 0
    WORKDIR = "/"
    MAXFD = 1024
    REDIRECT_TO = "/dev/null"
    if (hasattr(os, "devnull")):
        REDIRECT_TO = os.devnull

    try:
        pid = os.fork()
    except OSError, e:
        raise Exception, "%s [%d]" % (e.strerror, e.errno)
    if (pid == 0):
        os.setsid()
        try:
            pid = os.fork()
        except OSError, e:
            raise Exception, "%s [%d]" % (e.strerror, e.errno)

        if (pid == 0):
            os.chdir(WORKDIR)
            os.umask(UMASK)
        else:
            os._exit(0)
    else:
        os._exit(0)

    import resource
    maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
    if (maxfd == resource.RLIM_INFINITY):
        maxfd = MAXFD
    for fd in range(0, maxfd):
        try:
            os.close(fd)
        except OSError:
            pass
    os.open(REDIRECT_TO, os.O_RDWR)
    os.dup2(0, 1)
    os.dup2(0, 2)
    return(0)

def http_req(url):
    curl = pycurl.Curl()
    curl.setopt(pycurl.URL, url)
    response = cStringIO.StringIO()
    curl.setopt(pycurl.WRITEFUNCTION, response.write)
    response_headers = []
    curl.setopt(pycurl.HEADERFUNCTION, response_headers.append)
    try:
        curl.perform()
    except pycurl.error, e:
        print str(e)
    response_code = curl.getinfo(pycurl.RESPONSE_CODE)
    response_type = curl.getinfo(pycurl.CONTENT_TYPE)
    curl.close()
    response_data = response.getvalue()
    response.close()
    return response_code

def run():
    global terminate
    background = False

    # TODO: look for 'daemonize' and 'pir gpio pin' options from command line arguments

    if background:
        createDaemon()

    signal.signal(signal.SIGTERM, handle_signals)
    signal.signal(signal.SIGINT, handle_signals)

    GPIO.setmode(GPIO.BOARD)
    GPIO.setwarnings(False)
    GPIO.setup(ALARM_GPIO_PIN_1, GPIO.IN,pull_up_down = GPIO.PUD_DOWN)
    GPIO.setup(ALARM_GPIO_PIN_2, GPIO.IN,pull_up_down = GPIO.PUD_DOWN)
    GPIO.setup(ALARM_GPIO_PIN_3, GPIO.IN,pull_up_down = GPIO.PUD_DOWN)

    alarm_1 = GPIO.input(ALARM_GPIO_PIN_1)
    alarm_2 = GPIO.input(ALARM_GPIO_PIN_2)
    alarm_3 = GPIO.input(ALARM_GPIO_PIN_3)
    print alarm_1
    print alarm_2
    print alarm_3

    prev_state = None
    while not terminate:
        time.sleep(0.5)
        cur_state = alarm_1 or alarm_2 or alarm_3
        if cur_state == False:
            url_1 = 'http://localhost:7999/1/config/set?emulate_motion=0'
            url_2 = 'http://localhost:7999/2/config/set?emulate_motion=0'
            url_3 = 'http://localhost:7999/3/config/set?emulate_motion=0'
            url_4 = 'http://localhost:7999/1/config/set?text_left="%20"'
            url_5 = 'http://localhost:7999/2/config/set?text_left="%20"'
            url_6 = 'http://localhost:7999/3/config/set?text_left="%20"'
        elif cur_state == True:
            url_1 = 'http://localhost:7999/1/config/set?emulate_motion=1'
            url_2 = 'http://localhost:7999/2/config/set?emulate_motion=1'
            url_3 = 'http://localhost:7999/3/config/set?emulate_motion=1'
            if alarm_1 == True:
        print 'alarm1'
                url_4 = 'http://localhost:7999/1/config/set?text_left="motionDetected"'
                url_5 = 'http://localhost:7999/2/config/set?text_left="%20"'
                url_6 = 'http://localhost:7999/3/config/set?text_left="%20"'
            if alarm_2 == True:
        print 'alarm2'
                url_4 = 'http://localhost:7999/1/config/set?text_left="%20"'
                url_5 = 'http://localhost:7999/2/config/set?text_left="motionDetected"'
                url_6 = 'http://localhost:7999/3/config/set?text_left="%20"'
            if alarm_3 == True:
        print 'alarm3'
                url_4 = 'http://localhost:7999/1/config/set?text_left="%20"'
                url_5 = 'http://localhost:7999/2/config/set?text_left="%20"'
                url_6 = 'http://localhost:7999/3/config/set?text_left="motionDetected"'

        if prev_state != cur_state:
            rc_1 = http_req(url_1)
            rc_2 = http_req(url_2)
            rc_3 = http_req(url_3)
            rc_4 = http_req(url_4)
            rc_5 = http_req(url_5)
            rc_6 = http_req(url_6)
            print rc_1
            print rc_2
            print rc_3
            prev_state = cur_state

if __name__ == "__main__":
    run()
jasaw commented 5 years ago

@schnabelnator Try something like this (I haven't tested this code):

def set_cam_config(cam_index, config):
    url = 'http://localhost:7999/' + cam_index + '/config/set?' + config
    rc = http_req(url)
    print "alarm %d %s : %d" % (cam_index, config, rc)

def run():
    global terminate
    background = False

    # TODO: look for 'daemonize' and 'pir gpio pin' options from command line arguments

    if background:
        createDaemon()

    signal.signal(signal.SIGTERM, handle_signals)
    signal.signal(signal.SIGINT, handle_signals)

    GPIO.setmode(GPIO.BOARD)
    GPIO.setwarnings(False)
    GPIO.setup(ALARM_GPIO_PIN_1, GPIO.IN,pull_up_down = GPIO.PUD_DOWN)
    GPIO.setup(ALARM_GPIO_PIN_2, GPIO.IN,pull_up_down = GPIO.PUD_DOWN)
    GPIO.setup(ALARM_GPIO_PIN_3, GPIO.IN,pull_up_down = GPIO.PUD_DOWN)

    prev_url_em_1 = None
    prev_url_em_2 = None
    prev_url_em_3 = None
    prev_url_tl_1 = None
    prev_url_tl_2 = None
    prev_url_tl_3 = None
    while not terminate:
        time.sleep(0.5)
        alarm_1 = GPIO.input(ALARM_GPIO_PIN_1)
        alarm_2 = GPIO.input(ALARM_GPIO_PIN_2)
        alarm_3 = GPIO.input(ALARM_GPIO_PIN_3)
        if alarm_1 or alarm_2 or alarm_3:
            url_em_1 = '1'
            url_em_2 = '1'
            url_em_3 = '1'
        else:
            url_em_1 = '0'
            url_em_2 = '0'
            url_em_3 = '0'
        if alarm_1:
            url_tl_1 = '"motionDetected"'
        else:
            url_tl_1 = '"%20"'
        if alarm_2:
            url_tl_2 = '"motionDetected"'
        else:
            url_tl_2 = '"%20"'
        if alarm_3:
            url_tl_3 = '"motionDetected"'
        else:
            url_tl_3 = '"%20"'

        if prev_url_em_1 != url_em_1:
            set_cam_config(1, 'emulate_motion='+url_em_1)
            prev_url_em_1 = url_em_1
        if prev_url_em_2 != url_em_2:
            set_cam_config(2, 'emulate_motion='+url_em_2)
            prev_url_em_2 = url_em_2
        if prev_url_em_3 != url_em_3:
            set_cam_config(3, 'emulate_motion='+url_em_3)
            prev_url_em_3 = url_em_3
        if prev_url_tl_1 != url_tl_1:
            set_cam_config(1, 'text_left='+url_tl_1)
            prev_url_tl_1 = url_tl_1
        if prev_url_tl_2 != url_tl_2:
            set_cam_config(2, 'text_left='+url_tl_2)
            prev_url_tl_2 = url_tl_2
        if prev_url_tl_3 != url_tl_3:
            set_cam_config(3, 'text_left='+url_tl_3)
            prev_url_tl_3 = url_tl_3
mdeviprasad commented 5 years ago

Hello Is it possible to add a LCD I2C so that it can show time .... The idea is to make it look like a watch, leave it aside in a room ... newbie for Rpi // phyton ..

jasaw commented 5 years ago

@mdeviprasad Sure, but most likely you'll have to write some code to write to the I2C bus (/dev/i2c-1). What to write depends on your LCD. Read your LCD datasheet.

joland commented 5 years ago

I am also looking for a simple GPIO doorbell on/off button hookup. IFTTT offers a straight forward webhook option. All i need is motion eye os to accept external GPIO connections and 1 line of code to connect to IFTTT with curl...

judalvarezca commented 5 years ago

Hello! Thanks for the great work. A quick question: How should I build the URL for the HTTP request? I have tried with url = 'http://localhost:7999/1/config/set?emulate_motion=0' as you did in your example but it has no success. The port is the motioneye port? I keep receiving {"error": "not found"} as response. Have a great day.

ccrisan commented 5 years ago

Port 7999 is, by default, the Motion port. 80 or 8765 is used by motionEye. The funny thing is that you got an error from motionEye, accessing the Motion port. I can see the following possibilities:

judalvarezca commented 5 years ago

Thank you for the quick response. Digging into my configuration files, I found that my motion config is:

# @enabled on # @show_advanced on # @normal_password # @admin_username admin # @admin_password # @normal_username user

webcontrol_html_output on webcontrol_port 8999 setup_mode off webcontrol_parms 2 webcontrol_localhost off

I setted the webcontrol_localhost off to access from any machine to the motion port. However, when I do the request I receive "curl: (7) Failed to connect to localhost port 8999: Connection Refused". What am I missing here?

judalvarezca commented 5 years ago

Nevermind, I was trying to set the motion of a remote motionEye camera into my local server. Silly me. When I used the remote IP everything works fine. Thanks for all the support, always appreciated.

vinceemail commented 4 years ago

The script above is great! I'm using a PIR to trigger recording, and stop recording when the motion stops. This works well, BUT ONLY when motion detection is turned on.

This means that the Pi is actively processing the video stream, and detecting motion in the image.

I believe this is using up unnecessary processor bandwidth, in my case, because I would like to rely solely on the PIR sensor.

Is there a way to disable camera based detection, but still allow "emulate_motion"?

Many thanks :)