Beispiel #1
0
    def rename_script(self, old_script, new_script):
        """
        Rename script

        Args:
            old_script (string): old script name
            new_script (string): new script name

        Raises:
            MissingParameter, InvalidParameter
        """
        if old_script is None or len(old_script)==0:
            raise MissingParameter(u'Old_script parameter is missing')
        if new_script is None or len(new_script)==0:
            raise MissingParameter(u'New_script parameter is missing')
        if old_script==new_script:
            raise InvalidParameter(u'Script names must be differents')
        if not self.__scripts.has_key(old_script):
            raise InvalidParameter(u'Script "%s" does not exist' % old_script)
        if self.__scripts.has_key(new_script):
            raise InvalidParameter(u'Script "%s" already exists' % new_script)

        #rename script in filesystem
        self.cleep_filesystem.move(os.path.join(Actions.SCRIPTS_PATH, old_script), os.path.join(Actions.SCRIPTS_PATH, new_script))
        time.sleep(0.5)

        #rename script in config
        scripts = self._get_config_field(u'scripts')
        old = scripts[old_script]
        scripts[new_script] = old
        del scripts[old_script]
        self._set_config_field(u'scripts', scripts)

        #reload scripts
        self.__load_scripts()
Beispiel #2
0
    def __set_led(self, led_id, color, brightness=10):
        """
        Configure led color and brightness

        Args:
            led_id (int): led identifier (0..2)
            color (list): RGB tuple (0,0,0) or RGB+brightness value (0,0,0,0) [0..255]
            brightness (int): brightness percentage (default 10%) [0..100]
        """
        if self.leds_driver is None:
            raise InvalidParameter(u'Driver is not installed')
        if led_id < 0 or led_id > 2:
            raise InvalidParameter(u'Led_id must be 0..2')
        if brightness < 0 or brightness > 100:
            raise InvalidParameter(u'Brightness must be 0..100')
        if len(color) == 4 and (color[3] < 0 or color[3] > 100):
            raise InvalidParameter(u'Brightness must be 0..100')

#handle brightness within color value
        if len(color) == 4:
            #force brightness
            brightness = color[3]

        #set led color
        #self.logger.debug(u'Set led%s color R=%s G=%s B=%s with Brightness=%s' % (led_id, color[0], color[1], color[2], brightness))
        self.leds_driver.set_pixel(led_id, color[0], color[1], color[2],
                                   brightness)
Beispiel #3
0
    def save_configuration(self, duration, speed):
        """
        Save board configuration

        Args:
            duration (float): message duration (cycling time)
            speed (slow|normal|fast): message scrolling speed

        Raises:
            InvalidParameter, MissingParameter
        """
        if duration is None:
            raise MissingParameter(u'Duration parameter is missing')
        if duration < 5 or duration > 60:
            raise InvalidParameter(
                u'Duration value must be between 5 and 60 seconds')
        if speed is None or len(speed) == 0:
            raise MissingParameter(u'Speed parameter is missing')
        if speed not in self.SPEEDS:
            raise InvalidParameter(u'Speed value is not valid')

        #save config
        self._update_config({u'duration': float(duration), u'speed': speed})

        #update board configuration
        self.board.set_scroll_speed(self.SPEEDS[speed])

        #stop current task
        if self.__display_task:
            self.__display_task.stop()

        #and restart new one
        self.__display_task = BackgroundTask(self.__display_message,
                                             self.logger, float(duration))
        self.__display_task.start()
