Example #1
0
class MediaPlayerPiFaceCAD:
    def __init__(self, config):
        """
        Constructor
        :param config: instance of MediaPlayerConfig class
        """
        self._config = config
        self._cad = pifacecad.PiFaceCAD()
        self._cad.lcd.blink_off()
        self._cad.lcd.cursor_off()
        self._media_player = None
        self._switch_listener = None
        self._ir_listener = None
        self._temp_text = None
        self._temp_text_Timer = None
        self._listeners_barrier = None
        self._listeners_wait_for_deactivation_thread = None
        self._write_info_thread = None

    def init(self, media_player):
        """
        Sets up the PiFace CAD 2 module.
        :param media_player: instance of MediaPlayer class which is being controlled
        :return: None
        """
        self._media_player = media_player

        # https://github.com/piface/pifacedigitalio/issues/27
        self._listeners_barrier = Barrier(2)
        self._listeners_wait_for_deactivation_thread = Thread(target=self._switch_listener_wait_for_deactivation,
                                                              args=[])
        self._listeners_wait_for_deactivation_thread.setDaemon(True)
        self._listeners_wait_for_deactivation_thread.start()
        self._switch_listener = pifacecad.SwitchEventListener()
        self._switch_listener.register(0, pifacecad.IODIR_ON,
                                       lambda event: self._clear_and_call(media_player.prev_branch))
        self._switch_listener.register(1, pifacecad.IODIR_ON,
                                       lambda event: self._clear_and_call(media_player.next_branch))
        self._switch_listener.register(2, pifacecad.IODIR_ON,
                                       lambda event: media_player.volume_down())
        self._switch_listener.register(3, pifacecad.IODIR_ON,
                                       lambda event: media_player.volume_up())
        self._switch_listener.register(5, pifacecad.IODIR_ON,
                                       lambda event: media_player.play_pause())
        self._switch_listener.register(6, pifacecad.IODIR_ON,
                                       lambda event: self._clear_and_call(media_player.prev_track))
        self._switch_listener.register(7, pifacecad.IODIR_ON,
                                       lambda event: self._clear_and_call(media_player.next_track))
        self._switch_listener.activate()
        try:
            self._ir_listener = pifacecad.IREventListener(self._config['NAME'])
            self._ir_listener.register('play_pause', lambda event: call_and_sleep(media_player.play_pause))
            self._ir_listener.register('next_track',
                                       lambda event: call_and_sleep(self._clear_and_call, media_player.next_track))
            self._ir_listener.register('prev_track',
                                       lambda event: call_and_sleep(self._clear_and_call, media_player.prev_track))
            self._ir_listener.register('next_branch',
                                       lambda event: call_and_sleep(self._clear_and_call, media_player.next_branch))
            self._ir_listener.register('prev_branch',
                                       lambda event: call_and_sleep(self._clear_and_call, media_player.prev_branch))
            self._ir_listener.register('eject', lambda event: call_and_sleep(media_player.stop))
            self._ir_listener.register('volume_up', lambda event: call_and_sleep(media_player.volume_up))
            self._ir_listener.register('volume_down', lambda event: call_and_sleep(media_player.volume_down))
            self._ir_listener.activate()
        except Exception:
            print('LIRC cannot be initialized.')
        self._cad.lcd.clear()
        self._cad.lcd.backlight_on()
        self._cad.lcd.write('Loading')
        self._write_info_thread = Thread(target=self._write_info_thread_func)
        self._write_info_thread.setDaemon(True)
        self._write_info_thread.start()

    def _write_info_thread_func(self):
        """
        Meant to be run in separated thread, writes info to the display
        :return: None
        """
        while self._media_player.is_running:
            self.write_info(self._media_player.get_current_info())
            sleep(0.8)

    def _switch_listener_wait_for_deactivation(self):
        """
        Meant to be run in separated thread, waits for destroy function call
        :return: None
        """
        try:
            self._listeners_barrier.wait()
        except BrokenBarrierError:
            pass  # expected
        self._switch_listener.deactivate()
        self._ir_listener.deactivate()

    def _clear_and_call(self, func):
        """
        Clears the display and calls function from parameter
        :param func: function to be called
        :return: None
        """
        self._cad.lcd.clear()
        func()

    def destroy(self):
        """
        Deactivates the PiFace CAD 2 module
        :return: 
        """
        self._cad.lcd.clear()
        self._cad.lcd.backlight_off()
        self._listeners_barrier.reset()  # should never wait

    def _reset_temp_text(self):
        """
        Resets temporary text (first line on display)
        :return: None
        """
        self._temp_text = None

    def set_temp_text(self, temp_text):
        """
        Sets the temporary text for 1 second (first line on display)
        :param temp_text: 
        :return: None
        """
        self._temp_text = temp_text
        if self._temp_text_Timer is not None:
            self._temp_text_Timer.cancel()
        self._temp_text_Timer = Timer(1, lambda: self._reset_temp_text())
        self._temp_text_Timer.start()

    def write_info(self, media_player_info):
        """
        Writes info to the display
        :param media_player_info: instance of MediaPlayerInfo class - info to write
        :return: None
        """
        first_row_text = ''
        if media_player_info.status == 'paused':
            first_row_text = 'Paused'
        elif media_player_info.status == 'waitingForCD':
            self._cad.lcd.clear()
            first_row_text = 'Waiting for CD'
        elif media_player_info.status == 'playing' and media_player_info.cur_track_info is not None:
            if media_player_info.cur_track_info.track_number is not None:
                track_list = self._media_player.current_track_list
                # track name
                track_info = track_list[media_player_info.cur_track_info.track_number]
                first_row_text = track_info.artist + ' - ' + track_info.title
                # track count
                total_tracks = len(track_list)
                cur_track = media_player_info.cur_track_info.track_number + 1
                track_str_len = len(str(cur_track)) + len(str(total_tracks)) + 1
                self._cad.lcd.set_cursor(9, 1)
                if track_str_len < 7:
                    for i in range(0, 7 - track_str_len):
                        self._cad.lcd.write(' ')
                self._cad.lcd.write(str(cur_track) + '/' + str(total_tracks))
            if media_player_info.cur_track_info.cur_time is not None:
                # track time
                cur_track_time_total_millis = media_player_info.cur_track_info.cur_time
                cur_track_time_total_seconds = floor(cur_track_time_total_millis / 1000)
                cur_track_time_minutes = str(floor(cur_track_time_total_seconds / 60))
                cur_track_time_seconds = str(cur_track_time_total_seconds % 60)
                self._cad.lcd.set_cursor(0, 1)
                self._cad.lcd.write(cur_track_time_minutes.zfill(2) + ':' + cur_track_time_seconds.zfill(2))
        self._cad.lcd.home()
        if self._temp_text is not None:
            self._cad.lcd.write((self._temp_text + '                ')[:16])
        else:
            self._cad.lcd.write((first_row_text + '                ')[:16])

    @staticmethod
    def create_eject_listener(media_player):
        """
        Creates listener to the eject button
        :param media_player: instance of MediaPlayer class - media player to destroy when the button is pushed
        :return: 
        """
        eject_listener = pifacecad.SwitchEventListener()
        eject_listener.register(4, pifacecad.IODIR_ON,
                                lambda event: media_player.stop())
        eject_listener.activate()
        return eject_listener
