From 5aa901b68b18b64f7dc282ece2b11a214850cf2e Mon Sep 17 00:00:00 2001 From: "S. Seegel" Date: Mon, 30 Nov 2020 19:25:11 +0100 Subject: [PATCH] refactor protocols --- apps/rcprotocols.py | 304 ++++++++++++++++++++++++++++++-------------- apps/rcpulse.py | 143 +++------------------ apps/rfmnodered.py | 31 ++--- raspyrfm/rfm69.py | 7 +- rcpulse.py | 121 ------------------ 5 files changed, 240 insertions(+), 366 deletions(-) delete mode 100755 rcpulse.py diff --git a/apps/rcprotocols.py b/apps/rcprotocols.py index a148054..3e0a3df 100644 --- a/apps/rcprotocols.py +++ b/apps/rcprotocols.py @@ -2,6 +2,7 @@ import re from argparse import ArgumentParser from raspyrfm import * import threading +import time class RcProtocol: def __init__(self): @@ -10,6 +11,8 @@ class RcProtocol: self.__bbuf = 0 self.__bval = 0 self._parser = ArgumentParser() + self._lastdecode = None + self._lastdecodetime = 0 sympulses = [] for i in self._symbols: @@ -88,12 +91,18 @@ class RcProtocol: break if not match: - return None, None + return None, None, None + print("code: ", dec) if re.match("^" + self._pattern + "$", dec): - return dec, int(1.0 * sumpulse / sumstep) + rep = True + if (self._lastdecode != dec) or (time.time() - self._lastdecodetime > 0.5): + self._lastdecode = dec + rep = False + self._lastdecodetime = time.time() + return dec, int(1.0 * sumpulse / sumstep), rep - return None, None + return None, None, None def decode(self, pulsetrain): pass @@ -123,7 +132,7 @@ class IT32(RcProtocol): #switch1 self._add_symbols(code) self._add_pulses([1, 39]) self._add_finish() - return self._ookdata + return self._ookdata, self._timebase, self._repetitions def encode(self, args): if hasattr(args, "code") and args.code: @@ -138,7 +147,7 @@ class IT32(RcProtocol): #switch1 return self.__encode(code) def decode(self, pulsetrain): - code, tb = self._decode_symbols(pulsetrain[0:-2]) + code, tb, rep = self._decode_symbols(pulsetrain[0:-2]) if code: return { "protocol": self._name, @@ -148,7 +157,7 @@ class IT32(RcProtocol): #switch1 "group": int(code[26:27], 2), "state": int(code[27:28], 2), "unit": int(code[28:32], 2) + 1, - } + }, rep class ITTristate(RcProtocol): #old intertechno systems def __init__(self): @@ -170,20 +179,20 @@ class ITTristate(RcProtocol): #old intertechno systems self._parser.add_argument("-s", "--state", type=int) def decode(self, pulsetrain): - code, tb = self._decode_symbols(pulsetrain[0:-2]) + code, tb, rep = self._decode_symbols(pulsetrain[0:-2]) if code: return { "protocol": self._name, "code": code, "timebase": tb, - } + }, rep def __encode(self, code): self._reset() self._add_symbols(code) self._add_pulses([1, 31]) self._add_finish() - return self._ookdata + return self._ookdata, self._timebase, self._repetitions def __encode_int(self, ival, digits): code = "" @@ -222,20 +231,20 @@ class Bistate24(RcProtocol): self._parser.add_argument("-c", "--code", required=True) def decode(self, pulsetrain): - code, tb = self._decode_symbols(pulsetrain[0:-2]) + code, tb, rep = self._decode_symbols(pulsetrain[0:-2]) if code: return { "protocol": self._name, "code": code, "timebase": tb, - } + }, rep def encode(self, args): self._reset() self._add_symbols(args.code) self._add_pulses([1, 31]) self._add_finish() - return self._ookdata + return self._ookdata, self._timebase, self._repetitions class Switch15(Bistate24): #e. g. logilight def __init__(self): @@ -249,7 +258,7 @@ class Switch15(Bistate24): #e. g. logilight self._parser.add_argument("-s", "--state", type=int, required=True) def decode(self, pulsetrain): - code, tb = self._decode_symbols(pulsetrain[0:-2]) + code, tb, rep = self._decode_symbols(pulsetrain[0:-2]) if code: state = int(code[20:21]) unit = int(code[21:24], 2) @@ -273,7 +282,7 @@ class Switch15(Bistate24): #e. g. logilight "id": int(code[0:20], 2), "unit": unit, "state": state, - } + }, rep def encode(self, args): self._reset() @@ -294,7 +303,7 @@ class Switch15(Bistate24): #e. g. logilight self._add_symbols(sym) self._add_pulses([1, 31]) self._add_finish() - return self._ookdata + return self._ookdata, self._timebase, 10 if args.state == 2 else self._repetitions class Emylo(Bistate24): def __init__(self): @@ -307,7 +316,7 @@ class Emylo(Bistate24): self._parser.add_argument("-k", "--key", required=True) def decode(self, pulsetrain): - code, tb = self._decode_symbols(pulsetrain[0:-2]) + code, tb, rep = self._decode_symbols(pulsetrain[0:-2]) if code: key = int(code[20:24], 2) if key == 1: @@ -326,7 +335,7 @@ class Emylo(Bistate24): "timebase": tb, "id": int(code[0:20], 2), "key": key, - } + }, rep def encode(self, args): self._reset() @@ -345,7 +354,7 @@ class Emylo(Bistate24): self._add_symbols(sym) self._add_pulses([1, 31]) self._add_finish() - return self._ookdata + return self._ookdata, self._timebase, self._repetitions class FS20(RcProtocol): def __init__(self): @@ -381,10 +390,10 @@ class FS20(RcProtocol): self.__encode_byte(q & 0xFF) self._add_pulses([1, 100]) self._add_finish() - return self._ookdata + return self._ookdata, self._timebase, self._repetitions def decode(self, pulsetrain): - code, tb = self._decode_symbols(pulsetrain[0:-2]) + code, tb, rep = self._decode_symbols(pulsetrain[0:-2]) if code: return { "protocol": self._name, @@ -393,7 +402,7 @@ class FS20(RcProtocol): "housecode": int(code[13:21] + code[22:30] , 2), "address": int(code[31:39], 2), "cmd": int(code[40:48], 2), - } + }, rep class Voltcraft(RcProtocol): def __init__(self): @@ -411,7 +420,7 @@ class Voltcraft(RcProtocol): self._parser.add_argument("-s", "--state", type=int, required=True) def decode(self, pulsetrain): - code, tb = self._decode_symbols(pulsetrain[1:-1]) + code, tb, rep = self._decode_symbols(pulsetrain[1:-1]) if code: return { "protocol": self._name, @@ -420,7 +429,7 @@ class Voltcraft(RcProtocol): "id": int(code[0:12][::-1], 2), "unit": int(code[12:14][::-1], 2) + 1, "state": int(code[14:17][::-1], 2) #0=off, 1=alloff, 2=on, 3=allon, 5=bright, 7=dim - } + }, rep def encode(self, args): if not (args.state in [0, 2]): @@ -438,7 +447,7 @@ class Voltcraft(RcProtocol): self._add_symbols(symbols) self._add_pulses([132]) self._add_finish() - return self._ookdata + return self._ookdata, self._timebase, self._repetitions class PDM32(RcProtocol): def __init__(self): @@ -454,20 +463,20 @@ class PDM32(RcProtocol): self._parser.add_argument("-c", "--code") def decode(self, pulsetrain): - code, tb = self._decode_symbols(pulsetrain[0:-2]) + code, tb, rep = self._decode_symbols(pulsetrain[0:-2]) if code: return { "protocol": self._name, "code": code, "timebase": tb, - } + }, rep def encode(self, args): self._reset() self._add_symbols(args.code) self._add_pulses([1, 11]) self._add_finish() - return self._ookdata + return self._ookdata, self._timebase, self._repetitions class PCPIR(RcProtocol): #pilota casa PIR sensor def __init__(self): @@ -483,68 +492,83 @@ class PCPIR(RcProtocol): #pilota casa PIR sensor self._parser.add_argument("-c", "--code", required=True) def decode(self, pulsetrain): - code, tb = self._decode_symbols(pulsetrain[0:-2]) + code, tb, rep = self._decode_symbols(pulsetrain[0:-2]) if code: return { "protocol": self._name, "code": code, "timebase": tb, - } + }, rep def encode(self, args): self._reset() self._add_symbols(args.code) self._add_pulses([1, 12]) self._add_finish() - return self._ookdata + return self._ookdata, self._timebase, self._repetitions + +class PDM1(RcProtocol): + ''' + PDM1: Pulse Distance Modulation + Every bit consists of 2 shortpulses. Long distance between these pulses 2 pulses -> 1, else -> 0 + Frame: header, payload, footer + Used by Intertechno self learning, Hama, ... + ''' + def __init__(self): + self._name = "pdm1" + self._timebase = 275 + self._repetitions = 4 + self._pattern = "[01]*" + self._symbols = { + '0': [1, 1, 1, 5], + '1': [1, 5, 1, 1], + } + self._header = [1, 11] + self._footer = [1, 39] + #self._values = [ + # ("c", "code") + #] + RcProtocol.__init__(self) + self._parser.add_argument("-c", "--code", required=True) + + def decode(self, pulsetrain): + print("decoding pwm 1") + code, tb, rep = self._decode_symbols(pulsetrain[0:-2]) + print(code) + if code: + return { + "protocol": self._name, + "code": code, + "timebase": tb, + }, rep + + def encode(self, args): + self._reset() + self._add_symbols(args.code) + self._add_pulses([1, 31]) + self._add_finish() + return self._ookdata, self._timebase, self._repetitions protocols = [ - IT32(), - Switch15(), - ITTristate(), - Voltcraft(), - FS20(), - Emylo(), - PDM32(), - Bistate24(), - PCPIR(), + #IT32(), + #Switch15(), + #ITTristate(), + #Voltcraft(), + #FS20(), + #Emylo(), + #PDM32(), + #Bistate24(), + #PCPIR(), + PDM1(), ] -def encode(protocol, args): - for p in protocols: - if (protocol): - if p._name == protocol: - return (p.encode(p._parser.parse_args(args)), p._timebase, p._repetitions) - -class RCStruct: - def __init__(self, **entries): - self.__dict__.update(entries) - -def encode_dict(dict): - s = RCStruct(**dict) - for p in protocols: - if p._name == s.protocol: - return (p.encode(s), p._timebase, p._repetitions) - -def decode(pulsetrain): - dec = None - res = [] - for p in protocols: - dec = p.decode(pulsetrain) - if dec: - res.append(dec) - - if len(res) > 0: - return res - -class PulseTRX(threading.Thread): - def __init__(self, module): - self.__trainbuf = [] +RXDATARATE = 20.0 #kbit/s +class RfmPulseTRX(threading.Thread): + def __init__(self, module, rxcb, frequency): self.__rfm = RaspyRFM(module, RFM69) self.__rfm.set_params( - Freq = 433.92, #MHz - Datarate = 20.0, #kbit/s - Bandwidth = 300, #kHz + Freq = frequency, #MHz + Bandwidth = 200, #kHz SyncPattern = [], RssiThresh = -105, #dBm ModulationType = rfm69.OOK, @@ -553,58 +577,148 @@ class PulseTRX(threading.Thread): Preamble = 0, TxPower = 13 ) + self.__rxtraincb = rxcb self.__event = threading.Event() self.__event.set() threading.Thread.__init__(self) self.daemon = True self.start() - def getEvents(self): - if len(self.__trainbuf) > 0: - train = self.__trainbuf.pop() - for i, v in enumerate(train): - train[i] = 50 * v - return decode(train) - def run(self): while True: self.__event.wait() - rfm.set_params( - Datarate = 20.0 #kbit/s + self.__rfm.set_params( + Datarate = RXDATARATE #kbit/s ) - rfm.start_receive(self.__rxcb) - + self.__rfm.start_receive(self.__rxcb) - def __cb(self, rfm): + def __rxcb(self, rfm): bit = False cnt = 1 train = [] - - while True: + bitfifo = 0 + while self.__event.isSet(): fifo = rfm.read_fifo_wait(64) - ba = bytearray() for b in fifo: mask = 0x80 while mask != 0: - if (b & mask) != 0: - ba.append(245) - else: - ba.append(10) + #bitfifo <<= 1 + #if (b & mask != 0): + # bitfifo |= 1 + #v = bitfifo & 0x3 + #c = 0 + #while v > 0: + # v &= v - 1 + # c += 1 + newbit = (b & mask) != 0 - if ((b & mask) != 0) == bit: + if newbit == bit: cnt += 1 else: - if cnt < 3: #<150 us + if cnt < 150*RXDATARATE/1000: #<150 us train *= 0 #clear - elif cnt > 50: + elif cnt > 3000*RXDATARATE/1000: if not bit: train.append(cnt) if len(train) > 20: - self.__trainbuf.append(list(train)) + self.__rxtraincb(train) train *= 0 #clear elif len(train) > 0 or bit: train.append(cnt) cnt = 1 bit = not bit mask >>= 1 + + def send(self, train, timebase, repetitions): + self.__event.clear() + self.__rfm.set_params( + Datarate = 1000.0 / timebase + ) + self.__event.set() + self.__rfm.send(train * repetitions) + +class RCStruct: + def __init__(self, **entries): + self.__dict__.update(entries) + +class RcTransceiver(threading.Thread): + def __init__(self, module, frequency, rxcallback): + threading.Thread.__init__(self) + self.__lock = threading.Lock() + self.__event = threading.Event() + self.__trainbuf = [] + self.daemon = True + self.start() + self.__rxcb = rxcallback + self.__rfmtrx = RfmPulseTRX(module, self.__pushPulseTrain, frequency) + + def __del__(self): + del self.__rfmtrx + + def __pushPulseTrain(self, train): + self.__lock.acquire() + self.__trainbuf.append(list(train)) + self.__event.set() + self.__lock.release() + + def __decode(self, train): + dec = None + res = [] + succ = False + for p in protocols: + dec = p.decode(train) + if dec: + succ = True + if not dec[1]: #repeated? + res.append(dec[0]) + return res, succ + + def send_dict(self, dict): + s = RCStruct(**dict) + for p in protocols: + if p._name == s.protocol: + try: + txdata, tb, rep = p.encode(s) + if hasattr(s, "timebase"): + tb = s.timebase + if hasattr(s, "repeats"): + rep = s.repeats + print("repeats", rep) + self.__rfmtrx.send(txdata, tb, rep) + except: + print("Error in args!") + break + + def send_args(self, protocol, args, timebase=None, repeats=None): + for p in protocols: + if p._name == protocol: + try: + txdata, tb, rep = p.encode(p._parser.parse_args(args)) + if timebase: + tb = timebase + if repeats: + rep = repeats + self.__rfmtrx.send(txdata, tb, rep) + except: + print("Error in args!") + break + + def run(self): + while True: + self.__event.wait() + self.__lock.acquire() + train = None + if len(self.__trainbuf) > 0: + train = self.__trainbuf.pop() + else: + self.__event.clear() + self.__lock.release() + if (train != None): + for i, v in enumerate(train): + train[i] = int(v * 1000 / RXDATARATE) #convert to microseconds + dec = self.__decode(train) + #dec[0]: array of decoded protocols + #dec[1]: true if at least 1 protocol was decoded + if (not dec[1]) or (len(dec[0]) > 0): + self.__rxcb(dec[0], train) \ No newline at end of file diff --git a/apps/rcpulse.py b/apps/rcpulse.py index da7b0d0..b933b60 100755 --- a/apps/rcpulse.py +++ b/apps/rcpulse.py @@ -3,7 +3,6 @@ from raspyrfm import * import sys import time -#import fs20 from argparse import ArgumentParser import wave, struct import threading @@ -18,137 +17,29 @@ parser.add_argument("-p", "--protocol", help=u"Protocol for sending") parser.add_argument("-w", "--write", help=u"write wavefile") args, remainargs = parser.parse_known_args() -txdata = None -if len(remainargs) > 0: - txdata = rcprotocols.encode(args.protocol, remainargs) - - if txdata is None: - print("invalid code!") - exit() +def rxcb(dec, train): + for p in dec: + print(p) + if len(dec) == 0: + print(train) if not raspyrfm_test(args.module, RFM69): print("Error! RaspyRFM not found") exit() -rfm = RaspyRFM(args.module, RFM69) -rfm.set_params( - Freq = args.frequency, #MHz - Datarate = 20.0, #kbit/s - Bandwidth = 300, #kHz - SyncPattern = [], - RssiThresh = -105, #dBm - ModulationType = rfm69.OOK, - OokThreshType = 1, #peak thresh - OokPeakThreshDec = 3, - Preamble = 0, - TxPower = 13 -) +rctrx = rcprotocols.RcTransceiver(args.module, args.frequency, rxcb) -if txdata: - rfm.set_params( - SyncPattern = [], - Datarate = 1000.0 / (args.timebase if args.timebase else txdata[1]) - ) - rep = (args.repeats if args.repeats else txdata[2]) - rfm.send(txdata[0] * rep) - print("Code sent!") +if len(remainargs) > 0: + rctrx.send_args(args.protocol, remainargs, args.timebase, args.repeats) + del rctrx exit() -trainbuf = [] - -class RxThread(threading.Thread): - def __init__(self): - self.__event = threading.Event() - self.__event.set() - threading.Thread.__init__(self) - - def __rxcb(self, rfm): - bit = False - cnt = 1 - train = [] - #if args.write: - # wf = wave.open(args.write, "wb") - # wf.setnchannels(1) - # wf.setsampwidth(1) - # wf.setframerate(20000) - #else: - wf = None - - while self.__event.isSet(): - fifo = rfm.read_fifo_wait(64) - ba = bytearray() - - for b in fifo: - mask = 0x80 - while mask != 0: - if (b & mask) != 0: - ba.append(245) - else: - ba.append(10) - - if ((b & mask) != 0) == bit: - cnt += 1 - else: - if cnt < 3: #<150 us - train *= 0 #clear - elif cnt > 50: - if not bit: - train.append(cnt) - if len(train) > 20: - trainbuf.append(list(train)) - train *= 0 #clear - elif len(train) > 0 or bit: - train.append(cnt) - cnt = 1 - bit = not bit - mask >>= 1 - - if wf: - wf.writeframesraw(ba) - wf.writeframes('') - - def run(self): - while True: - self.__event.wait() - rfm.set_params( - Datarate = 20.0 #kbit/s - ) - rfm.start_receive(self.__rxcb) - - def suspend(self): - self.__event.clear() - - def resume(self): - self.__event.set() - -rxthread = RxThread() -rxthread.daemon = True -rxthread.start() -lasttime = time.time() + 3 - +state = 1 while True: - time.sleep(0.1) - if len(trainbuf) > 0: - train = trainbuf.pop() - for i, v in enumerate(train): - train[i] = v * 50 - - dec = rcprotocols.decode(train) - if (dec): - print(dec) - else: - print(train) - - if time.time() > lasttime: - lasttime = time.time() + 3 - rxthread.suspend() - try: - txdata = rcprotocols.encode_dict({"protocol": "emylo", "id": 970046, "key": "A"}) - rfm.set_params( - Datarate = 1000.0 / txdata[1] - ) - rep = txdata[2] - rfm.send(txdata[0] * rep) - except: - pass - rxthread.resume() \ No newline at end of file + time.sleep(10) + + rctrx.send_dict({"protocol": "ittristate", "house": "A", "unit": 1, "state": state}) + if (state == 1): + state = 0 + else: + state = 1 \ No newline at end of file diff --git a/apps/rfmnodered.py b/apps/rfmnodered.py index 5bc84b5..3c654d0 100755 --- a/apps/rfmnodered.py +++ b/apps/rfmnodered.py @@ -9,27 +9,22 @@ from argparse import ArgumentParser parser = ArgumentParser() parser.add_argument("-m", "--module", type=int, metavar="1-4", help=u"RaspyRFM module 1-4", default=1) -parser.add_argument("-o", "--mode", help=u"Mode (rcpulse, lacrosse)", default="rcpulse") -args = parser.parse_known_args() +parser.add_argument("-f", "--frequency", type=float, help=u"frequency in MHz", default=433.92) +args, remargs = parser.parse_known_args() srvsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) srvsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) srvsock.bind(('', 1989)) srvsock.listen(5) -rfm = RaspyRFM(1, RFM69) -rfm.set_params( - Freq = 433.92, #MHz - Datarate = 20.0, #kbit/s - Bandwidth = 300, #kHz - SyncPattern = [], - RssiThresh = -105, #dBm - ModulationType = rfm69.OOK, - OokThreshType = 1, #peak thresh - OokPeakThreshDec = 3, - Preamble = 0, - TxPower = 13 -) +def rxcb(dec, train): + pass + +if not raspyrfm_test(args.module, RFM69): + print("Error! RaspyRFM not found") + exit() + +rctrx = rcprotocols.RcTransceiver(args.module, args.frequency, rxcb) lock = threading.Lock() @@ -47,12 +42,8 @@ class clientthread(threading.Thread): print(chunk) try: lock.acquire() + rctrx.send_dict(json.loads(chunk)) txdata = rcprotocols.encode_dict(json.loads(chunk)) - rfm.set_params( - SyncPattern = [], - Datarate = 1000.0 / txdata[1] - ) - rfm.send(txdata[0] * txdata[2]) except: pass lock.release() diff --git a/raspyrfm/rfm69.py b/raspyrfm/rfm69.py index e4acce4..30da88a 100644 --- a/raspyrfm/rfm69.py +++ b/raspyrfm/rfm69.py @@ -338,7 +338,6 @@ class Rfm69(threading.Thread): elif key == "Datarate": rate = int(round(FXOSC / (value * 1000))) self.__write_reg_word(RegBitrateMsb, rate) - print("written datarate") elif key == "Deviation": dev = int(round(value * 1000 / FSTEP)) @@ -530,9 +529,9 @@ class Rfm69(threading.Thread): b = self.read_fifo_wait() if b != 0: thresh += 1 - break; + break if i == 149: - break; + break #restore registers self.__write_reg(RegRssiThresh, rssithresh) @@ -556,7 +555,7 @@ class Rfm69(threading.Thread): self.__wait_int() self.__mutex.acquire() if self.__mode == MODE_RX: - break; + break def start_receive(self, cb): self.__start_rx(0) diff --git a/rcpulse.py b/rcpulse.py deleted file mode 100755 index c7e908a..0000000 --- a/rcpulse.py +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env python2.7 - -from raspyrfm import * -import sys -import time -from argparse import ArgumentParser - -parser = ArgumentParser() -parser.add_argument("-t", "--timebase", type=int, help=u"timebase in \u03bcs") -parser.add_argument("-r", "--repeats", type=int, help=u"number of repetitions") -parser.add_argument("code", nargs='*', help="code, e. g. '000000000FFF', 'A 1 2 on' or '10111100011101011111111110001110'") -args = parser.parse_args() - -txdata = None -if len(args.code) > 0: - txdata = None - for proto in protos: - data = proto.Encode(args.code) - if data: - txdata = data - break - - if txdata is None: - print("invalid code!") - exit() - -rfm = RaspyRFM(1, RFM69) -rfm.set_params( - Freq = 868.35, #MHz - Datarate = 20.0, #kbit/s - Bandwidth = 200, #kHz - SyncPattern = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07], - RssiThresh = -105, #dBm - ModulationType = rfm69.OOK, - OokThreshType = 1, #peak thresh - OokPeakThreshDec = 3, -) - -if txdata: - rfm.SetParams( - SyncPattern = [], - Datarate = 5.0 - ) - rep = (args.repeats if args.repeats else txdata[1]) - rfm.SendPacket(txdata[0] * rep) - print("Code sent!") - exit() - -def Decode(pulses): - if len(pulses) != 118: - return; - - b = "" - for p in pulses: - if (p>=6) and (p<=10): - b += "s" - elif (p > 10) and (p<15): - b += "l" - else: - b += '?' - s = "" - while len(b) > 0: - if b[:2] == 'ss': - s += '0' - elif b[:2] == 'll': - s += '1' - else: - s += '?' - b = b[2:] - print(s) - print("SYNC " + s[1:13] + " HC1 " + s[13:22] + " HC2 " + s[22:31] + - " ADR " + s[31:40]) - return - for i in range(len(pulses)): - pulses[i] *= 50 - - dec = None - for proto in protos: - dec = proto.Decode(pulses) - if dec: - print(dec) - - if not dec: - print("Len " + str(len(pulses)) + ": " + str(pulses)) - -while True: - data = rfm.receive_packet(400) - s = "" - - pulsecount = 3 - glitchcount = 0 - bit = True - pulses = [] - - for d in data[0]: - s += format(d, '08b') - mask = 0x80 - while mask > 0: - newbit = (d & mask) > 0 - - if glitchcount > 0: - glitchcount += 1 - if newbit == bit: - pulsecount += glitchcount - glitchcount = 0 - else: - if glitchcount == 3: - pulses.append(pulsecount) - if pulsecount > 50: - Decode(pulses) - pulses = [] - bit = newbit - pulsecount = 3 - glitchcount = 0 - else: - if newbit == bit: - pulsecount += 1 - else: - glitchcount = 1 - - mask >>= 1