Beispiel #4
0
    def add_leds_profile(self, name, repeat, actions):
        """
        Add leds profile

        Args:
            name (string): profile name
            repeat (int): repeat value (see REPEAT_XXX)
            actions (list): list of actions (see ACTION_XXX)

        Returns:
            bool: True if led profile added successfully

        Raises:
            InvalidParameter: if invalid function parameter is specified
            MissingParameter: if function parameter is missing
        """
        #check params
        if name is None or len(name) == 0:
            raise MissingParameter(u'Parameter name is missing')
        if repeat is None:
            raise MissingParameter(u'Parameter repeat is missing')
        if repeat not in (self.REPEAT_NONE, self.REPEAT_1, self.REPEAT_2,
                          self.REPEAT_3, self.REPEAT_4, self.REPEAT_5,
                          self.REPEAT_INF):
            raise InvalidParameter(
                u'Parameter repeat is not valid. See available values')
        if actions is None:
            raise MissingParameter(u'Parameter actions is missing')
        if len(actions) == 0:
            raise InvalidParameter(
                u'You must add at least one action in leds profile')

        #check name
        leds_profiles = self._get_config_field(u'leds_profiles')
        for profile in leds_profiles:
            if profile[u'name'] == name:
                raise InvalidParameter(
                    u'Profile with same name already exists')

        #append new profile
        leds_profiles.append({
            u'name': name,
            u'repeat': repeat,
            u'uuid': str(uuid.uuid4()),
            u'actions': actions,
            u'default': False
        })

        #save config
        if not self._set_config_field(u'leds_profiles', leds_profiles):
            raise CommandError(u'Unable to save leds profile')

        return True
Beispiel #5
0
    def get_script(self, script):
        """
        Return a script

        Args:
            script (string): script name

        Returns:
            dict: script data::

                {
                    visual (string): visual editor used to edit file or None if no editor used
                    code (string): source code
                    header (string): source file header (can contains necessary infos for visual editor)
                }

        Raises:
            InvalidParameter: if script not found
            CommandError: if error occured processing script
        """
        self.logger.debug(u'Config: %s' % self._get_config())
        if not self.__scripts.has_key(script):
            raise InvalidParameter(u'Unknown script "%s"' % script)
        path = os.path.join(Actions.SCRIPTS_PATH, script)
        if not os.path.exists(path):
            raise InvalidParameter(u'Script "%s" does not exist' % script)

        output = {
            u'visual': None,
            u'code': None,
            u'header': None
        }

        #read file content
        self.logger.debug(u'Loading script: %s' % path)
        lines = self.cleep_filesystem.read_data(path, encoding='utf-8')
        self.logger.debug('Loaded lines: %s' % lines)
        content = u''.join(lines)

        #parse file
        groups = re.findall(u'# -\*- coding: utf-8 -\*-\n(?:\"\"\"\neditor:(\w+)\n(.*)\n\"\"\"\s)?(.*)', content, re.S | re.U)
        self.logger.debug(groups)
        if len(groups)==1:
            if len(groups[0])==3:
                output[u'editor'] = groups[0][0]
                output[u'header'] = groups[0][1]
                output[u'code'] = groups[0][2]
            else:
                raise CommandError(u'Unable to load script: invalid format')
        else:
            self.logger.warning(u'Unhandled source code: %s' % groups)

        return output
Beispiel #6
0
    def set_credentials(self, username, password, phone_numbers):
        """
        Set BulkSms credentials

        Args:
            username (string): username
            password (string): password
            phone_numbers (string): phone numbers (coma separated if many)

        Returns:
            bool: True if credentials saved successfully
        """
        if username is None or len(username)==0:
            raise MissingParameter(u'Username parameter is missing')
        if password is None or len(password)==0:
            raise MissingParameter(u'Password parameter is missing')
        if phone_numbers is None or len(phone_numbers)==0:
            raise MissingParameter(u'Phone_numbers parameter is missing')
        if phone_numbers.strip().find(u' ')!=-1 or phone_numbers.strip().find(u';')!=-1:
            raise InvalidParameter(u'Phone numbers must be separated by coma (,)')

        #try to get credits
        credits = self.get_credits(username, password)

        return self._update_config({
            u'username': username,
            u'password': password,
            u'phone_numbers': phone_numbers,
            u'credits': credits
        })
Beispiel #7
0
    def add_music(self, filepath):
        """
        Add new music

        Args:
            filepath (string): uploaded and local filepath

        Returns:
            bool: True if file uploaded successfully
            
        Raises:
            Exception, InvalidParameter
        """
        #check parameters
        file_ext = os.path.splitext(filepath)
        self.logger.debug(u'Add music of extension: %s' % file_ext[1])
        if file_ext[1][1:] not in Sounds.ALLOWED_MUSIC_EXTS:
            raise InvalidParameter(
                u'Invalid music file uploaded (only %s are supported)' %
                ','.join(Sounds.ALLOWED_MUSIC_EXTS))

        #move file to valid dir
        if os.path.exists(filepath):
            name = os.path.basename(filepath)
            path = os.path.join(Sounds.MUSICS_PATH, name)
            self.logger.debug(u'Name=%s path=%s' % (name, path))
            shutil.move(filepath, path)
            self.logger.info(u'File "%s" uploaded successfully' % name)
        else:
            #file doesn't exists
            self.logger.error(u'Music file "%s" doesn\'t exist' % filepath)
            raise Exception(u'Music file "%s"  doesn\'t exists' % filepath)

        return True
