Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Secondary upload destination #189

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 25 additions & 3 deletions enviro/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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]}'")
Expand Down
8 changes: 7 additions & 1 deletion enviro/config_defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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):
Expand Down
7 changes: 7 additions & 0 deletions enviro/config_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down