Example #1
0
class AppTest:
    def __init__(self):
        self.token_handler = TokenHandler()
        self.app_config = ApplicationConfig()
        self.mic = MicrophoneHelper()
        self.dataset = Dataset()
        self.color_print = Color()
        self.sensors = []

        if self.app_config.local_config.is_dht22:
            self.sensors.append("dht22")
        if self.app_config.local_config.is_ds18b20:
            self.sensors.append("ds18b20")
        if self.app_config.local_config.is_scale:
            self.sensors.append("scale")

    def app_status(self):
        # liefert den aktuellen Status der App zurück
        # wieviele failed attempts
        # führt messung durch oder wartet
        # läuft oder läuft nicht
        pass

    def token_test(self):
        # liefert true wenn user credentials richtig und valides token erhalten
        pass

    def config_test(self):
        # liefert true wenn konfigurationsdatei ist da und kann mit dem dw synchronisiert werden
        pass

    @staticmethod
    def get_available_space():
        path = '/'
        bytes_avail = psutil.disk_usage(path).free
        gigabytes_avail = bytes_avail / 1024 / 1024 / 1024

        return round(gigabytes_avail, 2)

    def dataset_test(self):
        self.color_print.bold("Starting test....")
        test_data = {}
        for sensor in self.sensors:
            testdata = self.dataset.get_data(sensor)
            if testdata:
                for data in testdata:
                    if hasattr(data, '__len__'):
                        test_data[sensor] = True
                        self.color_print.ok_green(f'{sensor} ..........OK!')
                    else:
                        test_data[sensor] = False
                        self.color_print.fail(f'{sensor} ..........FAILED!')
            else:
                test_data[sensor] = False
                self.color_print.fail(f'{sensor} ..........FAILED!')

        if self.app_config.local_config.is_microphone:
            mic_test = self.mic.get_fft_data()
            if mic_test:
                test_data["microphone"] = True
                self.color_print.ok_green("Microphone ..........OK!")
            else:
                test_data["microphone"] = False
                self.color_print.fail("Microphone ..........FAILED!")

        return test_data
