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
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