Beispiel #8
0
    def add_script(self, filepath):
        """
        Add new script using rpc upload

        Args:
            filepath (string): script full path

        Raises:
            InvalidParameter: if invalid parameter is specified
            Exception: if error occured
        """
        #check parameters
        file_ext = os.path.splitext(filepath)
        self.logger.info(u'uploaded file extension: %s - %s' % (unicode(file_ext), unicode(file_ext[1])))
        if file_ext[1]!=u'.py':
            self.logger.info(u'uploaded file extension: %s' % unicode(file_ext[1][1:]))
            raise InvalidParameter(u'Invalid script file uploaded (only python script are supported)')

        #move file to valid dir
        if os.path.exists(filepath):
            name = os.path.basename(filepath)
            path = os.path.join(Actions.SCRIPTS_PATH, name)
            self.logger.info(u'Name=%s path=%s' % (name, path))
            self.cleep_filesystem.move(filepath, path)
            self.logger.info(u'File "%s" uploaded successfully' % name)

            #reload scripts
            self.__load_scripts()

        else:
            #file doesn't exists
            self.logger.error(u'Script file "%s" doesn\'t exist' % filepath)
            raise Exception(u'Script file "%s"  doesn\'t exists' % filepath)
    def set_provider(self, provider_id, apikey):
        """
        Set speechtotext provider

        Args:
            provider_id (int): provider id
            apikey (string): provider apikey

        Return:
            bool: True if action succeed
        """
        if provider_id is None:
            raise MissingParameter(u'Parameter provider is missing')
        if not self.__check_provider(provider_id):
            raise InvalidParameter(u'Specified provider is not valid. Please check list of supported provider.')
        if apikey is None or len(apikey.strip())==0:
            raise MissingParameter(u'Parameter apikey is missing')

        #save config
        config = self._get_config()
        #need to convert provider id to string because json does not support int as map/dict key
        provider_id_str = str(provider_id)
        providersapikeys = self._get_config_field(u'providerapikeys')
        providersapikeys[provider_id_str] = apikey
        config = {
            u'providerid': provider_id_str,
            u'providerapikeys': providersapikeys
        }
        if not self._update_config(config):
            return False

        #restart speech recognition task
        self.__restart_speech_recognition_task()

        return True
Beispiel #10
0
    def debug_script(self, script, event_name=None, event_values=None):
        """
        Launch script debugging. Script output will be send to message bus as event

        Args:
            script (string): script name
            event_name (string): event name
            event_values (dict): event values

        Raises:
            InvalidParameter
        """
        if not self.__scripts.has_key(script):
            raise InvalidParameter(u'Unknown script "%s"' % script)
        path = os.path.join(Actions.SCRIPTS_PATH, script)
        if not os.path.exists(path):
            raise InvalidParameter(u'Script "%s" does not exist' % script)
        
        #TODO handle event
        debug = Action(os.path.join(Actions.SCRIPTS_PATH, script), self.push, False, True)
        debug.start()
Beispiel #11
0
    def set_volume(self, volume):
        """
        Set volume

        Args:
            volume (int): volume value
        """
        if volume is None:
            raise MissingParameter(u'Volume parameter is missing')
        if volume < 0 or volume > 100:
            raise InvalidParameter(u'Volume value must be 0..100')

        self.volume = volume
