Ejemplo n.º 1
0
 def __init__(self, context, owner):
     RadioState.__init__(self, context, owner)
     self.logger = logging.getLogger(type(self).__name__)
     self._essid_state = EssidState(context, self)
     self._passwd_state = PasswdState(context, self)
     self._sleep_state = SleepState(context, self)
     self._sub_state = None
Ejemplo n.º 2
0
 def __init__(self, context, owner):
     RadioState.__init__(self, context, owner)
     self.logger = logging.getLogger(type(self).__name__)
     self.password = ""
     self._allowed_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!\"#$%&'()*+,-./:;<=>?@[]^_`{|}\x01\x02"
     self._chars_pos = 0
     self._cursor_pos = 0
Ejemplo n.º 3
0
 def __init__(self, context, owner):
     RadioState.__init__(self, context, owner)
     self.logger = logging.getLogger(type(self).__name__)
     self._track_nb = 1
     self._playing_state = PlayingState(self._ctxt, self._track_nb, self)
     self._choosing_state = ChooseStationState(self._ctxt, self)
     self._volume_state = VolumeState(self._ctxt, self)
     self._sub_state = None
Ejemplo n.º 4
0
    def __init__(self, cpo):
        """

        :return: an opuscule_controller object.
        """

        self.commands = {  # Valid commands
            'advance': self.do_advance,
            'retreat': self.do_retreat,
            'select': self.do_select,
            'escape': self.do_escape,
            'shutdown': self.do_shutdown,
            'play': self.do_play,
            'pause': self.do_pause,
            'stop': self.do_stop,
            'add_favorite': self.do_add_favorite,
            'shuffle': self.do_shuffle,
            'repeat': self.do_repeat,
            'next': self.do_next,
            'previous': self.do_previous,
            'louder': self.do_louder,
            'softer': self.do_softer,
            'mute': self.do_mute,
            'refresh': self.do_refresh,
        }

        # Do Startup tasks

        # Configuration Parser object for those that need it
        self.cpo = cpo
        # Radio state object
        self.rs = RadioState()

        # Components
        self.registered_components = []

        # We don't want to add a sfavs MenuList to sfavs...
        self.sfavs = SuperFavoritesComponent()
        self.rs.menu.current_node.add_child(self.sfavs)
        self.rs.menu.selected_node = self.sfavs

        # Attempt to register the remainder of the available components
        self.register_component(LibraryComponent(self.sfavs))

        # self.register_component(PodcastsComponent(self.sfavs))

        self.register_component(StreamingComponent(self.sfavs, self.cpo))

        self.register_component(BoodlerComponent(self.sfavs))

        self.register_component(FmRadioComponent(self.sfavs))

        self.register_component(WxRadioComponent(self.sfavs))

        self.register_component(SettingsComponent())

        self.register_component(SystemComponent())
Ejemplo n.º 5
0
 def __init__(self, context, owner):
     RadioState.__init__(self, context, owner)
     self.logger = logging.getLogger(type(self).__name__)
     self.encoder_pressed = False
     self._clock_rolling_text = ScrollingText(self._get_time_text,
                                              self._time_callback,
                                              display_size=20,
                                              refresh_rate=1)
     self._clock_rolling_text.start()
     self._clock_rolling_text.pause()
Ejemplo n.º 6
0
 def __init__(self, ctxt, owner):
     RadioState.__init__(self, ctxt, owner)
     self.logger = logging.getLogger(type(self).__name__)
     # Timeout thread
     self._timeout = None
     self._timeout_value = ctxt.rsc.volume_timeout
     self._increment = ctxt.rsc.volume_increment
     # initialize volume from mpc
     try:
         proc = subprocess.Popen(["mpc", "volume"],
                                 stdout=subprocess.PIPE,
                                 universal_newlines=True)
         out, err = proc.communicate()
         self._volume = int(out.split(":")[1].strip().strip("%"))
     except:
         self._volume = 20
