Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 102 additions & 43 deletions ev3dev/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2681,7 +2681,9 @@ def process(self, new_state=None):
state_diff = new_state.symmetric_difference(old_state)
for button in state_diff:
handler = getattr(self, 'on_' + button)
if handler is not None: handler(button in new_state)

if handler is not None:
handler(button in new_state)

if self.on_change is not None and state_diff:
self.on_change([(button, button in new_state) for button in state_diff])
Expand Down Expand Up @@ -2787,33 +2789,49 @@ class InfraredSensor(Sensor, ButtonBase):
# pressed.
_BUTTON_VALUES = {
0: [],
1: ['red_up'],
2: ['red_down'],
3: ['blue_up'],
4: ['blue_down'],
5: ['red_up', 'blue_up'],
6: ['red_up', 'blue_down'],
7: ['red_down', 'blue_up'],
8: ['red_down', 'blue_down'],
1: ['top_left'],
2: ['bottom_left'],
3: ['top_right'],
4: ['bottom_right'],
5: ['top_left', 'top_right'],
6: ['top_left', 'bottom_right'],
7: ['bottom_left', 'top_right'],
8: ['bottom_left', 'bottom_right'],
9: ['beacon'],
10: ['red_up', 'red_down'],
11: ['blue_up', 'blue_down']
10: ['top_left', 'bottom_left'],
11: ['top_right', 'bottom_right']
}

#: Handles ``Red Up`` events.
on_red_up = None

#: Handles ``Red Down`` events.
on_red_down = None

#: Handles ``Blue Up`` events.
on_blue_up = None

#: Handles ``Blue Down`` events.
on_blue_down = None

#: Handles ``Beacon`` events.
on_beacon = None
_BUTTONS = ('top_left', 'bottom_left', 'top_right', 'bottom_right', 'beacon')

# See process() for an explanation on how to use these
#: Handles ``Red Up``, etc events on channel 1
on_channel1_top_left = None
on_channel1_bottom_left = None
on_channel1_top_right = None
on_channel1_bottom_right = None
on_channel1_beacon = None

#: Handles ``Red Up``, etc events on channel 2
on_channel2_top_left = None
on_channel2_bottom_left = None
on_channel2_top_right = None
on_channel2_bottom_right = None
on_channel2_beacon = None

#: Handles ``Red Up``, etc events on channel 3
on_channel3_top_left = None
on_channel3_bottom_left = None
on_channel3_top_right = None
on_channel3_bottom_right = None
on_channel3_beacon = None

#: Handles ``Red Up``, etc events on channel 4
on_channel4_top_left = None
on_channel4_bottom_left = None
on_channel4_top_right = None
on_channel4_bottom_right = None
on_channel4_beacon = None

def __init__(self, address=None, name_pattern=SYSTEM_DEVICE_NAME_CONVENTION, name_exact=False, **kwargs):
super(InfraredSensor, self).__init__(address, name_pattern, name_exact, driver_name=['lego-ev3-ir'], **kwargs)
Expand Down Expand Up @@ -2859,29 +2877,29 @@ def heading_and_distance(self, channel=1):
"""
return (self.heading(channel), self.distance(channel))

def red_up(self, channel=1):
def top_left(self, channel=1):
"""
Checks if `red_up` button is pressed.
Checks if `top_left` button is pressed.
"""
return 'red_up' in self.buttons_pressed(channel)
return 'top_left' in self.buttons_pressed(channel)

def red_down(self, channel=1):
def bottom_left(self, channel=1):
"""
Checks if `red_down` button is pressed.
Checks if `bottom_left` button is pressed.
"""
return 'red_down' in self.buttons_pressed(channel)
return 'bottom_left' in self.buttons_pressed(channel)

def blue_up(self, channel=1):
def top_right(self, channel=1):
"""
Checks if `blue_up` button is pressed.
Checks if `top_right` button is pressed.
"""
return 'blue_up' in self.buttons_pressed(channel)
return 'top_right' in self.buttons_pressed(channel)

def blue_down(self, channel=1):
def bottom_right(self, channel=1):
"""
Checks if `blue_down` button is pressed.
Checks if `bottom_right` button is pressed.
"""
return 'blue_down' in self.buttons_pressed(channel)
return 'bottom_right' in self.buttons_pressed(channel)

def beacon(self, channel=1):
"""
Expand All @@ -2897,14 +2915,55 @@ def buttons_pressed(self, channel=1):
channel = self._normalize_channel(channel)
return self._BUTTON_VALUES.get(self.value(channel), [])

def process(self, channel=1):
def process(self):
"""
ButtonBase expects buttons_pressed to be a @property but we need to
pass 'channel' to our buttons_pressed. Get the new_state and pass
that to ButtonBase.process().
Check for currenly pressed buttons. If the new state differs from the
old state, call the appropriate button event handlers.

To use the on_channel1_top_left, etc handlers your program would do something like:

def top_left_channel_1_action(state):
print("top left on channel 1: %s" % state)

def bottom_right_channel_4_action(state):
print("bottom right on channel 4: %s" % state)

ir = InfraredSensor()
ir.on_channel1_top_left = top_left_channel_1_action
ir.on_channel4_bottom_right = bottom_right_channel_4_action

while True:
ir.process()
time.sleep(0.01)
"""
new_state = set(self.buttons_pressed(channel))
ButtonBase.process(self, new_state)
new_state = []
state_diff = []

for channel in range(1,5):

for button in self.buttons_pressed(channel):
new_state.append((button, channel))

# Key was not pressed before but now is pressed
if (button, channel) not in self._state:
state_diff.append((button, channel))

# Key was pressed but is no longer pressed
for button in self._BUTTONS:
if (button, channel) not in new_state and (button, channel) in self._state:
state_diff.append((button, channel))

old_state = self._state
self._state = new_state

for (button, channel) in state_diff:
handler = getattr(self, 'on_channel' + str(channel) + '_' + button )

if handler is not None:
handler((button, channel) in new_state)

if self.on_change is not None and state_diff:
self.on_change([(button, channel, button in new_state) for (button, channel) in state_diff])


class SoundSensor(Sensor):
Expand Down