Example #2
0
class TestWindowCreator(object):
    '''
    Creates and cleans up windows to use for testing.
    '''

    def __init__(self):
        '''
        Constructor
        
        Attributes:
            windows (list): Holds references to the Frames from wxPython
                created for testing.
        '''
        self.windows = []
        
        self._syncBarrier = Barrier(2, timeout = 5)
        self._nextTitleNumber = 1
        self._wxApp = None
        self._wxThread = None
    
    
    def create(self, titleBase = 'TestWindow', numWindows = 1):
        '''
        Creates operating system windows (Frames in wxPython).
        Adds them to the list in the public 'windows' property.
        
        Every calls to create() should eventually end in a call to
        destroy_all(). This method cannot be called twice without
        a call to destroy_all() after the first call.
        
        Args:
            titleBase (Optional[str]): The left part of the created
                window titles. A number is added to the end (right)
                of the base title. Default is "TestWindow".
            numWindows (Optional[int]): The number of windows to create.
                Default is 1.
                
        Raises:
            RuntimeError: If two calls are made to create() without
                a destroy_all() call between them.
        '''
        
        if self._wxApp:
            raise RuntimeError('Caught attempt to call create() a second '
                               'time without first calling destroy_all().')
        
        self._wxApp = wx.App(False)
        
        # Create the windows (Frames) and add them to the public
        # windows list.
        for i in range(0, numWindows):
            windowTitle = titleBase + str(self._nextTitleNumber)
            self.windows.append(
                wx.Frame(None, wx.ID_ANY, windowTitle)
            )
            self.windows[i].Show()
            self._nextTitleNumber += 1
        
        # Run the wxPython main loop in a different thread.
        # One reason is that it loops indefinitely and would block
        # other code from running in the main thread.
        def wx_creation_thread_target():
            nonlocal self
            self._wxApp.MainLoop()
            
        # Start the wxPython thread as a daemon so it should exit
        # even if the main thread unexpectedly exits first.
        self._wxThread = Thread(
            target = wx_creation_thread_target,
            daemon = True
        )
        self._wxThread.start()
        
        # _Thread synchronization 1_
        # Make sure the wxPython thread waits in the barrier after
        # processing the window (Frame) creation.
        wx.CallAfter(self._syncBarrier.wait)
        # Make sure this main thread waits in the barrier until the
        # wxPython thread is finished with the window (Frame) creation.
        self._syncBarrier.wait()
        
        # We synchronized at the barrier. Reset the barrier for next time.
        self._syncBarrier.reset()
        
    def destroy_all(self):
        '''
        Destroys all created windows (wxPython Frames) and the wxPython
            App object.
        
        Does not reset the window title numbers.
        
        Note: As of 2015-6, this method doesn't actually work correctly.
            The spawned wxPython threads and windows only die when
            the main thread dies.
        '''       
        
        # Destroy the windows (Frames) in the wxPython thread.
        for window in self.windows:
            window.Destroy()

        wx.Exit()
        # We need some way to wake up the wxPython thread and tell it
        # to die, but an easy way does not seem to exist yet.
        #wx.WakeUpMainThread()

        # Empty the public list of windows.
        self.windows.clear()
        
        # Mark the wxPython App and thread as killed.
        self._wxApp = None
        self._wxThread = None