Ejemplo n.º 7
0
 def __init__(self, ctxt, track_nb, owner):
     """ Initialisation
     """
     RadioState.__init__(self, ctxt, owner)
     self.logger = logging.getLogger(type(self).__name__)
     self.track_nb = track_nb
     self._lcd = ctxt.lcd
     self._rsc = ctxt.rsc
     self._wifi_level = 0
     self.random_msg = ""
     self._random_msg_display = ScrollingText(
         self._random_msg,
         self._random_msg_callback,
         display_size=20,
         refresh_rate=0,
         scroll_begin_delay=self._rsc.scroll_begin,
         scroll_end_delay=self._rsc.scroll_end,
         scroll_rate=self._rsc.scroll_rate)
     self._random_msg_display.pause()
     self._random_msg_display.start()
     # The name of the radio is not updated automatically when setting refresh_rate = 0
     self._name_display = ScrollingText(
         self._radio_name,
         self._radio_name_callback,
         display_size=20,
         refresh_rate=0,
         scroll_begin_delay=self._rsc.scroll_begin,
         scroll_end_delay=self._rsc.scroll_end,
         scroll_rate=self._rsc.scroll_rate)
     self._name_display.pause()
     self._name_display.start()
     # The title of the track is updated automatically every 5 seconds
     self._title_display = ScrollingText(
         self._track_title,
         self._track_title_callback,
         display_size=20,
         refresh_rate=1,
         scroll_begin_delay=self._rsc.scroll_begin,
         scroll_end_delay=self._rsc.scroll_end,
         scroll_rate=self._rsc.scroll_rate)
     self._title_display.pause()
     self._title_display.start()
Ejemplo n.º 8
0
    def __init__(self, context, owner):
        RadioState.__init__(self, context, owner)
        self.logger = logging.getLogger(type(self).__name__)

        # Random msg inittialisation
        self.random_msg = ""
        self._random_msg_display = ScrollingText(
            self._random_msg,
            self._random_msg_callback,
            display_size=20,
            refresh_rate=0,
            scroll_begin_delay=self._ctxt.rsc.scroll_begin,
            scroll_end_delay=self._ctxt.rsc.scroll_end,
            scroll_rate=self._ctxt.rsc.scroll_rate)
        self._random_msg_display.start()
        self._random_msg_display.pause()

        # clock initialisation
        self._clock_rolling_text = ScrollingText(self._get_time_text,
                                                 self._time_callback,
                                                 display_size=5,
                                                 refresh_rate=1)
        self._clock_rolling_text.start()
        self._clock_rolling_text.pause()

        self._blink_thread = None
        self._blinking = False
        # substates
        self._volume_state = VolumeState(self._ctxt, self)
        self._idle_state = BtIdleState(self._ctxt, self)
        self._sub_state = None

        # ensure the bluetooth device is pairable
        subprocess.call(["bluetoothctl", "pairable", "on"])
        subprocess.call(["bluetoothctl", "agent", "NoInputNoOutput"])
        subprocess.call(["bluetoothctl", "default-agent"])

        return
Ejemplo n.º 9
0
 def __init__(self, ctxt, owner):
     RadioState.__init__(self, ctxt, owner)
     self.target_nb = 0
     self.playlist = self._ctxt.rsc.playlist
     self._timeout = None
Ejemplo n.º 10
0
 def __init__(self, context, owner):
     RadioState.__init__(self, context, owner)
     return
