domotic-gateway/python/DomoticGateway.py

111 lines
2.6 KiB
Python
Executable File

#!/usr/bin/python3
import serial
import math
from time import sleep
packet_src_t = {
'CMD_CLIMA': 0,
'CMD_TEMP': 1,
'CMD_ERR': 2,
'CMD_DEBUG': 3
}
def tohexstring(arg):
string = ""
for i in arg:
string += hex(i)+" "
return string
def get_label(_dict, _value):
return list(_dict.keys())[list(_dict.values()).index(_value)]
def packet_builder(src_label, data):
src = packet_src_t[src_label]
chk = src
# Build packet
packet = [src]
# size + CHK + header
datasize = len(packet) + 2
if data != None:
datasize += len(data)
packet += data
for i in data:
chk += i
# append CHK to the packet
chk += datasize
packet.append(chk & 0xFF)
# add size at top
packet = [datasize] + packet
return packet
def temperature_conversion(raw):
temperature = 1023.0/raw - 1.0
temperature = math.log(temperature * 0.976)/3435.0
temperature += 1.0/298.15
temperature = 1.0/temperature - 273.15
return temperature
class DomoticGateway:
def __init__(self):
for i in range(0, 3):
try:
self.ser = serial.Serial(
"/dev/ttyUSB0", 115200, timeout=0.5, exclusive=True)
sleep(0.1)
except:
sleep(1)
continue
break
# Flush data
while self.ser.read(1) != b'':
continue
def __del__(self):
self.ser.close()
def sendCommand(self, cmd, args = [0x00]):
self.ser.write(bytearray(packet_builder(cmd, args)))
def receiveData(self):
# Receive size
size = self.ser.read(1)
if (len(size) == 0):
raise ValueError('No incoming data')
size = size[0]
size -= 1
payload = self.ser.read(size)
if (len(payload) == 0):
raise ValueError('Invalid payload')
cmd = payload[0]
chk = payload[-1]
# I'm having some troubles with CHK check. Surely my fault on Arduino code
'''if chk != (size + sum(payload[:-1])) & 0xff:
raise ValueError('Invalid CHK')
return 'invalid chk %s' % tohexstring(payload)'''
payload = payload[1:-1]
if get_label(packet_src_t, cmd) == 'CMD_CLIMA':
raise ValueError('this should not exist (at the moment)')
elif get_label(packet_src_t, cmd) == 'CMD_TEMP':
# check payload length
payload = payload[0] + (payload[1] << 8)
return temperature_conversion(payload)
else:
raise ValueError('Invalid command')