Rewrite, refactoring
This commit is contained in:
parent
5aa901b68b
commit
a79cca2d1f
3 changed files with 314 additions and 351 deletions
|
@ -93,7 +93,6 @@ class RcProtocol:
|
||||||
if not match:
|
if not match:
|
||||||
return None, None, None
|
return None, None, None
|
||||||
|
|
||||||
print("code: ", dec)
|
|
||||||
if re.match("^" + self._pattern + "$", dec):
|
if re.match("^" + self._pattern + "$", dec):
|
||||||
rep = True
|
rep = True
|
||||||
if (self._lastdecode != dec) or (time.time() - self._lastdecodetime > 0.5):
|
if (self._lastdecode != dec) or (time.time() - self._lastdecodetime > 0.5):
|
||||||
|
@ -104,64 +103,27 @@ class RcProtocol:
|
||||||
|
|
||||||
return None, None, None
|
return None, None, None
|
||||||
|
|
||||||
def decode(self, pulsetrain):
|
def _build_frame(self, symbols, timebase=None, repetitions=None):
|
||||||
pass
|
|
||||||
|
|
||||||
def encode(self, args):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class IT32(RcProtocol): #switch1
|
|
||||||
def __init__(self):
|
|
||||||
self._name = "it32"
|
|
||||||
self._timebase = 250
|
|
||||||
self._repetitions = 4
|
|
||||||
self._pattern = "[01]{32}"
|
|
||||||
self._symbols = {
|
|
||||||
'0': [1, 1, 1, 5],
|
|
||||||
'1': [1, 5, 1, 1],
|
|
||||||
}
|
|
||||||
RcProtocol.__init__(self)
|
|
||||||
self._parser.add_argument("-c", "--code")
|
|
||||||
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 __encode(self, code):
|
|
||||||
self._reset()
|
self._reset()
|
||||||
self._add_pulses([1, 11])
|
|
||||||
self._add_symbols(code)
|
if hasattr(self, '_header'):
|
||||||
self._add_pulses([1, 39])
|
self._add_pulses(self._header)
|
||||||
|
self._add_symbols(symbols)
|
||||||
|
if hasattr(self, '_footer'):
|
||||||
|
self._add_pulses(self._footer)
|
||||||
self._add_finish()
|
self._add_finish()
|
||||||
return self._ookdata, self._timebase, self._repetitions
|
if repetitions is None:
|
||||||
|
repetitions = self._repetitions
|
||||||
def encode(self, args):
|
return self._ookdata * repetitions, timebase if timebase else self._timebase
|
||||||
if hasattr(args, "code") and args.code:
|
|
||||||
if re.match("^[01]{32}$", args.code):
|
|
||||||
return self.__encode(args.code)
|
|
||||||
|
|
||||||
code = ""
|
|
||||||
code += "{:026b}".format(args.id)
|
|
||||||
code += "0" #group
|
|
||||||
code += "1" if args.state != 0 else "0"
|
|
||||||
code += "{:04b}".format(args.unit - 1)
|
|
||||||
return self.__encode(code)
|
|
||||||
|
|
||||||
def decode(self, pulsetrain):
|
def decode(self, pulsetrain):
|
||||||
code, tb, rep = self._decode_symbols(pulsetrain[0:-2])
|
pass
|
||||||
if code:
|
|
||||||
return {
|
|
||||||
"protocol": self._name,
|
|
||||||
"code": code,
|
|
||||||
"timebase": tb,
|
|
||||||
"id": int(code[0:26], 2),
|
|
||||||
"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 encode(self, params):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class TristateBase(RcProtocol): #Baseclass for old intertechno, Brennenstuhl, ...
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._name = "ittristate"
|
|
||||||
self._timebase = 300
|
self._timebase = 300
|
||||||
self._repetitions = 4
|
self._repetitions = 4
|
||||||
self._pattern = "[01fF]{12}"
|
self._pattern = "[01fF]{12}"
|
||||||
|
@ -171,55 +133,148 @@ class ITTristate(RcProtocol): #old intertechno systems
|
||||||
'f': [1, 4, 4, 1],
|
'f': [1, 4, 4, 1],
|
||||||
'F': [1, 4, 4, 1],
|
'F': [1, 4, 4, 1],
|
||||||
}
|
}
|
||||||
|
self._footer = [1, 31]
|
||||||
RcProtocol.__init__(self)
|
RcProtocol.__init__(self)
|
||||||
self._parser.add_argument("-c", "--code")
|
|
||||||
self._parser.add_argument("-o", "--house")
|
|
||||||
self._parser.add_argument("-g", "--group", type=int)
|
|
||||||
self._parser.add_argument("-u", "--unit", type=int)
|
|
||||||
self._parser.add_argument("-s", "--state", type=int)
|
|
||||||
|
|
||||||
def decode(self, pulsetrain):
|
def _encode_int(self, ival, digits):
|
||||||
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, self._timebase, self._repetitions
|
|
||||||
|
|
||||||
def __encode_int(self, ival, digits):
|
|
||||||
code = ""
|
code = ""
|
||||||
for i in range(digits):
|
for i in range(digits):
|
||||||
code += "f" if (ival & 0x01) > 0 else "0"
|
code += "f" if (ival & 0x01) > 0 else "0"
|
||||||
ival >>= 1
|
ival >>= 1
|
||||||
return code
|
return code
|
||||||
|
|
||||||
def encode(self, args):
|
def _decode_int(self, tristateval):
|
||||||
if hasattr(args, 'code') and args.code:
|
i = 0
|
||||||
if re.match("^[01Ff]{12}$", args.code):
|
while tristateval != "":
|
||||||
return self.__encode(args.code)
|
i <<= 1
|
||||||
|
if tristateval[-1] != '0':
|
||||||
|
i |= 1
|
||||||
|
tristateval = tristateval[:-1]
|
||||||
|
return i
|
||||||
|
|
||||||
code = ""
|
|
||||||
code += self.__encode_int(ord(args.house[0]) - ord('A'), 4)
|
|
||||||
if hasattr(args, 'group') and args.group:
|
|
||||||
code += self.__encode_int(args.group - 1, 2)
|
|
||||||
code += self.__encode_int(args.unit - 1, 2)
|
|
||||||
else:
|
|
||||||
code += self.__encode_int(args.unit - 1, 4)
|
|
||||||
code += "0f"
|
|
||||||
code += "ff" if args.state > 0 else "f0"
|
|
||||||
return self.__encode(code)
|
|
||||||
|
|
||||||
class Bistate24(RcProtocol):
|
class Tristate(TristateBase): #old intertechno
|
||||||
|
def __init__(self):
|
||||||
|
self._name = "tristate"
|
||||||
|
TristateBase.__init__(self)
|
||||||
|
self.params = [
|
||||||
|
('c', 'code'),
|
||||||
|
]
|
||||||
|
|
||||||
|
def encode(self, params, timebase=None, repetitions=None):
|
||||||
|
return self._build_frame(params["code"], timebase, repetitions)
|
||||||
|
|
||||||
|
def decode(self, pulsetrain):
|
||||||
|
symbols, tb, rep = self._decode_symbols(pulsetrain[0:-2])
|
||||||
|
if symbols:
|
||||||
|
return self._name, {"code": symbols}, tb, rep
|
||||||
|
|
||||||
|
class ITTristate(TristateBase): #old intertechno
|
||||||
|
def __init__(self):
|
||||||
|
self._name = "ittristate"
|
||||||
|
TristateBase.__init__(self)
|
||||||
|
self.params = [
|
||||||
|
('o', 'house'), #A-P
|
||||||
|
('g', 'group'), #1-4
|
||||||
|
('u', 'unit'), #1-4
|
||||||
|
('a', 'command'), #on|off
|
||||||
|
]
|
||||||
|
|
||||||
|
def encode(self, params, timebase=None, repetitions=None):
|
||||||
|
symbols = ""
|
||||||
|
symbols += self._encode_int(ord(params["house"][0]) - ord('A'), 4)
|
||||||
|
symbols += self._encode_int(int(params["unit"]) - 1, 2)
|
||||||
|
symbols += self._encode_int(int(params["group"]) - 1, 2)
|
||||||
|
symbols += "0f"
|
||||||
|
symbols += "ff" if params["command"] == "on" else "f0"
|
||||||
|
return self._build_frame(symbols, timebase, repetitions)
|
||||||
|
|
||||||
|
def decode(self, pulsetrain):
|
||||||
|
symbols, tb, rep = self._decode_symbols(pulsetrain[0:-2])
|
||||||
|
if symbols:
|
||||||
|
params = {
|
||||||
|
"house": chr(self._decode_int(symbols[:4]) + ord('A')),
|
||||||
|
"unit": self._decode_int(symbols[4:6]) + 1,
|
||||||
|
"group": self._decode_int(symbols[6:8]) + 1,
|
||||||
|
"command": "on" if symbols[10:12].upper() == "FF" else "off",
|
||||||
|
}
|
||||||
|
return self._name, params, tb, rep
|
||||||
|
|
||||||
|
class PPM1(RcProtocol): #Intertechno, Hama, ...
|
||||||
|
'''
|
||||||
|
PDM1: Pulse Position 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._timebase = 250
|
||||||
|
self._repetitions = 4
|
||||||
|
self._pattern = "[01]{32}"
|
||||||
|
self._header = [1, 11]
|
||||||
|
self._symbols = {
|
||||||
|
'0': [1, 1, 1, 5],
|
||||||
|
'1': [1, 5, 1, 1],
|
||||||
|
}
|
||||||
|
self._footer = [1, 39]
|
||||||
|
RcProtocol.__init__(self)
|
||||||
|
|
||||||
|
class Intertechno(PPM1):
|
||||||
|
def __init__(self):
|
||||||
|
PPM1.__init__(self)
|
||||||
|
self._name = "intertechno"
|
||||||
|
self._timebase = 275
|
||||||
|
self.params = [
|
||||||
|
('i', 'id'),
|
||||||
|
('u', 'unit'),
|
||||||
|
('a', 'command'),
|
||||||
|
]
|
||||||
|
|
||||||
|
def _encode_unit(self, unit):
|
||||||
|
return "{:04b}".format(int(unit) - 1)
|
||||||
|
|
||||||
|
def _decode_unit(self, unit):
|
||||||
|
return int(unit, 2) + 1
|
||||||
|
|
||||||
|
def encode(self, params, timebase=None, repetitions=None):
|
||||||
|
symbols = ""
|
||||||
|
symbols += "{:026b}".format(int(params["id"]))
|
||||||
|
symbols += "0" #group
|
||||||
|
symbols += "1" if params["command"] == "on" else "0"
|
||||||
|
symbols += self._encode_unit(params["unit"])
|
||||||
|
return self._build_frame(symbols, timebase, repetitions)
|
||||||
|
|
||||||
|
def decode(self, pulsetrain):
|
||||||
|
symbols, tb, rep = self._decode_symbols(pulsetrain[2:-2])
|
||||||
|
if symbols:
|
||||||
|
params = {
|
||||||
|
"id": int(symbols[:26], 2),
|
||||||
|
"unit": self._decode_unit(symbols[28:32]),
|
||||||
|
"command": "on" if symbols[27] == "1" else "off"
|
||||||
|
}
|
||||||
|
return self._name, params, tb, rep
|
||||||
|
|
||||||
|
class Hama(Intertechno):
|
||||||
|
def __init__(self):
|
||||||
|
Intertechno.__init__(self)
|
||||||
|
self._name = "hama"
|
||||||
|
self._timebase = 250
|
||||||
|
|
||||||
|
def _encode_unit(self, unit):
|
||||||
|
return "{:04b}".format(16 - int(unit))
|
||||||
|
|
||||||
|
def _decode_unit(self, unit):
|
||||||
|
return 16 - int(unit, 2)
|
||||||
|
|
||||||
|
|
||||||
|
class PWM1(RcProtocol):
|
||||||
|
'''
|
||||||
|
PWM1: Pulse Width Modulation
|
||||||
|
Wide pulse -> 1, small pulse -> 0
|
||||||
|
Frame: header, payload, footer
|
||||||
|
Used by Intertechno self learning, Hama, ...
|
||||||
|
'''
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._name = "bistate24"
|
|
||||||
self._timebase = 300
|
self._timebase = 300
|
||||||
self._repetitions = 6
|
self._repetitions = 6
|
||||||
self._pattern = "[01]{24}"
|
self._pattern = "[01]{24}"
|
||||||
|
@ -227,182 +282,144 @@ class Bistate24(RcProtocol):
|
||||||
'1': [3, 1],
|
'1': [3, 1],
|
||||||
'0': [1, 3],
|
'0': [1, 3],
|
||||||
}
|
}
|
||||||
|
self._footer = [1, 31]
|
||||||
RcProtocol.__init__(self)
|
RcProtocol.__init__(self)
|
||||||
self._parser.add_argument("-c", "--code", required=True)
|
|
||||||
|
class Logilight(PWM1):
|
||||||
|
def __init__(self):
|
||||||
|
PWM1.__init__(self)
|
||||||
|
self._name = "logilight"
|
||||||
|
self.params = [
|
||||||
|
('i', 'id'),
|
||||||
|
('u', 'unit'),
|
||||||
|
('a', 'command'),
|
||||||
|
]
|
||||||
|
|
||||||
|
def _encode_unit(self, unit):
|
||||||
|
res = ""
|
||||||
|
mask = 0x01
|
||||||
|
while mask < 0x08:
|
||||||
|
res += '1' if ((int(unit) - 1) & mask) == 0 else '0'
|
||||||
|
mask <<= 1
|
||||||
|
return res
|
||||||
|
|
||||||
|
def _decode_unit(self, unit):
|
||||||
|
i = 0
|
||||||
|
while unit:
|
||||||
|
i <<= 1
|
||||||
|
if unit[-1] == '0':
|
||||||
|
i |= 1
|
||||||
|
unit = unit[:-1]
|
||||||
|
return i + 1
|
||||||
|
|
||||||
|
def encode(self, params, timebase=None, repetitions=None):
|
||||||
|
symbols = ""
|
||||||
|
symbols += "{:020b}".format(int(params["id"]))
|
||||||
|
symbols += "1" if params["command"] in ["on", "learn"] else "0"
|
||||||
|
symbols += self._encode_unit(params["unit"])
|
||||||
|
if (params["command"] == "learn"):
|
||||||
|
repetitions = 10
|
||||||
|
return self._build_frame(symbols, timebase, repetitions)
|
||||||
|
|
||||||
def decode(self, pulsetrain):
|
def decode(self, pulsetrain):
|
||||||
code, tb, rep = self._decode_symbols(pulsetrain[0:-2])
|
symbols, tb, rep = self._decode_symbols(pulsetrain[:-2])
|
||||||
if code:
|
if symbols:
|
||||||
return {
|
params = {
|
||||||
"protocol": self._name,
|
"id": int(symbols[:20], 2),
|
||||||
"code": code,
|
"unit": self._decode_unit(symbols[21:24]),
|
||||||
"timebase": tb,
|
"command": "on" if symbols[20] == "1" else "off"
|
||||||
}, rep
|
}
|
||||||
|
return self._name, params, tb, rep
|
||||||
|
|
||||||
def encode(self, args):
|
class Emylo(PWM1):
|
||||||
self._reset()
|
|
||||||
self._add_symbols(args.code)
|
|
||||||
self._add_pulses([1, 31])
|
|
||||||
self._add_finish()
|
|
||||||
return self._ookdata, self._timebase, self._repetitions
|
|
||||||
|
|
||||||
class Switch15(Bistate24): #e. g. logilight
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Bistate24.__init__(self)
|
PWM1.__init__(self)
|
||||||
self._name = "switch15"
|
|
||||||
#remove code argument
|
|
||||||
carg = self._parser._actions[-1]
|
|
||||||
carg.container._remove_action(carg)
|
|
||||||
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, rep = self._decode_symbols(pulsetrain[0:-2])
|
|
||||||
if 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,
|
|
||||||
}, rep
|
|
||||||
|
|
||||||
def encode(self, args):
|
|
||||||
self._reset()
|
|
||||||
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, self._timebase, 10 if args.state == 2 else self._repetitions
|
|
||||||
|
|
||||||
class Emylo(Bistate24):
|
|
||||||
def __init__(self):
|
|
||||||
Bistate24.__init__(self)
|
|
||||||
self._name = "emylo"
|
self._name = "emylo"
|
||||||
#remove code argument
|
self.params = [
|
||||||
carg = self._parser._actions[-1]
|
('i', 'id'),
|
||||||
carg.container._remove_action(carg)
|
('k', 'key'),
|
||||||
self._parser.add_argument("-i", "--id", type=int, required=True)
|
]
|
||||||
self._parser.add_argument("-k", "--key", required=True)
|
self.__keys = {'A': '0001', 'B': '0010', 'C': '0100', 'D': '1000'}
|
||||||
|
|
||||||
|
def encode(self, params, timebase=None, repetitions=None):
|
||||||
|
symbols = ""
|
||||||
|
symbols += "{:020b}".format(int(params["id"]))
|
||||||
|
if not params["key"] in self.__keys:
|
||||||
|
return
|
||||||
|
symbols += self.__keys[params["key"]]
|
||||||
|
return self._build_frame(symbols, timebase, repetitions)
|
||||||
|
|
||||||
def decode(self, pulsetrain):
|
def decode(self, pulsetrain):
|
||||||
code, tb, rep = self._decode_symbols(pulsetrain[0:-2])
|
symbols, tb, rep = self._decode_symbols(pulsetrain[:-2])
|
||||||
if code:
|
if symbols:
|
||||||
key = int(code[20:24], 2)
|
key = None
|
||||||
if key == 1:
|
for k in self.__keys:
|
||||||
key = 'A'
|
if self.__keys[k] == symbols[-4:]:
|
||||||
elif key == 2:
|
key = k
|
||||||
key = 'B'
|
break
|
||||||
elif key == 4:
|
print(k)
|
||||||
key = 'C'
|
print(symbols[-4:])
|
||||||
elif key == 8:
|
if key is None:
|
||||||
key = 'D'
|
|
||||||
else:
|
|
||||||
return
|
return
|
||||||
|
|
||||||
return {
|
params = {
|
||||||
"protocol": self._name,
|
"id": int(symbols[:20], 2),
|
||||||
"timebase": tb,
|
|
||||||
"id": int(code[0:20], 2),
|
|
||||||
"key": key,
|
"key": key,
|
||||||
}, rep
|
}
|
||||||
|
return self._name, params, tb, rep
|
||||||
def encode(self, args):
|
|
||||||
self._reset()
|
|
||||||
sym = '{:020b}'.format(args.id)
|
|
||||||
if args.key == "A":
|
|
||||||
sym += "0001"
|
|
||||||
elif args.key == "B":
|
|
||||||
sym += "0010"
|
|
||||||
elif args.key == "C":
|
|
||||||
sym += "0100"
|
|
||||||
elif args.key == "D":
|
|
||||||
sym += "1000"
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
|
|
||||||
self._add_symbols(sym)
|
|
||||||
self._add_pulses([1, 31])
|
|
||||||
self._add_finish()
|
|
||||||
return self._ookdata, self._timebase, self._repetitions
|
|
||||||
|
|
||||||
class FS20(RcProtocol):
|
class FS20(RcProtocol):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._name = "fs20"
|
self._name = "fs20"
|
||||||
self._timebase = 200
|
self._timebase = 200
|
||||||
self._repetitions = 4
|
self._repetitions = 6
|
||||||
self._pattern = "0000000000001[01]{45}"
|
self._pattern = "0000000000001[01]{45}"
|
||||||
self._symbols = {
|
self._symbols = {
|
||||||
'0': [2, 2],
|
'0': [2, 2],
|
||||||
'1': [3, 3],
|
'1': [3, 3],
|
||||||
}
|
}
|
||||||
|
self._header = [2, 2] * 12 + [3, 3]
|
||||||
|
self._footer = [1, 100]
|
||||||
|
self.params = [
|
||||||
|
('i', 'id'),
|
||||||
|
('u', 'unit'),
|
||||||
|
('a', 'command')
|
||||||
|
]
|
||||||
RcProtocol.__init__(self)
|
RcProtocol.__init__(self)
|
||||||
self._parser.add_argument("-o", "--house", type=int, required=True)
|
|
||||||
self._parser.add_argument("-a", "--address", type=int, required=True)
|
|
||||||
self._parser.add_argument("-d", "--cmd", type=int, required=True)
|
|
||||||
|
|
||||||
def __encode_byte(self, b):
|
def __encode_byte(self, b):
|
||||||
self._add_symbols('{:08b}'.format(b))
|
b &= 0xFF
|
||||||
|
result = '{:08b}'.format(b)
|
||||||
par = 0
|
par = 0
|
||||||
while b:
|
while b:
|
||||||
par ^= 1
|
par ^= 1
|
||||||
b &= b-1
|
b &= b-1
|
||||||
self._add_symbols('1' if par != 0 else '0')
|
result += '1' if par != 0 else '0'
|
||||||
|
return result
|
||||||
|
|
||||||
def encode(self, args):
|
def encode(self, params, timebase=None, repetitions=None):
|
||||||
self._reset()
|
symbols = ""
|
||||||
self._add_symbols("0000000000001")
|
id = int(params["id"])
|
||||||
self.__encode_byte(args.house >> 8)
|
unit = int(params["unit"]) - 1
|
||||||
self.__encode_byte(args.house & 0xFF)
|
command = int(params["command"])
|
||||||
self.__encode_byte(args.address)
|
symbols += self.__encode_byte((id >> 8))
|
||||||
self.__encode_byte(args.cmd)
|
symbols += self.__encode_byte(id)
|
||||||
q = 0x06 + (args.house >> 8) + (args.house & 0xFF) + args.address + args.cmd
|
symbols += self.__encode_byte(unit)
|
||||||
self.__encode_byte(q & 0xFF)
|
symbols += self.__encode_byte(command)
|
||||||
self._add_pulses([1, 100])
|
q = 0x06 + (id >> 8) + (id & 0xFF) + unit + command
|
||||||
self._add_finish()
|
symbols += self.__encode_byte(q)
|
||||||
return self._ookdata, self._timebase, self._repetitions
|
return self._build_frame(symbols, timebase, repetitions)
|
||||||
|
|
||||||
def decode(self, pulsetrain):
|
def decode(self, pulsetrain):
|
||||||
code, tb, rep = self._decode_symbols(pulsetrain[0:-2])
|
code, tb, rep = self._decode_symbols(pulsetrain[0:-2])
|
||||||
|
print(code)
|
||||||
if code:
|
if code:
|
||||||
return {
|
params = {
|
||||||
"protocol": self._name,
|
"house": int(code[13:21] + code[22:30] , 2),
|
||||||
"code": code,
|
"unit": int(code[31:39], 2) + 1,
|
||||||
"timebase": tb,
|
"command": int(code[40:48], 2),
|
||||||
"housecode": int(code[13:21] + code[22:30] , 2),
|
}
|
||||||
"address": int(code[31:39], 2),
|
return self._name, params, tb, rep
|
||||||
"cmd": int(code[40:48], 2),
|
|
||||||
}, rep
|
|
||||||
|
|
||||||
class Voltcraft(RcProtocol):
|
class Voltcraft(RcProtocol):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -507,61 +524,28 @@ class PCPIR(RcProtocol): #pilota casa PIR sensor
|
||||||
self._add_finish()
|
self._add_finish()
|
||||||
return self._ookdata, self._timebase, self._repetitions
|
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 = [
|
protocols = [
|
||||||
#IT32(),
|
Tristate(),
|
||||||
#Switch15(),
|
ITTristate(),
|
||||||
#ITTristate(),
|
Intertechno(),
|
||||||
|
Hama(),
|
||||||
|
Logilight(),
|
||||||
|
Emylo(),
|
||||||
|
|
||||||
#Voltcraft(),
|
#Voltcraft(),
|
||||||
#FS20(),
|
|
||||||
#Emylo(),
|
|
||||||
#PDM32(),
|
#PDM32(),
|
||||||
#Bistate24(),
|
|
||||||
#PCPIR(),
|
#PCPIR(),
|
||||||
PDM1(),
|
#PDM1(),
|
||||||
|
FS20(),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def get_protocol(name):
|
||||||
|
for p in protocols:
|
||||||
|
if p._name == name:
|
||||||
|
return p
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
RXDATARATE = 20.0 #kbit/s
|
RXDATARATE = 20.0 #kbit/s
|
||||||
class RfmPulseTRX(threading.Thread):
|
class RfmPulseTRX(threading.Thread):
|
||||||
def __init__(self, module, rxcb, frequency):
|
def __init__(self, module, rxcb, frequency):
|
||||||
|
@ -603,22 +587,25 @@ class RfmPulseTRX(threading.Thread):
|
||||||
for b in fifo:
|
for b in fifo:
|
||||||
mask = 0x80
|
mask = 0x80
|
||||||
while mask != 0:
|
while mask != 0:
|
||||||
#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
|
newbit = (b & mask) != 0
|
||||||
|
|
||||||
|
''' filter
|
||||||
|
bitfifo <<= 1
|
||||||
|
if newbit:
|
||||||
|
bitfifo |= 1
|
||||||
|
v = bitfifo & 0x3
|
||||||
|
c = 0
|
||||||
|
while v > 0:
|
||||||
|
v &= v - 1
|
||||||
|
c += 1
|
||||||
|
'''
|
||||||
|
|
||||||
if newbit == bit:
|
if newbit == bit:
|
||||||
cnt += 1
|
cnt += 1
|
||||||
else:
|
else:
|
||||||
if cnt < 150*RXDATARATE/1000: #<150 us
|
if cnt < 150*RXDATARATE/1000: #<150 us
|
||||||
train *= 0 #clear
|
train *= 0 #clear
|
||||||
elif cnt > 3000*RXDATARATE/1000:
|
elif cnt > 4000*RXDATARATE/1000:
|
||||||
if not bit:
|
if not bit:
|
||||||
train.append(cnt)
|
train.append(cnt)
|
||||||
if len(train) > 20:
|
if len(train) > 20:
|
||||||
|
@ -630,17 +617,13 @@ class RfmPulseTRX(threading.Thread):
|
||||||
bit = not bit
|
bit = not bit
|
||||||
mask >>= 1
|
mask >>= 1
|
||||||
|
|
||||||
def send(self, train, timebase, repetitions):
|
def send(self, train, timebase):
|
||||||
self.__event.clear()
|
self.__event.clear()
|
||||||
self.__rfm.set_params(
|
self.__rfm.set_params(
|
||||||
Datarate = 1000.0 / timebase
|
Datarate = 1000.0 / timebase
|
||||||
)
|
)
|
||||||
self.__event.set()
|
self.__event.set()
|
||||||
self.__rfm.send(train * repetitions)
|
self.__rfm.send(train)
|
||||||
|
|
||||||
class RCStruct:
|
|
||||||
def __init__(self, **entries):
|
|
||||||
self.__dict__.update(entries)
|
|
||||||
|
|
||||||
class RcTransceiver(threading.Thread):
|
class RcTransceiver(threading.Thread):
|
||||||
def __init__(self, module, frequency, rxcallback):
|
def __init__(self, module, frequency, rxcallback):
|
||||||
|
@ -669,40 +652,18 @@ class RcTransceiver(threading.Thread):
|
||||||
for p in protocols:
|
for p in protocols:
|
||||||
dec = p.decode(train)
|
dec = p.decode(train)
|
||||||
if dec:
|
if dec:
|
||||||
|
print(dec)
|
||||||
succ = True
|
succ = True
|
||||||
if not dec[1]: #repeated?
|
|
||||||
res.append(dec[0])
|
|
||||||
return res, succ
|
return res, succ
|
||||||
|
|
||||||
def send_dict(self, dict):
|
def send(self, protocol, params, timebase=None, repeats=None):
|
||||||
s = RCStruct(**dict)
|
proto = get_protocol(protocol)
|
||||||
for p in protocols:
|
if proto:
|
||||||
if p._name == s.protocol:
|
|
||||||
try:
|
try:
|
||||||
txdata, tb, rep = p.encode(s)
|
txdata, tb = proto.encode(params, timebase, repeats)
|
||||||
if hasattr(s, "timebase"):
|
self.__rfmtrx.send(txdata, tb)
|
||||||
tb = s.timebase
|
|
||||||
if hasattr(s, "repeats"):
|
|
||||||
rep = s.repeats
|
|
||||||
print("repeats", rep)
|
|
||||||
self.__rfmtrx.send(txdata, tb, rep)
|
|
||||||
except:
|
except:
|
||||||
print("Error in args!")
|
print("Encode error")
|
||||||
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):
|
def run(self):
|
||||||
while True:
|
while True:
|
||||||
|
@ -717,8 +678,4 @@ class RcTransceiver(threading.Thread):
|
||||||
if (train != None):
|
if (train != None):
|
||||||
for i, v in enumerate(train):
|
for i, v in enumerate(train):
|
||||||
train[i] = int(v * 1000 / RXDATARATE) #convert to microseconds
|
train[i] = int(v * 1000 / RXDATARATE) #convert to microseconds
|
||||||
dec = self.__decode(train)
|
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)
|
|
|
@ -14,7 +14,6 @@ parser.add_argument("-r", "--repeats", type=int, help=u"number of repetitions")
|
||||||
parser.add_argument("-m", "--module", type=int, metavar="1-4", help=u"RaspyRFM module 1-4", default=1)
|
parser.add_argument("-m", "--module", type=int, metavar="1-4", help=u"RaspyRFM module 1-4", default=1)
|
||||||
parser.add_argument("-f", "--frequency", type=float, help=u"frequency in MHz", default=433.92)
|
parser.add_argument("-f", "--frequency", type=float, help=u"frequency in MHz", default=433.92)
|
||||||
parser.add_argument("-p", "--protocol", help=u"Protocol for sending")
|
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()
|
args, remainargs = parser.parse_known_args()
|
||||||
|
|
||||||
def rxcb(dec, train):
|
def rxcb(dec, train):
|
||||||
|
@ -29,17 +28,25 @@ if not raspyrfm_test(args.module, RFM69):
|
||||||
|
|
||||||
rctrx = rcprotocols.RcTransceiver(args.module, args.frequency, rxcb)
|
rctrx = rcprotocols.RcTransceiver(args.module, args.frequency, rxcb)
|
||||||
|
|
||||||
if len(remainargs) > 0:
|
if args.protocol:
|
||||||
rctrx.send_args(args.protocol, remainargs, args.timebase, args.repeats)
|
proto = rcprotocols.get_protocol(args.protocol)
|
||||||
|
if proto:
|
||||||
|
parser2 = ArgumentParser()
|
||||||
|
for param in proto.params:
|
||||||
|
parser2.add_argument("-" + param[0], "--" + param[1], required=True)
|
||||||
|
params = parser2.parse_args(remainargs)
|
||||||
|
rctrx.send(args.protocol, params.__dict__, args.timebase, args.repeats)
|
||||||
|
else:
|
||||||
|
print("Unknown protocol.")
|
||||||
del rctrx
|
del rctrx
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
state = 1
|
state = "on"
|
||||||
while True:
|
while True:
|
||||||
time.sleep(10)
|
time.sleep(15)
|
||||||
|
|
||||||
rctrx.send_dict({"protocol": "ittristate", "house": "A", "unit": 1, "state": state})
|
rctrx.send("ittristate", {"house": "A", "group": 1, "unit": 1, "command": state})
|
||||||
if (state == 1):
|
if (state == "on"):
|
||||||
state = 0
|
state = "off"
|
||||||
else:
|
else:
|
||||||
state = 1
|
state = "on"
|
|
@ -10,7 +10,7 @@ from argparse import ArgumentParser
|
||||||
parser = ArgumentParser()
|
parser = ArgumentParser()
|
||||||
parser.add_argument("-m", "--module", type=int, metavar="1-4", help=u"RaspyRFM module 1-4", default=1)
|
parser.add_argument("-m", "--module", type=int, metavar="1-4", help=u"RaspyRFM module 1-4", default=1)
|
||||||
parser.add_argument("-f", "--frequency", type=float, help=u"frequency in MHz", default=433.92)
|
parser.add_argument("-f", "--frequency", type=float, help=u"frequency in MHz", default=433.92)
|
||||||
args, remargs = parser.parse_known_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
srvsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
srvsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
srvsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
srvsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||||
|
@ -39,11 +39,10 @@ class clientthread(threading.Thread):
|
||||||
if len(chunk) == 0:
|
if len(chunk) == 0:
|
||||||
del self.__socket
|
del self.__socket
|
||||||
break
|
break
|
||||||
print(chunk)
|
|
||||||
try:
|
try:
|
||||||
lock.acquire()
|
lock.acquire()
|
||||||
rctrx.send_dict(json.loads(chunk))
|
d = json.loads(chunk)
|
||||||
txdata = rcprotocols.encode_dict(json.loads(chunk))
|
rctrx.send(d["protocol"], d["params"])
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
lock.release()
|
lock.release()
|
||||||
|
|
Loading…
Reference in a new issue