From d7bdeb11be48bdf86cba78c2d372d8e2de41af93 Mon Sep 17 00:00:00 2001 From: Stefan Seegel Date: Tue, 11 Feb 2020 20:05:33 +0100 Subject: [PATCH] added PDM32 rc protocol added mqtt dashbutton app --- apps/mqttdash.py | 37 +++++++++++++ apps/rcprotocols.py | 123 ++++++++++++++++++++++++++------------------ apps/rcpulse.py | 6 ++- 3 files changed, 115 insertions(+), 51 deletions(-) create mode 100755 apps/mqttdash.py diff --git a/apps/mqttdash.py b/apps/mqttdash.py new file mode 100755 index 0000000..d92cf99 --- /dev/null +++ b/apps/mqttdash.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python2.7 + +import rcprotocols +import time +import paho.mqtt.client as mqtt + +mqttClient = mqtt.Client() +mqttClient.connect("localhost", 1883, 60) +mqttClient.loop_start() + +rx = rcprotocols.PulseReceiver(1) + +lastEvents = {} + +def publish(proto, code): + print("Publish: " + str(proto) + " / " + str(code)) + mqttClient.publish("home/rcbuttons/" + proto, code) + +while True: + time.sleep(0.1) + evts = rx.getEvents() + if evts: + for e in evts: + if e["protocol"] in lastEvents: + le = lastEvents[e["protocol"]] + if e["code"] != le["code"]: + publish(e["protocol"], e["code"]) + le["code"] = e["code"] + elif (time.time() - le["ts"] > 1): + publish(e["protocol"], e["code"]) + le["ts"] = time.time() + else: + lastEvents[e["protocol"]] = { + "ts": time.time(), + "code": e["code"] + } + publish(e["protocol"], e["code"]) diff --git a/apps/rcprotocols.py b/apps/rcprotocols.py index ad7013b..2cede00 100644 --- a/apps/rcprotocols.py +++ b/apps/rcprotocols.py @@ -1,5 +1,7 @@ import re from argparse import ArgumentParser +from raspyrfm import * +import threading class RcProtocol: def __init__(self): @@ -390,9 +392,9 @@ class Voltcraft(RcProtocol): self._add_finish() return self._ookdata -class Test(RcProtocol): +class PDM32(RcProtocol): def __init__(self): - self._name = "test" + self._name = "pdm32" self._timebase = 600 self._repetitions = 4 self._pattern = "[01]{32}" @@ -401,59 +403,16 @@ class Test(RcProtocol): '0': [2, 1], } RcProtocol.__init__(self) - self._parser.add_argument("-i", "--id", type=int, required=True) - self._parser.add_argument("-u", "--unit", type=int, required=True) - self._parser.add_argument("-s", "--state", type=int, required=True) def decode(self, pulsetrain): code, tb = self._decode_symbols(pulsetrain[0:-2]) if code: - print(code) - return code - state = int(code[20:21]) - unit = int(code[21:24], 2) - all = False - if unit == 7: - unit = 1 - elif unit == 3: - unit = 2 - elif unit == 5: - unit = 3 - elif unit == 6: - unit = 4 - else: - unit = 0 - state = not state - return { "protocol": self._name, "code": code, "timebase": tb, - "id": int(code[0:20], 2), - "unit": unit, - "state": state, } - def encode(self, args): - sym = '{:020b}'.format(args.id) - - if args.unit == 1: - unit = 7 - elif args.unit == 2: - unit = 3 - elif args.unit == 3: - unit = 5 - elif args.unit == 4: - unit = 6 - else: - raise Exception("invalid unit") - sym += '1' if args.state > 0 else '0' - sym += '{:03b}'.format(unit) - self._add_symbols(sym) - self._add_pulses([1, 31]) - self._add_finish() - return self._ookdata - protocols = [ IT32(), Switch15(), @@ -461,7 +420,7 @@ protocols = [ Voltcraft(), FS20(), Emylo(), - Test(), + PDM32(), ] def encode(protocol, args): @@ -472,11 +431,75 @@ def encode(protocol, args): def decode(pulsetrain): dec = None + res = [] for p in protocols: dec = p.decode(pulsetrain) if dec: - print(dec) + res.append(dec) - if not dec: - print(len(pulsetrain), pulsetrain) - \ No newline at end of file + if len(res) > 0: + return res + +class PulseReceiver(threading.Thread): + def __init__(self, module): + self.__trainbuf = [] + self.__rfm = RaspyRFM(module, RFM69) + self.__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 + ) + 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): + self.__rfm.start_receive(self.__cb) + + def __cb(self, rfm): + bit = False + cnt = 1 + train = [] + + while True: + 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: + self.__trainbuf.append(list(train)) + train *= 0 #clear + elif len(train) > 0 or bit: + train.append(cnt) + cnt = 1 + bit = not bit + mask >>= 1 diff --git a/apps/rcpulse.py b/apps/rcpulse.py index 5e91f97..f20b836 100755 --- a/apps/rcpulse.py +++ b/apps/rcpulse.py @@ -122,4 +122,8 @@ while True: for i, v in enumerate(train): train[i] = v * 50 - rcprotocols.decode(train) + dec = rcprotocols.decode(train) + if (dec): + print(dec) + else: + print(train)