2021-02-22 06:13:30 +00:00
import boto3
import botocore . credentials
from botocore . awsrequest import AWSRequest
from botocore . endpoint import URLLib3Session
from botocore . auth import SigV4Auth
import json
import os
from datetime import datetime , timedelta , timezone
2021-09-13 05:41:23 +00:00
import sys
import traceback
2021-02-22 06:13:30 +00:00
import http . client
2021-03-22 09:25:58 +00:00
import math
2021-04-04 00:47:31 +00:00
import logging
2021-09-12 13:25:34 +00:00
import gzip
from io import BytesIO
2021-02-22 06:13:30 +00:00
HOST = os . getenv ( " ES " )
2021-04-04 00:47:31 +00:00
2021-02-22 06:13:30 +00:00
def predict ( event , context ) :
2021-09-13 05:41:23 +00:00
path = " predictions-*/_search "
2021-02-22 06:13:30 +00:00
payload = {
2021-09-13 05:41:23 +00:00
" aggs " : {
" 2 " : {
" terms " : {
" field " : " serial.keyword " ,
" order " : {
2021-02-22 06:13:30 +00:00
" _key " : " desc "
} ,
2021-09-13 05:41:23 +00:00
" size " : 1000
} ,
" aggs " : {
" 1 " : {
" top_hits " : {
" _source " : True ,
" size " : 1 ,
" sort " : [
2021-02-22 06:13:30 +00:00
{
" datetime " : {
2021-09-13 05:41:23 +00:00
" order " : " desc "
2021-02-22 06:13:30 +00:00
}
}
2021-09-13 05:41:23 +00:00
]
2021-02-22 06:13:30 +00:00
}
}
2021-09-13 05:41:23 +00:00
}
}
} ,
" size " : 0 ,
" stored_fields " : [
" * "
] ,
" script_fields " : { } ,
" docvalue_fields " : [
{
" field " : " datetime " ,
" format " : " date_time "
}
] ,
" _source " : {
" excludes " : [ ]
} ,
" query " : {
" bool " : {
" must " : [ ] ,
" filter " : [
2021-02-22 06:13:30 +00:00
{
" range " : {
" datetime " : {
2021-09-13 05:41:23 +00:00
" gte " : " now-3d " ,
" lte " : " now " ,
" format " : " strict_date_optional_time "
2021-02-22 06:13:30 +00:00
}
}
}
2021-09-13 05:41:23 +00:00
] ,
" should " : [
] ,
" must_not " : [ ]
2021-02-22 06:13:30 +00:00
}
2021-09-13 05:41:23 +00:00
}
}
2021-02-22 06:13:30 +00:00
if " queryStringParameters " in event :
2021-09-13 05:41:23 +00:00
if " vehicles " in event [ " queryStringParameters " ] and event [ " queryStringParameters " ] [ " vehicles " ] != " RS_*;*chase " and event [ " queryStringParameters " ] [ " vehicles " ] != " " :
for serial in event [ " queryStringParameters " ] [ " vehicles " ] . split ( " , " ) :
payload [ " query " ] [ " bool " ] [ " should " ] . append (
{
" match_phrase " : {
" serial.keyword " : serial
}
2021-02-22 06:13:30 +00:00
}
2021-09-13 05:41:23 +00:00
)
# for single sonde allow longer predictions
payload [ ' query ' ] [ ' bool ' ] [ ' filter ' ] . pop ( 0 )
2021-04-04 00:47:31 +00:00
logging . debug ( " Start ES Request " )
2021-02-22 06:13:30 +00:00
results = es_request ( payload , path , " GET " )
2021-04-04 00:47:31 +00:00
logging . debug ( " Finished ES Request " )
2021-02-22 06:13:30 +00:00
output = [ ]
2021-09-13 05:41:23 +00:00
for sonde in results [ ' aggregations ' ] [ ' 2 ' ] [ ' buckets ' ] :
data = sonde [ ' 1 ' ] [ ' hits ' ] [ ' hits ' ] [ 0 ] [ ' _source ' ]
output . append ( {
" vehicle " : data [ " serial " ] ,
" time " : data [ ' datetime ' ] ,
2021-09-14 00:56:26 +00:00
" latitude " : data [ ' position ' ] [ 1 ] ,
" longitude " : data [ ' position ' ] [ 0 ] ,
2021-09-13 05:41:23 +00:00
" altitude " : data [ ' altitude ' ] ,
" ascent_rate " : data [ ' ascent_rate ' ] ,
" descent_rate " : data [ ' descent_rate ' ] ,
" burst_altitude " : data [ ' burst_altitude ' ] ,
" descending " : 1 if data [ ' descending ' ] == True else 0 ,
" landed " : 1 if data [ ' landed ' ] == True else 0 ,
" data " : json . dumps ( data [ ' data ' ] )
} )
2021-02-22 06:13:30 +00:00
return json . dumps ( output )
2021-09-13 05:41:23 +00:00
2021-02-22 06:13:30 +00:00
def es_request ( payload , path , method ) :
# get aws creds
session = boto3 . Session ( )
params = json . dumps ( payload )
2021-09-13 05:41:23 +00:00
2021-09-12 13:25:34 +00:00
compressed = BytesIO ( )
with gzip . GzipFile ( fileobj = compressed , mode = ' w ' ) as f :
f . write ( params . encode ( ' utf-8 ' ) )
params = compressed . getvalue ( )
2021-09-13 05:41:23 +00:00
headers = { " Host " : HOST , " Content-Type " : " application/json " ,
" Content-Encoding " : " gzip " }
2021-02-22 06:13:30 +00:00
request = AWSRequest (
2021-09-12 13:25:34 +00:00
method = method , url = f " https:// { HOST } / { path } " , data = params , headers = headers
2021-02-22 06:13:30 +00:00
)
2021-09-13 05:41:23 +00:00
SigV4Auth ( boto3 . Session ( ) . get_credentials ( ) ,
" es " , " us-east-1 " ) . add_auth ( request )
2021-02-22 06:13:30 +00:00
session = URLLib3Session ( )
r = session . send ( request . prepare ( ) )
return json . loads ( r . text )
if __name__ == " __main__ " :
# print(get_sondes({"queryStringParameters":{"lat":"-28.22717","lon":"153.82996","distance":"50000"}}, {}))
# mode: 6hours
2021-09-13 05:41:23 +00:00
# type: positions
# format: json
# max_positions: 0
# position_id: 0
# vehicles: RS_*;*chase
2021-06-18 07:15:39 +00:00
print ( predict (
2021-09-13 05:41:23 +00:00
{ " queryStringParameters " : {
" vehicles " : " "
} } , { }
) )
2021-02-22 06:13:30 +00:00
# get list of sondes, serial, lat,lon, alt
# and current rate
# for each one, request http://predict.cusf.co.uk/api/v1/?launch_latitude=-37.8136&launch_longitude=144.9631&launch_datetime=2021-02-22T00:15:18.513413Z&launch_altitude=30000&ascent_rate=5&burst_altitude=30000.1&descent_rate=5
# have to set the burst alt slightly higher than the launch