Smart doorbell
-
Hello World
Here is my latest project, near completion: smart doorbell.
Old raspberry 1B connected to the regular RaspiCam V1 and a push button.
As soon as pushbutton is pressed :
- RPi sends an MQTT message to network
- Cam takes a picture and stores it to my local NAS
- Gateway sends a notification all my portable devices connected to openHAB
- RPi sends and email with picture attached
This post has 2 goals :
- share my findings. My house was until now still relying on openhab2 and mysensors binding. All working very happily. But there was no direct answer to get a raspberry to behave as a MySensor device and talk directly to the gateway. It was also time to move to openhab3. I was then advised to have a go at MQTT. So be it !!!
- get some help linux-wise for completion of this project.
I had to learn new tricks along the way... like mounting a network drive to the RPi. It's kind of linking/sharing a folder between my NAS and my RPi. If a file is dropped into that "mounted folder" it then appears on each device. Magic
To do so edit your fstab file$ sudo nano /etc/fstab
and add something like :
//192.168.1.77/home/DoorBell /home/pi/doorbell/ cifs vers=2.0,username=username, password=passwordthatgoeswithit,credentials=/home/pi/doorbell .smbcred,noauto,x-systemd.automount 0 0
I have tested this setup both at work and at home. I had to remove "credentials" and everything after at home as i could never get it to work (got some errors). I also had to change from "vers=3.0" to "vers=2.0". Googling never got me a real explanation...
This is my python script, working as it should :
import os import subprocess from datetime import datetime from gpiozero import Button button = Button(17) while True: button.wait_for_press() os.system('mosquitto_pub -h openhabian -t doorbell/50/1/0/0/1 -m "1"') time = datetime.now() filename = "capture-%04d%02d%02d-%02d%02d%02d.jpg" % (time.year, time.month, time.day, time.hour, time.minute, time.second) subprocess.call("raspistill -t 500 -o %s" % filename, shell=True) subprocess.call("echo '' | mutt -s 'Someone ringing !' -i messageBody.txt myemailaddress@someprovider.com -a %s" % filename, shell=True) os.system('sudo /home/pi/movefile.sh') os.system('mosquitto_pub -h openhabian -t doorbell/50/1/0/0/1 -m "0"')
The picture is stored with a convenient name (date and time) like so : capture-20210910-224322.jpg
mutt is some simple, cool and efficient mailing program.
messageBody.txt is a plain text file containing the body of the generic email.
movefile.sh is a script that moves the jpg file from RPi's SD card up to NAS shared folder once the email has been sent.As i said previously it's all working as intended with
$ python doorbell.py
Next step is to get that python script to be launched at startup. A job for cron:
$ sudo nano launcher.sh
#!/bin/sh # launcher.sh # navigate to home directory, then to this directory, then execute python script, then back home cd / cd home/pi sudo python doorbell.py cd /
$ chmod 755 launcher.sh $ sh launcher.sh $ mkdir logs $ sudo crontab -e
add this to file :
@reboot sh /home/pi/launcher.sh >/home/pi/logs/cronlog 2>&1
$ sudo reboot
Quick check at logfile to make sure it all went well:
$ cat logs/cronlog
From then the email part of my script doesn't work anymore.
Trouble with rights ?ps aux
returns that launcher.sh belongs to root but python script belongs to pi :
root 475 0.0 0.0 0 0 ? S 16:51 0:00 [cifsd] root 500 0.0 0.6 7932 2300 ? Ss 16:51 0:00 /usr/sbin/cron -f root 502 0.0 0.6 9452 2384 ? S 16:51 0:00 /usr/sbin/CRON -f root 506 0.0 0.3 1924 1148 ? Ss 16:51 0:00 /bin/sh -c sh /home/pi/launcher.sh >/home/pi/logs/cronlog 2>&1 root 511 0.0 0.2 1924 1108 ? S 16:51 0:00 sh /home/pi/launcher.sh root 513 1.5 2.5 34348 9728 ? Sl 16:51 4:25 python doorbell02.py root 514 0.0 0.3 27640 1364 ? SLsl 16:51 0:00 /usr/sbin/rngd -r /dev/hwrng root 525 0.0 0.4 4292 1588 tty1 Ss+ 16:51 0:00 /sbin/agetty -o -p -- \u --noclear tty1 linux root 527 0.0 0.4 6600 1852 ? Ss+ 16:51 0:00 /sbin/agetty -o -p -- \u --keep-baud 115200,38400,9600 ttyAMA0 vt220 root 757 0.0 1.6 12224 6228 ? Ss 16:53 0:00 sshd: pi [priv] pi 760 0.0 1.8 14584 7072 ? Ss 16:53 0:00 /lib/systemd/systemd --user
Does it ring a bell to anyone ?
Thanks a lot for your help guys!
-
My openhab is setup via files.
I had some hard time discovering MQTT which was new to me and setging up openhab as it changed quite a lot since version 2.
So here are my files, gin case it might help someone sometime :
"items" file :
Switch doorBell01state "Door Bell" <alarm> {channel="mqtt:topic:mosquitto:doorBell01:doorBell01state"}
"things" file :
Bridge mqtt:broker:mosquitto "MySensorsGateway"@"Home" [host="192.168.1.20", port="1883", secure=false] { Thing topic doorBell01 "Door Bell"@"Front Gate" { Channels: Type switch : doorBell01state [stateTopic="doorbell/50/1/0/0/1", transformationPattern="MAP:onoff.map"] } }
"rules" file :
rule "frontgate bell ringing" when Item doorBell01state changed to ON then sendBroadcastNotification("Someone ringing at da gate!") end
"map" file : (needed because i cant cope with types, numbers, decimals, values, ... so i tried many tricks and that one worked)
0=OFF 1=ON
-
Just some things to check (I'm NOT a linux ninja):
-crontab: why do "sudo crontab -e"? Would using just "crontab -e" use pi-users crontab and have less conflicting permissions?
-fstab has multiple credentials currently
-the launcher I believe has unnecessary lines (the changing directories)
-did you have multiple pythons? (bbt.py, doorbell.py?)Just my two cents. Most of my problems are like this or permissions issues that just take too damn long to figure out.
-
Hi @MasMat
Thanks a lot for your suggestions ! You DO talk like a linux ninja though
I'll have a go at these
First let's try to understand :
-fstab has multiple credentials currently
what do you mean and how does this affect my "share"? I am very eager to understand. (although this part of my project is doing fine)
did you have multiple pythons? (bbt.py, doorbell.py?)
Sorry, no. My mistake. I tried to sanitise that post and forgot some dirt only "doorbell.py running. Initial message corrected now.
the launcher I believe has unnecessary lines (the changing directories)
Ok i'll get that cleaned up
crontab: why do "sudo crontab -e"? Would using just "crontab -e" use pi-users crontab and have less conflicting permissions?
Ok i'll have a go as well, it makes sense. Trouble is i tend to put "sudo" everywhere so it kinda "forces" things to go as i planned them... not necessarily clever i agree...
I let you know tonight
Would you have a suggestion on how to debug this script running in the background ? I tried pdb but it messes things up (starts multiple instances of doorbell.py... camera is constantly taking pictures, whole thing goes crazy) There must be some log of some sort that gets error message from programs running in background ?
Thank you ever so much for spending time here. I'm really stuck now (been 2 weeks) and i really appreciate your effort here
-
@ben999 : I would like to see what the hardware looked like and where the various components were installed -- ie: at the location of the old doorbell and if any changes were needed at the doorbell exterior location.
-
OK. The fstab has credentials file and username password - I recommend picking one. Cred file probably more secure (but permission issues may arise again).
What I like to do is add my own log entries (into a logfile of my own - not syslog) into the script - to begin with, it logs all kinds of steps the program goes thru. That way I can figure out what makes it stuck - or go crazy otherwise. Then remove all the crazy logging once the script works.
Example from a shell script of mine of one of many lines marking up whatever steps:
echo "date -u
InetReboot script" >> /home/pi/reboots.log"Camera taking pictures constantly" does sound like bouncing..? Reading the button? Could be hardware. Maybe slow down the script also - add "time.sleep(50)" at the end?
I'm not sure but does python need the GPIO-definitions at the beginning?
i.e.:
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
and maybe add a pullup/pulldown depending on your wiring.
-
@adamf663 sorry for delay! I am focusing on mostly software at the moment. So nothing to show so far i'll be posting as soon as the project moves forward again please read on !!!
@MasMat thanks a lot for your suggestions. As suggested first it is more than probably a case of rights/permissions.
There are many ways to launch a script at startup but in my case some deamons were started via "root" and some others via "user".
As stated before, all worked perfectly when logged under "user" (pi).
So, to summarise:- rc.local didn't work
- crontab didn't work
- .bashrc didn't work
These might work in the end but i'm not brainy enought to get to it.
Then came "systemctl" !
First create a .service file$ sudo nano /etc/systemd/system/doorbell.service
[Unit] Description=My test service After=multi-user.target [Service] Type=simple Restart=always ExecStart=/usr/bin/python /home/pi/doorbell02.py [Install] WantedBy=multi-user.target #WantedBy=default.target -> test this if previous doesn't work
Reload all daemons to check if your new .service file is ok
Then allow your new service file to be loaded at boot
Last, check if loading worked. If status returns "active" then it's a win$ sudo systemctl daemon-reload $ sudo systemctl --user enable doorbell.service $ sudo systemctl --user start doorbell.service $ systemctl --user is-active doorbell.service
Last step: systemctl loads these services at loggin by default (as in : enter user and password). I need it to start automaticaly with no human input. systelctl offers a way to load services without loggin for a given user :
$ loginctl user-status pi
Check status with
$ loginctl user-status pi
If status returns "linger: yes" then it's (once again) a win
Thanks again @MasMat for suggesting paths to investigate
That's it for now, i'll be back on the hardware point of view next time !