@@ -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
29352994class SoundSensor (Sensor ):
0 commit comments