From fe951ab1d883e8a0e73733e5f847a347cce87d89 Mon Sep 17 00:00:00 2001 From: David Rollinson Date: Sun, 10 Jan 2021 11:28:45 +0800 Subject: [PATCH] Add capability to display last received telemetry after restart --- chasemapper/config.py | 17 ++++++++++-- chasemapper/logread.py | 61 +++++++++++++++++++++++++++++++++++++++++ horusmapper.cfg.example | 6 ++-- horusmapper.py | 13 +++++++++ 4 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 chasemapper/logread.py diff --git a/chasemapper/config.py b/chasemapper/config.py index b335960..8c7bfa3 100644 --- a/chasemapper/config.py +++ b/chasemapper/config.py @@ -42,8 +42,8 @@ default_config = { 'range_ring_color': 'red', 'range_ring_custom_color': '#FF0000', - # Chase Car Speedometer - 'chase_car_speed': True, + # Chase Car Speedometer + 'chase_car_speed': True, # Bearing processing 'max_bearings': 300, @@ -54,6 +54,9 @@ default_config = { 'bearing_color': 'black', 'bearing_custom_color': '#FF0000', + # History + 'reload_last_position': True + } @@ -179,11 +182,21 @@ def parse_config_file(filename): logging.critical("Default profile selection does not exist.") return None + # History + logging.info("Checking to see if reload_last_position is set") + chase_config['reload_last_position'] = config.getboolean('history', 'reload_last_position', fallback=False) + if (chase_config['reload_last_position']): + logging.info("Scanning logs to reload last position") + else: + logging.info("Not scanning logs to reload last position") + + return chase_config + def read_config(filename, default_cfg="horusmapper.cfg.example"): """ Read in a Horus Mapper configuration file,and return as a dict. """ diff --git a/chasemapper/logread.py b/chasemapper/logread.py new file mode 100644 index 0000000..0439d18 --- /dev/null +++ b/chasemapper/logread.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python +# +# Project Horus - Log read operations +# +# Copyright (C) 2019 Mark Jessop +# Released under GNU GPL v3 or later +# +import datetime +import json +import logging +import os +import pytz +import time +from threading import Thread, Lock +try: + # Python 2 + from Queue import Queue +except ImportError: + # Python 3 + from queue import Queue +from datetime import datetime + + + +def read_file(filename): + """ Read log file, and output an array of dicts. """ + _output = [] + + _f = open(filename, 'r') + for _line in _f: + try: + _data = json.loads(_line) + _output.append(_data) + except Exception as e: + logging.debug("Error reading line: %s" % str(e)) + if len(_output) != 0 : + logging.info("Read %d log entries from %s" % (len(_output), filename)) + + return _output + + + +def read_last_balloon_telemetry(log_dir): + """ Read last balloon telemetry. Need to work back from last file to find balloon telemetry and read the last entry - don't return until whole file scanned + """ + _lasttelemetry = [] + dirs = sorted(os.listdir("./log_files"),reverse = True) # Generate a reverse sorted list - will have to look through to find last log_file with telemetry + for file in dirs: + if file.endswith(".log"): + telemetry_found = False + try: + log = read_file("./log_files/" + file) + except Exception as e: + logging.debug("Error reading file - maybe in use") + for _entry in log: + if _entry['log_type'] == "BALLOON TELEMETRY": + telemetry_found = True + if telemetry_found == True: + logging.info("Last balloon telemetry at %s, %s, %.5f, %.5f" % (_entry['callsign'], _entry['time'], _entry['lat'],_entry['lon'])) + _entry['time_dt'] = datetime.fromisoformat(_entry.pop('time')) + return _entry diff --git a/horusmapper.cfg.example b/horusmapper.cfg.example index 18611ce..2a5432a 100644 --- a/horusmapper.cfg.example +++ b/horusmapper.cfg.example @@ -242,7 +242,9 @@ unitselection = metric # This is the threshold for switching from miles to feet, set in metres. switch_miles_feet = 400 - - +[history] + +# Enable load of last position from log files (True/False) +reload_last_postion = True diff --git a/horusmapper.py b/horusmapper.py index b02545c..55089e0 100644 --- a/horusmapper.py +++ b/horusmapper.py @@ -28,6 +28,7 @@ from chasemapper.listeners import OziListener, UDPListener, fix_datetime from chasemapper.predictor import predictor_spawn_download, model_download_running from chasemapper.habitat import HabitatChaseUploader, initListenerCallsign, uploadListenerPosition from chasemapper.logger import ChaseLogger +from chasemapper.logread import read_last_balloon_telemetry from chasemapper.bearings import Bearings from chasemapper.tawhiri import get_tawhiri_prediction @@ -998,6 +999,18 @@ if __name__ == "__main__": habitat_uploader = HabitatChaseUploader(update_rate = chasemapper_config['habitat_update_rate'], callsign=chasemapper_config['habitat_call']) + # Read in last known position, if enabled + + if chasemapper_config['reload_last_position']: + logging.info("Read in last position requested") + try: + handle_new_payload_position(read_last_balloon_telemetry("./log_dir")); + except Exception as e: + logging.info("Unable to read in last position") + else: + logging.info("Read in last position not requested") + + # Start up the data age monitor thread. _data_age_monitor = Thread(target=check_data_age) _data_age_monitor.start()