mirror of
https://github.com/bitlair/bitlair_doorduino.git
synced 2025-05-13 04:10:08 +02:00
Initial pi-configs from running system
This commit is contained in:
parent
595dd8a30e
commit
5727a9aa71
5 changed files with 300 additions and 2 deletions
|
@ -4,7 +4,7 @@ import serial
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
SERIAL_PORTS = [ '/dev/ttyS1', '/dev/ttyS2' ]
|
SERIAL_PORTS = [ '/dev/ttyS2' ]
|
||||||
|
|
||||||
|
|
||||||
def open_port(tty):
|
def open_port(tty):
|
||||||
|
@ -56,7 +56,7 @@ def remove_button(ports, button):
|
||||||
break
|
break
|
||||||
print(line)
|
print(line)
|
||||||
|
|
||||||
def add_button(ser, button, secret):
|
def add_button(ports, button, secret):
|
||||||
for port in ports:
|
for port in ports:
|
||||||
with open_port(port) as ser:
|
with open_port(port) as ser:
|
||||||
ser.write(b'\r\n')
|
ser.write(b'\r\n')
|
||||||
|
|
10
pi-config/config/settings
Normal file
10
pi-config/config/settings
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[mqtt]
|
||||||
|
doorbell.subject=bitlair/doorduino/doorbell
|
||||||
|
dooropen.subject=bitlair/doorduino/dooropen
|
||||||
|
lockstate.subject=bitlair/doorduino/lockstate
|
||||||
|
server=mqtt.bitlair.nl
|
||||||
|
mqtt-simple=/usr/local/bin/mqtt-simple
|
||||||
|
|
||||||
|
[serial]
|
||||||
|
device=/dev/ttyS2
|
||||||
|
|
111
pi-config/doorduino-init
Normal file
111
pi-config/doorduino-init
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
#!/bin/sh
|
||||||
|
### BEGIN INIT INFO
|
||||||
|
# Provides: generic-prog
|
||||||
|
# Required-Start: $local_fs $remote_fs $network
|
||||||
|
# Required-Stop: $local_fs $remote_fs $network
|
||||||
|
# Default-Start: 2 3 4 5
|
||||||
|
# Default-Stop: 0 1 6
|
||||||
|
# Short-Description: Generic Program
|
||||||
|
# Description: Generic Program is a generic program to do generic things with
|
||||||
|
### END INIT INFO
|
||||||
|
|
||||||
|
|
||||||
|
# Documentation available at
|
||||||
|
# http://refspecs.linuxfoundation.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptfunc.html
|
||||||
|
# Debian provides some extra functions though
|
||||||
|
. /lib/lsb/init-functions
|
||||||
|
|
||||||
|
|
||||||
|
DAEMON_NAME="root"
|
||||||
|
DAEMON_USER="root"
|
||||||
|
DAEMON_PATH="/root/bitlair_doorduino/pi-config/doorduino.py"
|
||||||
|
DAEMON_OPTS="-c /root/bitlair_doorduino/pi-config/config"
|
||||||
|
DAEMON_PWD="${PWD}"
|
||||||
|
DAEMON_DESC=$(get_lsb_header_val $0 "Short-Description")
|
||||||
|
DAEMON_PID="/var/run/${DAEMON_NAME}.pid"
|
||||||
|
DAEMON_NICE=0
|
||||||
|
DAEMON_LOG='/var/log/doorduino'
|
||||||
|
|
||||||
|
[ -r "/etc/default/${DAEMON_NAME}" ] && . "/etc/default/${DAEMON_NAME}"
|
||||||
|
|
||||||
|
do_start() {
|
||||||
|
local result
|
||||||
|
|
||||||
|
pidofproc -p "${DAEMON_PID}" "${DAEMON_PATH}" > /dev/null
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
log_warning_msg "${DAEMON_NAME} is already started"
|
||||||
|
result=0
|
||||||
|
else
|
||||||
|
log_daemon_msg "Starting ${DAEMON_DESC}" "${DAEMON_NAME}"
|
||||||
|
touch "${DAEMON_LOG}"
|
||||||
|
chown $DAEMON_USER "${DAEMON_LOG}"
|
||||||
|
chmod u+rw "${DAEMON_LOG}"
|
||||||
|
if [ -z "${DAEMON_USER}" ]; then
|
||||||
|
start-stop-daemon --start --quiet --oknodo --background \
|
||||||
|
--nicelevel $DAEMON_NICE \
|
||||||
|
--chdir "${DAEMON_PWD}" \
|
||||||
|
--pidfile "${DAEMON_PID}" --make-pidfile \
|
||||||
|
--exec "${DAEMON_PATH}" -- $DAEMON_OPTS
|
||||||
|
result=$?
|
||||||
|
else
|
||||||
|
start-stop-daemon --start --quiet --oknodo --background \
|
||||||
|
--nicelevel $DAEMON_NICE \
|
||||||
|
--chdir "${DAEMON_PWD}" \
|
||||||
|
--pidfile "${DAEMON_PID}" --make-pidfile \
|
||||||
|
--chuid "${DAEMON_USER}" \
|
||||||
|
--exec "${DAEMON_PATH}" -- $DAEMON_OPTS
|
||||||
|
result=$?
|
||||||
|
fi
|
||||||
|
log_end_msg $result
|
||||||
|
fi
|
||||||
|
return $result
|
||||||
|
}
|
||||||
|
|
||||||
|
do_stop() {
|
||||||
|
local result
|
||||||
|
|
||||||
|
pidofproc -p "${DAEMON_PID}" "${DAEMON_PATH}" > /dev/null
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
log_warning_msg "${DAEMON_NAME} is not started"
|
||||||
|
result=0
|
||||||
|
else
|
||||||
|
log_daemon_msg "Stopping ${DAEMON_DESC}" "${DAEMON_NAME}"
|
||||||
|
killproc -p "${DAEMON_PID}" "${DAEMON_PATH}"
|
||||||
|
result=$?
|
||||||
|
log_end_msg $result
|
||||||
|
rm "${DAEMON_PID}"
|
||||||
|
fi
|
||||||
|
return $result
|
||||||
|
}
|
||||||
|
|
||||||
|
do_restart() {
|
||||||
|
local result
|
||||||
|
do_stop
|
||||||
|
result=$?
|
||||||
|
if [ $result = 0 ]; then
|
||||||
|
do_start
|
||||||
|
result=$?
|
||||||
|
fi
|
||||||
|
return $result
|
||||||
|
}
|
||||||
|
|
||||||
|
do_status() {
|
||||||
|
local result
|
||||||
|
status_of_proc -p "${DAEMON_PID}" "${DAEMON_PATH}" "${DAEMON_NAME}"
|
||||||
|
result=$?
|
||||||
|
return $result
|
||||||
|
}
|
||||||
|
|
||||||
|
do_usage() {
|
||||||
|
echo $"Usage: $0 {start | stop | restart | status}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start) do_start; exit $? ;;
|
||||||
|
stop) do_stop; exit $? ;;
|
||||||
|
restart) do_restart; exit $? ;;
|
||||||
|
status) do_status; exit $? ;;
|
||||||
|
*) do_usage; exit 1 ;;
|
||||||
|
esac
|
||||||
|
|
169
pi-config/doorduino.py
Normal file
169
pi-config/doorduino.py
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
from serial.tools import list_ports
|
||||||
|
import serial
|
||||||
|
import io
|
||||||
|
import time
|
||||||
|
import subprocess
|
||||||
|
import csv
|
||||||
|
import getopt
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import math
|
||||||
|
import paramiko
|
||||||
|
from pathlib import Path
|
||||||
|
import configparser
|
||||||
|
import re
|
||||||
|
import threading
|
||||||
|
import syslog
|
||||||
|
|
||||||
|
def read_configuration(configdir):
|
||||||
|
if (configdir == ''):
|
||||||
|
print("Missing configdir.")
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
if not os.path.exists(configdir):
|
||||||
|
print("Directory ", configdir, " does not exist");
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
configfile = Path(os.path.join(configdir, 'settings'))
|
||||||
|
if not configfile.is_file():
|
||||||
|
print(configfile, " does not exist")
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
config.readfp(configfile.open())
|
||||||
|
|
||||||
|
expected_config_options = { 'mqtt': [ 'doorbell.subject', 'dooropen.subject', 'lockstate.subject', 'server', 'mqtt-simple' ],
|
||||||
|
'serial': [ 'device' ] }
|
||||||
|
|
||||||
|
for section, options in expected_config_options.items():
|
||||||
|
for option in options:
|
||||||
|
if not config.has_option(section, option):
|
||||||
|
print("Missing config option ", option, "in section", section)
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
return config
|
||||||
|
|
||||||
|
def mqtt_thread(config, subject, value, persistent):
|
||||||
|
if persistent:
|
||||||
|
subprocess.call([config.get('mqtt', 'mqtt-simple'), "-h", config.get('mqtt', 'server'), "-r", "-p", subject, "-m", value])
|
||||||
|
else:
|
||||||
|
subprocess.call([config.get('mqtt', 'mqtt-simple'), "-h", config.get('mqtt', 'server'), "-p", subject, "-m", value])
|
||||||
|
|
||||||
|
def mqtt(config, subject, value, persistent=False):
|
||||||
|
threading.Thread(target = mqtt_thread, args = (config, subject, value, persistent)).start()
|
||||||
|
|
||||||
|
def log(message):
|
||||||
|
print("LOG " + message)
|
||||||
|
syslog.syslog(message)
|
||||||
|
|
||||||
|
def main(argv):
|
||||||
|
global users
|
||||||
|
|
||||||
|
configdir = ''
|
||||||
|
|
||||||
|
syslog.openlog('doorduino')
|
||||||
|
|
||||||
|
try:
|
||||||
|
opts, args = getopt.getopt(argv,"c:",["config="])
|
||||||
|
except getopt.GetoptError:
|
||||||
|
print('doorduino.py -c <configdir>')
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
for opt, arg in opts:
|
||||||
|
if opt == "-c" or opt == "--config":
|
||||||
|
configdir = arg
|
||||||
|
|
||||||
|
config = read_configuration(configdir)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
#cdc = next(list_ports.grep(config.get('serial', 'device')))
|
||||||
|
#ser = serial.Serial(cdc[0])
|
||||||
|
ser = serial.Serial(config.get('serial', 'device'), 115200)
|
||||||
|
|
||||||
|
time.sleep(2);
|
||||||
|
# ser.write(b"R\n");
|
||||||
|
print("Doorduino started");
|
||||||
|
|
||||||
|
while True:
|
||||||
|
data = ser.readline()
|
||||||
|
action = data.decode("iso-8859-1").strip()
|
||||||
|
|
||||||
|
print("Data:" + action)
|
||||||
|
if action == "Horn activated":
|
||||||
|
print("Horn activated")
|
||||||
|
log("Horn activated")
|
||||||
|
mqtt(config, config.get('mqtt','doorbell.subject'), '1', False)
|
||||||
|
time.sleep(2)
|
||||||
|
mqtt(config, config.get('mqtt','doorbell.subject'), '0', False)
|
||||||
|
elif action == "Solenoid activated":
|
||||||
|
print("Solenoid activated")
|
||||||
|
log("Solenoid activated")
|
||||||
|
mqtt(config, config.get('mqtt','dooropen.subject'), '1', False)
|
||||||
|
time.sleep(2)
|
||||||
|
mqtt(config, config.get('mqtt','dooropen.subject'), '0', False)
|
||||||
|
elif action == "iButton authenticated":
|
||||||
|
print("iButton authenticated")
|
||||||
|
log("iButton authenticated")
|
||||||
|
elif action == "opening lock":
|
||||||
|
print("lock open")
|
||||||
|
log("lock open")
|
||||||
|
mqtt(config, config.get('mqtt','lockstate.subject'), 'open', True)
|
||||||
|
elif action == "closing lock":
|
||||||
|
print("lock closed")
|
||||||
|
log("lock closed")
|
||||||
|
mqtt(config, config.get('mqtt','lockstate.subject'), 'closed', True)
|
||||||
|
|
||||||
|
# if action == 'B':
|
||||||
|
# print("Arduino ready")
|
||||||
|
# ser.write(b"R\n")
|
||||||
|
# elif action == 'A':
|
||||||
|
# print("Authenticating", value)
|
||||||
|
# try:
|
||||||
|
# if users[value]:
|
||||||
|
# ser.write(b"U");
|
||||||
|
# if users[value]['maintenance']:
|
||||||
|
# ser.write(b'T')
|
||||||
|
# else:
|
||||||
|
# ser.write(b'F')
|
||||||
|
#
|
||||||
|
# ser.write(users[value]['price'].encode('utf-8'))
|
||||||
|
# ser.write(users[value]['revbank'].encode('utf-8'))
|
||||||
|
# ser.write(b"\n")
|
||||||
|
#
|
||||||
|
# log("Laser unlock by " + users[value]['revbank'] + " (" + value + ")")
|
||||||
|
#
|
||||||
|
# active_user = users[value]
|
||||||
|
# except KeyError:
|
||||||
|
# log("Laser unlock attempt by unknown iButton " + value)
|
||||||
|
# ser.write(b"FNiet gevonden\n");
|
||||||
|
# threading.Thread(target = git_update, args = (config.get('git', 'git'), configdir)).start()
|
||||||
|
#
|
||||||
|
# elif action == 'W':
|
||||||
|
# mqtt(config, config.get('mqtt','water.subject'), value, False);
|
||||||
|
# elif action == 'T':
|
||||||
|
# mqtt(config, config.get('mqtt', 'temperature.subject'), value, False);
|
||||||
|
# elif action == 'S':
|
||||||
|
# log("Laser job started for " + active_user['revbank'])
|
||||||
|
# mqtt(config, config.get('mqtt', 'laseractive.subject'), '1', True)
|
||||||
|
# elif action == 'E':
|
||||||
|
# log("Laser job finished for " + active_user['revbank'] + " in " + value + "ms")
|
||||||
|
# mqtt(config, config.get('mqtt', 'laseractive.subject'), '0', True)
|
||||||
|
# payment(config, active_user, float(value))
|
||||||
|
# elif action == 'M':
|
||||||
|
# log("Maintenance state entered by " + active_user['revbank'])
|
||||||
|
# elif action == 'L':
|
||||||
|
# log("Left maintenance state by " + active_user['revbank'])
|
||||||
|
|
||||||
|
except serial.SerialException:
|
||||||
|
print("Serial connection error")
|
||||||
|
time.sleep(2)
|
||||||
|
except StopIteration:
|
||||||
|
print("No device found")
|
||||||
|
time.sleep(2)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main(sys.argv[1:])
|
||||||
|
|
8
pi-config/reset_arduino.sh
Normal file
8
pi-config/reset_arduino.sh
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/bash
|
||||||
|
cd /sys/class/gpio/
|
||||||
|
echo 6 > export
|
||||||
|
echo out > gpio6/direction
|
||||||
|
echo 0 > gpio6/value
|
||||||
|
echo 1 > gpio6/value
|
||||||
|
echo 6 > unexport
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue