Skip to content

Commit c555ad4

Browse files
committed
Refactor methods into functions that can be shared.
1 parent 4bd1691 commit c555ad4

File tree

1 file changed

+102
-97
lines changed

1 file changed

+102
-97
lines changed

adafruit_irremote.py

Lines changed: 102 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,6 @@
5151
5252
"""
5353

54-
# Pretend self matter because we may add object level config later.
55-
# pylint: disable=no-self-use
56-
5754
import array
5855
import time
5956

@@ -69,107 +66,115 @@ class IRNECRepeatException(Exception):
6966
"""Exception when a NEC repeat is decoded"""
7067

7168

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.
9671
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
116156
else:
117-
pulses_end = None
157+
raise IRDecodeException("Pulses outside mark/space")
118158

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
121166

122-
# bin both halves
123-
even_bins = self.bin_data(evens)
124-
odd_bins = self.bin_data(odds)
125167

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"""
129170

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)
132174

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)
173178

174179
def _read_pulses_non_blocking(
175180
self, input_pulses, max_pulse=10000, pulse_window=0.10

0 commit comments

Comments
 (0)