Example #2
0
class Application:
    def __init__(self):
        self.dataset_helper = DatasetLogHelper(
        )  # saving and sends the dataset
        self.dataset = Dataset()  # dataset for take sensor data
        self.app_config = ApplicationConfig(
        )  # configuration data (on- and offline)
        self.wifi_helper = WifiHelper(
        )  # gets signal strength for debug purpose
        self.attempts = 0
        self.dwh_api = DataApi()
        self.token_handler = TokenHandler()
        self.error_helper = ErrorHelper()
        self.failed_sensor = ""
        self.handle_online_status()
        self.checker = SelfChecker()

        # send status:
        try:
            send_log(
                f'Start Application: {self.app_config.local_config.version}',
                "debug")
            send_log(f'Config Name: {self.app_config.local_config.group}',
                     "debug")
            send_log(
                f'Signal Strength: {self.wifi_helper.get_signal_strength()}',
                "debug")
            if self.current_volt():
                send_log(f'Voltage: {self.current_volt()}', "debug")

            set_timezone(self.app_config.local_config.timezone)

            for file, status in self.checker.check_files().items():
                send_log(f"created file: {file}.", "warning")
            for failed_sensor in self.error_helper.get_sensors_with_errors():
                send_log(
                    f'Please check {str(failed_sensor)} and reset all errors to reactivate the sensor.',
                    "warning")
        except Exception as e:
            print(e)

    def start(self):
        while True:
            try:
                # before do anything, handle on / offline status and try to sync config
                self.handle_online_status()
                sensors = []
                if not self.app_config.local_config.ignore_error:  # if not ignore error
                    if self.app_config.local_config.is_ds18b20 and not self.error_helper.has_error(
                            "DS18B20"):
                        sensors.append("ds18b20")  # TEMP SENSOR
                    if self.app_config.local_config.is_dht22 and not self.error_helper.has_error(
                            "DHT22"):
                        sensors.append("dht22")  # TEMP and HUMIDITY SENSOR
                    if self.app_config.local_config.is_scale and not self.error_helper.has_error(
                            "SCALE"):
                        sensors.append("scale")
                    if self.app_config.local_config.is_microphone and not self.error_helper.has_error(
                            "MICROPHONE"):
                        sensors.append("microphone")
                else:  # if ignore all errors
                    if self.app_config.local_config.is_ds18b20:
                        sensors.append("ds18b20")  # TEMP SENSOR
                    if self.app_config.local_config.is_dht22:
                        sensors.append("dht22")  # TEMP and HUMIDITY SENSOR
                    if self.app_config.local_config.is_scale:
                        sensors.append("scale")
                    if self.app_config.local_config.is_microphone:
                        sensors.append("microphone")

                # START GET AND SEND DATASET BLOCK
                for sensor in sensors:
                    dataset = self.dataset.get_data(
                        sensor)  # get dataset from sensor
                    if dataset:
                        for x in range(len(dataset)):
                            if not dataset[x] or not hasattr(
                                    dataset[x], '__len__'):
                                self.sensor_error(sensor.upper())
                            else:
                                response = self.dwh_api.send_data(dataset[x])
                                if not response:
                                    self.dataset_helper.insert(
                                        dataset[x])  # save data
                    else:
                        self.sensor_error(sensor.upper())

                # END DATASET BLOCK ###

                # START POST LOG FILES ####
                if self.wifi_helper.is_online():
                    response = self.dataset_helper.post_log_files()
                    if not response:
                        self.attempts += 1
                # END POST LOG FILES ####

                # START CHECKING FAILED ATTEMPTS BLOCK
                if int(self.attempts) >= int(self.app_config.local_config.
                                             interval_attempts_before_restart):
                    self.error_helper.set_sensor_restarted(self.failed_sensor)
                    self.restart_hive("Too many errors: reboot system!",
                                      "error")
                # END FAILED ATTEMPTS BLOCK ###

                # START CHECKING UPDATE
                if self.wifi_helper.is_online(
                ) and self.app_config.local_config.auto_update:
                    self.update()
                # END CHECKING UPDATE

                # START AUTO SHUTDOWN BLOCK
                if self.app_config.local_config.auto_shutdown:
                    send_log(f'Power off. System time: {str(get_time())}',
                             "debug")
                    time.sleep(30)
                    os.system("sudo poweroff")
                # END AUTO SHUTDOWN BLOCK ###

                # WAIT BEFORE TAKE NEW DATASET
                time.sleep(
                    int(self.app_config.local_config.interval_app_wait_seconds)
                )
                # END WAIT ###

            except Exception as e:
                print(f'app crashed: {e}')
                self.restart_hive(
                    f'Application crashed! Error: {e}. Reboot System', "error")

    @staticmethod
    def restart_hive(message, level):
        send_log(message, level)
        time.sleep(120)
        os.system('sudo reboot')

    def sensor_error(self, sensor):  # sensor is offline or sends no valid data
        self.attempts += 1
        self.failed_sensor = str(sensor)
        if os.path.exists(mapping.witty_pi):
            self.error_helper.set_sensor_with_error(sensor)
            self.error_helper.set_sensor_restarted(sensor)
        else:
            self.error_helper.set_sensor_with_error(sensor)

        send_log(f'{sensor} failed!', "error")

    def update(self):
        try:
            r = requests.get(mapping.version_url)
            data = r.json()
            git_version = data['files']['version']['content']
            old_version = self.app_config.local_config.version

            if float(git_version) > float(
                    self.app_config.local_config.version):
                if os.path.exists(mapping.update_file):
                    os.remove(mapping.update_file)
                update_file = requests.get(mapping.update_file_url)
                with open(mapping.update_file, 'wb+') as f:
                    f.write(update_file.content)
                self.app_config.local_config.set_update()
                self.app_config.local_config.set_config_data(
                    "DEFAULT", "version", str(git_version))
                self.restart_hive(
                    f"update from {old_version} to {git_version}", "debug")

        except Exception as e:
            print(e)

    def handle_online_status(self):
        try:
            # check if system has valid access token
            # write online status
            if not self.token_handler.get_access_token():
                self.wifi_helper.update_online_status(False)
            else:
                self.wifi_helper.update_online_status(True)
            # check online status
            # sync config (on- or offline)
            if self.wifi_helper.is_online():
                self.app_config.sync_config()
            else:
                self.app_config.local_config.get_config_data()
        except Exception as e:
            print(e)

    @staticmethod
    def current_volt():
        try:
            v_out = []
            with open(mapping.witty_pi_log) as f:
                for i, line in enumerate(f):
                    if 'Current Vout' in line:
                        v_out.append(line)
            length = len(v_out) - 1

            return v_out[length][:-1]
        except Exception:
            return False