示例#1
0
    def tweak_power_led(self, enable):
        """
        Tweak raspberry pi power led

        Note:
            Infos from https://www.jeffgeerling.com/blogs/jeff-geerling/controlling-pwr-act-leds-raspberry-pi

        Args:
            enable (bool): True to turn on led
        """
        if not os.path.exists('/sys/class/leds/led1'):
            self.logger.info('Power led not found on this device')
            return

        raspi = Tools.raspberry_pi_infos()
        off_value = '0' if raspi['model'].lower().find('zero') else '1'
        on_value = '1' if raspi['model'].lower().find('zero') else '0'
        echo_value = on_value if enable else off_value
        console = Console()
        resp = console.command('echo %s > /sys/class/leds/led1/brightness' %
                               echo_value)
        if resp['returncode'] != 0:
            raise CommandError('Error tweaking power led')

        # store led status
        self._set_config_field('enablepowerled', enable)
示例#2
0
 def _on_audio_registered(self):
     """
     Audio driver registered
     """
     self.asoundconf = EtcAsoundConf(self.cleep_filesystem)
     self.configtxt = ConfigTxt(self.cleep_filesystem)
     self.console = Console()
示例#3
0
    def download_documentation(self, module_name):
        """
        Download documentation (html as archive tar.gz)

        Args:
            module_name (string): module name

        Returns:
            dict: archive infos::

                {
                    data: filepath
                    filename: new filename
                }

        Raises:
            CommandError: command failed error

        """
        self.logger.info('Download documentation html archive')

        cmd = self.CLI_DOCS_ZIP_PATH_CMD % (self.CLI, module_name)
        self.logger.debug('Doc zip path cmd: %s' % cmd)
        console = Console()
        res = console.command(cmd)
        if res['returncode'] != 0:
            raise CommandError(''.join(res['stdout']))

        zip_path = res['stdout'][0].split('=')[1]
        self.logger.debug('Module "%s" docs path "%s"' %
                          (module_name, zip_path))
        return {'filepath': zip_path, 'filename': os.path.basename(zip_path)}
示例#4
0
    def build_application(self, module_name):
        """
        Build application archive (zip format)
        Archive is not protected by password

        Args:
            module_name (string): module name

        Raises:
            Exception: if build failed
        """
        cmd = self.CLI_BUILD_APP_CMD % (self.CLI, module_name)
        self.logger.debug('Build app cmd: %s' % cmd)

        console = Console()
        res = console.command(cmd, 60.0)
        self.logger.info('Build app result: %s | %s' %
                         (res['stdout'], res['stderr']))
        if res['returncode'] != 0:
            raise CommandError('Error building application. Check Cleep logs.')

        try:
            self.__last_application_build = json.loads(res['stdout'][0])
        except Exception as error:
            self.logger.exception(
                'Error parsing app build command "%s" output' % cmd)
            raise CommandError(
                'Error building application. Check Cleep logs.') from error
示例#5
0
    def __cli_check(self, command, timeout=15.0):
        """
        Execute cleep-cli check specified by command

        Args:
            command (string): cli command to execute

        Returns:
            dict: command output
        """
        console = Console()
        res = console.command(command, timeout)
        self.logger.debug('Cli command "%s" output: %s | %s' %
                          (command, res['stdout'], res['stderr']))
        if res['returncode'] != 0:
            self.logger.exception('Command "%s"', command)
            raise CommandError('Command failed')

        try:
            return json.loads(''.join(res['stdout']))
        except Exception as error:
            self.logger.exception('Error parsing command "%s" output' %
                                  command)
            raise CommandError(
                'Error parsing check result. Check Cleep logs') from error
示例#6
0
    def create_application(self, module_name):
        """
        Create new application skel

        Args:
            module_name (string): module name

        Raises:
            CommandError: if command failed
        """
        self.__stop_watcher()

        cmd = self.CLI_NEW_APPLICATION_CMD % (self.CLI, module_name)
        self.logger.debug('Create app cmd: %s' % cmd)

        try:
            console = Console()
            res = console.command(cmd, 10.0)
            self.logger.info('Create app cmd result: %s %s' %
                             (res['stdout'], res['stderr']))
            if res['returncode'] != 0:
                raise CommandError(
                    'Error during application creation. Check Cleep logs.')

            # sync new app content
            console.command(self.CLI_SYNC_MODULE_CMD % module_name)
        finally:
            self.__start_watcher()
示例#7
0
    def restart_cleep(self, delay=3.0):
        """
        Restart Cleep
        """
        # backup configuration
        self.backup_cleep_config()

        # send event
        self.cleep_restart_event.send({'delay': delay})

        # and restart cleep
        console = Console()
        console.command_delayed('/etc/cleep/cleephelper.sh restart', delay)
示例#8
0
    def poweroff_device(self, delay=5.0):
        """
        Poweroff device
        """
        # backup configuration
        self.backup_cleep_config()

        # send event
        self.device_poweroff_event.send({'delay': delay})

        # and reboot system
        console = Console()
        console.command_delayed('poweroff', delay)
