commit 1ce10813759703dd07829b34fcac152caad63255 Author: Mike Cifelli <1836280-mike-cifelli@users.noreply.gitlab.com> Date: Mon Dec 26 17:03:35 2022 -0500 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..03ea543 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +__pycache__/ +*.swp +*.tmp +garage.cfg +www/* +!www/.gitkeep diff --git a/README.md b/README.md new file mode 100644 index 0000000..8afe482 --- /dev/null +++ b/README.md @@ -0,0 +1,47 @@ +# garage + +## Dependencies +``` +sudo raspi-config nonint do_spi 0 +sudo apt install python3-pip python3-dev python3-spidev +sudo pip3 install unicornhathd +``` + +## Configuration +``` +cp garage.sample.cfg garage.cfg +``` + +## Installation +``` +sudo ./install +``` + +## Output +By default output will be in `/var/log/syslog`. +A separate log file can be used by creating `/etc/rsyslog.d/30-garage.conf` containing: +``` +if $programname == 'garage' then /var/log/garage.log +& stop +``` +and then restart the rsyslog service: +``` +sudo systemctl restart rsyslog +``` +This log file can be rotated by creating `/etc/logrotate.d/garage` containing: +``` +/var/log/garage.log +{ + rotate 14 + daily + create + missingok + notifempty + compress + delaycompress + postrotate + /usr/lib/rsyslog/rsyslog-rotate + endscript +} + +``` diff --git a/garage.py b/garage.py new file mode 100644 index 0000000..513380d --- /dev/null +++ b/garage.py @@ -0,0 +1,82 @@ +import json +import sys + +from configparser import ConfigParser +from gpio import Button +from signal import pause +from signal import signal +from signal import SIGTERM +from threading import Lock + +state = {"east-door": "opened", "west-door": "opened"} +threadLock = Lock() +stateFile = 'www/garage.json' + + +def main(): + signal(SIGTERM, cleanExit()) + config = ConfigParser() + config.read('garage.cfg') + eastPin = config['garage'].getint('east-pin') + westPin = config['garage'].getint('west-pin') + # eastUri = config['push'].getint('east-uri') + # westUri = config['push'].getint('west-uri') + + persistState() + + eastButton = Button(eastPin) + westButton = Button(westPin) + + pause() + + +def eastDoorOpened(): + try: + threadLock.aquire() + state["east-door"] = "opened" + persistState() + finally: + threadLock.release() + + +def eastDoorClosed(): + try: + threadLock.aquire() + state["east-door"] = "closed" + persistState() + finally: + threadLock.release() + + +def westDoorOpened(): + try: + threadLock.aquire() + state["west-door"] = "opened" + persistState() + finally: + threadLock.release() + + +def westDoorClosed(): + try: + threadLock.aquire() + state["west-door"] = "closed" + persistState() + finally: + threadLock.release() + + +def persistState(): + with open(stateFile, 'w') as file: + json.dump(state, file) + + +def cleanExit(): + def _exit_(signum, frame): + sys.exit(0) + + return _exit_ + + +if __name__ == '__main__': + main() diff --git a/garage.sample.cfg b/garage.sample.cfg new file mode 100644 index 0000000..1ca14c9 --- /dev/null +++ b/garage.sample.cfg @@ -0,0 +1,7 @@ +[garage] +east-pin=1 +west-pin=1 + +[push] +east-uri=uri +west-uri=uri diff --git a/garage.service b/garage.service new file mode 100644 index 0000000..01e1b6d --- /dev/null +++ b/garage.service @@ -0,0 +1,15 @@ +[Unit] +Description=Garage +After=multi.user.target + +[Service] +Type=simple +KillMode=mixed +WorkingDirectory=$workingDirectory +ExecStart=$execStart +Restart=on-failure +SyslogIdentifier=garage +User=$user + +[Install] +WantedBy=multi-user.target diff --git a/install b/install new file mode 100755 index 0000000..f115665 --- /dev/null +++ b/install @@ -0,0 +1,36 @@ +#! /usr/bin/env python3 + +import os +import sys + +from string import Template +from subprocess import check_call +from subprocess import check_output + +EXEC = 'garage.py' +SERVICE = 'garage.service' +SYSTEM_DIR = '/etc/systemd/system' + +CURRENT_DIR = os.path.dirname(os.path.realpath(__file__)) +SERVICE_TEMPLATE = os.path.join(CURRENT_DIR, SERVICE) +SERVICE_FILE = os.path.join(SYSTEM_DIR, SERVICE) +PYTHON = sys.executable +EXEC_START = f'{PYTHON} {EXEC}' +USER = check_output(['logname']).decode('utf-8').strip() + +with open(SERVICE_TEMPLATE) as f: + serviceTemplate = Template(f.read()) + +serviceFile = serviceTemplate.substitute( + workingDirectory=CURRENT_DIR, + execStart=EXEC_START, + user=USER +) + +with open(SERVICE_FILE, 'w') as f: + f.write(serviceFile) + +check_call(['systemctl', 'daemon-reload']) +check_call(['systemctl', 'enable', '--no-pager', SERVICE]) +check_call(['systemctl', 'restart', '--no-pager', SERVICE]) +check_call(['systemctl', 'status', '--no-pager', SERVICE]) diff --git a/www/.gitkeep b/www/.gitkeep new file mode 100644 index 0000000..e69de29