@@ -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