├── gpio_layout.jpg ├── raspberrypi-with-PIR-sensor.jpg ├── uninstall.sh ├── motion-display-control.service ├── .gitignore ├── install.sh ├── .github └── FUNDING.yml ├── LICENSE ├── motion-display-control.py └── README.md /gpio_layout.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fire1ce/raspberry-pi-pir-motion-display-control/HEAD/gpio_layout.jpg -------------------------------------------------------------------------------- /raspberrypi-with-PIR-sensor.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fire1ce/raspberry-pi-pir-motion-display-control/HEAD/raspberrypi-with-PIR-sensor.jpg -------------------------------------------------------------------------------- /uninstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sudo systemctl disable motion-display-control.service 4 | sudo systemctl stop motion-display-control.service 5 | sudo rm -rf /etc/systemd/system/motion-display-control.service 6 | sudo rm -rf /usr/local/bin/motion-display-control.py 7 | 8 | echo "done." 9 | -------------------------------------------------------------------------------- /motion-display-control.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Screen control with GPIO PIR motion sensor 3 | After=network.target 4 | 5 | [Service] 6 | Type=simple 7 | Restart=always 8 | RestartSec=1 9 | User=root 10 | ExecStart=/usr/bin/python3 /usr/local/bin/motion-display-control.py 11 | 12 | [Install] 13 | WantedBy=multi-user.target 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # General 2 | .DS_Store 3 | .AppleDouble 4 | .LSOverride 5 | 6 | # Icon must end with two \r 7 | Icon 8 | 9 | # Thumbnails 10 | ._* 11 | 12 | # Files that might appear in the root of a volume 13 | .DocumentRevisions-V100 14 | .fseventsd 15 | .Spotlight-V100 16 | .TemporaryItems 17 | .Trashes 18 | .VolumeIcon.icns 19 | .com.apple.timemachine.donotpresent 20 | 21 | # Directories potentially created on remote AFP share 22 | .AppleDB 23 | .AppleDesktop 24 | Network Trash Folder 25 | Temporary Items 26 | .apdisk 27 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | curl -O https://raw.githubusercontent.com/fire1ce/raspberry-pi-pir-motion-display-control/main/motion-display-control.py 4 | curl -O https://raw.githubusercontent.com/fire1ce/raspberry-pi-pir-motion-display-control/main/motion-display-control.service 5 | 6 | if [ ! -d "/usr/local/bin" ]; then 7 | sudo mkdir -p /usr/local/bin 8 | fi 9 | 10 | sudo chmod +x motion-display-control.py 11 | sudo mv motion-display-control.py /usr/local/bin 12 | sudo mv motion-display-control.service /etc/systemd/system 13 | sudo systemctl start motion-display-control.service 14 | sudo systemctl enable motion-display-control.service 15 | 16 | echo "done." 17 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: fire1ce 4 | patreon: fire1ce 5 | # open_collective: # Replace with a single Open Collective username 6 | # ko_fi: # Replace with a single Ko-fi username 7 | # tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | # community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | # liberapay: # Replace with a single Liberapay username 10 | # issuehunt: # Replace with a single IssueHunt username 11 | # otechie: # Replace with a single Otechie username 12 | custom: ["https://www.paypal.com/donate/?hosted_button_id=Y5NSXQQ6VPSK6&Z3JncnB0", "https://www.buymeacoffee.com/fire1ce"] 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Stas Yakobov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /motion-display-control.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import logging 4 | from threading import Timer 5 | from subprocess import getoutput, run, DEVNULL 6 | from gpiozero import MotionSensor 7 | from signal import pause 8 | 9 | 10 | class Display: 11 | @staticmethod 12 | def isTurnedOn(): 13 | status = getoutput("vcgencmd display_power") 14 | isTurnedOn = status == "display_power=1" 15 | logging.debug(f"[Display]: Is turned on: {isTurnedOn}") 16 | return isTurnedOn 17 | 18 | @staticmethod 19 | def turnOn(): 20 | logging.debug("[Display]: Turning ON the display..") 21 | run(['vcgencmd', 'display_power', '1'], stdout=DEVNULL) 22 | 23 | @staticmethod 24 | def turnOff(): 25 | logging.debug("[Display]: Turning OFF the display..") 26 | run(['vcgencmd', 'display_power', '0'], stdout=DEVNULL) 27 | 28 | 29 | class Motion: 30 | timer = None 31 | 32 | def __init__(self, gpio_pin, display_delay, verbose): 33 | if verbose == True: 34 | logging.basicConfig(level=logging.DEBUG) 35 | else: 36 | logging.basicConfig(level=logging.INFO) 37 | 38 | logging.info( 39 | f"[Motion]: Initializing - GPIO_PIN: {gpio_pin}, DISPLAY_DELAY: {display_delay}, VERBOSE: {verbose}") 40 | 41 | if verbose == True: 42 | logging.basicConfig(level=logging.DEBUG) 43 | 44 | self.display_delay = display_delay 45 | self.pir = MotionSensor(gpio_pin) 46 | self.pir.when_motion = self.onMotion 47 | self.resetTimer() 48 | pause() 49 | 50 | def resetTimer(self): 51 | logging.debug("[Motion]: Resetting timer..") 52 | 53 | if self.timer: 54 | logging.debug("[Motion]: Old timer found! Destroying it!") 55 | self.timer.cancel() 56 | 57 | logging.debug(f"[Motion]: Setting timer for {self.display_delay}") 58 | self.timer = Timer(self.display_delay, Display.turnOff) 59 | self.timer.start() 60 | 61 | def onMotion(self): 62 | logging.debug("[Motion]: Motion detected!") 63 | 64 | if Display.isTurnedOn() == False: 65 | logging.debug("[Motion]: Display is off, turning it on!") 66 | Display.turnOn() 67 | 68 | self.resetTimer() 69 | 70 | 71 | motion = Motion(gpio_pin=4, display_delay=60, verbose=False) 72 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Raspberry Pi Display Control Based on Motion (PIR) Sensor 2 | 3 | ## Information 4 | 5 | This script uses pin GPIO4(7) to read data from Motion (PIR) Sensor, Any 5v and ground for PIR Sensor 6 | 7 | ![gpio layout](https://github.com/fire1ce/raspberry-pi-pir-motion-display-control/raw/main/gpio_layout.jpg) 8 | 9 | ![raspberrypi-with-PIR-sensor](https://github.com/fire1ce/raspberry-pi-pir-motion-display-control/raw/main/raspberrypi-with-PIR-sensor.jpg) 10 | 11 | ## Requirements 12 | 13 | - python3-gpiozero 14 | 15 | Can be install via apt 16 | 17 | ```bash 18 | sudo apt install python3-gpiozero 19 | ``` 20 | 21 | ## Install 22 | 23 | This will install the script as `service` and it will run at boot 24 | 25 | ```bash 26 | curl https://raw.githubusercontent.com/fire1ce/raspberry-pi-pir-motion-display-control/main/install.sh | bash 27 | ``` 28 | 29 | ## Uninstall 30 | 31 | ```bash 32 | curl https://raw.githubusercontent.com/fire1ce/raspberry-pi-pir-motion-display-control/main/uninstall.sh | bash 33 | ``` 34 | 35 | ## Default Behavior 36 | 37 | | **Condition** | **Behavior** | 38 | | --------------------------- | ----------------------------------- | 39 | | Motion while display is off | Turns on display for 60 sec | 40 | | Motion while display is on | Resets the timer for another 60 sec | 41 | | No motion > 60 sec | Turns off the display | 42 | 43 | ## Config 44 | 45 | File 46 | 47 | ```bash 48 | /usr/local/bin/motion-display-control.py 49 | ``` 50 | 51 | You can change Data Pin of the PIR Sensor at **gpio_pin** value 52 | You can change Delay at **display_delay** value 53 | 54 | Line 55 | 56 | ```python 57 | motion = Motion(gpio_pin=4, display_delay=60, verbose=False) 58 | ``` 59 | 60 | Restart the service to apply changes 61 | 62 | ```bash 63 | sudo systemctl restart power_button.service 64 | ``` 65 | 66 | ## Debug 67 | 68 | In order to allow verbose debug change the following 69 | 70 | File 71 | 72 | ```bash 73 | /usr/local/bin/motion-display-control.py 74 | ``` 75 | 76 | Line 77 | 78 | Set **verbose** value to **True** 79 | 80 | ```python 81 | motion = Motion(gpio_pin=4, display_delay=60, verbose=True) 82 | ``` 83 | 84 | Restart the service to apply changes 85 | 86 | ```bash 87 | sudo systemctl restart motion-display-control.service 88 | ``` 89 | 90 | ## Check if service is running 91 | 92 | ```bash 93 | sudo systemctl status motion-display-control.service 94 | 95 | ``` 96 | 97 | ## Contributors 98 | 99 | Thanks to [Boris Berman 100 | ](https://github.com/bermanboris/raspberry-pi-pir-motion-display-control) for the script rewrite from function to classes 101 | --------------------------------------------------------------------------------