Beispiel #1
0
class Worker(Threader):
    core = None
    music = None
    display = None
    gpio = None
    ir_sender = None
    ir_receiver = None
    timer_on = None
    timer_off = None
    alert = None
    timer_alert = None
    time = None
    date = None
    menu = None

    response_code = None

    def start(self, config, core):
        self.config = config
        self.core = core
        super(Worker, self).start()

    def run(self):
        try:
            self._init_menu()
            self.music = Music(self.core, self.config['default_tracks'],
                               self.config['default_preset'])
            self.display = DisplayWithPowerSaving(
                self.config['display_min_brightness'],
                self.config['display_max_brightness'],
                self.config['display_off_time_from'],
                self.config['display_off_time_to'])
            self.gpio = Gpio(
                self.config['buttons_enabled'], self.play_stop_music,
                self._on_menu_click, self._on_menu_click_left,
                self._on_menu_click_right, self.config['light_sensor_enabled'],
                self._on_light_sensor, self.config['relay_enabled'])
            self.ir_sender = IrSender(self.config['ir_remote'],
                                      self.gpio.switch_relay)
            self.ir_receiver = IrReceiver(
                self.config['ir_receiver_enabled'], self.play_stop_music,
                self._on_menu_click, self._on_menu_click_left,
                self._on_menu_click_right, self.music.decrease_volume,
                self.music.increase_volume, self.run_alert,
                self._on_change_preset)
            self.timer_on = TimerOn(self.play_music)
            self.timer_off = TimerOff(self.stop_music)
            self.alert = Alert(self.music, self.ir_sender,
                               self.config['alert_files'])
            self.timer_alert = TimerAlert(self.run_alert)
            self.time = Time()
            self.date = Date([self.timer_on, self.timer_off, self.timer_alert])
            self.menu = Menu(self.display, self.MENU, [
                self.time, self.date, self.timer_on, self.timer_off,
                self.timer_alert
            ])

            while True:
                self.menu.run()

                if (self.stopped()):
                    break
                else:
                    sleep(1)

        except Exception as inst:
            logging.error(inst)
        finally:
            self.ir_sender.stop()
            self.ir_receiver.stop()
            self.display.shutdown()
            self.gpio.cleanup()

    def _init_menu(self):
        self.MENU = {
            "get_sub_menu":
            lambda: [{
                "get_sub_menu":
                lambda: [
                    self.MENU_TIMER, self.MENU_PLAY_1, self.MENU_RUN_SH, self.
                    MENU_VOLUME, self.MENU_STYLE, self.MENU_DEMO, self.
                    MENU_SYSTEM
                ]
            }]
        }
        self.MENU_TIMER = {
            "get_buffer":
            lambda: [
                0, Symbols.T1, Symbols.T2, Symbols.I, Symbols.M1, Symbols.M2,
                Symbols.E, Symbols.R
            ],
            "get_sub_menu":
            lambda: [self.MENU_ALERT, self.MENU_TIMER_OFF, self.MENU_TIMER_ON]
        }
        self.MENU_ALERT = {
            "get_buffer":
            lambda: [
                0, Symbols.A, Symbols.L, Symbols.E, Symbols.R, Symbols.T1,
                Symbols.T2, 0
            ],
            "get_sub_menu":
            lambda:
            [self.MENU_ALERT_ADD, self.MENU_ALERT_CLEAR, self.MENU_ALERT_RUN]
        }
        self.MENU_ALERT_ADD = {
            "get_buffer":
            lambda: [0, 0, 0, Symbols.A, Symbols.D, Symbols.D, 0, 0],
            "get_sub_menu":
            lambda: [{
                "get_buffer":
                self.timer_alert.get_draw_menu_buffer,
                "click":
                lambda:
                (self.timer_alert.add_timer(),
                 self.display.draw(self.timer_alert.get_draw_menu_buffer())),
                "click_left":
                self.timer_alert.decrease,
                "click_right":
                self.timer_alert.increase
            }]
        }
        self.MENU_ALERT_CLEAR = {
            "get_buffer":
            lambda:
            [0, 0, Symbols.C, Symbols.L, Symbols.E, Symbols.A, Symbols.R, 0],
            "click":
            lambda: self.timer_alert.reset(),
            "click_animation":
            True
        }
        self.MENU_ALERT_RUN = {
            "get_buffer":
            lambda: [0, 0, 0, Symbols.R, Symbols.U, Symbols.N, 0, 0],
            "click": lambda: self.run_alert(),
            "click_animation": True
        }
        self.MENU_TIMER_OFF = {
            "group":
            "timer_off",
            "get_buffer":
            lambda: [0, 0, 0, Symbols.O, Symbols.F, Symbols.F, 0, 0],
            "get_sub_menu":
            lambda: [{
                "get_buffer": self.timer_off.get_draw_buffer,
                "click_left": self.timer_off.decrease,
                "click_right": self.timer_off.increase
            }]
        }
        self.MENU_TIMER_ON = {
            "group":
            "timer_on",
            "get_buffer":
            lambda: [0, 0, 0, Symbols.O, Symbols.N, 0, 0, 0],
            "get_sub_menu":
            lambda: [{
                "get_buffer": self.timer_on.get_draw_buffer,
                "click_left": self.timer_on.decrease,
                "click_right": self.timer_on.increase
            }]
        }
        self.MENU_PLAY_1 = {
            "get_buffer":
            lambda: [
                0, Symbols.P, Symbols.L, Symbols.A, Symbols.Y, 0, Symbols.
                NUMBER[1], 0
            ],
            "click":
            lambda: self.play_music(self.music.get_default_tracks())
        }
        self.MENU_VOLUME = {
            "group":
            "volume",
            "get_buffer":
            lambda: [
                0, Symbols.U, Symbols.O, Symbols.L, Symbols.U, Symbols.M1,
                Symbols.M2, Symbols.E
            ],
            "get_sub_menu":
            lambda: [{
                "get_buffer": self.music.get_draw_volume,
                "click_left": self.music.decrease_volume,
                "click_right": self.music.increase_volume
            }]
        }
        self.MENU_STYLE = {
            "group":
            "style",
            "get_buffer":
            lambda: [
                0, Symbols.S, Symbols.T1, Symbols.T2, Symbols.Y, Symbols.L,
                Symbols.E, 0
            ],
            "get_sub_menu":
            lambda: list(
                map(
                    lambda x: {
                        "get_buffer": lambda: x["buffer"],
                        "on_draw": lambda: self.music.set_preset(x["name"])
                    }, self.music.get_presets()))
        }
        self.MENU_RUN_SH = {
            "get_buffer":
            lambda:
            [0, Symbols.R, Symbols.U, Symbols.N, 0, Symbols.S, Symbols.H, 0],
            "click":
            lambda: self.music.run_sh(),
            "click_animation":
            True
        }
        self.MENU_DEMO = {
            "get_buffer":
            lambda:
            [0, 0, Symbols.D, Symbols.E, Symbols.M1, Symbols.M2, Symbols.O, 0],
            "click":
            lambda: (self.menu.draw_sub_menu_animation(
                self.music.get_draw_equalizer_animation()),
                     self.menu.reset_sub_menu())
        }
        self.MENU_SYSTEM = {
            "get_buffer":
            lambda: [
                Symbols.S, Symbols.Y, Symbols.S, Symbols.T1, Symbols.T2,
                Symbols.E, Symbols.M1, Symbols.M2
            ],
            "get_sub_menu":
            lambda: [self.MENU_REBOOT, self.MENU_HALT]
        }
        self.MENU_REBOOT = {
            "get_buffer":
            lambda: [
                0, Symbols.R, Symbols.E, Symbols.B, Symbols.O, Symbols.O,
                Symbols.T1, Symbols.T2
            ],
            "click":
            lambda: self.music.reboot(),
            "click_animation":
            True
        }
        self.MENU_HALT = {
            "get_buffer":
            lambda:
            [0, 0, Symbols.H, Symbols.A, Symbols.L, Symbols.T1, Symbols.T2, 0],
            "click":
            lambda: self.music.halt(),
            "click_animation":
            True
        }

    def _on_menu_click(self):
        self.menu.click()

    def _on_menu_click_left(self):
        if (self.menu.is_sub_menu_visible()):
            self.menu.click_left()
        else:
            self._decrease_timer()

    def _on_menu_click_right(self):
        if (self.menu.is_sub_menu_visible()):
            self.menu.click_right()
        else:
            self._increase_timer()

    def _on_light_sensor(self, now, is_dark):
        if (self.music.is_playing()
                and (now.hour >= self.config['light_sensor_time_from']
                     or now.hour < self.config['light_sensor_time_to'])):
            if (is_dark):
                if (self.music.get_volume() >
                        self.config['light_sensor_volume']):
                    self.music.set_volume(self.config['light_sensor_volume'])
                self.music.set_preset(self.config['light_sensor_preset'])
                self.timer_off.reset()
                self.timer_off.increase()
                self.timer_off.increase()
                self.timer_off.increase()
                self.timer_off.increase()
                self.menu.draw_sub_menu_animation(
                    self.gpio.get_draw_sleep_animation())
            else:
                self.timer_off.reset()

    def _on_change_preset(self, value):
        self.music.set_preset(value)
        if (value < 0):
            self.menu.click_left(self.MENU_STYLE)
        else:
            self.menu.click_right(self.MENU_STYLE)

    def _increase_timer(self):
        if (self.music.is_playing()):
            self.timer_off.increase()
            self.menu.draw_sub_menu(self.MENU_TIMER_OFF)
        else:
            self.timer_on.increase()
            self.menu.draw_sub_menu(self.MENU_TIMER_ON)

    def _decrease_timer(self):
        if (self.music.is_playing()):
            self.timer_off.decrease()
            self.menu.draw_sub_menu(self.MENU_TIMER_OFF)
        else:
            self.timer_on.decrease()
            self.menu.draw_sub_menu(self.MENU_TIMER_ON)

    def run_alert(self):
        self.menu.draw_sub_menu_animation(
            self.alert.get_draw_alert_animation())
        self.alert.run()

    def get_presets(self):
        return self.music.get_presets()

    def set_preset(self, value):
        self.music.set_preset(value)

    def get_volume(self):
        return self.music.get_volume()

    def set_volume(self, volume):
        self.music.set_volume(volume)

    def get_state(self):
        return self.music.get_state()

    def play_stop_music(self):
        if (self.music.is_playing()):
            self.stop_music()
        else:
            self.play_music()

    def play_music(self, tracks=None):
        self.music.set_volume(self.config['default_volume'])
        self.music.set_preset(self.config['default_preset'])
        self.music.play(tracks)
        self.on_started()

    def pause_music(self):
        self.music.pause()
        self.on_paused()

    def stop_music(self):
        self.music.stop()
        self.on_stopped()

    def on_started(self):
        self.menu.draw_sub_menu_animation(
            self.music.get_draw_start_animation())

    def on_stopped(self):
        self.menu.draw_sub_menu_animation(self.music.get_draw_stop_animation())
        self.timer_off.reset()
        self.ir_sender.power(False)

    def on_playing(self):
        self.menu.draw_sub_menu_animation(self.music.get_draw_play_animation())
        self.timer_on.reset()
        if (self.music.is_playing()):
            self.ir_sender.power(True)

    def on_paused(self):
        self.menu.draw_sub_menu_animation(
            self.music.get_draw_pause_animation())

    def on_seeked(self):
        self.menu.draw_sub_menu_animation(self.music.get_draw_seek_animation())

    def on_mute(self, mute):
        if mute:
            self.on_volume_changed(0)
        else:
            self.on_volume_changed()

    def on_volume_changed(self, volume=None):
        if (self.menu is not None and self.music is not None
                and self.music.is_volume_changed(volume)):
            self.menu.draw_sub_menu(self.MENU_VOLUME)

    def on_playback_state_changed(self, old_state, new_state):
        if (old_state != new_state):
            if (self.music.is_playing(new_state)):
                self.on_playing()
            elif (self.music.is_paused(new_state)):
                self.on_paused()
