OK, a new attempt
The response above, b'\xaa\x01U\x00\xaa\x01\x10\xbb', seems partly correct, the last 4 bytes are actually the response we are expecting. So selecting those last bytes would give a correct result. I have introduced a small check that try to recover those, hopefully rare, occasions (and printing the incoming response to give a log of those, who knows how many and if they will look differently?)
Added also printout of the actual command that is sent to turn a relay on/off. This seemed not working? So we need to verify that I got it correct, at least from formatting and checksum calculation perspective
Hopefully it works, fingers crossed
# coding: utf-8
import sys
import os
import socket
import time
import subprocess
import signal
import paho.mqtt.client as mqtt
from setproctitle import setproctitle
def on_connect(client, obj, flags, rc):
client.subscribe("cmnds", 0)
def on_subscribe(client, userdata, mid, granted_qos):
print ('Subscribed:', userdata, mid, granted_qos)
print ('We are here, waiting for button commands...')
def on_message(mosq, obj, msg):
global abort
TCP_PORT = 2101
BUFFER_SIZE = 1024
cmds = {
"R1_ON" : bytes ((170,3,254,108,1,24)),
"R1_OFF" : bytes ((170,3,254,100,1,16)),
"R2_ON" : bytes ((170,3,254,109,1,25)),
"R2_OFF" : bytes ((170,3,254,101,1,17)),
"R3_ON" : bytes ((170,3,254,110,1,26)),
"R3_OFF" : bytes((170,3,254,102,1,18)),
"R4_ON" : bytes ((170,3,254,111,1,27)),
"R4_OFF" : bytes ((170,3,254,103,1,19)),
"R5_ON" : bytes ((170,3,254,112,1,28)),
"R5_OFF" : bytes ((170,3,254,104,1,20)),
"R6_ON" : bytes ((170,3,254,113,1,29)),
"R6_OFF" : bytes((170,3,254,105,1,21)),
"R7_ON" : bytes ((170,3,254,114,1,30)),
"R7_OFF" : bytes ((170,3,254,106,1,22)),
"R8_ON" : bytes ((170,3,254,115,1,31)),
"R8_OFF" : bytes ((170,3,254,107,1,23))
}
event = msg.payload.decode("utf-8").split(',')
print (event)
if event[0] == 'abort':
abort = True
if "_O" in event[0]:
print ("filtered:", event[0])
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
p = s.connect((event[1], TCP_PORT))
s.sendall((cmds[event[0]]))
s.close()
del(s)
if "I2C" in event[0]:
Ip = event[1]
iPort = int(event[2])
iRelay = int(event[3])
relayState = event[4]
dValues = {"1":1, "2":2, "3":4, "4":8, "5":16, "6":32, "7":64, "8":128}
rValues = [1,2,4,8,16,32,64,128]
#Check relay states
chkSum = (170+5+188+iPort+1+65+1) & 255
cmd = bytes ((170,5,188,iPort,1,65,1,chkSum))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
p = s.connect((Ip, TCP_PORT))
s.sendall((cmd))
res = s.recv((BUFFER_SIZE))
# res = b'\xaa\x01U\x00\xaa\x01\x10\xbb'
#Check that the response length is not > 4
if len(res) > 4:
print (res)
res = res[-4:]
iSum = int(res[2])
print ("Sum of current relay statuses: ", iSum)
rStates = []
for i in rValues[::-1]:
if iSum-i >= 0:
rStates.append(i)
iSum = iSum-i
else:
rStates.append(0)
#Reverse resulting list of current relay statuses
rStates = rStates[::-1]
if relayState == "ON":
rStates[iRelay-1]=rValues[iRelay-1]
if relayState == "OFF":
rStates[iRelay-1]=0
#Send the new relay command
time.sleep(0.01)
iSum = sum(rStates)
print ("Sum of new relay statuses: ", iSum)
chkSum = (170+7+188+iPort+3+64+9+iSum+0) & 255
cmd = bytes ((170,7,188,iPort,3,64,9,iSum,0,chkSum))
print (170,7,188,iPort,3,64,9,iSum,0,chkSum)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
p = s.connect((Ip, TCP_PORT))
s.sendall((cmd))
time.sleep(0.1)
s.close()
del(s)
p = subprocess.Popen(['ps', '-A'], stdout=subprocess.PIPE)
out, err = p.communicate()
for line in out.splitlines():
#print (line)
if b'relay_control' in line:
pid = int(line.split(None, 1)[0])
print ('Killing ', pid)
os.kill(pid, signal.SIGKILL)
time.sleep(2)
nn = 'relay_control'
setproctitle (nn)
abort = False
client = mqtt.Mosquitto()
client.on_connect = on_connect
client.on_message = on_message
client.on_subscribe = on_subscribe
client.connect("127.0.0.1", 1883, 60)
client.loop_start()
#if not os.geteuid() == 0:
# sys.exit("script only works as root")
while not abort:
time.sleep(1)
client.loop_stop()
client.disconnect()
del client
exit(0)