def run(): try: log.info('micropython p1 meter is starting...') fb.clear() asyncio.run(main(glb_mqtt_client)) finally: # status fb.clear(fb.RED) log.info("Clear async loop retained state") asyncio.new_event_loop() # Clear retained state reboot(10)
def connect(self): global _conn_errors if self.mqtt_client is None: log.info("create mqtt client {0}".format(self.server)) self.mqtt_client = MQTTClient(NETWORK_ID, self.server, port=self.port, user=self.user, password=self.password) if wlan.status() == network.STAT_GOT_IP: try: print("connecting to mqtt server {0}".format(self.server)) self.mqtt_client.connect() print("Connected") except (MQTTException, OSError) as e: # try to give a decent error for common problems if type(e) is type(MQTTException()): if e.args[0] == 5: # EIO log.error("MQTT server error {}: {}".format( e, "check username/password")) elif e.args[0] == 2: # ENOENT log.error("MQTT server error {}: {}".format( e, "server address or network")) else: log.error("{} {}".format(type(e).__name__, e)) else: ## OSError if int(e.args[0]) == -2: # could not resolve ? log.error("OS Error {}: {}".format( e, "Host unreachable, is mDNS working to resolve MQTT server name ?" )) elif e.args[0] in (113, 23): # EHOSTUNREACH log.error("OS Error {}: {}".format( e, "Host unreachable, check server address or network" )) elif e.args[0] < 0: # some negative socket error _conn_errors = +1 if _conn_errors > 10: log.error("OS Error {}: {}".format( e, "attempting reboot to fix")) reboot() else: log.error("OS Error {}".format(e)) else: log.error("{} {}".format(type(e).__name__, e)) else: log.warning('network not ready/stable')
def measure(q, offline, debug, ts_channels, ts_server_url, filtered_temperature, ds18b20Sensors, bme680Sensors, bme680Inits, dhtSensors, aht10Sensors, sht31Sensors, hdc1008Sensors, bh1750Sensors, tcSensors, bme280Sensors, pcf8591Sensors, ee895Sensors, weightSensors, hxInits, connectionErrors, measurementIsRunning): measurementIsRunning.value = 1 # set flag ts_fields = {} try: ts_fields, bme680Inits = measure_all_sensors(debug, filtered_temperature, ds18b20Sensors, bme680Sensors, bme680Inits, dhtSensors, aht10Sensors, sht31Sensors, hdc1008Sensors, bh1750Sensors, tcSensors, bme280Sensors, pcf8591Sensors, ee895Sensors, weightSensors, hxInits) if len(ts_fields) > 0: ts_datetime=thingspeak_datetime() if offline == 1 or offline == 3: try: s = write_csv(ts_fields, ts_channels, ts_datetime) if s and debug: logger.info("Data succesfully saved to CSV-File.") except Exception as ex: logger.exception("Exception in measure / write_csv") # if transfer to thingspeak is set if (offline == 0 or offline == 1 or offline == 2) and ts_channels: # update ThingSpeak / transfer values connectionErrorHappened = manage_transfer_to_ts(ts_channels, ts_fields, ts_server_url, offline, debug, ts_datetime) if connectionErrorHappened: MAX_RETRIES_IN_A_ROW = 3 # Do Rebooting if to many connectionErrors in a row connectionErrors.value +=1 logger.error("Failed internet connection. Count: " + str(connectionErrors.value) + "/" + str(MAX_RETRIES_IN_A_ROW)) if connectionErrors.value >= MAX_RETRIES_IN_A_ROW: if not debug: logger.critical("Too many Connection Errors in a row => Rebooting Raspberry") time.sleep(4) reboot() else: logger.critical("Too many Connection Errors in a row but did not reboot because console debug mode is enabled.") else: if connectionErrors.value > 0: if debug: logger.warning("Connection Errors (" + str(connectionErrors.value) + ") Counting resetet because transfer succeded.") # reset connectionErrors because transfer succeded connectionErrors.value = 0 elif debug: logger.info("No measurement data to send.") except Exception as ex: logger.exception("Exception during measure (outer).") measurementIsRunning.value = 0 # clear flag
def start_measurement(measurement_stop): try: global burn_in_time start_time = time.time() # load settings settings = get_settings() ts_channels = settings[ "ts_channels"] # ThingSpeak data (ts_channel_id, ts_write_key) ts_server_url = settings["ts_server_url"] debuglevel = settings["debuglevel"] if debuglevel <= 10: debug = True # flag to enable debug mode (HDMI output enabled and no rebooting) else: debug = False # flag to enable debug mode (HDMI output enabled and no rebooting) wittyPi = settings["wittyPi"] offline = settings["offline"] # flag to enable offline csv storage isLowVoltage = getStateFromStorage('isLowVoltage', False) if isLowVoltage == True: interval = wittyPi["low"]["interval"] shutdownAfterTransfer = wittyPi["low"]["shutdownAfterTransfer"] else: interval = wittyPi["normal"]["interval"] shutdownAfterTransfer = wittyPi["normal"]["shutdownAfterTransfer"] if debug: logger.info("The measurements have started.") # with process shared variables connectionErrors = Value('i', 0) measurementIsRunning = Value('i', 0) if interval and not isinstance(interval, int) or interval == 0: interval = 0 logger.info("Stop measurement because interval is null.") measurement_stop.set() # read configured sensors from settings.json ds18b20Sensors = get_sensors(settings, 0) bme680Sensors = get_sensors(settings, 1) weightSensors = get_sensors(settings, 2) dhtSensors = get_sensors(settings, 3) tcSensors = get_sensors(settings, 4) bme280Sensors = get_sensors(settings, 5) pcf8591Sensors = get_sensors(settings, 6) ee895Sensors = get_sensors(settings, 7) aht10Sensors = get_sensors(settings, 8) sht31Sensors = get_sensors(settings, 9) hdc1008Sensors = get_sensors(settings, 10) bme680Inits = [] # -- Run Pre Configuration -- # if bme680 is configured for (sensorIndex, bme680Sensor) in enumerate(bme680Sensors): bme680Init = {} if 'burn_in_time' in bme680Sensor: burn_in_time = bme680Sensor["burn_in_time"] sensor = initBME680FromMain(bme680Sensor) gas_baseline = burn_in_bme680(sensor, burn_in_time) bme680Init['sensor'] = sensor bme680Init['gas_baseline'] = gas_baseline bme680Inits.append(bme680Init) # if hx711 is set hxInits = [] for (i, sensor) in enumerate(weightSensors): _hx = init_hx711(sensor) hxInits.append(_hx) # PCF8591 if pcf8591Sensors and len(pcf8591Sensors) == 1: voltage = get_raw_voltage( pcf8591Sensors[0] ) # initial measurement as first measurement is always wrong # -- End Pre Configuration -- # start at -6 because we want to get 6 values before we can filter some out counter = -6 time_measured = 0 time_measured_Voltage = 0 # Main loop which checks every second while not measurement_stop.is_set(): counter += 1 time_now = time.time() for (sensorIndex, sensor) in enumerate(ds18b20Sensors): checkIfSensorExistsInArray(sensorIndex) if 'device_id' in sensor: read_unfiltered_temperatur_values(sensorIndex, sensor) time_measured_Voltage, interval, shutdownAfterTransfer, isLowVoltage = check_wittypi_voltage( time_measured_Voltage, wittyPi, pcf8591Sensors, isLowVoltage, interval, shutdownAfterTransfer) # wait seconds of interval before next check # free ThingSpeak account has an upload limit of 15 seconds isTimeToMeasure = ((time_now - time_measured >= interval) or (interval == 1)) and counter > 0 if isTimeToMeasure: now = time.strftime("%H:%M", time.localtime(time_now)) lastMeasurement = time.strftime("%H:%M", time.localtime(time_measured)) if time_measured == 0: print("First time measurement. Now: " + str(now)) else: print("Last measurement was at " + str(lastMeasurement)) print("Time over for a new measurement. Time is now: " + str(now)) time_measured = time.time() check_undervoltage('0x7') if measurementIsRunning.value == 0: q = Queue() p = Process(target=measure, args=(q, offline, debug, ts_channels, ts_server_url, filtered_temperature, ds18b20Sensors, bme680Sensors, bme680Inits, dhtSensors, aht10Sensors, sht31Sensors, hdc1008Sensors, tcSensors, bme280Sensors, pcf8591Sensors, ee895Sensors, weightSensors, hxInits, connectionErrors, measurementIsRunning)) p.start() p.join() else: logger.warning( "Forerun measurement is not finished yet. Consider increasing interval." ) # stop measurements after uploading once if interval == 1: print("Only one measurement was set => stop measurements.") measurement_stop.set() if shutdownAfterTransfer: isMaintenanceActive = getStateFromStorage( 'isMaintenanceActive', False) print("Wert isMaintenanceActive: " + str(isMaintenanceActive)) while isMaintenanceActive: isMaintenanceActive = getStateFromStorage( 'isMaintenanceActive', False) print( "Shutting down was set but Maintenance mode is active, delaying shutdown!" ) print("Wert isMaintenanceActive: " + str(isMaintenanceActive)) time.sleep(10) print( "Shutting down was set => Waiting 10seconds and then shutdown." ) tblink = threading.Thread(target=blink_led, args=(settings["led_pin"], 0.25)) tblink.start() time.sleep(10) shutdown() time.sleep(6) # wait 6 seconds before next measurement check end_time = time.time() time_taken = end_time - start_time # time_taken is in seconds time_taken_s = float( "{0:.2f}".format(time_taken)) # remove microseconds print("Measurement-Script runtime was " + str(time_taken_s) + " seconds.") except Exception as ex: logger.exception("Unhandled Exception in start_measurement") if not debug: time.sleep(10) reboot()
def main(): try: global isActive, measurement_stop, measurement, debug, GPIO_BTN, GPIO_LED logger = logging.getLogger('HoneyPi') logger.setLevel(logging.DEBUG) fh = logging.FileHandler(logfile) fh.setLevel(logging.DEBUG) # create console handler with a higher log level ch = logging.StreamHandler() ch.setLevel(logging.INFO) # create formatter and add it to the handlers formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s') fh.setFormatter(formatter) ch.setFormatter(formatter) # add the handlers to the logger logger.addHandler(fh) logger.addHandler(ch) #logging.basicConfig(filename=logfile, format='%(asctime)s %(levelname)-8s %(message)s', level=logging.INFO) #logging.getLogger().addHandler(logging.StreamHandler(sys.stdout)) logger.info('HoneyPi Started') # Zaehlweise der GPIO-PINS auf der Platine GPIO.setmode(GPIO.BCM) # read settings for number of GPIO pin settings = get_settings() debuglevel = settings["debuglevel"] print("Debuglevel: " + str(debuglevel)) time.sleep(5) if debuglevel <= 10: debug = True # flag to enable debug mode (HDMI output enabled and no rebooting) else: debug = False # flag to enable debug mode (HDMI output enabled and no rebooting) GPIO_BTN = settings["button_pin"] GPIO_LED = settings["led_pin"] # setup LED as output GPIO.setup(GPIO_LED, GPIO.OUT) # blink with LED on startup tblink = threading.Thread(target=blink_led, args=(GPIO_LED, )) tblink.start() # after start is AccessPoint down stop_ap() # Create virtual uap0 for WLAN create_ap() # Call wvdial for surfsticks start_wvdial() if not debuglevel <= 20: # stop HDMI power (save energy) print("Info: Shutting down HDMI to save energy.") stop_tv() stop_hdd_led() else: logger.info("Info: Raspberry Pi has been powered on.") start_hdd_led() logger.info("Default gateway used for Internet connection is: " + str(get_default_gateway_linux())) logger.info("Interface eth0 is up: " + str(get_interface_upstatus_linux('eth0'))) logger.info("Interface wlan0 is up: " + str(get_interface_upstatus_linux('wlan0'))) # start as seperate background thread # because Taster pressing was not recognised isMaintenanceActive = setStateToStorage('isMaintenanceActive', False) measurement_stop = threading.Event( ) # create event to stop measurement measurement = threading.Thread(target=start_measurement, args=(measurement_stop, )) measurement.start() # start measurement # setup Button GPIO.setup( GPIO_BTN, GPIO.IN, pull_up_down=GPIO.PUD_DOWN ) # Set pin 16 to be an input pin and set initial value to be pulled low (off) #GPIO.setup(GPIO_LED, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) # Set LED to be an input pin and set initial value to be pulled low (off) bouncetime = 100 # ignoring further edges for 100ms for switch bounce handling # register button press event GPIO.add_event_detect(GPIO_BTN, GPIO.BOTH, callback=button_pressed, bouncetime=bouncetime) #GPIO.add_event_detect(GPIO_LED, GPIO.BOTH, callback=get_led_state) # Main Lopp: Cancel with STRG+C while True: time.sleep( 0.2) # wait 200 ms to give CPU chance to do other things pass print("This text will never be printed.") except Exception as e: logger.critical("Unhandled Exception in main " + repr(e)) if not debug: time.sleep(60) reboot()
callback=button_pressed, bouncetime=bouncetime) #GPIO.add_event_detect(GPIO_LED, GPIO.BOTH, callback=get_led_state) # Main Lopp: Cancel with STRG+C while True: time.sleep( 0.2) # wait 200 ms to give CPU chance to do other things pass print("This text will never be printed.") except Exception as e: logger.critical("Unhandled Exception in main " + repr(e)) if not debug: time.sleep(60) reboot() if __name__ == '__main__': try: main() except (KeyboardInterrupt, SystemExit): close_script() except Exception as e: logger.error("Unhandled Exception in __main__ " + repr(e)) if not debug: time.sleep(60) reboot()
def main(): try: global isActive, measurement_stop, measurement, debug, GPIO_BTN, GPIO_LED # Zaehlweise der GPIO-PINS auf der Platine GPIO.setmode(GPIO.BCM) # read settings for number of GPIO pin settings = get_settings() debuglevel = int(settings["debuglevel"]) debuglevel_logfile = int(settings["debuglevel_logfile"]) logger = logging.getLogger('HoneyPi') logger.setLevel(logging.DEBUG) fh = RotatingFileHandler(logfile, maxBytes=5 * 1024 * 1024, backupCount=365) fh.setLevel(logging.getLevelName(debuglevel_logfile)) # create console handler with a higher log level ch = logging.StreamHandler() ch.setLevel(logging.getLevelName(debuglevel)) # create formatter and add it to the handlers formatter = logging.Formatter( '%(asctime)s | %(levelname)s | %(name)s | %(message)s') fh.setFormatter(formatter) ch.setFormatter(formatter) # add the handlers to the logger logger.addHandler(fh) logger.addHandler(ch) time.sleep(1) if debuglevel <= 10: debug = True # flag to enable debug mode (HDMI output enabled and no rebooting) else: debug = False # flag to enable debug mode (HDMI output enabled and no rebooting) if debuglevel > 20: # stop HDMI power (save energy) logger.info('HoneyPi ' + get_rpiscripts_version() + ' Started on ' + get_pi_model() + ', Debuglevel: "' + logging.getLevelName(debuglevel) + '", Debuglevel logfile: "' + logging.getLevelName(debuglevel_logfile) + '"') stop_tv() stop_hdd_led() else: logger.info('HoneyPi ' + get_rpiscripts_version() + ' Started on ' + get_pi_model()) start_hdd_led() runpostupgradescript() GPIO_BTN = settings["button_pin"] GPIO_LED = settings["led_pin"] # setup LED as output GPIO.setup(GPIO_LED, GPIO.OUT) # blink with LED on startup tblink = threading.Thread(target=blink_led, args=(GPIO_LED, )) tblink.start() # Call wvdial for surfsticks connect_internet_modem(settings) # check undervolate for since system start check_undervoltage() # start as seperate background thread # because Taster pressing was not recognised isMaintenanceActive = setStateToStorage('isMaintenanceActive', False) measurement_stop = threading.Event( ) # create event to stop measurement measurement = threading.Thread(target=start_measurement, args=(measurement_stop, )) measurement.start() # start measurement # setup Button GPIO.setup( GPIO_BTN, GPIO.IN, pull_up_down=GPIO.PUD_DOWN ) # Set pin 16 to be an input pin and set initial value to be pulled low (off) bouncetime = 100 # ignoring further edges for 100ms for switch bounce handling # register button press event GPIO.add_event_detect(GPIO_BTN, GPIO.BOTH, callback=button_pressed, bouncetime=bouncetime) # Main Lopp: Cancel with STRG+C while True: time.sleep( 0.2) # wait 200 ms to give CPU chance to do other things pass print("This text will never be printed.") except Exception as ex: logger.critical("Unhandled Exception in main: " + repr(ex)) if not debug: time.sleep(60) reboot()
def measure(offline, debug, channel, filtered_temperature, ds18b20Sensors, bme680Sensors, bme680IsInitialized, dhtSensors, tcSensors, bme280Sensors, weightSensors, hxInits, connectionErrors, measurementIsRunning): measurementIsRunning.value = 1 # set flag # filter the values out for (sensorIndex, sensor) in enumerate(ds18b20Sensors): filter_temperatur_values(sensorIndex) # dict with all fields and values which will be tranfered to ThingSpeak later ts_fields = {} # measure every sensor with type 0 for (sensorIndex, sensor) in enumerate(ds18b20Sensors): # if we have at leat one filtered value we can upload if len(filtered_temperature[sensorIndex]) > 0 and 'ts_field' in sensor: ds18b20_temperature = filtered_temperature[sensorIndex].pop( ) # get last value from array ts_field_ds18b20 = sensor["ts_field"] if ts_field_ds18b20: ts_fields.update({ts_field_ds18b20: ds18b20_temperature}) # measure BME680 (can only be one) [type 1] if bme680Sensors and len(bme680Sensors) == 1 and bme680IsInitialized: bme680_values = measure_bme680(bme680Sensors[0], 30) ts_fields.update(bme680_values) # measure every sensor with type 3 [DHT11/DHT22] for (i, sensor) in enumerate(dhtSensors): tempAndHum = measure_dht(sensor) ts_fields.update(tempAndHum) # measure every sensor with type 4 [MAX6675] for (i, sensor) in enumerate(tcSensors): tc_temp = measure_tc(sensor) ts_fields.update(tc_temp) # measure BME280 (can only be one) [type 5] if bme280Sensors and len(bme280Sensors) == 1: bme280_values = measure_bme280(bme280Sensors[0]) ts_fields.update(bme280_values) start_single() # measure every sensor with type 2 [HX711] for (i, sensor) in enumerate(weightSensors): weight = measure_weight(sensor, hxInits[i]) weight = compensate_temperature(sensor, weight, ts_fields) ts_fields.update(weight) stop_single() # print all measurement values stored in ts_fields for key, value in ts_fields.items(): print(key + ": " + str(value)) if len(ts_fields) > 0: if offline == 1 or offline == 3: try: s = write_csv(ts_fields) if s and debug: error_log("Info: Data succesfully saved to CSV-File.") except Exception as ex: error_log(ex, "Exception") # if transfer to thingspeak is set if offline == 0 or offline == 1 or offline == 2: # do-while to retry failed transfer retries = 0 connectionError = True while True: try: # update ThingSpeak / transfer values channel.update(ts_fields) if debug: error_log( "Info: Data succesfully transfered to ThingSpeak.") if connectionErrors.value > 0: if debug: error_log("Info: Connection Errors (" + str(connectionErrors.value) + ") Counting resetet.") # reset connectionErrors because transfer succeded connectionErrors.value = 0 # break do-while because transfer succeded connectionError = False break except requests.exceptions.HTTPError as errh: error_log(errh, "Http Error") except requests.exceptions.ConnectionError as errc: pass except requests.exceptions.Timeout as errt: error_log(errt, "Timeout Error") except requests.exceptions.RequestException as err: error_log(err, "Something Else") except Exception as ex: error_log(ex, "Exception while sending Data") finally: if connectionError: print( "Warning: Waiting for internet connection to try transfer again..." ) wait_for_internet_connection( 15) # wait before next try retries += 1 # Maximum 3 retries if retries >= 3: break # break do-while if connectionError: # Write to CSV-File if ConnectionError occured if offline == 2: s = write_csv(ts_fields) if s and debug: error_log("Info: Data succesfully saved to CSV-File.") # Do Rebooting if to many connectionErrors in a row connectionErrors.value += 1 error_log("Error: Failed internet connection. Count: " + str(connectionErrors.value)) if connectionErrors.value >= 5: if not debug: error_log( "Info: Too many ConnectionErrors in a row => Rebooting" ) time.sleep(4) reboot() else: error_log( "Info: Did not reboot because debug mode is enabled." ) elif debug: error_log("Info: No measurement data to send.") measurementIsRunning.value = 0 # clear flag
def start_measurement(measurement_stop): try: start_time = time.time() # load settings settings = get_settings() # ThingSpeak data channel_id = settings["ts_channel_id"] write_key = settings["ts_write_key"] interval = settings["interval"] debug = settings[ "debug"] # flag to enable debug mode (HDMI output enabled and no rebooting) shutdownAfterTransfer = settings["shutdownAfterTransfer"] offline = settings["offline"] # flag to enable offline csv storage if debug: print("Debug-Mode is enabled.") error_log("Info: The measurements have started.") # with process shared variables connectionErrors = Value('i', 0) measurementIsRunning = Value('i', 0) if interval and not isinstance( interval, int) or interval == 0 or not channel_id or not write_key: error_log( "Info: No measurement because ThingSpeak settings are not complete or measurement interval is null." ) measurement_stop.set() # read configured sensors from settings.json ds18b20Sensors = get_sensors(settings, 0) bme680Sensors = get_sensors(settings, 1) weightSensors = get_sensors(settings, 2) dhtSensors = get_sensors(settings, 3) tcSensors = get_sensors(settings, 4) bme280Sensors = get_sensors(settings, 5) # -- Run Pre Configuration -- # if bme680 is configured if bme680Sensors and len(bme680Sensors) == 1: bme680IsInitialized = initBME680FromMain() else: bme680IsInitialized = 0 # if hx711 is set hxInits = [] for (i, sensor) in enumerate(weightSensors): _hx = init_hx711(sensor, debug) hxInits.append(_hx) # ThingSpeak channel channel = thingspeak.Channel(id=channel_id, write_key=write_key) # start at -6 because we want to get 6 values before we can filter some out counter = -6 time_measured = 0 while not measurement_stop.is_set(): counter += 1 # read values from sensors every second for (sensorIndex, sensor) in enumerate(ds18b20Sensors): checkIfSensorExistsInArray(sensorIndex) if 'device_id' in sensor: read_unfiltered_temperatur_values(sensorIndex, sensor['device_id']) # wait seconds of interval before next check # free ThingSpeak account has an upload limit of 15 seconds time_now = time.time() isTimeToMeasure = (time_now - time_measured >= interval ) and counter > 0 # old: counter%interval == 0 if isTimeToMeasure or interval == 1: now = time.strftime("%H:%M", time.localtime(time_now)) lastMeasurement = time.strftime("%H:%M", time.localtime(time_measured)) if time_measured == 0: print("First time measurement. Now: " + str(now)) else: print("Last measurement was at " + str(lastMeasurement)) print("Time over for a new measurement. Time is now: " + str(now)) time_measured = time.time() if measurementIsRunning.value == 0: q = Queue() p = Process(target=measure, args=(offline, debug, channel, filtered_temperature, ds18b20Sensors, bme680Sensors, bme680IsInitialized, dhtSensors, tcSensors, bme280Sensors, weightSensors, hxInits, connectionErrors, measurementIsRunning)) p.start() p.join() else: error_log( "Warning: Forerun measurement is not finished yet. Consider increasing interval." ) # stop measurements after uploading once if interval == 1: print("Only one measurement was set => stop measurements.") measurement_stop.set() if shutdownAfterTransfer: print( "Shutting down was set => Waiting 10seconds and then shutdown." ) time.sleep(10) shutdown() time.sleep(6) # wait 6 seconds before next measurement check end_time = time.time() time_taken = end_time - start_time # time_taken is in seconds time_taken_s = float( "{0:.2f}".format(time_taken)) # remove microseconds print("Measurement-Script runtime was " + str(time_taken_s) + " seconds.") except Exception as e: error_log(e, "Unhandled Exception while Measurement") if not debug: time.sleep(10) reboot()
def measure(offline, debug, ts_channels, ts_server_url, filtered_temperature, ds18b20Sensors, bme680Sensors, bme680IsInitialized, dhtSensors, aht10Sensors, sht31Sensors, hdc1008Sensors, tcSensors, bme280Sensors, voltageSensors, ee895Sensors, weightSensors, hxInits, connectionErrors, measurementIsRunning): measurementIsRunning.value = 1 # set flag ts_fields = {} try: ts_fields = measure_all_sensors( debug, filtered_temperature, ds18b20Sensors, bme680Sensors, bme680IsInitialized, dhtSensors, aht10Sensors, sht31Sensors, hdc1008Sensors, tcSensors, bme280Sensors, voltageSensors, ee895Sensors, weightSensors, hxInits) if len(ts_fields) > 0: if offline == 1 or offline == 3: try: s = write_csv(ts_fields, ts_channels) if s and debug: error_log("Info: Data succesfully saved to CSV-File.") except Exception as ex: error_log(ex, "Exception in measure (1)") # if transfer to thingspeak is set if (offline == 0 or offline == 1 or offline == 2) and ts_channels: # update ThingSpeak / transfer values connectionErrorHappened = manage_transfer_to_ts( ts_channels, ts_fields, ts_server_url, offline, debug) if connectionErrorHappened: MAX_RETRIES_IN_A_ROW = 3 # Do Rebooting if to many connectionErrors in a row connectionErrors.value += 1 error_log("Error: Failed internet connection. Count: " + str(connectionErrors.value) + "/" + str(MAX_RETRIES_IN_A_ROW)) if connectionErrors.value >= MAX_RETRIES_IN_A_ROW: if not debug: error_log( "Warning: Too many Connection Errors in a row => Rebooting Raspberry" ) time.sleep(4) reboot() else: error_log( "Info: Did not reboot because debug mode is enabled." ) else: if connectionErrors.value > 0: if debug: error_log( "Info: Connection Errors (" + str(connectionErrors.value) + ") Counting resetet because transfer succeded." ) # reset connectionErrors because transfer succeded connectionErrors.value = 0 elif debug: error_log("Info: No measurement data to send.") measurementIsRunning.value = 0 # clear flag except Exception as ex: error_log(ex, "Exception during measure (2)") measurementIsRunning.value = 0 # clear flag
def start_measurement(measurement_stop): try: print("The measurements have started.") start_time = time.time() # load settings settings = get_settings() # ThingSpeak data channel_id = settings["ts_channel_id"] write_key = settings["ts_write_key"] interval = settings["interval"] if interval and not isinstance( interval, int) or interval == 0 or not channel_id or not write_key: print("ThingSpeak settings are not complete or interval is 0") measurement_stop.set() # read configured sensors from settings.json ds18b20Sensors = get_sensors(settings, 0) bme680Sensors = get_sensors(settings, 1) weightSensors = get_sensors(settings, 2) dhtSensors = get_sensors(settings, 3) # if bme680 is configured if bme680Sensors and len(bme680Sensors) == 1: gas_baseline = None if initBME680FromMain(): # bme680 sensor must be burned in before use gas_baseline = burn_in_bme680(30) # if burning was canceled => exit if gas_baseline is None: print("gas_baseline can't be None") # ThingSpeak channel channel = thingspeak.Channel(id=channel_id, write_key=write_key) # counting connection Errors connectionErros = 0 # start at -6 because we want to get 6 values before we can filter some out counter = -6 while not measurement_stop.is_set(): # read values from sensors every second for (sensorIndex, sensor) in enumerate(ds18b20Sensors): checkIfSensorExistsInArray(sensorIndex) if 'device_id' in sensor: read_unfiltered_temperatur_values(sensorIndex, sensor['device_id']) # for testing: #try: # weight = measure_weight(weightSensors[0]) # print("weight: " + str(list(weight.values())[0])) #except IOError: # print "IOError occurred" #except TypeError: # print "TypeError occurred" #except IndexError: # print "IndexError occurred" # wait seconds of interval before next check # free ThingSpeak account has an upload limit of 15 seconds if counter % interval == 0: print("Time over for a new measurement.") # filter the values out for (sensorIndex, sensor) in enumerate(ds18b20Sensors): filter_temperatur_values(sensorIndex) # dict with all fields and values which will be tranfered to ThingSpeak later ts_fields = {} # measure every sensor with type 0 for (sensorIndex, sensor) in enumerate(ds18b20Sensors): # if we have at leat one filtered value we can upload if len(filtered_temperature[sensorIndex] ) > 0 and 'ts_field' in sensor: ds18b20_temperature = filtered_temperature[ sensorIndex].pop() # get last value from array ts_field_ds18b20 = sensor["ts_field"] if ts_field_ds18b20: ts_fields.update( {ts_field_ds18b20: ds18b20_temperature}) # measure BME680 (can only be once) [type 1] if bme680Sensors and len(bme680Sensors) == 1 and gas_baseline: bme680_values = measure_bme680(gas_baseline, bme680Sensors[0]) ts_fields.update(bme680_values) # measure every sensor with type 2 [HX711] for (i, sensor) in enumerate(weightSensors): weight = measure_weight(sensor) ts_fields.update(weight) # measure every sensor with type 3 [DHT11/DHT22] for (i, sensor) in enumerate(dhtSensors): tempAndHum = measure_dht(sensor) ts_fields.update(tempAndHum) # print measurement values for debug reasons for key, value in ts_fields.iteritems(): print key + ": " + str(value) try: # update ThingSpeak / transfer values if len(ts_fields) > 0: channel.update(ts_fields) # reset connectionErros because transfer succeded connectionErros = 0 except requests.exceptions.HTTPError as errh: error_log(errh, "Http Error") except requests.exceptions.ConnectionError as errc: error_log(errc, "Error Connecting") connectionErros += 1 # multiple connectionErrors in a row => Exception if connectionErros > 4: raise MyRebootException except requests.exceptions.Timeout as errt: error_log(errt, "Timeout Error") except requests.exceptions.RequestException as err: error_log(err, "Something Else") counter += 1 sleep(0.96) end_time = time.time() time_taken = end_time - start_time # time_taken is in seconds time_taken_s = float( "{0:.2f}".format(time_taken)) # remove microseconds print("Measurement-Script runtime was " + str(time_taken_s) + " seconds.") except MyRebootException as re: error_log(re, "Too many ConnectionErrors in a row => Rebooting") time.sleep(1) reboot() except Exception as e: error_log(e, "Unhandled Exception while Measurement") time.sleep(60) reboot()