class ProcessHandling:
    def __init__(self,status_update_func,screen):
        config = Config('space_window.conf',__file__)    
        self._start_with=config.get('global','start_with','streams')
        self._current_stream=None
        self._resume_stream=None
        self._check_timer_delay=20
        self._check_timer=None
        self._wait=False
        self._streams=Streams.load()
        self._nasa=NasaPod(screen)
        self._gallery=Gallery(status_update_func,screen)
        self._music=Music(status_update_func)
        self._clock=Clock(screen)
        self._mopidy=None
        self._status_update=status_update_func    
        if not _standalone:
            threading.Thread(target=self.launch_mopidy).start()
        self._streams.set_status_func(status_update_func)
        self._resume_func=self.run_something

    def pause(self):
        self._stop_timer()
        self.wait()
        if self._streams.is_playing():
            self._resume_stream=self._current_stream
            self._resume_func=self._play_current_stream
        elif self._nasa.is_playing():
            self._resume_func=self.play_nasa
        elif self._clock.is_playing():
            self._resume_func=self.play_clock
        elif self._gallery.is_playing():
            self._resume_func=self.play_gallery
        self.kill_running()
        
    def resume(self):
        self.stop_waiting()
        _log.info('resume func is %s' % self._resume_func)
        self._current_stream=self._resume_stream
        self._resume_stream=None
        self._resume_func()
        self._resume_func=self.run_something

    def reload_config(self):
        self._status_update('Applying configuration')
        self.pause()
        sleep(5)
        self._nasa.load_config()
        self._gallery.load_config()
        self._music.load_config()
        self._clock.load_config()
        self.resume()

    def launch_mopidy(self):
        try:
            if _standalone: return
            self._mopidy=MopidyUpdates(self._status_update,self._mopidy_started)
            self._mopidy.show_updates()
        except:
            _log.exception('exception while launching mopidy')
            
    def streams(self):
        return self._streams

    def _mopidy_started(self):
        if self._streams.is_playing():
            self._streams._stop()
        if self._music.is_playing():
            self._music._stop()
        if not self._something_playing():
            self.play_clock()
 
    def kill_running(self):
        _log.info('stopping running shows')
        self._stop_timer()
        self._streams.stop()
        self._nasa.stop()
        self._gallery.stop()
        self._music.stop()
        self._clock.stop()
        if not _standalone and self._mopidy is not None:
            self._mopidy.stop()
        self._current_stream=None
       
    def wait(self):
        self._wait=True

    def stop_waiting(self):
        self._wait=False

    def _stop_timer(self):
        if self._check_timer is not None: self._check_timer.cancel()

    def _start_timer(self):
        self._check_timer=Timer(self._check_timer_delay, self.run_something)
        self._check_timer.start()
 
    def _play_current_stream(self):
        if self._current_stream is None:
            self.play_next()
        else:
            self.play_stream(self._current_stream)

    def play_stream(self,name):
        self._stop_timer()
        _log.info('starting %s' % name)
        if self._current_stream==name and self._streams.is_playing():
            _log.info('stream %s is already playing' % name)
            return
        self.kill_running()   
        self._status_update('starting %s' % name)
        self._current_stream=name
        self._streams.play(name)
        self._status_update('about to play %s' % name)
        self._start_timer()

    def play_music(self,shuffle,i):
        _log.info('stopping running shows')
        self._stop_timer()
        if self._streams.is_playing():
            self._streams.stop()
        if not _standalone and self._mopidy is not None:
            self._mopidy.stop()
        self._current_stream=None
        self._music.stop()
        self._music.play(shuffle,i)
        self._start_timer()
    
    def play_gallery(self):
        if self._gallery.is_playing(): return
        _log.info('stopping running shows')
        self._stop_timer()
        if self._streams.is_playing():
            self._streams.stop()
        self._nasa.stop()
        self._gallery.stop()
        self._clock.stop()
        self._current_stream=None
        self._gallery.play()
        self._start_timer()
    
    def play_nasa(self):
        if self._nasa.is_playing(): return
        self._stop_timer()
        if self._streams.is_playing():
            self._streams.stop()
        self._gallery.stop()
        self._clock.stop()
        self._current_stream=None
        self._nasa.play()
        self._start_timer()
    
    def play_clock(self):
        if self._clock.is_playing(): return
        self._stop_timer()
        if self._streams.is_playing():
            self._streams.stop()
        self._nasa.stop()
        self._gallery.stop()
        self._clock.stop()
        self._current_stream=None
        self._clock.play()
        self._start_timer()
    
    def play_next(self):
        if self._streams.is_playlist():
            self._streams.playlist_next()
            return
        if self._current_stream is None:
            name=self._streams.first()
        else:
            name=self._streams.next(self._current_stream) 
        
        if name is None: 
            _log.info('about to play apod')
            self.play_nasa()
        else: 
            _log.info('about to play stream %s' % name)
            self.play_stream(name)

    def _something_playing(self):
        return (self._streams.is_playing() or self._nasa.is_playing()\
            or self._clock.is_playing() or self._gallery.is_playing() or \
            self._music.is_playing() or self._wait)

    def run_first_time(self):
        if _standalone:
            self.run_something()
            return
        self._stop_timer()
        if self._something_playing():
            self._start_timer()
            return

        if self._start_with=='clock':
            self.play_clock()
        elif self._start_with=='nasa':
            self.play_nasa()
        elif self._start_with=='gallery':
            self.play_gallery()
        else:
            try:
                self.play_next()
            except:
                self.play_nasa()
        self._start_timer()

    def run_something(self):
        self._stop_timer()
        if self._something_playing():
            self._start_timer()
            self._status_update('')
            return

        if _standalone:
            if self._start_with=='gallery':
                self.play_gallery()
            else:    
                name=self._streams.first()
                if name is not None:
                    _log.info('about to play %s' % name)
                    self.play_stream(name)
                else:
                    self.play_gallery()
            self._start_timer()
            return

        self.play_next()
        self._start_timer()
        
    def refresh_caches(self):
        self.pause()
        self._streams.refresh_caches()
        self.resume()

    def gallery(self):
        return self._gallery
    
    def music(self):
        return self._music