Skip to content

Commit e1d56cf

Browse files
committed
updates Universal decoder so it will handle biphase nd also pulse width IR codes.
1 parent 8e929c1 commit e1d56cf

File tree

2 files changed

+185
-4
lines changed

2 files changed

+185
-4
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ __pycache__/
33
*.py[cod]
44
*$py.class
55

6+
.idea
7+
68
# C extensions
79
*.so
810

pyIRDecoder/universal.py

Lines changed: 183 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,179 @@ class Universal(protocol_base.IrProtocolBase):
3434
IR decoder for unknown protocols.
3535
"""
3636

37-
def decode(self, data, frequency):
37+
def __decode_1(self, norm_data):
38+
bit_encoding = 'pulsetime'
39+
bits = []
3840

39-
norm_data = utils.clean_code(data[:], self.tolerance)
40-
norm_data = utils.build_mce_rlc(norm_data)
41+
bursts = norm_data[2:]
42+
for i in range(0, len(bursts), 2):
43+
mark, space = bursts[i], bursts[i + 1]
44+
if [mark, space] not in bits and [mark, space] != norm_data[-2:]:
45+
bits += [[mark, space]]
46+
47+
timings = []
48+
49+
last_pair = bits[0]
50+
51+
for pair in bits[1:]:
52+
if (
53+
(pair[0] > 0 > last_pair[0] and pair[1] < 0 < last_pair[1]) or
54+
(pair[0] < 0 < last_pair[0] and pair[1] > 0 > last_pair[1])
55+
):
56+
bit_encoding = 'biphase'
57+
break
58+
59+
last_pair = pair
60+
61+
if bit_encoding == 'biphase':
62+
63+
if len(bits) > 2:
64+
for mark_1, space_1 in bits[:]:
65+
for mark_2, space_2 in bits:
66+
if mark_2 == mark_1 and space_2 == space_1:
67+
continue
68+
69+
if mark_1 > abs(space_2) and abs(space_1) > mark_2:
70+
mark = space_1 + mark_2
71+
space = mark_1 + space_2
72+
73+
elif mark_1 < abs(space_2) and abs(space_1) < mark_2:
74+
mark = mark_2 + space_1
75+
space = space_2 + mark_1
76+
77+
elif mark_1 // space_2 == -2 and space_2 * -2 == mark_1:
78+
mark = mark_1 // 2
79+
space = space_2
80+
81+
elif space_1 // mark_2 == -2 and space_1 * -2 == mark_2:
82+
space = space_1 // 2
83+
mark = mark_2
84+
85+
else:
86+
continue
87+
88+
if mark == 0 or space == 0:
89+
continue
90+
91+
if mark < 0 > space or mark > 0 < space:
92+
continue
93+
94+
if [mark, space] not in timings:
95+
timings += [[mark, space]]
96+
97+
if len(timings) == 1:
98+
timings += [[timings[0][1], timings[0][0]]]
99+
100+
if len(timings) > 2:
101+
for mark_1, space_1 in timings:
102+
for mark_2, space_2 in timings:
103+
if mark_1 == mark_2 and space_1 == space_2:
104+
continue
105+
106+
if mark_1 == mark_2 or space_1 == space_2:
107+
timings.remove([mark_2, space_2])
108+
109+
if len(timings) > 2:
110+
neg_count = 0
111+
pos_count = 0
112+
113+
for mark, space in timings[:]:
114+
if mark < 0:
115+
neg_count += 1
116+
else:
117+
pos_count += 1
118+
if [space, mark] not in timings:
119+
timings.remove([mark, space])
120+
121+
e_mark, e_space = timings[0]
122+
123+
offset = 0
124+
bursts = norm_data[1:-1]
125+
for i, timing in enumerate(bursts[:]):
126+
127+
if timing == e_space or timing == e_mark:
128+
continue
129+
130+
elif timing / e_mark == 2:
131+
bursts[i + offset] = e_mark
132+
bursts.insert(i + offset, e_mark)
133+
offset += 1
134+
135+
elif timing / e_space == 2:
136+
bursts[i + offset] = e_space
137+
bursts.insert(i + offset, e_space)
138+
offset += 1
139+
140+
elif timing > 0 < e_mark or timing < 0 > e_mark:
141+
timings = [timings[1], timings[0]]
142+
bursts[i + offset] = e_mark
143+
144+
elif timing > 0 < e_space or timing < 0 > e_space:
145+
timings = [timings[1], timings[0]]
146+
bursts[i + offset] = e_space
147+
148+
pairs = []
149+
pair = []
150+
for item in bursts:
151+
if pair:
152+
if pair[0] == e_mark:
153+
if item == e_space:
154+
pair += [item]
155+
pairs += [pair[:]]
156+
del pair[:]
157+
else:
158+
pair += [e_space]
159+
pairs += [pair[:]]
160+
del pair[:]
161+
pair += [item]
162+
163+
elif pair[0] == e_space:
164+
if item == e_mark:
165+
pair += [item]
166+
pairs += [pair[:]]
167+
del pair[:]
168+
else:
169+
pair += [e_mark]
170+
pairs += [pair[:]]
171+
del pair[:]
172+
pair += [item]
173+
else:
174+
pair += [item]
175+
176+
if pair:
177+
if len(pair) == 1:
178+
if pair[0] == e_mark:
179+
pair += [e_space]
180+
else:
181+
pair += [e_mark]
182+
pairs += [pair[:]]
183+
184+
else:
185+
pairs = []
186+
timings = bits[:2]
187+
188+
for i in range(0, len(norm_data), 2):
189+
mark = norm_data[i]
190+
space = norm_data[i + 1]
191+
192+
if [mark, space] in timings:
193+
pairs += [[mark, space]]
194+
195+
elif i + 1 == len(norm_data) - 1:
196+
for e_mark, e_space in timings:
197+
if mark == e_mark:
198+
pairs += [[mark, e_space]]
199+
break
200+
201+
code = 0
202+
203+
for i, pair in enumerate(pairs):
204+
bit = timings.index(pair)
205+
code = self._set_bit(code, i, bit)
206+
207+
return code
208+
209+
def __decode_2(self, norm_data):
41210

42211
for item in norm_data[:]:
43212
if norm_data.count(item) == 1:
@@ -70,8 +239,18 @@ def decode(self, data, frequency):
70239
mask <<= 1
71240
code |= mask
72241

73-
params = {'CODE': code, 'frequency': frequency}
242+
return code
243+
244+
def decode(self, data, frequency=0):
245+
norm_data = utils.clean_code(data[:], self.tolerance)
246+
norm_data = utils.build_mce_rlc(norm_data)
247+
248+
try:
249+
code = self.__decode_1(norm_data[:])
250+
except:
251+
code = self.__decode_2(norm_data[:])
74252

253+
params = {'CODE': code, 'frequency': frequency}
75254
code = protocol_base.IRCode(self, data, norm_data, params)
76255

77256
return code

0 commit comments

Comments
 (0)