motioneye-project / motioneye

A web frontend for the motion daemon.
GNU General Public License v3.0
3.93k stars 651 forks source link

Send Notification To Pushover (Attachment Picture) #869

Open petakcore opened 6 years ago

petakcore commented 6 years ago

detail os :- motionEye Version : 0.39 Motion Version : 4.1.1 OS Version : Raspbian 9.4

Hello, I am successfully sending messages to pushover from motioneye using the code below: (https://github.com/raspberrycoulis/pushover)

!/usr/bin/python

import httplib, urllib

conn = httplib.HTTPSConnection("api.pushover.net:443") conn.request("POST", "/1/messages.json", urllib.urlencode({ "token": "APP_TOKEN", # Insert app token here "user": "USER_TOKEN", # Insert user token here "html": "1", # 1 for HTML, 0 to disable "title": "Motion Detected!", # Title of the message "message": "Front Door camera!", # Content of the message "url": "http://IP.ADD.RE.SS", # Link to be included in message "url_title": "View live stream", # Text for the link "sound": "siren", # Define the sound played }), { "Content-type": "application/x-www-form-urlencoded" }) conn.getresponse()`

However the above code only send a msg/url link to streaming to pushover: https://imgur.com/nQtBE2Y - (code work run manually & Run a Command function from motioneye)

I would like to attach a picture to the pushover notification as introduced in the latest api(pushover)

  1. https://pushover.net/api#attachments
  2. https://pushover.net/faq#library-python

i alread tried 2 code below:

1) import requests r = requests.post("https://api.pushover.net/1/messages.json", data={"token":"APP_TOKEN","user":"USER_KEY","message":"Got Image?"}, files={"attachment":open("PATH_TO_IMAGE","rb")})

2) import requests r = requests.post("https://api.pushover.net/1/messages.json", data = { "token": "APP_TOKEN", "user": "USER_KEY", "message": "hello world" }, files = { "attachment": ("image.jpg", open("your_image.jpg", "rb"), "image/jpeg") }) print(r.text)

Both code is working fine sending notification with picture when i run this script manually --> python pushover.py from terminal. But when i try to Run a Command from Motioneye: https://imgur.com/6pKOhQO i dont get any pushover notification when a motion is detected.

Does anyone experience the same problem?

rbohlmann1 commented 6 years ago

Perhaps the attachment is greater than 2,621,440 bytes (2.5 megabytes)? Which is the max limit for Pushover file size...

I am attempting to do the same thing right now. Just starting actually, which is how I found your post.. :)

tommy-rk commented 6 years ago

Anyone got successful with sending the current picture with the motion detection event to pushover?

rbohlmann1 commented 6 years ago

I was, yes, Tested on MotioneEyeOS OS Version 20180224. Was also able to get it to work with Raspbian and installing MotionEye (not the OS version). Try the following to get you started (MotionEyeOS example):

IN THE CLI

Make / filesystem writable mount -o remount,rw /

Save the following text to /root/pushover.py NOTE: You'll be replacing the text YOURpushoverTOKEN and YOURpushoverUSER with your unique PushOver token and user.

#!/usr/bin/python
import sys,requests
r = requests.post("https://api.pushover.net/1/messages.json", data={"token":"YOURpushoverTOKEN","user":"YOURpushoverUSER","message":"Front Door Motion Detected"}, files={"attachment":open(sys.argv[1],"rb")})

The python code above requires three modules be installed [chardet, urllib3, requests]. Using Raspbian with motionEye installed this should be easy (try PIP) if I recall. Using motionEyeOS I simply created tarballs of the three packages from a 'different' system which had them installed and copied them over to the motionEyeOS system.

You can then test the script to make sure it works. It expects that you pass it a picture file, so as an example: /root/pushover.py /data/output/Camera1/lastsnap.jpg

IN THE GUI

Goto the "File Storage" section for the camera and enable "Run A Command". Then set the value to: /bin/pushover.py %f

You can test by taking a snapshot from the GUI.

Now, every new picture taken will execute that command! So that could be a bit overwhelming. Suggest you play with the motion detection section.

I ended up NOT using this because I was simply getting too many false positives on motion and have not had the time to try and 'tweak' it.

Hope this helps. Cheers!

Russell

tommy-rk commented 6 years ago

Thank you Russell! This works absolutely perfectly. I'll update this thread with a doc on how to replicate this in details.

Any idea how I can trigger the pushover.py script ONLY for .jpg images and NOT for the created videos?

Right now "File Storage" "Run a command" is triggering for every file that is written out - JPG and MP4.

Obviously I get these log errors for MP4 attachments: dmesg.log:[Tue Jan 13 00:05:38 1970] CPU: 2 PID: 1534 Comm: pushoverPic.py Tainted: G C 4.14.30-v7 #1 dmesg.log:[Tue Jan 13 00:05:38 1970] Process pushoverPic.py (pid: 1534, stack limit = 0xa7228210)

rbohlmann1 commented 6 years ago

Glad I could help. "Run a command" will always execute pushoverPic.py. However, you can decide within that file to act upon only .jpg files. Try changing the code to the following:

#!/usr/bin/python
import sys,requests
filename = sys.argv[1];
if filename.endswith('.jpg'):
        r = requests.post("https://api.pushover.net/1/messages.json", data={"token":"YOURpushoverTOKEN","user":"YOURpushoverUSER","message":"Front Door Motion Detected"}, files={"attachment":open(filename,"rb")})

Take note that the indent before "r =' is required by Python.

Cheers

tommy-rk commented 6 years ago

Here are the needed python site-packages to make the r request working: (Tested with motionEyeOS 20180627)

pythonlibs.tar.zip

To install them, you need to unzip the file and scp the .tar file to e.g. /data

And then: mount -o remount,rw / tar xvf /data/pythonlibs.tar -C /usr/lib/python2.7/site-packages/ mount -r -o remount /

RadianM commented 6 years ago

I've been trying to follow Russell's directions above but it hasn't quite worked out.

Goto the "File Storage" section for the camera and enable "Run A Command". Then set the value to: /bin/pushover.py %f

I think /bin/ should be /root/ where the .py script was created. If I configure it correctly, the script is called but nothing seems to happen. In /var/log/motion.log the request post line gives IndexError: list index out of range

To test the script I tried looking for a still jpeg in ls /var/lib/motioneye/Camera1/ but the promising looking lastsnap.jpg turns out to be a broken symbolic link. Choosing a .jpg from the Camera1 subfolder with the current date i.e.

sudo /root/pushover.py /var/lib/motioneye/Camera1/2018-08-20/17-55-30.jpg

...works as hoped for and I get my pushover notification! So it looks like the %f parameter isn't being passed properly, and my sneaky work-around of hard-wiring a file into the request (lastsnap.jpg) isn't any help either. I think I'm close to getting the desired result but no cigar yet.

rbohlmann1 commented 6 years ago

RadianM - I would suggest you post what version of MotionEye/MotionEyeOS you are using. Since you state it works when you manually run the command and suspect the "%f" is not functioning, maybe it is a bug (or missing feature) in the version you are running... The developer of MotionEye may be able to respond quickly with an answer if you provide this detail.

On a side note... You could try to redirect some debug info (i.e. %f) within the script to a file to see what, if anything, is being passed to it...

RadianM commented 6 years ago

Versions:

motionEye Version 0.39.3 Motion Version 4.1.1 OS Version Raspbian 9.4

OK, like you suggested, I put in some debug and I now realise I misunderstood the use of Motion Notifications > Run A Command. The command entered in this section does not pass a filename through %f.

I thought enabling Motion Triggered still images would pass the filename to the notification command but it doesn't. This obviously explains why you said to put the command in File Storage section! I shouldn't have tried to think for myself (always goes wrong).

Adding the filter for .jpg files (as you also described) is a workaround. I suppose the problem is that motion can trigger stills as well as video files. The notification section would have to be duplicated in each image type section to associate the correct type of file with the notification so I can maybe see why it's not done like this.

lwvining commented 5 years ago

I was struggling with sending an image on motion triggered and resolved it simply by using a text message in the email . I have Verizon so I can use the mms alternative which is my phonenumuber@vzwpix.com . The attachment worked and actually sends messages whenever I’m outside of my home firewall. I have Hughesnet and am not able to setup a static ip for external porting. It works like a charm, sending images via MMS text messages.

developerfromjokela commented 5 years ago

Hello! I did it this way:

We know that motionEye can pass parameters such as dates, years, frame numbers and event numbers in Run A Command option. If we set our pictures filename format to %Y-%m-%d/%H-%M-%S_%q_%v, then filenames should look like this: 11-00-47_13_01.jpg.

All parameters used in filenames and folders are available in motion notifications Command. I modified @rbohlmann1 script to pass 2 parameters.

#!/usr/bin/python
import sys,requests
filename = "/var/lib/motioneye/CameraName/"+sys.argv[2]+"/"+sys.argv[1]+".jpg"
r = requests.post("https://api.pushover.net/1/messages.json", data={"token":"token","user":"userToken","message":"Front Door Motion Detected"}, files={"attachment":open(filename,"rb")}) 

Replace userToken, token and CameraName with yours. This works without getting full file path from motionEye.

Then in motionEye WebUI set it up: Go to Motion notifications, and enable Run A Command, then paste this:

python /home/pi/scripts/push.py %H-%M-%S_%q_%v %Y-%m-%d

Apply changes and you're done!

lmarceg commented 5 years ago

Thank you very very very much, @tommy-rk , for the explanation and above all for the tarball of the files, which I could easily install in my 20190119 release of MotionEyeOS!

zagrim commented 4 years ago

@kuroi8989 Not an answer, but you probably should redact your credentials when posting scripts and/or configs publicly (I'm referring to "token" and "user" in the script here). Everyone watching the issue feed now has a copy of those in their inbox, anyway.

kuroi8989 commented 4 years ago

@zagrim whooips, totally forgot to do that, thanks.

johncblacker commented 2 years ago

Thanks for this, the script works for me...except the files aren't showing up with the same timestamp as when the script is run, so I keep getting a file or directory not found when it's triggered by motion; however, if I take a snapshot manually, it works fine. I'm thinking about dropping the "%S" off the filenames in order to get around this problem. Any other ideas?

johncblacker commented 2 years ago

Actually ended up dropping the %S, %q and %v off the filenames and everything works fine now. I capture an image and send a notification with the image to pushover. Pretty slick...but for some reason I seem to lose the wifi connection and everything comes to a grinding halt and never starts back up unless I reboot the rPi. Don't know if the logs will tell me anything or not...not even sure what to be looking for...

ChrisDeath commented 2 years ago

Just want to add my version, that is a bit more dynamic. The call is adjusted to python2 /etc/motioneye/notification.py %H-%M-%S %Y-%m-%d %f, where the difference is the %f what directly gives the path to the file itself. So changing the media root later will be possible without need to touch the script. I left the rest of args in, to have them available if ever needed.

IMPORTANT: I am calling the script at "File Storage", so i have to check the file extension. I do that cause i don't want to have my cam in internet, but if something happens it is uploaded to personal Google Drive and deleted there automatically after defined time. And i do trigger a snappshot by custom script, what also should notify me ;)

#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys,requests,os.path
filename = sys.argv[3]
if os.path.exists(filename) and filename.endswith(".jpg"):
    r = requests.post("https://api.pushover.net/1/messages.json", data={"html":"1","token":"APPTOKEN","user":"USERTOKEN","sound":"magic","message":"Die Kamara <b>HINTEN</b> hat eine Bewegung festgestellt. Das Video sollte in Kürze mit dem ungefähren Zeitstempel " + sys.argv[1] + " im Google Drive sichtbar sein: <a href=\"https://drive.google.com/SHAREDFOLDER_DIRECT_LINK\">Video ansehen</a> (evntuell mit Nachuntenziehen die Video-Liste aktualisieren)"}, files={"attachment":open(filename,"rb")})

It is also using HTML and a defined sound parameter. Message is German but i think you will get the trick.

developerfromjokela commented 3 months ago

Just want to add my version, that is a bit more dynamic. The call is adjusted to python2 /etc/motioneye/notification.py %H-%M-%S %Y-%m-%d %f, where the difference is the %f what directly gives the path to the file itself. So changing the media root later will be possible without need to touch the script. I left the rest of args in, to have them available if ever needed.

IMPORTANT: I am calling the script at "File Storage", so i have to check the file extension. I do that cause i don't want to have my cam in internet, but if something happens it is uploaded to personal Google Drive and deleted there automatically after defined time. And i do trigger a snappshot by custom script, what also should notify me ;)

#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys,requests,os.path
filename = sys.argv[3]
if os.path.exists(filename) and filename.endswith(".jpg"):
    r = requests.post("https://api.pushover.net/1/messages.json", data={"html":"1","token":"APPTOKEN","user":"USERTOKEN","sound":"magic","message":"Die Kamara <b>HINTEN</b> hat eine Bewegung festgestellt. Das Video sollte in Kürze mit dem ungefähren Zeitstempel " + sys.argv[1] + " im Google Drive sichtbar sein: <a href=\"https://drive.google.com/SHAREDFOLDER_DIRECT_LINK\">Video ansehen</a> (evntuell mit Nachuntenziehen die Video-Liste aktualisieren)"}, files={"attachment":open(filename,"rb")})

It is also using HTML and a defined sound parameter. Message is German but i think you will get the trick.

bruh literally did the same as I did :D