Skip to content

Commit 799920e

Browse files
authored
InfraredSensor on_red_up, etc support for multiple channels (#388)
* InfraredSensor on_red_up, etc support for multiple channels * Rename buttons red_up -> top_left, etc * Rename buttons red_up -> top_left, etc * Add on_ to the channel1_top_left, etc handlers
1 parent 1d61fee commit 799920e

File tree

1 file changed

+102
-43
lines changed

1 file changed

+102
-43
lines changed

ev3dev/core.py

Lines changed: 102 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2706,7 +2706,9 @@ def process(self, new_state=None):
27062706
state_diff = new_state.symmetric_difference(old_state)
27072707
for button in state_diff:
27082708
handler = getattr(self, 'on_' + button)
2709-
if handler is not None: handler(button in new_state)
2709+
2710+
if handler is not None:
2711+
handler(button in new_state)
27102712

27112713
if self.on_change is not None and state_diff:
27122714
self.on_change([(button, button in new_state) for button in state_diff])
@@ -2812,33 +2814,49 @@ class InfraredSensor(Sensor, ButtonBase):
28122814
# pressed.
28132815
_BUTTON_VALUES = {
28142816
0: [],
2815-
1: ['red_up'],
2816-
2: ['red_down'],
2817-
3: ['blue_up'],
2818-
4: ['blue_down'],
2819-
5: ['red_up', 'blue_up'],
2820-
6: ['red_up', 'blue_down'],
2821-
7: ['red_down', 'blue_up'],
2822-
8: ['red_down', 'blue_down'],
2817+
1: ['top_left'],
2818+
2: ['bottom_left'],
2819+
3: ['top_right'],
2820+
4: ['bottom_right'],
2821+
5: ['top_left', 'top_right'],
2822+
6: ['top_left', 'bottom_right'],
2823+
7: ['bottom_left', 'top_right'],
2824+
8: ['bottom_left', 'bottom_right'],
28232825
9: ['beacon'],
2824-
10: ['red_up', 'red_down'],
2825-
11: ['blue_up', 'blue_down']
2826+
10: ['top_left', 'bottom_left'],
2827+
11: ['top_right', 'bottom_right']
28262828
}
28272829

2828-
#: Handles ``Red Up`` events.
2829-
on_red_up = None
2830-
2831-
#: Handles ``Red Down`` events.
2832-
on_red_down = None
2833-
2834-
#: Handles ``Blue Up`` events.
2835-
on_blue_up = None
2836-
2837-
#: Handles ``Blue Down`` events.
2838-
on_blue_down = None
2839-
2840-
#: Handles ``Beacon`` events.
2841-
on_beacon = None
2830+
_BUTTONS = ('top_left', 'bottom_left', 'top_right', 'bottom_right', 'beacon')
2831+
2832+
# See process() for an explanation on how to use these
2833+
#: Handles ``Red Up``, etc events on channel 1
2834+
on_channel1_top_left = None
2835+
on_channel1_bottom_left = None
2836+
on_channel1_top_right = None
2837+
on_channel1_bottom_right = None
2838+
on_channel1_beacon = None
2839+
2840+
#: Handles ``Red Up``, etc events on channel 2
2841+
on_channel2_top_left = None
2842+
on_channel2_bottom_left = None
2843+
on_channel2_top_right = None
2844+
on_channel2_bottom_right = None
2845+
on_channel2_beacon = None
2846+
2847+
#: Handles ``Red Up``, etc events on channel 3
2848+
on_channel3_top_left = None
2849+
on_channel3_bottom_left = None
2850+
on_channel3_top_right = None
2851+
on_channel3_bottom_right = None
2852+
on_channel3_beacon = None
2853+
2854+
#: Handles ``Red Up``, etc events on channel 4
2855+
on_channel4_top_left = None
2856+
on_channel4_bottom_left = None
2857+
on_channel4_top_right = None
2858+
on_channel4_bottom_right = None
2859+
on_channel4_beacon = None
28422860

28432861
def __init__(self, address=None, name_pattern=SYSTEM_DEVICE_NAME_CONVENTION, name_exact=False, **kwargs):
28442862
super(InfraredSensor, self).__init__(address, name_pattern, name_exact, driver_name=['lego-ev3-ir'], **kwargs)
@@ -2884,29 +2902,29 @@ def heading_and_distance(self, channel=1):
28842902
"""
28852903
return (self.heading(channel), self.distance(channel))
28862904

2887-
def red_up(self, channel=1):
2905+
def top_left(self, channel=1):
28882906
"""
2889-
Checks if `red_up` button is pressed.
2907+
Checks if `top_left` button is pressed.
28902908
"""
2891-
return 'red_up' in self.buttons_pressed(channel)
2909+
return 'top_left' in self.buttons_pressed(channel)
28922910

2893-
def red_down(self, channel=1):
2911+
def bottom_left(self, channel=1):
28942912
"""
2895-
Checks if `red_down` button is pressed.
2913+
Checks if `bottom_left` button is pressed.
28962914
"""
2897-
return 'red_down' in self.buttons_pressed(channel)
2915+
return 'bottom_left' in self.buttons_pressed(channel)
28982916

2899-
def blue_up(self, channel=1):
2917+
def top_right(self, channel=1):
29002918
"""
2901-
Checks if `blue_up` button is pressed.
2919+
Checks if `top_right` button is pressed.
29022920
"""
2903-
return 'blue_up' in self.buttons_pressed(channel)
2921+
return 'top_right' in self.buttons_pressed(channel)
29042922

2905-
def blue_down(self, channel=1):
2923+
def bottom_right(self, channel=1):
29062924
"""
2907-
Checks if `blue_down` button is pressed.
2925+
Checks if `bottom_right` button is pressed.
29082926
"""
2909-
return 'blue_down' in self.buttons_pressed(channel)
2927+
return 'bottom_right' in self.buttons_pressed(channel)
29102928

29112929
def beacon(self, channel=1):
29122930
"""
@@ -2922,14 +2940,55 @@ def buttons_pressed(self, channel=1):
29222940
channel = self._normalize_channel(channel)
29232941
return self._BUTTON_VALUES.get(self.value(channel), [])
29242942

2925-
def process(self, channel=1):
2943+
def process(self):
29262944
"""
2927-
ButtonBase expects buttons_pressed to be a @property but we need to
2928-
pass 'channel' to our buttons_pressed. Get the new_state and pass
2929-
that to ButtonBase.process().
2945+
Check for currenly pressed buttons. If the new state differs from the
2946+
old state, call the appropriate button event handlers.
2947+
2948+
To use the on_channel1_top_left, etc handlers your program would do something like:
2949+
2950+
def top_left_channel_1_action(state):
2951+
print("top left on channel 1: %s" % state)
2952+
2953+
def bottom_right_channel_4_action(state):
2954+
print("bottom right on channel 4: %s" % state)
2955+
2956+
ir = InfraredSensor()
2957+
ir.on_channel1_top_left = top_left_channel_1_action
2958+
ir.on_channel4_bottom_right = bottom_right_channel_4_action
2959+
2960+
while True:
2961+
ir.process()
2962+
time.sleep(0.01)
29302963
"""
2931-
new_state = set(self.buttons_pressed(channel))
2932-
ButtonBase.process(self, new_state)
2964+
new_state = []
2965+
state_diff = []
2966+
2967+
for channel in range(1,5):
2968+
2969+
for button in self.buttons_pressed(channel):
2970+
new_state.append((button, channel))
2971+
2972+
# Key was not pressed before but now is pressed
2973+
if (button, channel) not in self._state:
2974+
state_diff.append((button, channel))
2975+
2976+
# Key was pressed but is no longer pressed
2977+
for button in self._BUTTONS:
2978+
if (button, channel) not in new_state and (button, channel) in self._state:
2979+
state_diff.append((button, channel))
2980+
2981+
old_state = self._state
2982+
self._state = new_state
2983+
2984+
for (button, channel) in state_diff:
2985+
handler = getattr(self, 'on_channel' + str(channel) + '_' + button )
2986+
2987+
if handler is not None:
2988+
handler((button, channel) in new_state)
2989+
2990+
if self.on_change is not None and state_diff:
2991+
self.on_change([(button, channel, button in new_state) for (button, channel) in state_diff])
29332992

29342993

29352994
class SoundSensor(Sensor):

0 commit comments

Comments
 (0)