Added Decoder for New Binary Payload Format

This commit is contained in:
seiichiro 2020-02-08 16:27:46 +01:00
parent ce362fde33
commit 5848252bff
2 changed files with 42 additions and 29 deletions

View file

@ -5,6 +5,8 @@ import spidev
import RPi.GPIO as GPIO import RPi.GPIO as GPIO
import time import time
GPIO.setwarnings(False)
class RFM69(object): class RFM69(object):
def __init__(self, freqBand, nodeID, networkID, isRFM69HW = False, intPin = 18, rstPin = 28, spiBus = 0, spiDevice = 0): def __init__(self, freqBand, nodeID, networkID, isRFM69HW = False, intPin = 18, rstPin = 28, spiBus = 0, spiDevice = 0):

View file

@ -4,7 +4,7 @@ rfm69receiver - A RFM69 433MHz Receiver Using the Observer Pattern
import time import time
import struct import struct
from pprint import pprint from pprint import pprint, pformat
import RFM69 import RFM69
from RFM69registers import RF69_433MHZ from RFM69registers import RF69_433MHZ
@ -13,7 +13,7 @@ class RFM69Receiver(object):
Multiple Observers to Process the Messages Multiple Observers to Process the Messages
""" """
def __init__(self, nodeID, netID, encKey=None): def __init__(self, nodeID, netID, encKey=None, debug=False):
""" Initialize the Transceiver Module """ Initialize the Transceiver Module
Arguments: Arguments:
@ -26,6 +26,7 @@ class RFM69Receiver(object):
self.__running = False self.__running = False
self.__lastsid = None self.__lastsid = None
self.__lastts = 0 self.__lastts = 0
self.__debug = debug
try: try:
print("Initializing RFM69 Module as Node " + str(nodeID) + " on Network " + str(netID)) print("Initializing RFM69 Module as Node " + str(nodeID) + " on Network " + str(netID))
@ -42,23 +43,14 @@ class RFM69Receiver(object):
print("Shutting Down RFM69 Module") print("Shutting Down RFM69 Module")
self.__rfm.shutdown() self.__rfm.shutdown()
def _rawbytes(self, s):
"""Convert a string to raw bytes without encoding"""
outlist = []
for cp in s:
num = ord(cp)
if num < 255:
outlist.append(struct.pack('B', num))
elif num < 65535:
outlist.append(struct.pack('>H', num))
else:
b = (num & 0xFF0000) >> 16
H = num & 0xFFFF
outlist.append(struct.pack('>bH', b, H))
return b''.join(outlist)
def _debug(self, message):
""" Print Debug Output """
if self.__debug:
print('[' + time.strftime('%H:%M:%S %d %b %Y') + '][DBG] ', end='')
print(message)
def _process(self, sid, data, rssi): def _process(self, sid, rdata, rssi):
""" Process received Data and Notify Registered Observers """ Process received Data and Notify Registered Observers
Arguments: Arguments:
@ -77,6 +69,12 @@ class RFM69Receiver(object):
msg = {} msg = {}
msg['sid'] = sid msg['sid'] = sid
msg['rssi'] = rssi msg['rssi'] = rssi
try:
data = rdata.decode("ascii")
except UnicodeDecodeError:
data = ""
if (data.find(';') != -1 and data.find('=') != -1): if (data.find(';') != -1 and data.find('=') != -1):
values = data.split(";") values = data.split(";")
for value in values: for value in values:
@ -88,13 +86,29 @@ class RFM69Receiver(object):
else: else:
msg[vsplit[0]] = int(vsplit[1].rstrip()) msg[vsplit[0]] = int(vsplit[1].rstrip())
else: else:
bdata = self._rawbytes(data) self._debug("Interpreting " + str(len(rdata)) + " Bytes of Binary Data from " + str(sid) + ": " + pformat(rdata))
msg['t'] = int.from_bytes(bdata[0:3], byteorder='little', signed=True)/100 if len(rdata) == 9:
msg['p'] = int.from_bytes(bdata[4:7], byteorder='little', signed=True)/100 voltage, temp, humidity = struct.unpack('<Bll', rdata)
msg['h'] = int.from_bytes(bdata[8:11], byteorder='little', signed=True)/100 msg['v'] = voltage*20/1000
msg['v'] = int.from_bytes(bdata[12:15], byteorder='little', signed=True)/1000 msg['t'] = temp/100
msg['h'] = humidity/100
elif len(rdata) == 13:
voltage, temp, humidity, pressure = struct.unpack('<Blll', rdata)
msg['v'] = voltage*20/1000
msg['t'] = temp/100
msg['h'] = humidity/100
msg['p'] = pressure/100
elif len(rdata) == 16:
temp, pressure, humidity, voltage = struct.unpack('<llll', rdata)
msg['t'] = temp/100
msg['p'] = pressure/100
msg['h'] = humidity/100
msg['v'] = voltage/1000
else:
self._debug("Unknown data Format, could not decode!")
for observer in self.__observers: if (msg['v'] < 4 and msg['h'] <= 100):
for observer in self.__observers:
observer.notify(msg) observer.notify(msg)
def attach_observer(self, obs): def attach_observer(self, obs):
@ -118,16 +132,13 @@ class RFM69Receiver(object):
sid = self.__rfm.SENDERID sid = self.__rfm.SENDERID
rssi = self.__rfm.RSSI rssi = self.__rfm.RSSI
rdata = bytes(self.__rfm.DATA)
data = ""
for char in self.__rfm.DATA:
data += chr(char)
if self.__rfm.ACKRequested(): if self.__rfm.ACKRequested():
self.__rfm.sendACK() self.__rfm.sendACK()
if rssi != 0: if rssi != 0:
self._process(sid, data, rssi) self._process(sid, rdata, rssi)
def stop(self): def stop(self):
""" Stop the Receiving Loop """ """ Stop the Receiving Loop """
@ -145,5 +156,5 @@ class LogConsole(object):
def notify(msg): def notify(msg):
""" Pretty-Print the received Data """ """ Pretty-Print the received Data """
print('[' + time.strftime('%H:%M:%S %d %b %Y') + '] Message Received: ', end='') print('[' + time.strftime('%H:%M:%S %d %b %Y') + '][NFO] Message Received: ', end='')
pprint(msg) pprint(msg)