示例#9
0
    def reboot_device(self, delay=5.0):
        """
        Reboot device
        """
        # backup configuration
        self.backup_cleep_config()

        # send event
        self.device_reboot_event.send({'delay': delay})

        # and reboot system
        console = Console()
        console.command_delayed('reboot', delay)
示例#10
0
    def _execute_command(self, sensor):  # pragma: no cover
        """
        Execute dht22 binary command
        Useful for unit testing
        """
        console = Console()
        cmd = self.DHT22_CMD % sensor["gpios"][0]["pin"]
        self.logger.debug('Read DHT22 sensor values from command "%s"' % cmd)
        resp = console.command(cmd, timeout=11)
        self.logger.debug("Read DHT command response: %s" % resp)
        if resp['error'] or resp['killed']:
            self.logger.error("DHT22 command failed: %s" % resp)

        return json.loads(resp['stdout'][0])
示例#11
0
    def sync_time():
        """
        Synchronize device time using NTP server

        Note:
            This command may lasts some seconds

        Returns:
            bool: True if NTP sync succeed, False otherwise
        """
        console = Console()
        resp = console.command("/usr/sbin/ntpdate-debian", timeout=60.0)

        return resp["returncode"] == 0
示例#12
0
    def tweak_activity_led(self, enable):
        """
        Tweak raspberry pi activity led

        Args:
            enable (bool): True to turn on led
        """
        if not os.path.exists('/sys/class/leds/led0'):
            self.logger.info('Activity led not found on this device')
            return

        raspi = Tools.raspberry_pi_infos()
        off_value = '0' if raspi['model'].lower().find('zero') else '1'
        on_value = '1' if raspi['model'].lower().find('zero') else '0'
        echo_value = on_value if enable else off_value
        console = Console()
        resp = console.command('echo %s > /sys/class/leds/led0/brightness' %
                               echo_value)
        if resp['returncode'] != 0:
            raise CommandError('Error tweaking activity led')

        # store led status
        self._set_config_field('enableactivityled', enable)
示例#13
0
    def set_timezone(self):
        """
        Set timezone according to coordinates

        Returns:
            bool: True if function succeed, False otherwise

        Raises:
            CommandError: if unable to save timezone
        """
        # get position
        position = self._get_config_field("position")
        if not position["latitude"] and not position["longitude"]:
            self.logger.warning(
                "Unable to set timezone from unspecified position (%s)" %
                position)
            return False

        # compute timezone
        current_timezone = None
        try:
            # try to find timezone at position
            current_timezone = self.timezonefinder.timezone_at(
                lat=position["latitude"], lng=position["longitude"])
            if current_timezone is None:
                # extend search to closest position
                # TODO increase delta_degree to extend research, careful it use more CPU !
                current_timezone = self.timezonefinder.closest_timezone_at(
                    lat=position["latitude"], lng=position["longitude"])
        except ValueError:
            # the coordinates were out of bounds
            self.logger.exception("Coordinates out of bounds")
        except Exception:
            self.logger.exception(
                "Error occured searching timezone at position")
        if not current_timezone:
            self.logger.warning(
                "Unable to set device timezone because it was not found")
            return False

        # save timezone value
        self.logger.debug("Save new timezone: %s" % current_timezone)
        if not self._set_config_field("timezone", current_timezone):
            raise CommandError("Unable to save timezone")

        # configure system timezone
        zoneinfo = os.path.join(self.SYSTEM_ZONEINFO_DIR, current_timezone)
        self.logger.debug("Checking zoneinfo file: %s" % zoneinfo)
        if not os.path.exists(zoneinfo):
            raise CommandError('No system file found for "%s" timezone' %
                               current_timezone)
        self.logger.debug('zoneinfo file "%s" exists' % zoneinfo)
        self.cleep_filesystem.rm(self.SYSTEM_LOCALTIME)

        self.logger.debug('Writing timezone "%s" in "%s"' %
                          (current_timezone, self.SYSTEM_TIMEZONE))
        if not self.cleep_filesystem.write_data(self.SYSTEM_TIMEZONE,
                                                "%s" % current_timezone):
            self.logger.error(
                'Unable to write timezone data on "%s". System timezone is not configured!'
                % self.SYSTEM_TIMEZONE)
            return False

        # launch timezone update in background
        self.logger.debug("Updating system timezone")
        command = Console()
        res = command.command(
            "/usr/sbin/dpkg-reconfigure -f noninteractive tzdata",
            timeout=15.0)
        self.logger.debug("Timezone update command result: %s" % res)
        if res["returncode"] != 0:
            self.logger.error("Error reconfiguring system timezone: %s" %
                              res["stderr"])
            return False

        # TODO configure all wpa_supplicant.conf country code

        # propagate changes to cleep
        self.timezone = timezone(current_timezone)
        self._time_task()

        return True
示例#14
0
 def __kill_watchers(self):
     """
     Kill all watchers instances
     """
     console = Console()
     console.command('/usr/bin/pkill -9 -f "cleep-cli watch"')