Add relay scripts.

This commit is contained in:
yohan 2024-06-07 22:03:40 +02:00
parent 9342675ab2
commit bc55458642
5 changed files with 197 additions and 0 deletions

View File

@ -6,6 +6,8 @@ RUN apt-get update && apt-get -y install gunicorn sqlite3 python3-pip python3-re
ENV PIP_BREAK_SYSTEM_PACKAGES 1 ENV PIP_BREAK_SYSTEM_PACKAGES 1
RUN pip install flask-restx==1.3.0 RUN pip install flask-restx==1.3.0
WORKDIR /root WORKDIR /root
COPY find_ttyUSB.sh /root/
COPY relay.py /root/
COPY thermostat.py /root/ COPY thermostat.py /root/
ENV FLASK_APP thermostat.py ENV FLASK_APP thermostat.py
ENTRYPOINT ["/usr/bin/gunicorn", "thermostat:gunicorn_app"] ENTRYPOINT ["/usr/bin/gunicorn", "thermostat:gunicorn_app"]

76
README_relay.txt Normal file
View File

@ -0,0 +1,76 @@
*****************************************************************************
Configuration port série: 1 start, 8 bit, 1 stop (vitesse 9600 bauds)
*****************************************************************************
La trame est composée de 5 caractères (minuscule ou majuscule) pouvant etre envoyés en ASCII ou en Hexadécimal
****************
Code ascii
****************
Start of frame: RLY
N° channel: 0 à 8
CMD: 0 ou 1
Exemple de trame:
RLY11 // commute le relais 1 en position travail
RLY10 // commute le relais 1 en position repos
RLY21 // commute le relais 2 en position travail
...........................................................................
RLY80 commute le relais 8 en position repos
En cas de mauvaise commande la carte renvoi un retour chariot et le caractère ?
****************
Code hexa
****************
Start of frame: 0x52 0x4C 0x59 ou 0x72 0x6C 0x79
N° channel: 0x31 à 0x38
Cmd: 0x30 ou 0x31
Exemple de trame:
0x52 0x4C 0x59 0x31 0x31 // commute le relais 1 en position travail
0x52 0x4C 0x59 0x31 0x30 // commute le relais 1 en position repos
0x52 0x4C 0x59 0x32 0x31 // commute le relais 2 en position travail
...........................................................................
0x52 0x4C 0x59 0x38 0x30 commute le relais 8 en position repos
Pour tout autre caractère ou chaines de caractères la carte renvoi le code suivant:
0x0D 0x3F
*******************************************************************************
Modification du :04/09/2009
*******************************************************************************
Rajout du mode mémoire: la carte garde la dernière configuration en mémoire en cas de coupure d'alimentation.
****************
Code ascii
****************
M0 // Mode mémore désactivé
M1 // Mode mémoire activé
****************
Code hexa
****************
0x4D 0x30 // Mode mémore désactivé
0x4D 0x31 // Mode mémoire activé
*******************************************************************************
Rajout d'une commande pour connaitre l'état des relais.
****************
Code ascii
****************
?RLY // Renvoi l'état logique des 8 relais sous la forme >00000000 (le caractère le plus à droite correspond au relais 8)
****************
Code hexa
****************
0X3F 0x52 0x4C 0x59 // Renvoi l'état logique des 8 relais sous la forme >00000000 (le caractère le plus à droite correspond au relais 8)
******************************************************************************

3
TODO Normal file
View File

@ -0,0 +1,3 @@
- Upgrade relay.py to Python3
- Retry after failure in relay.py
- Store relays state in DB so we can have the info in /status API endpoint

10
find_ttyUSB.sh Executable file
View File

@ -0,0 +1,10 @@
#!/bin/bash
for sysdevpath in $(find /sys/bus/usb/devices/usb*/ -name dev); do
syspath="${sysdevpath%/dev}"
devname="$(udevadm info -q name -p $syspath)"
[[ "$devname" == "ttyUSB"* ]] || continue
eval "$(udevadm info -q property --export -p $syspath)"
[[ -z "$ID_SERIAL" ]] && exit
echo "/dev/$devname - $ID_SERIAL"
done

106
relay.py Executable file
View File

@ -0,0 +1,106 @@
#!/usr/bin/env python3
# Pilotage GCE USB 8 Relay Board
import time
import serial
import argparse
import sys
import subprocess
parser = argparse.ArgumentParser(description='Control relays.')
parser.add_argument('relay_list', type=str,
help='list of relays in ["1", ..., "8"] separated by comma, no spaces. "all" means all relays.')
parser.add_argument('action', type=str, choices=['on', 'off', 'status'],
help='Action on the list of relays.')
args = parser.parse_args()
if args.relay_list == 'all':
relays = [ 'RLY'+str(i) for i in range(1,9)]
else:
relays = []
for relay in args.relay_list.split(','):
if relay in [ str(i) for i in range(1,9)]:
relays.append('RLY'+relay)
else:
print("ERROR: Relay '"+relay+"' does not exist.")
sys.exit(1)
if args.action == 'on':
action = '1'
elif args.action == 'off':
action = '0'
else:
action = 'status'
#print(relays)
find_ttyUSB_output = subprocess.check_output(["./find_ttyUSB.sh"])
device = None
for line in find_ttyUSB_output.split("\n"):
if "FTDI_FT232R_USB_UART_A50285BI" in line:
device = line.split(" ")[0]
break
if device is None:
print ("Relay board not found.")
sys.exit(1)
def init_serial(pPort):
global ser
ser = serial.Serial()
ser.baudrate = 9600
ser.port = pPort
ser.bytesize = 8
ser.parity = 'N'
ser.timeout = None
ser.xonxoff = False
ser.rtscts=False
ser.dsrdtr=False
ser.timeout = 1
ser.open()
if ser.isOpen():
pass
#print('Connected to ' + ser.portstr)
else:
print('Could not connect to ' + ser.portstr)
sys.exit(1)
init_serial(device)
if action != 'status':
for relay in relays:
ser.write(relay.encode('ascii')+action+'\r\n')
bytes = ser.readline()
#print ('Renvoie :\r\n' + bytes)
ser.write('?RLY\r\n')
answer = ser.readline()
status = ''
for char in answer:
if char in ['0', '1']:
status+= char
if len(status) != 8:
print(len(status))
print("ERROR: status cannot be parsed.")
print('status:\r\n' + status)
sys.exit(1)
elif action != 'status':
print ('status:\r\n' + status)
if action != 'status':
for i in range(1,9):
relay = status[i-1]
if relay not in ['0', '1']:
print("ERROR: unrecognized value '"+relay+"' for relay "+str(i))
elif relay in relays and relay != action:
print("ERROR: wrong status '"+relay+"' for relay "+str(i))
else:
for i in [int(relay[3]) for relay in relays]:
relay = status[i-1]
if relay not in ['0', '1']:
print("ERROR: unrecognized value '"+relay+"' for relay "+str(i))
else:
print(relay, end='')
ser.close()