Beispiel #12
0
    def save_script(self, script, editor, header, code):
        """
        Save script content. If script name if not found, it will create new script

        Args:
            script (string): script name
            editor (string): editor name
            header (string): script header (header comments, may contains editor specific stuff)
            code (string): source code

        Returns:
            bool: True if script saved successfully

        Raises:
            MissingParameter: if parameter is missing
            CommandError: if error processing script
        """
        if script is None or len(script)==0:
            raise InvalidParameter(u'Script parameter is missing')
        if editor is None or len(editor)==0:
            raise InvalidParameter(u'editor parameter is missing')
        if header is None:
            raise InvalidParameter(u'Header parameter is missing')
        if code is None:
            raise InvalidParameter(u'Code parameter is missing')

        #open script for writing
        path = os.path.join(Actions.SCRIPTS_PATH, script)
        self.logger.debug(u'Opening script: %s' % path)
        #fd = io.open(path, u'w', encoding=u'utf-8')
        content = u'# -*- coding: utf-8 -*-\n"""\neditor:%s\n%s\n"""\n%s' % (editor, header, code)
        #fd.write(content)
        #fd.close()
        self.cleep_filesystem.write_data(path, content, encoding='utf-8')

        #force script loading
        self.__load_scripts()
Beispiel #13
0
    def set_lang(self, lang):
        """
        Set tts lang

        Params:
            lang (string): tts lang (see TTS_LANGS)
        """
        #check params
        if lang is None or len(lang) == 0:
            raise MissingParameter(u'Lang parameter is missing')
        if lang not in Sounds.TTS_LANGS.keys():
            raise InvalidParameter(u'Specified lang "%s" is invalid' % lang)

        #save lang
        return self._set_config_field(u'lang', lang)
Beispiel #14
0
    def disable_script(self, script, disabled):
        """
        Enable/disable specified script
        
        Args:
            script (string): script name
            disable (bool): disable flag

        Raises:
            InvalidParameter: if parameter is invalid
        """
        if not self.__scripts.has_key(script):
            raise InvalidParameter(u'Script not found')

        #enable/disable script
        scripts = self._get_config_field(u'scripts')
        scripts[script][u'disabled'] = disabled
        self._set_config_field(u'scripts', scripts)
        self.__scripts[script].set_disabled(disabled)
Beispiel #15
0
    def add_sound(self, filepath):
        """
        Add new sound

        Args:
            filepath (string): uploaded and local filepath

        Returns:
            bool: True if file uploaded successfully
            
        Raises:
            Exception, InvalidParameter
        """
        #check parameters
        file_ext = os.path.splitext(filepath)
        self.logger.debug(u'Add sound of extension: %s' % file_ext[1])
        if file_ext[1][1:] not in Sounds.ALLOWED_SOUND_EXTS:
            raise InvalidParameter(
                u'Invalid sound file uploaded (only %s are supported)' %
                ','.join(Sounds.ALLOWED_SOUND_EXTS))

        #move file to valid dir
        if os.path.exists(filepath):
            name = os.path.basename(filepath)
            path = os.path.join(Sounds.MUSICS_PATH, name)
            self.logger.debug(u'Name=%s path=%s' % (name, path))
            shutil.move(filepath, path)
            self.logger.info(u'Sound file "%s" uploaded successfully' % name)

            #once copied, try to bufferize file
            path = os.path.join(self.SOUNDS_PATH, sound[u'fullname'])
            if not self.__bufferize_sound(path):
                #invalid file, delete it
                self.delete_sound(sound[u'fullname'])
                raise Exception(u'Sound file format is not supported')

        else:
            #file doesn't exists
            self.logger.error(u'Sound file "%s" doesn\'t exist' % filepath)
            raise Exception(u'Sound file "%s"  doesn\'t exists' % filepath)

        return True
Beispiel #16
0
    def turn_off_leds(self, led1=True, led2=True, led3=True):
        """
        Turn off leds

        Args:
            led1 (bool): True to turn off led1
            led2 (bool): True to turn off led2
            led3 (bool): True to turn off led3
        """
        if self.leds_driver is None:
            raise InvalidParameter(u'Driver is not installed')

        if led1:
            self.__set_led(0, self.LED_OFF)
        if led2:
            self.__set_led(1, self.LED_OFF)
        if led3:
            self.__set_led(2, self.LED_OFF)

        #show leds
        self.leds_driver.show()