Ejemplo n.º 11
0
class OpusculeController:
    """Control object for the audio device; a singleton that manages all device functions."""

    def __init__(self, cpo):
        """

        :return: an opuscule_controller object.
        """

        self.commands = {  # Valid commands
            'advance': self.do_advance,
            'retreat': self.do_retreat,
            'select': self.do_select,
            'escape': self.do_escape,
            'shutdown': self.do_shutdown,
            'play': self.do_play,
            'pause': self.do_pause,
            'stop': self.do_stop,
            'add_favorite': self.do_add_favorite,
            'shuffle': self.do_shuffle,
            'repeat': self.do_repeat,
            'next': self.do_next,
            'previous': self.do_previous,
            'louder': self.do_louder,
            'softer': self.do_softer,
            'mute': self.do_mute,
            'refresh': self.do_refresh,
        }

        # Do Startup tasks

        # Configuration Parser object for those that need it
        self.cpo = cpo
        # Radio state object
        self.rs = RadioState()

        # Components
        self.registered_components = []

        # We don't want to add a sfavs MenuList to sfavs...
        self.sfavs = SuperFavoritesComponent()
        self.rs.menu.current_node.add_child(self.sfavs)
        self.rs.menu.selected_node = self.sfavs

        # Attempt to register the remainder of the available components
        self.register_component(LibraryComponent(self.sfavs))

        # self.register_component(PodcastsComponent(self.sfavs))

        self.register_component(StreamingComponent(self.sfavs, self.cpo))

        self.register_component(BoodlerComponent(self.sfavs))

        self.register_component(FmRadioComponent(self.sfavs))

        self.register_component(WxRadioComponent(self.sfavs))

        self.register_component(SettingsComponent())

        self.register_component(SystemComponent())

    def register_component(self, component):
        """
        Check component dependancies, and add component to the UI.

        With each component, we need to make sure it reports that all requirements are fulfilled (hardware is available
        for things like SDR, software subsystems are available for things like MPD and Boodler, etc.).

        :param component:
        :return:
        """
        if component.requirements_met():
            logger.info("Requirements for {} component met; loading component.".format(component.component))
            self.registered_components.append(component)
            self.rs.menu.current_node.add_child(component)
            if isinstance(component, AudioComponent):
                self.sfavs.add_child_menu(component.favorites_node)

    def handle(self, command):
        """Handle incoming commands.

        We have a simple guard to sanity check the input, and then run the function associated with the command.
        """

        logger.debug("[Opuscule] Got command {}".format(command))
        if command in self.commands:
            # change state
            self.commands[command]()
            return {"response": "OK", "text": "Command accepted."}
        else:
            return {"response": "ERROR", "text": "Unknown command."}

    # Commands that manipulate the menu state

    def do_advance(self):
        """Increment the active menu item in the active menu."""
        self.rs.menu_advance()

    def do_retreat(self):
        """Decrement the active item in the active menu."""
        self.rs.menu_retreat()

    def do_escape(self):
        """Move to the parent menu."""
        self.rs.menu_escape()

    def do_select(self):
        """ The select command can affect either menu state, play state, or execute a command, depending on the
        current selected node

        We want to handle different select behaviors here; namely, we need to decide
        if the command should be sent as a menu select (if it's a MenuList) or
        a play (if it's an opus) or a command.
        """

        if isinstance(self.rs.menu.selected_node, MenuList):
            self.rs.menu_select()
        elif isinstance(self.rs.menu.selected_node, Opus):
            self.rs.update('play')
        elif isinstance(self.rs.menu.selected_node, Command):
            self.rs.menu.selected_node.command_execute()
        else:
            pass

    # Commands to manipulate the play state of the server

    def do_play(self):
        self.rs.update('play')

    def do_stop(self):
        self.rs.update('stop')

    def do_pause(self):
        self.rs.update('pause')

    def do_repeat(self):
        self.rs.toggle_repeat()

    def do_shuffle(self):
        self.rs.toggle_shuffle()

    def do_next(self):
        self.rs.now_playing.current_opus.opus_next()

    def do_previous(self):
        self.rs.now_playing.current_opus.opus_previous()

    # Commands that affect volume of playback (possibly supported)

    def do_louder(self):
        self.rs.volume.louder()

    def do_softer(self):
        self.rs.volume.softer()

    def do_mute(self):
        self.rs.volume.toggle_mute()
        self.rs.indicators.set_mute(self.rs.volume.muted)

    # Utility commands

    def do_add_favorite(self):
        """
        Add the current opus to the favorites menu for that component, and then
        update the super favorites.

        :return:
        """
        home_comp = None

        # on startup, we might be in a state without a current opus
        if self.rs.now_playing.current_opus:
            for c in self.registered_components:
                if c.component == self.rs.now_playing.current_opus.component:
                    home_comp = c
                    break
            else:
                logger.error("Tried to add opus as a favorite, but current opus has no component.")
                return

            if home_comp == "superfavorites":
                return {"response": "ERROR", "text": "Operai in the super favorites are already favorites."}
            else:
                home_comp.add_favorite(self.rs.now_playing.current_opus)
                home_comp.save_favorites()
                self.sfavs.update_all_favorite_menus()
        else:
            return {"response": "ERROR", "text": "Only operai can be added as favorites."}

    def do_refresh(self):
        """
        Trigger a refresh for the requesting client

        :return:
        """
        pass

    def handle_internal(self):
        """
        Future hook for handling internal commands.

        """
        pass

    @staticmethod
    def do_shutdown():
        loop.stop()
Ejemplo n.º 12
0
 def __init__(self, context, owner):
     RadioState.__init__(self, context, owner)
     self.logger = logging.getLogger(type(self).__name__)
     self._essid_nb = 0
     self._ids = []
     self.essid = ""