Skip to content

Commit

Permalink
Tentatively completed remote telemetry system
Browse files Browse the repository at this point in the history
  • Loading branch information
connervieira committed Jan 7, 2025
1 parent 1e384bf commit 6d3d93b
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 73 deletions.
1 change: 1 addition & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ These are the features actively planned for Predator and are likely to be added
- [X] Document `developer>frame_count_method` configuration value in `docs/CONFIGURE.md.
- [X] Validate multi-channel recording.
- [ ] Add sound effect for parking mode.
- [ ] Add management mode option to manually upload telemetry back-log.


## Issues
Expand Down
148 changes: 75 additions & 73 deletions utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -897,7 +897,7 @@ def count_frames(video):


if ("telemetry" in config["dashcam"] and config["dashcam"]["telemetry"]["saved_failed_updates"]):
telemetry_backlog_file_location = config["general"]["interface_directory"] + "/telemetry_backlog.json"
telemetry_backlog_file_location = config["general"]["working_directory"] + "/telemetry_backlog.json"
if (os.path.exists(telemetry_backlog_file_location) == False): # If the backlog file doesn't exist, create it.
save_to_file(telemetry_backlog_file_location, "{}") # Save a blank placeholder dictionary to the backlog file.

Expand All @@ -914,84 +914,86 @@ def count_frames(video):
def send_telemetry(data):
global last_telemetry_sent
global telemetry_backlog
data["system"] = {}
data["system"]["timezone"] = timezone_offset_stamp # Add the system timezone to the data.

# Format:
# data = {
# "system": { # Must be present
# "timezone": "UTC+00:00" # Must be present and valid.
# },
# "image": { # Can be omitted if no image data is present.
# "main": [OpenCV image],
# "rear": "[OpenCV image]",
# ...
# },
# "location": { # Must be present, but can be set to all zeros.
# "time": 0.0,
# "lat": 0.0,
# "lon": 0.0,
# "alt": 0.0,
# "spd": 0.0,
# "head": 0.0
# }
# }
if (time.time() - last_telemetry_sent >= 10): # Check to see if it has been at least 10 seconds since the last telemetry update. Note: most external receivers (such as V0LT Portal) will reject any data within 10 seconds of a previous datapoint.
print("Sending telemetry") # TODO: REMOVE
for device in data["image"]:
# Rescale the image to 720p:
original_height, original_width = data["image"][device].shape[:2]
target_height = 720
scale_factor = target_height / original_height
if (scale_factor < 1): # Check to make sure we're shrinking the image, not upscaling it.
new_width = int(original_width * scale_factor)
data["image"][device] = cv2.resize(data["image"][device], (new_width, target_height)) # Resize the frame to the target size.

# Encode the image to base64 for transmission:
retval, buffer = cv2.imencode('.jpg', data["image"][device])
data["image"][device] = base64.b64encode(buffer).decode("utf-8")

last_telemetry_sent = time.time()

submission = json.dumps(data) # Convert the image information into a string.
try:
request = requests.post(config["dashcam"]["telemetry"]["target"], data={"identifier": config["dashcam"]["telemetry"]["identifier"], "data": submission}, timeout=8) # Submit the data.
response = request.content
if (is_json(response)):
response = json.loads(response)
if ("success" in response and response["success"] == True):
success = True
if (config["dashcam"]["telemetry"]["enabled"]):
data["system"] = {}
data["system"]["timezone"] = timezone_offset_stamp # Add the system timezone to the data.

# Format:
# data = {
# "system": { # Must be present
# "timezone": "UTC+00:00" # Must be present and valid.
# },
# "image": { # Can be omitted if no image data is present.
# "main": [OpenCV image],
# "rear": "[OpenCV image]",
# ...
# },
# "location": { # Must be present, but can be set to all zeros.
# "time": 0.0,
# "lat": 0.0,
# "lon": 0.0,
# "alt": 0.0,
# "spd": 0.0,
# "head": 0.0
# }
# }
if (time.time() - last_telemetry_sent >= 10): # Check to see if it has been at least 10 seconds since the last telemetry update. Note: most external receivers (such as V0LT Portal) will reject any data within 10 seconds of a previous datapoint.
for device in data["image"]:
# Rescale the image to 720p:
original_height, original_width = data["image"][device].shape[:2]
target_height = 720
scale_factor = target_height / original_height
if (scale_factor < 1): # Check to make sure we're shrinking the image, not upscaling it.
new_width = int(original_width * scale_factor)
data["image"][device] = cv2.resize(data["image"][device], (new_width, target_height)) # Resize the frame to the target size.

# Encode the image to base64 for transmission:
retval, buffer = cv2.imencode('.jpg', data["image"][device])
data["image"][device] = base64.b64encode(buffer).decode("utf-8")

last_telemetry_sent = time.time()

submission = json.dumps(data) # Convert the image information into a string.
try:
request = requests.post(config["dashcam"]["telemetry"]["target"], data={"identifier": config["dashcam"]["telemetry"]["vehicle_identifier"], "data": submission}, timeout=8) # Submit the data.
response = request.content
if (is_json(response)):
response = json.loads(response)
if ("success" in response and response["success"] == True):
success = True
else:
success = False
if ("reason" in response):
display_message("The remote telemetry provider responded with an error: " + str(response["reason"]), 2)
else:
display_message("The remote telemetry provider responded with an unknown error.", 2)
else:
display_message("The response from the remote telemetry provider was not valid JSON.", 2)
success = False
if ("reason" in response):
display_message("The remote telemetry provider responded with an error: " + str(response["reason"]), 2)
else:
display_message("The remote telemetry provider responded with an unknown error.", 2)
else:
display_message("The response from the remote telemetry provider was not valid JSON.", 2)
except Exception as exception:
display_message("The telemetry upload process failed with the following exception:", 2)
print(exception)
success = False
except:
display_message("The telemetry", 2)
success = False

if (success == True):
if (len(telemetry_backlog) > 0): # Check to see if there is at least one request in the back-log.
for timestamp in telemetry_backlog: # Iterate over each entry in the telemetry back-log.
try:
request = requests.post(config["dashcam"]["telemetry"]["target"], data={"identifier": config["dashcam"]["telemetry"]["identifier"], "data": json.dumps(telemetry_backlog[timestamp])}, timeout=8) # Submit the data.
response = request.content
if ("success" in response and response["success"] == True):
success = True
else:
if (success == True):
if (len(telemetry_backlog) > 0): # Check to see if there is at least one request in the back-log.
for timestamp in list(telemetry_backlog.keys()): # Iterate over each entry in the telemetry back-log.
try:
request = requests.post(config["dashcam"]["telemetry"]["target"], data={"identifier": config["dashcam"]["telemetry"]["vehicle_identifier"], "data": json.dumps(telemetry_backlog[timestamp])}, timeout=8) # Submit the data.
response = json.loads(request.content)
if ("success" in response and response["success"] == True):
success = True
else:
success = False
except Exception as e:
success = False
except:
success = False
if (success == True): # Check to see if the data submission was successful.
del telemetry_backlog[timestamp] # Delete this point from the back-log.
if (success == True): # Check to see if the data submission was successful.
del telemetry_backlog[timestamp] # Delete this point from the back-log.
save_to_file(telemetry_backlog_file_location, json.dumps(telemetry_backlog)) # Save the updated back-log file.
else:
del data["image"] # Delete the image data before adding it to the backlog.
telemetry_backlog[data["location"]["time"]] = data # Add this datapoint to the back-log.
save_to_file(telemetry_backlog_file_location, json.dumps(telemetry_backlog)) # Save the updated back-log file.
else:
telemetry_backlog[data["location"]["time"]] = data # Add this datapoint to the back-log.
save_to_file(telemetry_backlog_file_location, json.dumps(telemetry_backlog)) # Save the updated back-log file.



Expand Down

0 comments on commit 6d3d93b

Please sign in to comment.