Beispiel #17
0
    def delete_music(self, fullname):
        """
        Delete music

        Args:
            fullname (string): music file (with file extension) to delete

        Raises:
            InvalidParameter
        """
        if fullname is None or len(fullname) == 0:
            raise MissingParameter(u'Fullname parameter is missing')
        #build filepath
        filepath = os.path.join(Sounds.MUSICS_PATH, fullname)

        #delete file
        if os.path.exists(filepath):
            os.remove(filepath)
            return True

        raise InvalidParameter(u'Invalid music file')
Beispiel #18
0
    def turn_on_leds(self, led1=None, led2=None, led3=None):
        """
        Turn on leds with specified color. None value does nothing on led

        Args:
            led1 (list): RGB<Brightness> list [0..255, 0..255, 0.255, <0..100>]
            led2 (list): RGB<Brightness> list [0..255, 0..255, 0.255, <0..100>]
            led3 (list): RGB<Brightness> list [0..255, 0..255, 0.255, <0..100>]
        """
        if self.leds_driver is None:
            raise InvalidParameter(u'Driver is not installed')

        #led values checked in __set_led function
        if led1 is not None:
            self.__set_led(0, led1)
        if led2 is not None:
            self.__set_led(1, led2)
        if led3 is not None:
            self.__set_led(2, led3)

        #show leds
        self.leds_driver.show()
Beispiel #19
0
    def remove_leds_profile(self, profile_uuid):
        """
        Remove specified leds profile

        Args:
            profile_uuid (string): leds profile uuid
        """
        #check parameters
        if self.__leds_profile_task is not None:
            raise CommandError(
                u'Leds profile is running. Please wait until end of it.')
        if profile_uuid is None or len(profile_uuid) == 0:
            raise MissingParameter(u'Parameter profile_uuid is missing')
        if profile_uuid.isdigit():
            raise InvalidParameter(u'You can\'t delete default leds profiles')

        #get profile
        found = False
        leds_profiles = self._get_config_field(u'leds_profiles')
        for profile in leds_profiles:
            if profile[u'uuid'] == profile_uuid:
                #profile found, remove it
                found = True
                leds_profiles.remove(profile)
                break

        #check found
        if not found:
            self.logger.error(u'Unable to remove profile with uuid %s' %
                              profile_uuid)
            raise CommandError(u'Unable to remove profile')

        #save config
        if not self._set_config_field(u'leds_profiles', leds_profiles):
            raise CommandError(u'Unable to save config')

        return True
Beispiel #20
0
    def play_sound(self, fullname):
        """
        Play sound. Multiple sound can be played simultaneously

        Args:
            fullname (string): sound file to play
        """
        if fullname is None or len(fullname) == 0:
            raise MissingParameter(u'Parameter fullname is missing')

        #build filepath
        filepath = os.path.join(Sounds.SOUNDS_PATH, fullname)

        #check file validity
        if not os.path.exists(filepath):
            #invalid file specified
            raise InvalidParameter(u'Specified sound file "%s" is invalid' %
                                   fullname)
        if fullname not in self.sounds_buffer.keys():
            raise CommandError(u'Unable to play sound: sound "%s" not found')

        #play sound
        self.sounds_buffer[fullname].set_volume(float(self.volume) / 100.0)
        self.sounds_buffer[fullname].play()
Beispiel #21
0
    def play_music(self, fullname, force=False):
        """
        Play specified file. Only one music can be played at once, use force to stop current playback

        Args:
            fullname (string): music file to play
            force (bool): force playing music and stop currently playing music 

        Raises:
            Exception, InvalidParameter
        """
        if fullname is None or len(fullname) == 0:
            raise MissingParameter(u'Parameter fullname is missing')

        #build filepath
        filepath = os.path.join(Sounds.MUSICS_PATH, fullname)

        #check file validity
        if not os.path.exists(filepath):
            #invalid file specified
            raise InvalidParameter(u'Specified music file "%s" is invalid' %
                                   fullname)

        #check if music is already playing
        if self.__music_thread != None and self.__music_thread.is_alive():
            #music already is playing
            if not force:
                #rejct action
                raise Exception(u'Can\'t play 2 musics at the same time')
            else:
                #stop current music
                self.__music_thread.stop()

        #play music
        self.__music_thread = PlayMusic(filepath, self.volume)
        self.__music_thread.start()