diff --git a/ham_predictor.tf b/ham_predictor.tf index 986b33f..f1715ed 100644 --- a/ham_predictor.tf +++ b/ham_predictor.tf @@ -81,6 +81,9 @@ resource "aws_lambda_function" "ham_predict_updater" { tags = { Name = "ham_predict_updater" } + lifecycle { + ignore_changes = [environment] + } } diff --git a/lambda/ham_predict_updater/__init__.py b/lambda/ham_predict_updater/__init__.py index 272955e..fbe4a18 100644 --- a/lambda/ham_predict_updater/__init__.py +++ b/lambda/ham_predict_updater/__init__.py @@ -1,3 +1,7 @@ +import sys +sys.path.append("sns_to_mqtt/vendor") + +import paho.mqtt.client as mqtt import json from datetime import datetime from datetime import timedelta @@ -8,7 +12,11 @@ from math import radians, degrees, sin, cos, atan2, sqrt, pi import es import asyncio import functools +import os +import random +import time +TAWHIRI_SERVER = "tawhiri.v2.sondehub.org" # FLIGHT PROFILE DEFAULTS # @@ -39,6 +47,49 @@ ALTITUDE_AGL_THRESHOLD = 150.0 # Do not run predictions if the payload is below this altitude AMSL, and has an ascent rate below the above threshold. ALTITUDE_AMSL_THRESHOLD = 1500.0 + +# Setup MQTT +client = mqtt.Client(transport="websockets") + +connected_flag = False + +import socket +socket.setdefaulttimeout(1) + + +## MQTT functions +def connect(): + client.on_connect = on_connect + client.on_disconnect = on_disconnect + client.on_publish = on_publish + #client.tls_set() + client.username_pw_set(username=os.getenv("MQTT_USERNAME"), password=os.getenv("MQTT_PASSWORD")) + HOSTS = os.getenv("MQTT_HOST").split(",") + PORT = int(os.getenv("MQTT_PORT", default="8080")) + if PORT == 443: + client.tls_set() + HOST = random.choice(HOSTS) + print(f"Connecting to {HOST}") + client.connect(HOST, PORT, 5) + client.loop_start() + print("loop started") + +def on_disconnect(client, userdata, rc): + global connected_flag + print("disconnected") + connected_flag=False #set flag + +def on_connect(client, userdata, flags, rc): + global connected_flag + if rc==0: + print("connected") + connected_flag=True #set flag + else: + print("Bad connection Returned code") + +def on_publish(client, userdata, mid): + pass + def get_flight_docs(): path = "flight-doc/_search" payload = { @@ -252,7 +303,7 @@ def get_float_prediction(timestamp, latitude, longitude, altitude, current_rate= # Generate the prediction URL url = f"/api/v1/?launch_altitude={altitude}&launch_latitude={latitude}&launch_longitude={longitude}&launch_datetime={timestamp}&float_altitude={burst_altitude:.2f}&stop_datetime={(datetime.now() + timedelta(days=1)).isoformat()}Z&ascent_rate={ascent_rate:.2f}&profile=float_profile" logging.debug(url) - conn = http.client.HTTPSConnection("tawhiri.v2.sondehub.org") + conn = http.client.HTTPSConnection(TAWHIRI_SERVER) conn.request("GET", url) res = conn.getresponse() data = res.read() @@ -309,7 +360,7 @@ def get_standard_prediction(timestamp, latitude, longitude, altitude, current_ra # Generate the prediction URL url = f"/api/v1/?launch_latitude={latitude}&launch_longitude={longitude}&launch_datetime={timestamp}&launch_altitude={altitude:.2f}&ascent_rate={ascent_rate:.2f}&burst_altitude={burst_altitude:.2f}&descent_rate={descent_rate:.2f}" logging.debug(url) - conn = http.client.HTTPSConnection("tawhiri.v2.sondehub.org") + conn = http.client.HTTPSConnection(TAWHIRI_SERVER) conn.request("GET", url) res = conn.getresponse() data = res.read() @@ -343,37 +394,38 @@ def get_standard_prediction(timestamp, latitude, longitude, altitude, current_ra return None +# Need to mock this out if we ever use it again +# +# def get_ruaumoko(latitude, longitude): +# """ +# Request the ground level from ruaumoko. -def get_ruaumoko(latitude, longitude): - """ - Request the ground level from ruaumoko. +# Returns 0.0 if the ground level could not be determined, effectively +# defaulting to any checks based on this data being based on mean sea level. +# """ - Returns 0.0 if the ground level could not be determined, effectively - defaulting to any checks based on this data being based on mean sea level. - """ +# # Shift longitude into the appropriate range for Tawhiri +# if longitude < 0: +# longitude += 360.0 - # Shift longitude into the appropriate range for Tawhiri - if longitude < 0: - longitude += 360.0 +# # Generate the prediction URL +# url = f"/api/ruaumoko/?latitude={latitude}&longitude={longitude}" +# logging.debug(url) +# conn = http.client.HTTPSConnection(TAWHIRI_SERVER) +# conn.request("GET", url) +# res = conn.getresponse() +# data = res.read() - # Generate the prediction URL - url = f"/api/ruaumoko/?latitude={latitude}&longitude={longitude}" - logging.debug(url) - conn = http.client.HTTPSConnection("tawhiri.v2.sondehub.org") - conn.request("GET", url) - res = conn.getresponse() - data = res.read() - - if res.code != 200: - logging.debug(data) - return None +# if res.code != 200: +# logging.debug(data) +# return None - resp_data = json.loads(data.decode("utf-8")) +# resp_data = json.loads(data.decode("utf-8")) - if 'altitude' in resp_data: - return resp_data['altitude'] - else: - return 0.0 +# if 'altitude' in resp_data: +# return resp_data['altitude'] +# else: +# return 0.0 def bulk_upload_es(index_prefix,payloads): @@ -392,8 +444,11 @@ def bulk_upload_es(index_prefix,payloads): raise RuntimeError def predict(event, context): + # Connect to MQTT + connect() # Use asyncio.run to synchronously "await" an async function result = asyncio.run(predict_async(event, context)) + time.sleep(0.5) # give paho mqtt 500ms to send messages this could be improved on but paho mqtt is a pain to interface with return result async def predict_async(event, context): @@ -593,6 +648,18 @@ async def predict_async(event, context): if len(output) > 0: bulk_upload_es("ham-predictions", output) + # upload to mqtt + while not connected_flag: + time.sleep(0.01) # wait until connected + for prediction in output: + logging.debug(f'Publishing prediction for {prediction["payload_callsign"]} to MQTT') + client.publish( + topic=f'amateur-prediction/{prediction["payload_callsign"]}', + payload=json.dumps(prediction), + qos=0, + retain=False + ) + logging.debug(f'Published prediction for {prediction["payload_callsign"]} to MQTT') logging.debug("Finished") return @@ -639,6 +706,7 @@ async def run_predictions_for_serial(sem, flight_docs, serial, value): if (abs(value['rate']) <= ASCENT_RATE_THRESHOLD) and (value['alt'] < ALTITUDE_AMSL_THRESHOLD): # Payload is 'floating' (e.g. is probably on the ground), and is below 1500m AMSL. # Don't run a prediction in this case. It probably just hasn't been launched yet. + logging.debug(f"{serial} is floating and alt is low so not running prediction") return None diff --git a/lambda/ham_predict_updater/__main__.py b/lambda/ham_predict_updater/__main__.py index c9ab7c4..ebc82cf 100644 --- a/lambda/ham_predict_updater/__main__.py +++ b/lambda/ham_predict_updater/__main__.py @@ -1,43 +1,66 @@ from . import * +from . import mock_values, test_values +import unittest +from unittest.mock import MagicMock, call, patch -# Predictor test -# conn = http.client.HTTPSConnection("tawhiri.v2.sondehub.org") -# _now = datetime.utcnow().isoformat() + "Z" - -# _ascent = get_standard_prediction(conn, _now, -34.0, 138.0, 10.0, burst_altitude=26000) -# print(f"Got {len(_ascent)} data points for ascent prediction.") -# _descent = get_standard_prediction(conn, _now, -34.0, 138.0, 24000.0, burst_altitude=24000.5) -# print(f"Got {len(_descent)} data points for descent prediction.") - -# test = predict( -# {},{} -# ) -#print(get_launch_sites()) -#print(get_reverse_predictions()) -# for _serial in test: -# print(f"{_serial['serial']}: {len(_serial['data'])}") +# Mock OpenSearch requests +def mock_es_request(body, path, method): + if path.endswith("_bulk"): # handle when the upload happens + return {} + elif(path == "flight-doc/_search"): # handle flightdoc queries + return mock_values.flight_docs + elif(path == "ham-telm-*/_search"): # handle telm searches + return mock_values.ham_telm + else: + raise NotImplemented +# Mock out tawhiri +class MockResponse(object): + code = 200 + def read(self): + return mock_values.tawhiri_respose # currently we only mock a float profile + +class MockHTTPS(object): + logging.debug(object) + def __init__(self, url): + logging.debug(url) + def request(self,method, url): + pass + def getresponse(self): + return MockResponse() + +http.client.HTTPSConnection = MockHTTPS logging.basicConfig( format="%(asctime)s %(levelname)s:%(message)s", level=logging.DEBUG ) -print(predict( - {},{} - )) -# bulk_upload_es("reverse-prediction",[{ -# "datetime" : "2021-10-04", -# "data" : { }, -# "serial" : "R12341234", -# "station" : "-2", -# "subtype" : "RS41-SGM", -# "ascent_rate" : "5", -# "alt" : 1000, -# "position" : [ -# 1, -# 2 -# ], -# "type" : "RS41" -# }] -# ) +class TestAmateurPrediction(unittest.TestCase): + def setUp(self): + es.request = MagicMock(side_effect=mock_es_request) + client.connect = MagicMock() + client.loop_start = MagicMock() + client.username_pw_set = MagicMock() + client.tls_set = MagicMock() + client.publish = MagicMock() + on_connect(client, "userdata", "flags", 0) + @patch("time.sleep") + def test_float_prediction(self, MockSleep): + predict({},{}) + date_prefix = datetime.now().strftime("%Y-%m") + es.request.assert_has_calls( + [ + call(json.dumps(test_values.flight_doc_search),"flight-doc/_search", "POST"), + call(json.dumps(test_values.ham_telm_search), "ham-telm-*/_search", "GET"), + call(test_values.es_bulk_upload,f"ham-predictions-{date_prefix}/_bulk","POST") + ] + ) + client.username_pw_set.assert_called() + client.loop_start.assert_called() + client.connect.assert_called() + client.publish.assert_has_calls([test_values.mqtt_publish_call]) + time.sleep.assert_called_with(0.5) # make sure we sleep to let paho mqtt queue clear + +if __name__ == '__main__': + unittest.main() diff --git a/lambda/ham_predict_updater/mock_values.py b/lambda/ham_predict_updater/mock_values.py new file mode 100644 index 0000000..f93362a --- /dev/null +++ b/lambda/ham_predict_updater/mock_values.py @@ -0,0 +1,401 @@ +flight_docs = { + '_shards': {'failed': 0, 'skipped': 0, 'successful': 1, 'total': 1}, + 'aggregations': { + 'payload_callsign':{ + 'buckets': [ + { + 'doc_count': 1, + 'flight_doc': { + 'hits': { + 'hits': [ + { + '_id': 'Ev_Vt4kBUwTjhZAEMCYS', + '_index': 'flight-doc', + '_score': None, + '_source': { + 'ascent_rate': 5, + 'datetime': '2023-08-02T19:59:08.960867', + 'descent_rate': 5, + 'float_expected': True, + 'identity': 'cognito-idp.us-east-1.amazonaws.com/', + 'payload_callsign': 'WOHA-4FSK', + 'peak_altitude': 65000 + }, + 'sort': [1691006348960] + } + ], + 'max_score': None, + 'total': { + 'relation': 'eq', + 'value': 1 + } + } + }, + 'key': 'WOHA-4FSK' + }, + ], + 'doc_count_error_upper_bound': 0, + 'sum_other_doc_count': 0 + } + }, + 'hits': {'hits': [], + 'max_score': None, + 'total': {'relation': 'eq', 'value': 648}}, + 'timed_out': False, + 'took': 2 +} + + +ham_telm = {'_shards': {'failed': 0, 'skipped': 0, 'successful': 25, 'total': 25}, + 'aggregations': {'2': {'buckets': [{'3': {'buckets': [{'1': {'hits': {'hits': [{'_id': '9X2HUIsBkXdcobke7eOo', + '_index': 'ham-telm-2023-10', + '_score': None, + '_source': {'alt': 2410}, + 'fields': {'alt': [2410]}, + 'sort': [1697863141000]}], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 1}}}, + '4-metric': {'value': 241.0}, + '5': {'hits': {'hits': [{'_id': '9X2HUIsBkXdcobke7eOo', + '_index': 'ham-telm-2023-10', + '_score': None, + '_source': {'position': '49.88547897338867,8.073692321777344'}, + 'fields': {'position': ['49.88547893241048, ' + '8.073692293837667']}, + 'sort': [1697863141000]}], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 1}}}, + 'doc_count': 1, + 'key': 1697863140000, + 'key_as_string': '2023-10-21T04:39:00.000Z'}, + {'1': {'hits': {'hits': [{'_id': 'WX2IUIsBkXdcobke1Obq', + '_index': 'ham-telm-2023-10', + '_score': None, + '_source': {'alt': 2150}, + 'fields': {'alt': [2150]}, + 'sort': [1697863201000]}], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 1}}}, + '4-metric': {'value': 215.0}, + '5': {'hits': {'hits': [{'_id': 'WX2IUIsBkXdcobke1Obq', + '_index': 'ham-telm-2023-10', + '_score': None, + '_source': {'position': '49.88542938232422,8.073561668395996'}, + 'fields': {'position': ['49.88542935345322, ' + '8.073561619967222']}, + 'sort': [1697863201000]}], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 1}}}, + 'doc_count': 1, + 'key': 1697863200000, + 'key_as_string': '2023-10-21T04:40:00.000Z'}, + {'1': {'hits': {'hits': [{'_id': 'pH2JUIsBkXdcobkemuiu', + '_index': 'ham-telm-2023-10', + '_score': None, + '_source': {'alt': 2360}, + 'fields': {'alt': [2360]}, + 'sort': [1697863261000]}], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 1}}}, + '4-metric': {'value': 236.0}, + '5': {'hits': {'hits': [{'_id': 'pH2JUIsBkXdcobkemuiu', + '_index': 'ham-telm-2023-10', + '_score': None, + '_source': {'position': '49.88541030883789,8.073714256286621'}, + 'fields': {'position': ['49.885410284623504, ' + '8.073714254423976']}, + 'sort': [1697863261000]}], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 1}}}, + 'doc_count': 1, + 'key': 1697863260000, + 'key_as_string': '2023-10-21T04:41:00.000Z'}, + {'1': {'hits': {'hits': [{'_id': 'Hn2KUIsBkXdcobkenusr', + '_index': 'ham-telm-2023-10', + '_score': None, + '_source': {'alt': 2330}, + 'fields': {'alt': [2330]}, + 'sort': [1697863323000]}], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 1}}}, + '4': {'value': -8.0}, + '4-metric': {'value': 233.0}, + '5': {'hits': {'hits': [{'_id': 'Hn2KUIsBkXdcobkenusr', + '_index': 'ham-telm-2023-10', + '_score': None, + '_source': {'position': '49.88546371459961,8.073665618896484'}, + 'fields': {'position': ['49.885463677346706, ' + '8.07366555556655']}, + 'sort': [1697863323000]}], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 1}}}, + 'doc_count': 1, + 'key': 1697863320000, + 'key_as_string': '2023-10-21T04:42:00.000Z'}, + {'1': {'hits': {'hits': [{'_id': 'oX2LUIsBkXdcobkel-13', + '_index': 'ham-telm-2023-10', + '_score': None, + '_source': {'alt': 2540}, + 'fields': {'alt': [2540]}, + 'sort': [1697863386000]}], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 1}}}, + '4': {'value': 39.0}, + '4-metric': {'value': 254.0}, + '5': {'hits': {'hits': [{'_id': 'oX2LUIsBkXdcobkel-13', + '_index': 'ham-telm-2023-10', + '_score': None, + '_source': {'position': '49.88544845581055,8.073786735534668'}, + 'fields': {'position': ['49.885448422282934, ' + '8.073786674067378']}, + 'sort': [1697863386000]}], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 1}}}, + 'doc_count': 1, + 'key': 1697863380000, + 'key_as_string': '2023-10-21T04:43:00.000Z'}, + {'1': {'hits': {'hits': [{'_id': 'e32MUIsBkXdcobkeevCp', + '_index': 'ham-telm-2023-10', + '_score': None, + '_source': {'alt': 2250}, + 'fields': {'alt': [2250]}, + 'sort': [1697863443000]}], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 1}}}, + '4': {'value': -11.0}, + '4-metric': {'value': 225.0}, + '5': {'hits': {'hits': [{'_id': 'e32MUIsBkXdcobkeevCp', + '_index': 'ham-telm-2023-10', + '_score': None, + '_source': {'position': '49.88544845581055,8.073610305786133'}, + 'fields': {'position': ['49.885448422282934, ' + '8.073610235005617']}, + 'sort': [1697863443000]}], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 1}}}, + 'doc_count': 1, + 'key': 1697863440000, + 'key_as_string': '2023-10-21T04:44:00.000Z'}, + {'1': {'hits': {'hits': [{'_id': 'wH2NUIsBkXdcobkeb_Op', + '_index': 'ham-telm-2023-10', + '_score': None, + '_source': {'alt': 2480}, + 'fields': {'alt': [2480]}, + 'sort': [1697863505000]}], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 1}}}, + '4': {'value': 15.0}, + '4-metric': {'value': 248.0}, + '5': {'hits': {'hits': [{'_id': 'wH2NUIsBkXdcobkeb_Op', + '_index': 'ham-telm-2023-10', + '_score': None, + '_source': {'position': '49.885459899902344,8.073668479919434'}, + 'fields': {'position': ['49.88545986358076, ' + '8.073668405413628']}, + 'sort': [1697863505000]}], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 1}}}, + 'doc_count': 1, + 'key': 1697863500000, + 'key_as_string': '2023-10-21T04:45:00.000Z'}, + {'1': {'hits': {'hits': [{'_id': 'uH2OUIsBkXdcobkeVfYv', + '_index': 'ham-telm-2023-10', + '_score': None, + '_source': {'alt': 2390}, + 'fields': {'alt': [2390]}, + 'sort': [1697863563000]}], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 1}}}, + '4': {'value': -15.0}, + '4-metric': {'value': 239.0}, + '5': {'hits': {'hits': [{'_id': 'uH2OUIsBkXdcobkeVfYv', + '_index': 'ham-telm-2023-10', + '_score': None, + '_source': {'position': '49.88542938232422,8.073694229125977'}, + 'fields': {'position': ['49.88542935345322, ' + '8.073694221675396']}, + 'sort': [1697863563000]}], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 1}}}, + 'doc_count': 1, + 'key': 1697863560000, + 'key_as_string': '2023-10-21T04:46:00.000Z'}, + {'1': {'hits': {'hits': [{'_id': 'n32PUIsBkXdcobkeO_kP', + '_index': 'ham-telm-2023-10', + '_score': None, + '_source': {'alt': 2350}, + 'fields': {'alt': [2350]}, + 'sort': [1697863623000]}], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 1}}}, + '4': {'value': 10.0}, + '4-metric': {'value': 235.0}, + '5': {'hits': {'hits': [{'_id': 'n32PUIsBkXdcobkeO_kP', + '_index': 'ham-telm-2023-10', + '_score': None, + '_source': {'position': '49.88546371459961,8.073602676391602'}, + 'fields': {'position': ['49.885463677346706, ' + '8.073602607473731']}, + 'sort': [1697863623000]}], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 1}}}, + 'doc_count': 1, + 'key': 1697863620000, + 'key_as_string': '2023-10-21T04:47:00.000Z'}, + {'1': {'hits': {'hits': [{'_id': 'BH2QUIsBkXdcobkeKP5s', + '_index': 'ham-telm-2023-10', + '_score': None, + '_source': {'alt': 2540}, + 'fields': {'alt': [2540]}, + 'sort': [1697863683000]}], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 1}}}, + '4': {'value': 6.0}, + '4-metric': {'value': 254.0}, + '5': {'hits': {'hits': [{'_id': 'BH2QUIsBkXdcobkeKP5s', + '_index': 'ham-telm-2023-10', + '_score': None, + '_source': {'position': '49.88544464111328,8.073787689208984'}, + 'fields': {'position': ['49.88544460851699, ' + '8.073787679895759']}, + 'sort': [1697863683000]}], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 1}}}, + 'doc_count': 1, + 'key': 1697863680000, + 'key_as_string': '2023-10-21T04:48:00.000Z'}]}, + 'doc_count': 10, + 'key': 'WOHA-4FSK'}, + + + + + + + {'3': {'buckets': [{'1': {'hits': {'hits': [{'_id': '2H2LUIsBkXdcobkeO-zo', + '_index': 'ham-telm-2023-10', + '_score': None, + '_source': {'alt': 49.3776}, + 'fields': {'alt': [49.3776]}, + 'sort': [1697863269000]}], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 2}}}, + '4-metric': {'value': 49.3776}, + '5': {'hits': {'hits': [{'_id': '2H2LUIsBkXdcobkeO-zo', + '_index': 'ham-telm-2023-10', + '_score': None, + '_source': {'position': '31.18391575091575,-87.0951098901099'}, + 'fields': {'position': ['31.183915715664625, ' + '-87.09510996937752']}, + 'sort': [1697863269000]}], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 2}}}, + 'doc_count': 2, + 'key': 1697863260000, + 'key_as_string': '2023-10-21T04:41:00.000Z'}, + {'1': {'hits': {'hits': [{'_id': '2X2LUIsBkXdcobkeO-zo', + '_index': 'ham-telm-2023-10', + '_score': None, + '_source': {'alt': 51.2064}, + 'fields': {'alt': [51.2064]}, + 'sort': [1697863334000]}], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 4}}}, + '4-metric': {'value': 51.2064}, + '5': {'hits': {'hits': [{'_id': '2X2LUIsBkXdcobkeO-zo', + '_index': 'ham-telm-2023-10', + '_score': None, + '_source': {'position': '31.184078754578756,-87.0952032967033'}, + 'fields': {'position': ['31.18407874368131, ' + '-87.09520334377885']}, + 'sort': [1697863334000]}], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 4}}}, + 'doc_count': 4, + 'key': 1697863320000, + 'key_as_string': '2023-10-21T04:42:00.000Z'}, + {'1': {'hits': {'hits': [], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 0}}}, + '4-metric': {'value': None}, + '5': {'hits': {'hits': [], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 0}}}, + 'doc_count': 0, + 'key': 1697863380000, + 'key_as_string': '2023-10-21T04:43:00.000Z'}, + {'1': {'hits': {'hits': [], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 0}}}, + '4-metric': {'value': None}, + '5': {'hits': {'hits': [], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 0}}}, + 'doc_count': 0, + 'key': 1697863440000, + 'key_as_string': '2023-10-21T04:44:00.000Z'}, + {'1': {'hits': {'hits': [{'_id': 't32OUIsBkXdcobkeVfYv', + '_index': 'ham-telm-2023-10', + '_score': None, + '_source': {'alt': 79.8576}, + 'fields': {'alt': [79.8576]}, + 'sort': [1697863556000]}], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 1}}}, + '4': {'value': 28.651200000000003}, + '4-metric': {'value': 79.8576}, + '5': {'hits': {'hits': [{'_id': 't32OUIsBkXdcobkeVfYv', + '_index': 'ham-telm-2023-10', + '_score': None, + '_source': {'position': '31.184056776556776,-87.09497802197802'}, + 'fields': {'position': ['31.184056741185486, ' + '-87.0949780382216']}, + 'sort': [1697863556000]}], + 'max_score': None, + 'total': {'relation': 'eq', + 'value': 1}}}, + 'doc_count': 1, + 'key': 1697863500000, + 'key_as_string': '2023-10-21T04:45:00.000Z'}]}, + 'doc_count': 7, + 'key': 'WD4KTW-11'}], + 'doc_count_error_upper_bound': 0, + 'sum_other_doc_count': 0}}, + 'hits': {'hits': [], + 'max_score': None, + 'total': {'relation': 'eq', 'value': 17}}, + 'timed_out': False, + 'took': 6} + + +tawhiri_respose = b'{"metadata":{"complete_datetime":"2023-10-21T05:03:27.480569Z","start_datetime":"2023-10-21T05:03:27.050584Z"},"prediction":[{"stage":"ascent","trajectory":[{"altitude":2540.0,"datetime":"2023-10-21T04:48:00Z","latitude":49.88544460851699,"longitude":8.073787679895759},{"altitude":2541.40625,"datetime":"2023-10-21T04:48:01.40625Z","latitude":49.88556427078601,"longitude":8.074136043443652}]},{"stage":"float","trajectory":[{"altitude":2541.40625,"datetime":"2023-10-21T04:48:01.40625Z","latitude":49.88556427078601,"longitude":8.074136043443652},{"altitude":2541.40625,"datetime":"2023-10-21T05:08:01.40625Z","latitude":49.989646159875086,"longitude":8.372431529735952},{"altitude":2541.40625,"datetime":"2023-10-21T05:28:01.40625Z","latitude":50.09435875853791,"longitude":8.662271863362404},{"altitude":2541.40625,"datetime":"2023-10-21T05:48:01.40625Z","latitude":50.19499174744686,"longitude":8.93259728580706},{"altitude":2541.40625,"datetime":"2023-10-21T06:08:01.40625Z","latitude":50.29212936574956,"longitude":9.197622324831832},{"altitude":2541.40625,"datetime":"2023-10-21T06:28:01.40625Z","latitude":50.39546963598292,"longitude":9.471199745508276},{"altitude":2541.40625,"datetime":"2023-10-21T06:48:01.40625Z","latitude":50.506756201025055,"longitude":9.756777613589094},{"altitude":2541.40625,"datetime":"2023-10-21T07:08:01.40625Z","latitude":50.62408141443116,"longitude":10.055295780135987},{"altitude":2541.40625,"datetime":"2023-10-21T07:28:01.40625Z","latitude":50.74366711276691,"longitude":10.364096778886777},{"altitude":2541.40625,"datetime":"2023-10-21T07:48:01.40625Z","latitude":50.86547320898176,"longitude":10.690103035991303},{"altitude":2541.40625,"datetime":"2023-10-21T08:08:01.40625Z","latitude":50.98551585487632,"longitude":11.024736654944446},{"altitude":2541.40625,"datetime":"2023-10-21T08:28:01.40625Z","latitude":51.09837951176664,"longitude":11.354945531368442},{"altitude":2541.40625,"datetime":"2023-10-21T08:48:01.40625Z","latitude":51.209090539135104,"longitude":11.681246181484429},{"altitude":2541.40625,"datetime":"2023-10-21T09:08:01.40625Z","latitude":51.32395305531132,"longitude":12.012727783257938},{"altitude":2541.40625,"datetime":"2023-10-21T09:28:01.40625Z","latitude":51.4434004865406,"longitude":12.341236864327502},{"altitude":2541.40625,"datetime":"2023-10-21T09:48:01.40625Z","latitude":51.56575167367278,"longitude":12.66458053300588},{"altitude":2541.40625,"datetime":"2023-10-21T10:08:01.40625Z","latitude":51.68558353199418,"longitude":12.976928670952686},{"altitude":2541.40625,"datetime":"2023-10-21T10:28:01.40625Z","latitude":51.808197253364455,"longitude":13.27872052720281},{"altitude":2541.40625,"datetime":"2023-10-21T10:48:01.40625Z","latitude":51.935914194979496,"longitude":13.57632829947249},{"altitude":2541.40625,"datetime":"2023-10-21T11:08:01.40625Z","latitude":52.06541807383993,"longitude":13.874880645113347},{"altitude":2541.40625,"datetime":"2023-10-21T11:28:01.40625Z","latitude":52.193602554438385,"longitude":14.171146457013402},{"altitude":2541.40625,"datetime":"2023-10-21T11:48:01.40625Z","latitude":52.32516615260403,"longitude":14.463254797256221},{"altitude":2541.40625,"datetime":"2023-10-21T12:08:01.40625Z","latitude":52.46437173738165,"longitude":14.751900489535316},{"altitude":2541.40625,"datetime":"2023-10-21T12:28:01.40625Z","latitude":52.605556746372784,"longitude":15.04131581462667},{"altitude":2541.40625,"datetime":"2023-10-21T12:48:01.40625Z","latitude":52.744813707967154,"longitude":15.334159285242347},{"altitude":2541.40625,"datetime":"2023-10-21T13:08:01.40625Z","latitude":52.87922315857887,"longitude":15.631375762683154},{"altitude":2541.40625,"datetime":"2023-10-21T13:28:01.40625Z","latitude":53.005439140497295,"longitude":15.9334623350681},{"altitude":2541.40625,"datetime":"2023-10-21T13:48:01.40625Z","latitude":53.12266399758165,"longitude":16.239059644955017},{"altitude":2541.40625,"datetime":"2023-10-21T14:08:01.40625Z","latitude":53.23297840281449,"longitude":16.541098497689784},{"altitude":2541.40625,"datetime":"2023-10-21T14:28:01.40625Z","latitude":53.34232663122806,"longitude":16.84498296886326},{"altitude":2541.40625,"datetime":"2023-10-21T14:48:01.40625Z","latitude":53.45388036140508,"longitude":17.15332631028565},{"altitude":2541.40625,"datetime":"2023-10-21T15:08:01.40625Z","latitude":53.56291748503723,"longitude":17.46226436415671},{"altitude":2541.40625,"datetime":"2023-10-21T15:28:01.40625Z","latitude":53.66301108746143,"longitude":17.752367920987037},{"altitude":2541.40625,"datetime":"2023-10-21T15:48:01.40625Z","latitude":53.756125465166605,"longitude":18.020293117478975},{"altitude":2541.40625,"datetime":"2023-10-21T16:08:01.40625Z","latitude":53.84443764730249,"longitude":18.27094615040044},{"altitude":2541.40625,"datetime":"2023-10-21T16:28:01.40625Z","latitude":53.92920627407708,"longitude":18.511707932213074},{"altitude":2541.40625,"datetime":"2023-10-21T16:48:01.40625Z","latitude":54.01303656730144,"longitude":18.75323403151018},{"altitude":2541.40625,"datetime":"2023-10-21T17:08:01.40625Z","latitude":54.095868770133755,"longitude":18.999773296083827},{"altitude":2541.40625,"datetime":"2023-10-21T17:28:01.40625Z","latitude":54.17980857002759,"longitude":19.241755134435078},{"altitude":2541.40625,"datetime":"2023-10-21T17:48:01.40625Z","latitude":54.26580540479724,"longitude":19.47276923743176},{"altitude":2541.40625,"datetime":"2023-10-21T18:08:01.40625Z","latitude":54.35297597101382,"longitude":19.69677046063011},{"altitude":2541.40625,"datetime":"2023-10-21T18:28:01.40625Z","latitude":54.4407637537023,"longitude":19.919634444738552},{"altitude":2541.40625,"datetime":"2023-10-21T18:48:01.40625Z","latitude":54.52967121841839,"longitude":20.14521169658971},{"altitude":2541.40625,"datetime":"2023-10-21T19:08:01.40625Z","latitude":54.6195032781259,"longitude":20.369942303008454},{"altitude":2541.40625,"datetime":"2023-10-21T19:28:01.40625Z","latitude":54.71003017186386,"longitude":20.59404374946693},{"altitude":2541.40625,"datetime":"2023-10-21T19:48:01.40625Z","latitude":54.80466643235945,"longitude":20.815960971634162},{"altitude":2541.40625,"datetime":"2023-10-21T20:08:01.40625Z","latitude":54.902964454586034,"longitude":21.035736598675683},{"altitude":2541.40625,"datetime":"2023-10-21T20:28:01.40625Z","latitude":55.00398634443448,"longitude":21.256378841971856},{"altitude":2541.40625,"datetime":"2023-10-21T20:48:01.40625Z","latitude":55.10836252824465,"longitude":21.477860175240657},{"altitude":2541.40625,"datetime":"2023-10-21T21:08:01.40625Z","latitude":55.21285716396815,"longitude":21.699465793943475},{"altitude":2541.40625,"datetime":"2023-10-21T21:28:01.40625Z","latitude":55.31207189121156,"longitude":21.92250246903604},{"altitude":2541.40625,"datetime":"2023-10-21T21:48:01.40625Z","latitude":55.40804089620216,"longitude":22.147629083253396},{"altitude":2541.40625,"datetime":"2023-10-21T22:08:01.40625Z","latitude":55.50388391633759,"longitude":22.37641101405387},{"altitude":2541.40625,"datetime":"2023-10-21T22:28:01.40625Z","latitude":55.60097091347051,"longitude":22.60643869102728},{"altitude":2541.40625,"datetime":"2023-10-21T22:48:01.40625Z","latitude":55.70046472580808,"longitude":22.83728640484063},{"altitude":2541.40625,"datetime":"2023-10-21T23:08:01.40625Z","latitude":55.801340043985,"longitude":23.0690941616483},{"altitude":2541.40625,"datetime":"2023-10-21T23:28:01.40625Z","latitude":55.900629548018706,"longitude":23.299786471711673},{"altitude":2541.40625,"datetime":"2023-10-21T23:48:01.40625Z","latitude":55.99784855344522,"longitude":23.529437289597134},{"altitude":2541.40625,"datetime":"2023-10-22T00:08:01.40625Z","latitude":56.090478100535,"longitude":23.75789979269153},{"altitude":2541.40625,"datetime":"2023-10-22T00:28:01.40625Z","latitude":56.17543254796434,"longitude":23.98550452925505},{"altitude":2541.40625,"datetime":"2023-10-22T00:48:01.40625Z","latitude":56.256606763052865,"longitude":24.21308356047565},{"altitude":2541.40625,"datetime":"2023-10-22T01:08:01.40625Z","latitude":56.33756560035536,"longitude":24.4418647463315},{"altitude":2541.40625,"datetime":"2023-10-22T01:28:01.40625Z","latitude":56.419106381643275,"longitude":24.672389536447625},{"altitude":2541.40625,"datetime":"2023-10-22T01:48:01.40625Z","latitude":56.50197418218225,"longitude":24.903690860726023},{"altitude":2541.40625,"datetime":"2023-10-22T02:08:01.40625Z","latitude":56.58588786761463,"longitude":25.134258124823873},{"altitude":2541.40625,"datetime":"2023-10-22T02:28:01.40625Z","latitude":56.6672905989913,"longitude":25.36208730826666},{"altitude":2541.40625,"datetime":"2023-10-22T02:48:01.40625Z","latitude":56.74634439065202,"longitude":25.587158238646197},{"altitude":2541.40625,"datetime":"2023-10-22T03:08:01.40625Z","latitude":56.82250204256607,"longitude":25.80897263093161},{"altitude":2541.40625,"datetime":"2023-10-22T03:28:01.40625Z","latitude":56.89534177474188,"longitude":26.02525394969752},{"altitude":2541.40625,"datetime":"2023-10-22T03:48:01.40625Z","latitude":56.967476181568635,"longitude":26.23592429729052},{"altitude":2541.40625,"datetime":"2023-10-22T04:08:01.40625Z","latitude":57.040795262003144,"longitude":26.44095383363708},{"altitude":2541.40625,"datetime":"2023-10-22T04:28:01.40625Z","latitude":57.11598501166453,"longitude":26.641905025293593},{"altitude":2541.40625,"datetime":"2023-10-22T04:48:01.40625Z","latitude":57.19234861125557,"longitude":26.84155858348079},{"altitude":2541.40625,"datetime":"2023-10-22T05:08:01.40625Z","latitude":57.26970043106924,"longitude":27.039534770889716},{"altitude":2541.40625,"datetime":"2023-10-22T05:28:01.40625Z","latitude":57.34630952454888,"longitude":27.235545317285528},{"altitude":2541.40625,"datetime":"2023-10-22T05:48:01.40625Z","latitude":57.42145302997134,"longitude":27.430110122889875},{"altitude":2541.40625,"datetime":"2023-10-22T06:08:01.40625Z","latitude":57.495266176654134,"longitude":27.623896280075627},{"altitude":2541.40625,"datetime":"2023-10-22T06:28:01.40625Z","latitude":57.56734497414666,"longitude":27.82088476460215},{"altitude":2541.40625,"datetime":"2023-10-22T06:48:01.40625Z","latitude":57.639184490025,"longitude":28.02206774971835},{"altitude":2541.40625,"datetime":"2023-10-22T07:08:01.40625Z","latitude":57.71150408670198,"longitude":28.227922547267926},{"altitude":2541.40625,"datetime":"2023-10-22T07:28:01.40625Z","latitude":57.784556946336785,"longitude":28.438488470559136},{"altitude":2541.40625,"datetime":"2023-10-22T07:48:01.40625Z","latitude":57.85866649710846,"longitude":28.653441669541166},{"altitude":2541.40625,"datetime":"2023-10-22T08:08:01.40625Z","latitude":57.9338771357294,"longitude":28.870245383108312},{"altitude":2541.40625,"datetime":"2023-10-22T08:28:01.40625Z","latitude":58.010906495466244,"longitude":29.088057570995193},{"altitude":2541.40625,"datetime":"2023-10-22T08:48:01.40625Z","latitude":58.08737632444847,"longitude":29.30428376212974},{"altitude":2541.40625,"datetime":"2023-10-22T09:08:01.40625Z","latitude":58.162198479682935,"longitude":29.518609387620995},{"altitude":2541.40625,"datetime":"2023-10-22T09:28:01.40625Z","latitude":58.23137261302618,"longitude":29.732882592222396},{"altitude":2541.40625,"datetime":"2023-10-22T09:48:01.40625Z","latitude":58.29508400852999,"longitude":29.947907289574992},{"altitude":2541.40625,"datetime":"2023-10-22T10:08:01.40625Z","latitude":58.35441905051441,"longitude":30.163819564855885},{"altitude":2541.40625,"datetime":"2023-10-22T10:28:01.40625Z","latitude":58.40972494602832,"longitude":30.380508314522242},{"altitude":2541.40625,"datetime":"2023-10-22T10:48:01.40625Z","latitude":58.46123414189712,"longitude":30.59869380811678},{"altitude":2541.40625,"datetime":"2023-10-22T11:08:01.40625Z","latitude":58.508149721321125,"longitude":30.81747555829034},{"altitude":2541.40625,"datetime":"2023-10-22T11:28:01.40625Z","latitude":58.55052296638706,"longitude":31.037036623649286},{"altitude":2541.40625,"datetime":"2023-10-22T11:48:01.40625Z","latitude":58.58916046473396,"longitude":31.258550879125178},{"altitude":2541.40625,"datetime":"2023-10-22T12:08:01.40625Z","latitude":58.6252633751547,"longitude":31.4840140520567},{"altitude":2541.40625,"datetime":"2023-10-22T12:28:01.40625Z","latitude":58.65940699049595,"longitude":31.708091062151997},{"altitude":2541.40625,"datetime":"2023-10-22T12:48:01.40625Z","latitude":58.69124736434967,"longitude":31.929036400373636},{"altitude":2541.40625,"datetime":"2023-10-22T13:08:01.40625Z","latitude":58.72083984670862,"longitude":32.14715666111154},{"altitude":2541.40625,"datetime":"2023-10-22T13:28:01.40625Z","latitude":58.748784879474954,"longitude":32.36284629232269},{"altitude":2541.40625,"datetime":"2023-10-22T13:48:01.40625Z","latitude":58.775739273865746,"longitude":32.577971624054236},{"altitude":2541.40625,"datetime":"2023-10-22T14:08:01.40625Z","latitude":58.80217365297601,"longitude":32.79196617666642},{"altitude":2541.40625,"datetime":"2023-10-22T14:28:01.40625Z","latitude":58.82928087920663,"longitude":33.00519314546959},{"altitude":2541.40625,"datetime":"2023-10-22T14:48:01.40625Z","latitude":58.85758475761732,"longitude":33.21678594667968},{"altitude":2541.40625,"datetime":"2023-10-22T15:08:01.40625Z","latitude":58.886952359485605,"longitude":33.42664716286992},{"altitude":2541.40625,"datetime":"2023-10-22T15:28:01.40625Z","latitude":58.915446037107486,"longitude":33.63382141773347},{"altitude":2541.40625,"datetime":"2023-10-22T15:48:01.40625Z","latitude":58.94125218834526,"longitude":33.837198470703775},{"altitude":2541.40625,"datetime":"2023-10-22T16:03:29.53125Z","latitude":58.95943180877415,"longitude":33.99194649998202}]}],"request":{"ascent_rate":1.0,"dataset":"2023-10-21T00:00:00Z","float_altitude":2541.0,"format":"json","launch_altitude":2540.0,"launch_datetime":"2023-10-21T04:48:00Z","launch_latitude":49.88544460851699,"launch_longitude":8.073787679895759,"profile":"float_profile","stop_datetime":"2023-10-22T16:03:25.811505Z","version":1},"warnings":{}}\n' + diff --git a/lambda/ham_predict_updater/test_values.py b/lambda/ham_predict_updater/test_values.py new file mode 100644 index 0000000..223a694 --- /dev/null +++ b/lambda/ham_predict_updater/test_values.py @@ -0,0 +1,36 @@ +from unittest.mock import call +flight_doc_search = { + "aggs": { + "payload_callsign": { + "terms": { + "field": "payload_callsign.keyword", + "order": { + "_key": "desc" + }, + "size": 10000 + }, + "aggs": { + "flight_doc": { + "top_hits": { + "_source": True, + "size": 1, + "sort": [ + { + "datetime": { + "order": "desc" + } + } + ] + } + } + } + } + }, + "size": 0 + } +ham_telm_search = {"aggs": {"2": {"terms": {"field": "payload_callsign.keyword", "order": {"_key": "desc"}, "size": 1000}, "aggs": {"3": {"date_histogram": {"field": "datetime", "fixed_interval": "60s"}, "aggs": {"1": {"top_hits": {"docvalue_fields": [{"field": "alt"}], "_source": "alt", "size": 1, "sort": [{"datetime": {"order": "desc"}}]}}, "4": {"serial_diff": {"buckets_path": "4-metric", "gap_policy": "skip", "lag": 3}}, "5": {"top_hits": {"docvalue_fields": [{"field": "position"}], "_source": {"includes": ["position", "type", "subtype"]}, "size": 1, "sort": [{"datetime": {"order": "desc"}}]}}, "4-metric": {"avg": {"field": "alt"}}}}}}}, "size": 0, "stored_fields": ["*"], "script_fields": {}, "docvalue_fields": [{"field": "@timestamp", "format": "date_time"}, {"field": "datetime", "format": "date_time"}, {"field": "log_date", "format": "date_time"}, {"field": "time_received", "format": "date_time"}, {"field": "time_server", "format": "date_time"}, {"field": "time_uploaded", "format": "date_time"}], "_source": {"excludes": []}, "query": {"bool": {"must": [], "filter": [{"match_all": {}}, {"range": {"datetime": {"gte": "now-10m", "lte": "now", "format": "strict_date_optional_time"}}}], "should": []}}} + +es_bulk_upload = '{"index":{}}\n{"payload_callsign": "WOHA-4FSK", "datetime": "2023-10-21T04:48:00Z", "position": [8.073787679895759, 49.88544460851699], "altitude": 2540.0, "ascent_rate": 1.0, "descent_rate": null, "burst_altitude": null, "descending": false, "landed": false, "data": [{"time": 1697824080, "lat": 49.88544460851699, "lon": 8.073787679895759, "alt": 2540.0}, {"time": 1697824081, "lat": 49.88556427078601, "lon": 8.074136043443652, "alt": 2541.40625}, {"time": 1697824081, "lat": 49.88556427078601, "lon": 8.074136043443652, "alt": 2541.40625}, {"time": 1697825281, "lat": 49.989646159875086, "lon": 8.372431529735952, "alt": 2541.40625}, {"time": 1697826481, "lat": 50.09435875853791, "lon": 8.662271863362404, "alt": 2541.40625}, {"time": 1697827681, "lat": 50.19499174744686, "lon": 8.93259728580706, "alt": 2541.40625}, {"time": 1697828881, "lat": 50.29212936574956, "lon": 9.197622324831832, "alt": 2541.40625}, {"time": 1697830081, "lat": 50.39546963598292, "lon": 9.471199745508276, "alt": 2541.40625}, {"time": 1697831281, "lat": 50.506756201025055, "lon": 9.756777613589094, "alt": 2541.40625}, {"time": 1697832481, "lat": 50.62408141443116, "lon": 10.055295780135987, "alt": 2541.40625}, {"time": 1697833681, "lat": 50.74366711276691, "lon": 10.364096778886777, "alt": 2541.40625}, {"time": 1697834881, "lat": 50.86547320898176, "lon": 10.690103035991303, "alt": 2541.40625}, {"time": 1697836081, "lat": 50.98551585487632, "lon": 11.024736654944446, "alt": 2541.40625}, {"time": 1697837281, "lat": 51.09837951176664, "lon": 11.354945531368442, "alt": 2541.40625}, {"time": 1697838481, "lat": 51.209090539135104, "lon": 11.681246181484429, "alt": 2541.40625}, {"time": 1697839681, "lat": 51.32395305531132, "lon": 12.012727783257938, "alt": 2541.40625}, {"time": 1697840881, "lat": 51.4434004865406, "lon": 12.341236864327502, "alt": 2541.40625}, {"time": 1697842081, "lat": 51.56575167367278, "lon": 12.66458053300588, "alt": 2541.40625}, {"time": 1697843281, "lat": 51.68558353199418, "lon": 12.976928670952686, "alt": 2541.40625}, {"time": 1697844481, "lat": 51.808197253364455, "lon": 13.27872052720281, "alt": 2541.40625}, {"time": 1697845681, "lat": 51.935914194979496, "lon": 13.57632829947249, "alt": 2541.40625}, {"time": 1697846881, "lat": 52.06541807383993, "lon": 13.874880645113347, "alt": 2541.40625}, {"time": 1697848081, "lat": 52.193602554438385, "lon": 14.171146457013402, "alt": 2541.40625}, {"time": 1697849281, "lat": 52.32516615260403, "lon": 14.463254797256221, "alt": 2541.40625}, {"time": 1697850481, "lat": 52.46437173738165, "lon": 14.751900489535316, "alt": 2541.40625}, {"time": 1697851681, "lat": 52.605556746372784, "lon": 15.04131581462667, "alt": 2541.40625}, {"time": 1697852881, "lat": 52.744813707967154, "lon": 15.334159285242347, "alt": 2541.40625}, {"time": 1697854081, "lat": 52.87922315857887, "lon": 15.631375762683154, "alt": 2541.40625}, {"time": 1697855281, "lat": 53.005439140497295, "lon": 15.9334623350681, "alt": 2541.40625}, {"time": 1697856481, "lat": 53.12266399758165, "lon": 16.239059644955017, "alt": 2541.40625}, {"time": 1697857681, "lat": 53.23297840281449, "lon": 16.541098497689784, "alt": 2541.40625}, {"time": 1697858881, "lat": 53.34232663122806, "lon": 16.84498296886326, "alt": 2541.40625}, {"time": 1697860081, "lat": 53.45388036140508, "lon": 17.15332631028565, "alt": 2541.40625}, {"time": 1697861281, "lat": 53.56291748503723, "lon": 17.46226436415671, "alt": 2541.40625}, {"time": 1697862481, "lat": 53.66301108746143, "lon": 17.752367920987037, "alt": 2541.40625}, {"time": 1697863681, "lat": 53.756125465166605, "lon": 18.020293117478975, "alt": 2541.40625}, {"time": 1697864881, "lat": 53.84443764730249, "lon": 18.27094615040044, "alt": 2541.40625}, {"time": 1697866081, "lat": 53.92920627407708, "lon": 18.511707932213074, "alt": 2541.40625}, {"time": 1697867281, "lat": 54.01303656730144, "lon": 18.75323403151018, "alt": 2541.40625}, {"time": 1697868481, "lat": 54.095868770133755, "lon": 18.999773296083827, "alt": 2541.40625}, {"time": 1697869681, "lat": 54.17980857002759, "lon": 19.241755134435078, "alt": 2541.40625}, {"time": 1697870881, "lat": 54.26580540479724, "lon": 19.47276923743176, "alt": 2541.40625}, {"time": 1697872081, "lat": 54.35297597101382, "lon": 19.69677046063011, "alt": 2541.40625}, {"time": 1697873281, "lat": 54.4407637537023, "lon": 19.919634444738552, "alt": 2541.40625}, {"time": 1697874481, "lat": 54.52967121841839, "lon": 20.14521169658971, "alt": 2541.40625}, {"time": 1697875681, "lat": 54.6195032781259, "lon": 20.369942303008454, "alt": 2541.40625}, {"time": 1697876881, "lat": 54.71003017186386, "lon": 20.59404374946693, "alt": 2541.40625}, {"time": 1697878081, "lat": 54.80466643235945, "lon": 20.815960971634162, "alt": 2541.40625}, {"time": 1697879281, "lat": 54.902964454586034, "lon": 21.035736598675683, "alt": 2541.40625}, {"time": 1697880481, "lat": 55.00398634443448, "lon": 21.256378841971856, "alt": 2541.40625}, {"time": 1697881681, "lat": 55.10836252824465, "lon": 21.477860175240657, "alt": 2541.40625}, {"time": 1697882881, "lat": 55.21285716396815, "lon": 21.699465793943475, "alt": 2541.40625}, {"time": 1697884081, "lat": 55.31207189121156, "lon": 21.92250246903604, "alt": 2541.40625}, {"time": 1697885281, "lat": 55.40804089620216, "lon": 22.147629083253396, "alt": 2541.40625}, {"time": 1697886481, "lat": 55.50388391633759, "lon": 22.37641101405387, "alt": 2541.40625}, {"time": 1697887681, "lat": 55.60097091347051, "lon": 22.60643869102728, "alt": 2541.40625}, {"time": 1697888881, "lat": 55.70046472580808, "lon": 22.83728640484063, "alt": 2541.40625}, {"time": 1697890081, "lat": 55.801340043985, "lon": 23.0690941616483, "alt": 2541.40625}, {"time": 1697891281, "lat": 55.900629548018706, "lon": 23.299786471711673, "alt": 2541.40625}, {"time": 1697892481, "lat": 55.99784855344522, "lon": 23.529437289597134, "alt": 2541.40625}, {"time": 1697893681, "lat": 56.090478100535, "lon": 23.75789979269153, "alt": 2541.40625}, {"time": 1697894881, "lat": 56.17543254796434, "lon": 23.98550452925505, "alt": 2541.40625}, {"time": 1697896081, "lat": 56.256606763052865, "lon": 24.21308356047565, "alt": 2541.40625}, {"time": 1697897281, "lat": 56.33756560035536, "lon": 24.4418647463315, "alt": 2541.40625}, {"time": 1697898481, "lat": 56.419106381643275, "lon": 24.672389536447625, "alt": 2541.40625}, {"time": 1697899681, "lat": 56.50197418218225, "lon": 24.903690860726023, "alt": 2541.40625}, {"time": 1697900881, "lat": 56.58588786761463, "lon": 25.134258124823873, "alt": 2541.40625}, {"time": 1697902081, "lat": 56.6672905989913, "lon": 25.36208730826666, "alt": 2541.40625}, {"time": 1697903281, "lat": 56.74634439065202, "lon": 25.587158238646197, "alt": 2541.40625}, {"time": 1697904481, "lat": 56.82250204256607, "lon": 25.80897263093161, "alt": 2541.40625}, {"time": 1697905681, "lat": 56.89534177474188, "lon": 26.02525394969752, "alt": 2541.40625}, {"time": 1697906881, "lat": 56.967476181568635, "lon": 26.23592429729052, "alt": 2541.40625}, {"time": 1697908081, "lat": 57.040795262003144, "lon": 26.44095383363708, "alt": 2541.40625}, {"time": 1697909281, "lat": 57.11598501166453, "lon": 26.641905025293593, "alt": 2541.40625}, {"time": 1697910481, "lat": 57.19234861125557, "lon": 26.84155858348079, "alt": 2541.40625}, {"time": 1697911681, "lat": 57.26970043106924, "lon": 27.039534770889716, "alt": 2541.40625}, {"time": 1697912881, "lat": 57.34630952454888, "lon": 27.235545317285528, "alt": 2541.40625}, {"time": 1697914081, "lat": 57.42145302997134, "lon": 27.430110122889875, "alt": 2541.40625}, {"time": 1697915281, "lat": 57.495266176654134, "lon": 27.623896280075627, "alt": 2541.40625}, {"time": 1697916481, "lat": 57.56734497414666, "lon": 27.82088476460215, "alt": 2541.40625}, {"time": 1697917681, "lat": 57.639184490025, "lon": 28.02206774971835, "alt": 2541.40625}, {"time": 1697918881, "lat": 57.71150408670198, "lon": 28.227922547267926, "alt": 2541.40625}, {"time": 1697920081, "lat": 57.784556946336785, "lon": 28.438488470559136, "alt": 2541.40625}, {"time": 1697921281, "lat": 57.85866649710846, "lon": 28.653441669541166, "alt": 2541.40625}, {"time": 1697922481, "lat": 57.9338771357294, "lon": 28.870245383108312, "alt": 2541.40625}, {"time": 1697923681, "lat": 58.010906495466244, "lon": 29.088057570995193, "alt": 2541.40625}, {"time": 1697924881, "lat": 58.08737632444847, "lon": 29.30428376212974, "alt": 2541.40625}, {"time": 1697926081, "lat": 58.162198479682935, "lon": 29.518609387620995, "alt": 2541.40625}, {"time": 1697927281, "lat": 58.23137261302618, "lon": 29.732882592222396, "alt": 2541.40625}, {"time": 1697928481, "lat": 58.29508400852999, "lon": 29.947907289574992, "alt": 2541.40625}, {"time": 1697929681, "lat": 58.35441905051441, "lon": 30.163819564855885, "alt": 2541.40625}, {"time": 1697930881, "lat": 58.40972494602832, "lon": 30.380508314522242, "alt": 2541.40625}, {"time": 1697932081, "lat": 58.46123414189712, "lon": 30.59869380811678, "alt": 2541.40625}, {"time": 1697933281, "lat": 58.508149721321125, "lon": 30.81747555829034, "alt": 2541.40625}, {"time": 1697934481, "lat": 58.55052296638706, "lon": 31.037036623649286, "alt": 2541.40625}, {"time": 1697935681, "lat": 58.58916046473396, "lon": 31.258550879125178, "alt": 2541.40625}, {"time": 1697936881, "lat": 58.6252633751547, "lon": 31.4840140520567, "alt": 2541.40625}, {"time": 1697938081, "lat": 58.65940699049595, "lon": 31.708091062151997, "alt": 2541.40625}, {"time": 1697939281, "lat": 58.69124736434967, "lon": 31.929036400373636, "alt": 2541.40625}, {"time": 1697940481, "lat": 58.72083984670862, "lon": 32.14715666111154, "alt": 2541.40625}, {"time": 1697941681, "lat": 58.748784879474954, "lon": 32.36284629232269, "alt": 2541.40625}, {"time": 1697942881, "lat": 58.775739273865746, "lon": 32.577971624054236, "alt": 2541.40625}, {"time": 1697944081, "lat": 58.80217365297601, "lon": 32.79196617666642, "alt": 2541.40625}, {"time": 1697945281, "lat": 58.82928087920663, "lon": 33.00519314546959, "alt": 2541.40625}, {"time": 1697946481, "lat": 58.85758475761732, "lon": 33.21678594667968, "alt": 2541.40625}, {"time": 1697947681, "lat": 58.886952359485605, "lon": 33.42664716286992, "alt": 2541.40625}, {"time": 1697948881, "lat": 58.915446037107486, "lon": 33.63382141773347, "alt": 2541.40625}, {"time": 1697950081, "lat": 58.94125218834526, "lon": 33.837198470703775, "alt": 2541.40625}, {"time": 1697951009, "lat": 58.95943180877415, "lon": 33.99194649998202, "alt": 2541.40625}]}\n\n' + + +mqtt_publish_call = call(topic='amateur-prediction/WOHA-4FSK', payload='{"payload_callsign": "WOHA-4FSK", "datetime": "2023-10-21T04:48:00Z", "position": [8.073787679895759, 49.88544460851699], "altitude": 2540.0, "ascent_rate": 1.0, "descent_rate": null, "burst_altitude": null, "descending": false, "landed": false, "data": [{"time": 1697824080, "lat": 49.88544460851699, "lon": 8.073787679895759, "alt": 2540.0}, {"time": 1697824081, "lat": 49.88556427078601, "lon": 8.074136043443652, "alt": 2541.40625}, {"time": 1697824081, "lat": 49.88556427078601, "lon": 8.074136043443652, "alt": 2541.40625}, {"time": 1697825281, "lat": 49.989646159875086, "lon": 8.372431529735952, "alt": 2541.40625}, {"time": 1697826481, "lat": 50.09435875853791, "lon": 8.662271863362404, "alt": 2541.40625}, {"time": 1697827681, "lat": 50.19499174744686, "lon": 8.93259728580706, "alt": 2541.40625}, {"time": 1697828881, "lat": 50.29212936574956, "lon": 9.197622324831832, "alt": 2541.40625}, {"time": 1697830081, "lat": 50.39546963598292, "lon": 9.471199745508276, "alt": 2541.40625}, {"time": 1697831281, "lat": 50.506756201025055, "lon": 9.756777613589094, "alt": 2541.40625}, {"time": 1697832481, "lat": 50.62408141443116, "lon": 10.055295780135987, "alt": 2541.40625}, {"time": 1697833681, "lat": 50.74366711276691, "lon": 10.364096778886777, "alt": 2541.40625}, {"time": 1697834881, "lat": 50.86547320898176, "lon": 10.690103035991303, "alt": 2541.40625}, {"time": 1697836081, "lat": 50.98551585487632, "lon": 11.024736654944446, "alt": 2541.40625}, {"time": 1697837281, "lat": 51.09837951176664, "lon": 11.354945531368442, "alt": 2541.40625}, {"time": 1697838481, "lat": 51.209090539135104, "lon": 11.681246181484429, "alt": 2541.40625}, {"time": 1697839681, "lat": 51.32395305531132, "lon": 12.012727783257938, "alt": 2541.40625}, {"time": 1697840881, "lat": 51.4434004865406, "lon": 12.341236864327502, "alt": 2541.40625}, {"time": 1697842081, "lat": 51.56575167367278, "lon": 12.66458053300588, "alt": 2541.40625}, {"time": 1697843281, "lat": 51.68558353199418, "lon": 12.976928670952686, "alt": 2541.40625}, {"time": 1697844481, "lat": 51.808197253364455, "lon": 13.27872052720281, "alt": 2541.40625}, {"time": 1697845681, "lat": 51.935914194979496, "lon": 13.57632829947249, "alt": 2541.40625}, {"time": 1697846881, "lat": 52.06541807383993, "lon": 13.874880645113347, "alt": 2541.40625}, {"time": 1697848081, "lat": 52.193602554438385, "lon": 14.171146457013402, "alt": 2541.40625}, {"time": 1697849281, "lat": 52.32516615260403, "lon": 14.463254797256221, "alt": 2541.40625}, {"time": 1697850481, "lat": 52.46437173738165, "lon": 14.751900489535316, "alt": 2541.40625}, {"time": 1697851681, "lat": 52.605556746372784, "lon": 15.04131581462667, "alt": 2541.40625}, {"time": 1697852881, "lat": 52.744813707967154, "lon": 15.334159285242347, "alt": 2541.40625}, {"time": 1697854081, "lat": 52.87922315857887, "lon": 15.631375762683154, "alt": 2541.40625}, {"time": 1697855281, "lat": 53.005439140497295, "lon": 15.9334623350681, "alt": 2541.40625}, {"time": 1697856481, "lat": 53.12266399758165, "lon": 16.239059644955017, "alt": 2541.40625}, {"time": 1697857681, "lat": 53.23297840281449, "lon": 16.541098497689784, "alt": 2541.40625}, {"time": 1697858881, "lat": 53.34232663122806, "lon": 16.84498296886326, "alt": 2541.40625}, {"time": 1697860081, "lat": 53.45388036140508, "lon": 17.15332631028565, "alt": 2541.40625}, {"time": 1697861281, "lat": 53.56291748503723, "lon": 17.46226436415671, "alt": 2541.40625}, {"time": 1697862481, "lat": 53.66301108746143, "lon": 17.752367920987037, "alt": 2541.40625}, {"time": 1697863681, "lat": 53.756125465166605, "lon": 18.020293117478975, "alt": 2541.40625}, {"time": 1697864881, "lat": 53.84443764730249, "lon": 18.27094615040044, "alt": 2541.40625}, {"time": 1697866081, "lat": 53.92920627407708, "lon": 18.511707932213074, "alt": 2541.40625}, {"time": 1697867281, "lat": 54.01303656730144, "lon": 18.75323403151018, "alt": 2541.40625}, {"time": 1697868481, "lat": 54.095868770133755, "lon": 18.999773296083827, "alt": 2541.40625}, {"time": 1697869681, "lat": 54.17980857002759, "lon": 19.241755134435078, "alt": 2541.40625}, {"time": 1697870881, "lat": 54.26580540479724, "lon": 19.47276923743176, "alt": 2541.40625}, {"time": 1697872081, "lat": 54.35297597101382, "lon": 19.69677046063011, "alt": 2541.40625}, {"time": 1697873281, "lat": 54.4407637537023, "lon": 19.919634444738552, "alt": 2541.40625}, {"time": 1697874481, "lat": 54.52967121841839, "lon": 20.14521169658971, "alt": 2541.40625}, {"time": 1697875681, "lat": 54.6195032781259, "lon": 20.369942303008454, "alt": 2541.40625}, {"time": 1697876881, "lat": 54.71003017186386, "lon": 20.59404374946693, "alt": 2541.40625}, {"time": 1697878081, "lat": 54.80466643235945, "lon": 20.815960971634162, "alt": 2541.40625}, {"time": 1697879281, "lat": 54.902964454586034, "lon": 21.035736598675683, "alt": 2541.40625}, {"time": 1697880481, "lat": 55.00398634443448, "lon": 21.256378841971856, "alt": 2541.40625}, {"time": 1697881681, "lat": 55.10836252824465, "lon": 21.477860175240657, "alt": 2541.40625}, {"time": 1697882881, "lat": 55.21285716396815, "lon": 21.699465793943475, "alt": 2541.40625}, {"time": 1697884081, "lat": 55.31207189121156, "lon": 21.92250246903604, "alt": 2541.40625}, {"time": 1697885281, "lat": 55.40804089620216, "lon": 22.147629083253396, "alt": 2541.40625}, {"time": 1697886481, "lat": 55.50388391633759, "lon": 22.37641101405387, "alt": 2541.40625}, {"time": 1697887681, "lat": 55.60097091347051, "lon": 22.60643869102728, "alt": 2541.40625}, {"time": 1697888881, "lat": 55.70046472580808, "lon": 22.83728640484063, "alt": 2541.40625}, {"time": 1697890081, "lat": 55.801340043985, "lon": 23.0690941616483, "alt": 2541.40625}, {"time": 1697891281, "lat": 55.900629548018706, "lon": 23.299786471711673, "alt": 2541.40625}, {"time": 1697892481, "lat": 55.99784855344522, "lon": 23.529437289597134, "alt": 2541.40625}, {"time": 1697893681, "lat": 56.090478100535, "lon": 23.75789979269153, "alt": 2541.40625}, {"time": 1697894881, "lat": 56.17543254796434, "lon": 23.98550452925505, "alt": 2541.40625}, {"time": 1697896081, "lat": 56.256606763052865, "lon": 24.21308356047565, "alt": 2541.40625}, {"time": 1697897281, "lat": 56.33756560035536, "lon": 24.4418647463315, "alt": 2541.40625}, {"time": 1697898481, "lat": 56.419106381643275, "lon": 24.672389536447625, "alt": 2541.40625}, {"time": 1697899681, "lat": 56.50197418218225, "lon": 24.903690860726023, "alt": 2541.40625}, {"time": 1697900881, "lat": 56.58588786761463, "lon": 25.134258124823873, "alt": 2541.40625}, {"time": 1697902081, "lat": 56.6672905989913, "lon": 25.36208730826666, "alt": 2541.40625}, {"time": 1697903281, "lat": 56.74634439065202, "lon": 25.587158238646197, "alt": 2541.40625}, {"time": 1697904481, "lat": 56.82250204256607, "lon": 25.80897263093161, "alt": 2541.40625}, {"time": 1697905681, "lat": 56.89534177474188, "lon": 26.02525394969752, "alt": 2541.40625}, {"time": 1697906881, "lat": 56.967476181568635, "lon": 26.23592429729052, "alt": 2541.40625}, {"time": 1697908081, "lat": 57.040795262003144, "lon": 26.44095383363708, "alt": 2541.40625}, {"time": 1697909281, "lat": 57.11598501166453, "lon": 26.641905025293593, "alt": 2541.40625}, {"time": 1697910481, "lat": 57.19234861125557, "lon": 26.84155858348079, "alt": 2541.40625}, {"time": 1697911681, "lat": 57.26970043106924, "lon": 27.039534770889716, "alt": 2541.40625}, {"time": 1697912881, "lat": 57.34630952454888, "lon": 27.235545317285528, "alt": 2541.40625}, {"time": 1697914081, "lat": 57.42145302997134, "lon": 27.430110122889875, "alt": 2541.40625}, {"time": 1697915281, "lat": 57.495266176654134, "lon": 27.623896280075627, "alt": 2541.40625}, {"time": 1697916481, "lat": 57.56734497414666, "lon": 27.82088476460215, "alt": 2541.40625}, {"time": 1697917681, "lat": 57.639184490025, "lon": 28.02206774971835, "alt": 2541.40625}, {"time": 1697918881, "lat": 57.71150408670198, "lon": 28.227922547267926, "alt": 2541.40625}, {"time": 1697920081, "lat": 57.784556946336785, "lon": 28.438488470559136, "alt": 2541.40625}, {"time": 1697921281, "lat": 57.85866649710846, "lon": 28.653441669541166, "alt": 2541.40625}, {"time": 1697922481, "lat": 57.9338771357294, "lon": 28.870245383108312, "alt": 2541.40625}, {"time": 1697923681, "lat": 58.010906495466244, "lon": 29.088057570995193, "alt": 2541.40625}, {"time": 1697924881, "lat": 58.08737632444847, "lon": 29.30428376212974, "alt": 2541.40625}, {"time": 1697926081, "lat": 58.162198479682935, "lon": 29.518609387620995, "alt": 2541.40625}, {"time": 1697927281, "lat": 58.23137261302618, "lon": 29.732882592222396, "alt": 2541.40625}, {"time": 1697928481, "lat": 58.29508400852999, "lon": 29.947907289574992, "alt": 2541.40625}, {"time": 1697929681, "lat": 58.35441905051441, "lon": 30.163819564855885, "alt": 2541.40625}, {"time": 1697930881, "lat": 58.40972494602832, "lon": 30.380508314522242, "alt": 2541.40625}, {"time": 1697932081, "lat": 58.46123414189712, "lon": 30.59869380811678, "alt": 2541.40625}, {"time": 1697933281, "lat": 58.508149721321125, "lon": 30.81747555829034, "alt": 2541.40625}, {"time": 1697934481, "lat": 58.55052296638706, "lon": 31.037036623649286, "alt": 2541.40625}, {"time": 1697935681, "lat": 58.58916046473396, "lon": 31.258550879125178, "alt": 2541.40625}, {"time": 1697936881, "lat": 58.6252633751547, "lon": 31.4840140520567, "alt": 2541.40625}, {"time": 1697938081, "lat": 58.65940699049595, "lon": 31.708091062151997, "alt": 2541.40625}, {"time": 1697939281, "lat": 58.69124736434967, "lon": 31.929036400373636, "alt": 2541.40625}, {"time": 1697940481, "lat": 58.72083984670862, "lon": 32.14715666111154, "alt": 2541.40625}, {"time": 1697941681, "lat": 58.748784879474954, "lon": 32.36284629232269, "alt": 2541.40625}, {"time": 1697942881, "lat": 58.775739273865746, "lon": 32.577971624054236, "alt": 2541.40625}, {"time": 1697944081, "lat": 58.80217365297601, "lon": 32.79196617666642, "alt": 2541.40625}, {"time": 1697945281, "lat": 58.82928087920663, "lon": 33.00519314546959, "alt": 2541.40625}, {"time": 1697946481, "lat": 58.85758475761732, "lon": 33.21678594667968, "alt": 2541.40625}, {"time": 1697947681, "lat": 58.886952359485605, "lon": 33.42664716286992, "alt": 2541.40625}, {"time": 1697948881, "lat": 58.915446037107486, "lon": 33.63382141773347, "alt": 2541.40625}, {"time": 1697950081, "lat": 58.94125218834526, "lon": 33.837198470703775, "alt": 2541.40625}, {"time": 1697951009, "lat": 58.95943180877415, "lon": 33.99194649998202, "alt": 2541.40625}]}', qos=0, retain=False) \ No newline at end of file