51
51
52
52
"""
53
53
54
- # Pretend self matter because we may add object level config later.
55
- # pylint: disable=no-self-use
56
-
57
54
import array
58
55
import time
59
56
@@ -69,107 +66,115 @@ class IRNECRepeatException(Exception):
69
66
"""Exception when a NEC repeat is decoded"""
70
67
71
68
72
- class GenericDecode :
73
- """Generic decoding of infrared signals"""
74
-
75
- def bin_data (self , pulses ):
76
- """Compute bins of pulse lengths where pulses are +-25% of the average.
77
-
78
- :param list pulses: Input pulse lengths
79
- """
80
- bins = [[pulses [0 ], 0 ]]
81
-
82
- for _ , pulse in enumerate (pulses ):
83
- matchedbin = False
84
- # print(pulse, end=": ")
85
- for b , pulse_bin in enumerate (bins ):
86
- if pulse_bin [0 ] * 0.75 <= pulse <= pulse_bin [0 ] * 1.25 :
87
- # print("matches bin")
88
- bins [b ][0 ] = (pulse_bin [0 ] + pulse ) // 2 # avg em
89
- bins [b ][1 ] += 1 # track it
90
- matchedbin = True
91
- break
92
- if not matchedbin :
93
- bins .append ([pulse , 1 ])
94
- # print(bins)
95
- return bins
69
+ def bin_data (pulses ):
70
+ """Compute bins of pulse lengths where pulses are +-25% of the average.
96
71
97
- def decode_bits (self , pulses ):
98
- """Decode the pulses into bits."""
99
- # pylint: disable=too-many-branches,too-many-statements
100
-
101
- # special exception for NEC repeat code!
102
- if (
103
- (len (pulses ) == 3 )
104
- and (8000 <= pulses [0 ] <= 10000 )
105
- and (2000 <= pulses [1 ] <= 3000 )
106
- and (450 <= pulses [2 ] <= 700 )
107
- ):
108
- raise IRNECRepeatException ()
109
-
110
- if len (pulses ) < 10 :
111
- raise IRDecodeException ("10 pulses minimum" )
112
-
113
- # Ignore any header (evens start at 1), and any trailer.
114
- if len (pulses ) % 2 == 0 :
115
- pulses_end = - 1
72
+ :param list pulses: Input pulse lengths
73
+ """
74
+ bins = [[pulses [0 ], 0 ]]
75
+
76
+ for _ , pulse in enumerate (pulses ):
77
+ matchedbin = False
78
+ # print(pulse, end=": ")
79
+ for b , pulse_bin in enumerate (bins ):
80
+ if pulse_bin [0 ] * 0.75 <= pulse <= pulse_bin [0 ] * 1.25 :
81
+ # print("matches bin")
82
+ bins [b ][0 ] = (pulse_bin [0 ] + pulse ) // 2 # avg em
83
+ bins [b ][1 ] += 1 # track it
84
+ matchedbin = True
85
+ break
86
+ if not matchedbin :
87
+ bins .append ([pulse , 1 ])
88
+ # print(bins)
89
+ return bins
90
+
91
+
92
+ def decode_bits (pulses ):
93
+ """Decode the pulses into bits."""
94
+ # pylint: disable=too-many-branches,too-many-statements
95
+
96
+ # special exception for NEC repeat code!
97
+ if (
98
+ (len (pulses ) == 3 )
99
+ and (8000 <= pulses [0 ] <= 10000 )
100
+ and (2000 <= pulses [1 ] <= 3000 )
101
+ and (450 <= pulses [2 ] <= 700 )
102
+ ):
103
+ raise IRNECRepeatException ()
104
+
105
+ if len (pulses ) < 10 :
106
+ raise IRDecodeException ("10 pulses minimum" )
107
+
108
+ # Ignore any header (evens start at 1), and any trailer.
109
+ if len (pulses ) % 2 == 0 :
110
+ pulses_end = - 1
111
+ else :
112
+ pulses_end = None
113
+
114
+ evens = pulses [1 :pulses_end :2 ]
115
+ odds = pulses [2 :pulses_end :2 ]
116
+
117
+ # bin both halves
118
+ even_bins = bin_data (evens )
119
+ odd_bins = bin_data (odds )
120
+
121
+ outliers = [b [0 ] for b in (even_bins + odd_bins ) if b [1 ] == 1 ]
122
+ even_bins = [b for b in even_bins if b [1 ] > 1 ]
123
+ odd_bins = [b for b in odd_bins if b [1 ] > 1 ]
124
+
125
+ if not even_bins or not odd_bins :
126
+ raise IRDecodeException ("Not enough data" )
127
+
128
+ if len (even_bins ) == 1 :
129
+ pulses = odds
130
+ pulse_bins = odd_bins
131
+ elif len (odd_bins ) == 1 :
132
+ pulses = evens
133
+ pulse_bins = even_bins
134
+ else :
135
+ raise IRDecodeException ("Both even/odd pulses differ" )
136
+
137
+ if len (pulse_bins ) == 1 :
138
+ raise IRDecodeException ("Pulses do not differ" )
139
+ if len (pulse_bins ) > 2 :
140
+ raise IRDecodeException ("Only mark & space handled" )
141
+
142
+ mark = min (pulse_bins [0 ][0 ], pulse_bins [1 ][0 ])
143
+ space = max (pulse_bins [0 ][0 ], pulse_bins [1 ][0 ])
144
+
145
+ if outliers :
146
+ # skip outliers
147
+ pulses = [
148
+ p for p in pulses if not (outliers [0 ] * 0.75 ) <= p <= (outliers [0 ] * 1.25 )
149
+ ]
150
+ # convert marks/spaces to 0 and 1
151
+ for i , pulse_length in enumerate (pulses ):
152
+ if (space * 0.75 ) <= pulse_length <= (space * 1.25 ):
153
+ pulses [i ] = False
154
+ elif (mark * 0.75 ) <= pulse_length <= (mark * 1.25 ):
155
+ pulses [i ] = True
116
156
else :
117
- pulses_end = None
157
+ raise IRDecodeException ( "Pulses outside mark/space" )
118
158
119
- evens = pulses [1 :pulses_end :2 ]
120
- odds = pulses [2 :pulses_end :2 ]
159
+ # convert bits to bytes!
160
+ output = [0 ] * ((len (pulses ) + 7 ) // 8 )
161
+ for i , pulse_length in enumerate (pulses ):
162
+ output [i // 8 ] = output [i // 8 ] << 1
163
+ if pulse_length :
164
+ output [i // 8 ] |= 1
165
+ return output
121
166
122
- # bin both halves
123
- even_bins = self .bin_data (evens )
124
- odd_bins = self .bin_data (odds )
125
167
126
- outliers = [b [0 ] for b in (even_bins + odd_bins ) if b [1 ] == 1 ]
127
- even_bins = [b for b in even_bins if b [1 ] > 1 ]
128
- odd_bins = [b for b in odd_bins if b [1 ] > 1 ]
168
+ class GenericDecode :
169
+ """Generic decoding of infrared signals"""
129
170
130
- if not even_bins or not odd_bins :
131
- raise IRDecodeException ("Not enough data" )
171
+ def bin_data (self , pulses ):
172
+ "Wraps the top-level function bin_data for backward-compatibility."
173
+ return bin_data (pulses )
132
174
133
- if len (even_bins ) == 1 :
134
- pulses = odds
135
- pulse_bins = odd_bins
136
- elif len (odd_bins ) == 1 :
137
- pulses = evens
138
- pulse_bins = even_bins
139
- else :
140
- raise IRDecodeException ("Both even/odd pulses differ" )
141
-
142
- if len (pulse_bins ) == 1 :
143
- raise IRDecodeException ("Pulses do not differ" )
144
- if len (pulse_bins ) > 2 :
145
- raise IRDecodeException ("Only mark & space handled" )
146
-
147
- mark = min (pulse_bins [0 ][0 ], pulse_bins [1 ][0 ])
148
- space = max (pulse_bins [0 ][0 ], pulse_bins [1 ][0 ])
149
-
150
- if outliers :
151
- # skip outliers
152
- pulses = [
153
- p
154
- for p in pulses
155
- if not (outliers [0 ] * 0.75 ) <= p <= (outliers [0 ] * 1.25 )
156
- ]
157
- # convert marks/spaces to 0 and 1
158
- for i , pulse_length in enumerate (pulses ):
159
- if (space * 0.75 ) <= pulse_length <= (space * 1.25 ):
160
- pulses [i ] = False
161
- elif (mark * 0.75 ) <= pulse_length <= (mark * 1.25 ):
162
- pulses [i ] = True
163
- else :
164
- raise IRDecodeException ("Pulses outside mark/space" )
165
-
166
- # convert bits to bytes!
167
- output = [0 ] * ((len (pulses ) + 7 ) // 8 )
168
- for i , pulse_length in enumerate (pulses ):
169
- output [i // 8 ] = output [i // 8 ] << 1
170
- if pulse_length :
171
- output [i // 8 ] |= 1
172
- return output
175
+ def decode_bits (self , pulses ):
176
+ "Wraps the top-level function decode_bits for backward-compatibility."
177
+ return decode_bits (pulses )
173
178
174
179
def _read_pulses_non_blocking (
175
180
self , input_pulses , max_pulse = 10000 , pulse_window = 0.10
0 commit comments