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 !


Log in to reply
 

Suggested Topics

17
Online

11.4k
Users

11.1k
Topics

112.7k
Posts