Example #3
0
from threading import Condition,Thread,Lock,Event,Barrier
import threading
import logging



FORMAT= '%(asctime)s %(threadName)s %(thread)d %(message)s'
logging.basicConfig(format=FORMAT,level=logging.INFO)

bar = Barrier(3) #number of parties,every 3 threads will start work

def worker(bar:Barrier):
    logging.info("I am working-Number of waiting: {}".format(bar.n_waiting)) # numbers of threads stuck at barrier: once it;s 3, it will start
    try:
        bar.wait()  # if timeout, barrier will abort and broken
    except threading.BrokenBarrierError:
        logging.info('Broken Error')
    logging.info("Job done - Number of waiting: {}".format(bar.n_waiting))


for i in range(10): #10 threads
    if i ==2 :
        bar.abort()  #abort: barrier is broken.
    if i == 4:
        bar.reset()  #reset barrier
    Thread(target=worker,args=(bar,),name='Barrier').start()

print('=====end========')
Example #4
0
class BarrierDemo(Thread):
    def __init__(self, name, b):
        Thread.__init__(self)
        self.name = name
        self.b = b

    def run(self):
        print("Thread name : ", self.name)
        sleep(1)
        print("Parties (number of threads) : ", b.parties)
        sleep(2)
        print(
            "n_waiting (The number of threads currently waiting in the barrier) : ",
            b.n_waiting)
        b.wait()


if __name__ == "__main__":
    b = Barrier(3)
    t1 = BarrierDemo("Thread-1", b)
    t2 = BarrierDemo("Thread-2", b)
    t1.start()
    sleep(1)
    t2.start()
    b.wait()
    print("Barrier Broken (True if barrier is broken): ", b.broken)
    sleep(1)
    b.reset()
    print("n_waiting after barrier.reset() call : ", b.n_waiting)
    b.abort()
    print("Barrier Aborted")
