diff --git a/enviro/__init__.py b/enviro/__init__.py index 236f280..06c7cda 100644 --- a/enviro/__init__.py +++ b/enviro/__init__.py @@ -415,18 +415,34 @@ def upload_readings(): return False destination = config.destination + secondary_destination = config.secondary_destination + valid_secondary_destinations = ["http", "mqtt", "adafruit_io", "influxdb", "wunderground"] + try: exec(f"import enviro.destinations.{destination}") destination_module = sys.modules[f"enviro.destinations.{destination}"] - destination_module.log_destination() + + if secondary_destination in valid_secondary_destinations and secondary_destination != destination: + exec(f"import enviro.destinations.{secondary_destination}") + secondary_destination_module = sys.modules[f"enviro.destinations.{secondary_destination}"] for cache_file in os.ilistdir("uploads"): try: with open(f"uploads/{cache_file[0]}", "r") as upload_file: - status = destination_module.upload_reading(ujson.load(upload_file)) + filename = cache_file[0] + json = ujson.load(upload_file) + destination_module.log_destination() + status = destination_module.upload_reading(json) + + # Delete if primary upload succeeds regardless of secondary + # Prioritise stability over secondary destination data coverage + # This will mean multiple uploads to secondary if primary fails + # May need to improve destination success management depending on + # destination duplicate handling if status == UPLOAD_SUCCESS: + logging.info(f" - Primary destination upload success for {filename}") os.remove(f"uploads/{cache_file[0]}") - logging.info(f" - uploaded {cache_file[0]}") + logging.info(f" - removing file {cache_file[0]}") elif status == UPLOAD_RATE_LIMITED: # write out that we want to attempt a reupload with open("reattempt_upload.txt", "w") as attemptfile: @@ -452,6 +468,12 @@ def upload_readings(): else: logging.error(f" ! failed to upload '{cache_file[0]}' to {destination}") return False + + if secondary_destination in valid_secondary_destinations and secondary_destination != destination: + secondary_destination_module.log_destination() + secondary_status = secondary_destination_module.upload_reading(json) + if secondary_status == UPLOAD_SUCCESS: + logging.info(f" - Secondary destination upload success for {filename}") except OSError: logging.error(f" ! failed to open '{cache_file[0]}'") diff --git a/enviro/config_defaults.py b/enviro/config_defaults.py index cfdf5dd..4bb6f17 100644 --- a/enviro/config_defaults.py +++ b/enviro/config_defaults.py @@ -2,7 +2,7 @@ from phew import logging DEFAULT_USB_POWER_TEMPERATURE_OFFSET = 4.5 - +DEFAULT_SECONDARY_DESTINATION = None def add_missing_config_settings(): try: @@ -17,6 +17,12 @@ def add_missing_config_settings(): except AttributeError: warn_missing_config_setting("usb_power_temperature_offset") config.usb_power_temperature_offset = DEFAULT_USB_POWER_TEMPERATURE_OFFSET + + try: + config.secondary_destination + except AttributeError: + warn_missing_config_setting("secondary_destination") + config.secondary_destination = DEFAULT_SECONDARY_DESTINATION def warn_missing_config_setting(setting): diff --git a/enviro/config_template.py b/enviro/config_template.py index a345cc0..e1a22af 100644 --- a/enviro/config_template.py +++ b/enviro/config_template.py @@ -20,6 +20,13 @@ # where to upload to ("http", "mqtt", "adafruit_io", "influxdb") destination = None +# Optional secondary destination - this will consume more battery +# Cached uploads cleanup occurs only on primary destination success, this means +# secondary data will not retry if primary is successful, also secondary data +# will be reuploaded if the primary fails, ensure the secondary destination can +# handle duplicate uploads +# set to None if not in use +secondary_destination = None # how often to upload data (number of cached readings) upload_frequency = 5