class SimulationMaster:

    def __init__(self, n_threads=4, initial_port=19997, q_table_version=0,
                 batch_size=None, learner=None, explorer=None):
        self.barrier = Barrier(n_threads + 1, timeout=720)
        self.n_threads = n_threads
        self.initial_port = initial_port
        self.batch_size = batch_size

        self.controller = MyActionValueTable(q_table_version)
        if learner is None:
            self.learner = Q(0.5, 0.9)
        else:
            self.learner = learner

        if explorer is None:
            self.explorer = self.learner.explorer = EpsilonGreedyExplorer(0.2, 0.998)
        else:
            self.explorer = self.learner.explorer = explorer
        self.agent = LearningAgent(self.controller, self.learner)
        # Logger initialization
        self.logger = logging.getLogger('master_logger')
        self.logger.setLevel(logging.DEBUG)
        self.logger.addHandler(logging.FileHandler(Utils.DATA_PATH + 'learning-tables/master.log'))
        self.failed_simulations = []
        self.n_episodes = 0
        self.simulations = []
        self.initialize_simulations()

    def initialize_simulations(self):
        self.simulations = []
        for i in range(self.n_threads):
            if self.batch_size is not None:
                self.simulations.append(Simulation(self, self.initial_port + i, self.batch_size))
            else:
                self.simulations.append(Simulation(self, self.initial_port + i))

    def get_action(self, observation):
        action = self.controller.activate(observation)
        action = self.explorer.activate(observation, action)
        return action

    def add_observation(self, obs):
        """
            Adds observation in the agent memory
            :param obs: 3 dimensional vector containing [observation, action, reward]
        """
        self.agent.integrateObservation(obs[0])
        self.agent.lastaction = obs[1]
        self.agent.giveReward(obs[2])

    def update_q_table(self):
        """
            Updates the q table with the new simulators observations
        """
        for sim in self.simulations:
            for trace in sim.traces:
                for obs in trace:
                    self.add_observation(obs)
                self.agent.learn()
                self.agent.reset()
                self.n_episodes += 1

            sim.traces.clear()
        if self.explorer.epsilon > 0.1:
      	    self.explorer.epsilon=self.explorer.epsilon*self.explorer.decay
        if self.learner.alpha > 0.1:
            self.learner.alpha *= 0.999
        self.logger.info('new epsilon: {}'.format(self.explorer.epsilon))
        self.logger.info('new alpha: {}'.format(self.learner.alpha))
        self.logger.info('n episodes: {}'.format(self.n_episodes))

    def save_t_table(self):
        """
            Saves t tables, one for each thread
        """
        for sim in self.simulations:
            sim.save_t_table()

    def run(self):

        self.controller.initialize(self.agent)
        for sim in self.simulations:
            sim.start()
        counter = 0
        while True:
            try:
                self.barrier.wait()  # wait until all simulations are done
                self.update_q_table()
                self.save_t_table()
                self.barrier.wait()  # Free simulations threads and start a new cycle
                # Counter to avoid to save q-table too often
                if counter == 5:
                    self.controller.save()
                    counter = 0
                else:
                    counter += 1
                while self.failed_simulations:
                    sim = self.failed_simulations.pop()
                    self.restart_simulation(sim)
            except BrokenBarrierError as e:
                self.logger.error('Broken Barrier Error Occurred')
                for sim in self.simulations:
                    sim.stop()
                for sim in self.simulations:
                    sim.join()
                del self.simulations
                self.initialize_simulations()
                self.barrier.reset()
                self.failed_simulations.clear()
                for sim in self.simulations:
                    sim.start()

    def restart_simulation(self, simulation):
        self.logger.info('Restarting simulation with port {}'.format(simulation.port))
        self.simulations.remove(simulation)
        new_simulation = Simulation(self, simulation.port)
        self.simulations.append(new_simulation)
        new_simulation.start()
        del simulation