예제 #1
0
def poll_uss_for_flights_async():
    myDSSSubscriber = dss_rid_helper.RemoteIDOperations()

    stream_ops = flight_stream_helper.StreamHelperOps()
    push_cg = stream_ops.get_push_cg()
    all_observations = push_cg.all_observations

    # TODO: Get existing flight details from subscription
    r = redis.Redis(host=env.get('REDIS_HOST', "redis"),
                    port=env.get('REDIS_PORT', 6379),
                    decode_responses=True)
    flights_dict = {}
    # Get the flights URL from the DSS and put it in
    for keybatch in flight_stream_helper.batcher(
            r.scan_iter('all_uss_flights:*'),
            100):  # reasonably we wont have more than 100 subscriptions active
        key_batch_set = set(keybatch)
        for key in key_batch_set:
            if key:
                flights_dict = r.hgetall(key)
                logging.debug('Flights Dict %s' % flights_dict)
                if bool(flights_dict):
                    subscription_id = key.split(':')[1]
                    myDSSSubscriber.query_uss_for_rid(flights_dict,
                                                      all_observations,
                                                      subscription_id)
예제 #2
0
def get_rid_data(request, subscription_id):
    ''' This is the GET endpoint for remote id data given a DSS subscription id. Blender will store flight URLs and everytime the data is queried'''

    try:
        is_uuid = UUID(subscription_id, version=4)
    except ValueError as ve:
        return HttpResponse(
            "Incorrect UUID passed in the parameters, please send a valid subscription ID",
            status=400,
            mimetype='application/json')

    r = redis.Redis(host=env.get('REDIS_HOST', "redis"),
                    port=env.get('REDIS_PORT', 6379),
                    charset="utf-8",
                    decode_responses=True)
    flights_dict = {}
    # Get the flights URL from the DSS and put it in
    # reasonably we wont have more than 500 subscriptions active
    sub_to_check = 'sub-' + subscription_id

    if r.exists(sub_to_check):
        stored_subscription_details = "all_uss_flights:" + subscription_id
        flights_dict = r.get(stored_subscription_details)
        logger.info("Sleeping 2 seconds..")
        time.sleep(2)

    if bool(flights_dict):
        # TODO for Pull operations Flights Dict is not being used at all
        all_flights_rid_data = []
        stream_ops = flight_stream_helper.StreamHelperOps()
        push_cg = stream_ops.push_cg()
        obs_helper = flight_stream_helper.ObservationReadOperations()
        all_flights_rid_data = obs_helper.get_observations(push_cg)

        return HTTPResponse(json.dumps(all_flights_rid_data),
                            status=200,
                            content_type='application/json')
    else:
        return HTTPResponse(json.dumps({}),
                            status=404,
                            content_type='application/json')
예제 #3
0
 def ready(self):
     my_stream_ops = flight_stream_helper.StreamHelperOps()
     my_stream_ops.create_pull_cg()
     print("Created PULL CG...")
     my_stream_ops.create_push_cg()
     print("Created PUSH CG...")
예제 #4
0
def get_uss_flights(request):
    ''' This is the end point for the rid_qualifier to get details of a flight '''
    try:
        include_recent_positions = request.query_params[
            'include_recent_positions']
    except MultiValueDictKeyError as mvke:
        include_recent_positions = False
    # my_rid_output_helper = RIDOutputHelper()
    try:
        view = request.query_params['view']
        view_port = [float(i) for i in view.split(",")]
    except Exception as ke:
        incorrect_parameters = {
            "message":
            "A view bbox is necessary with four values: minx, miny, maxx and maxy"
        }
        return JsonResponse(json.loads(json.dumps(incorrect_parameters)),
                            status=400)
    view_port_valid = view_port_ops.check_view_port(view_port_coords=view_port)
    view_port_area = 0
    if view_port_valid:
        view_box = view_port_ops.build_view_port_box(
            view_port_coords=view_port)
        view_port_area = view_port_ops.get_view_port_area(view_box=view_box)

        if (view_port_area) < 250000 and (view_port_area) > 90000:
            view_port_too_large_msg = GenericErrorResponseMessage(
                message='The requested view %s rectangle is too large' % view)
            return JsonResponse(json.loads(
                json.dumps(asdict(view_port_too_large_msg))),
                                status=419)
    else:
        view_port_not_ok = GenericErrorResponseMessage(
            message=
            'The requested view %s rectangle is not valid format: lat1,lng1,lat2,lng2'
            % view)
        return JsonResponse(json.loads(json.dumps(asdict(view_port_not_ok))),
                            status=419)

    summary_information_only = True if view_port_area > 22500 else False

    stream_ops = flight_stream_helper.StreamHelperOps()
    pull_cg = stream_ops.get_pull_cg()
    all_streams_messages = pull_cg.read()
    unique_flights = []
    distinct_messages = []
    # Keep only the latest message

    for message in all_streams_messages:
        message_exist = message.data.get('icao_address', None) or None
        if message_exist:
            lat = float(message.data['lat_dd'])
            lng = float(message.data['lon_dd'])
            point = Point(lat, lng)
            point_in_polygon = view_box.contains(point)
            if point_in_polygon:
                unique_flights.append({
                    'timestamp': message.timestamp,
                    'seq': message.sequence,
                    'msg_data': message.data,
                    'address': message.data['icao_address']
                })
    # sort by date
    unique_flights.sort(key=lambda item: item['timestamp'], reverse=True)

    now = arrow.now().isoformat()
    if unique_flights:
        # Keep only the latest message
        distinct_messages = {
            i['address']: i
            for i in reversed(unique_flights)
        }.values()

        # except KeyError as ke:
        #     logger.error("Error in sorting distinct messages, key %s name not found" % ke)
        #     error_msg = GenericErrorResponseMessage(message="Error in retrieving flight data")
        #     return JsonResponse(json.loads(json.dumps(asdict(error_msg))), status=500)

        for all_observations_messages in distinct_messages:
            if summary_information_only:
                summary = SummaryFlightsOnly(
                    number_of_flights=len(distinct_messages))
                return JsonResponse(json.loads(json.dumps(asdict(summary))),
                                    status=200)
            else:
                rid_flights = []
                try:
                    observation_data = all_observations_messages['msg_data']
                except KeyError as ke:
                    logger.error("Error in data in the stream %s" % ke)
                else:
                    try:
                        observation_metadata = observation_data['metadata']
                        observation_data_dict = json.loads(
                            observation_metadata)
                    except KeyError as ke:
                        logger.error(
                            "Error in metadata data in the stream %s" % ke)

                    telemetry_data_dict = observation_data_dict['telemetry']
                    details_response_dict = observation_data_dict[
                        'details_response']
                    position = RIDAircraftPosition(
                        lat=telemetry_data_dict['position']['lat'],
                        lng=telemetry_data_dict['position']['lng'],
                        alt=telemetry_data_dict['position']['alt'],
                        accuracy_h=telemetry_data_dict['position']
                        ['accuracy_h'],
                        accuracy_v=telemetry_data_dict['position']
                        ['accuracy_v'],
                        extrapolated=telemetry_data_dict['position']
                        ['extrapolated'],
                        pressure_altitude=telemetry_data_dict['position']
                        ['pressure_altitude'])
                    height = RIDHeight(
                        distance=telemetry_data_dict['height']['distance'],
                        reference=telemetry_data_dict['height']['reference'])
                    current_state = RIDAircraftState(
                        timestamp=telemetry_data_dict['timestamp'],
                        timestamp_accuracy=telemetry_data_dict[
                            'timestamp_accuracy'],
                        operational_status=telemetry_data_dict[
                            'operational_status'],
                        position=position,
                        track=telemetry_data_dict['track'],
                        speed=telemetry_data_dict['speed'],
                        speed_accuracy=telemetry_data_dict['speed_accuracy'],
                        vertical_speed=telemetry_data_dict['vertical_speed'],
                        height=height)

                    current_flight = RIDFlightResponseDetails(
                        id=details_response_dict['details']['id'],
                        aircraft_type="NotDeclared",
                        current_state=current_state,
                        simulated=True,
                        recent_positions=[])

                    rid_flights.append(current_flight)
                    # see if it matches the viewport

                    # show / add metadata it if it does
                    rid_response = RIDFlightResponse(timestamp=now,
                                                     flights=rid_flights)

                    return JsonResponse(json.loads(
                        json.dumps(asdict(rid_response))),
                                        status=200)

    else:
        # show / add metadata it if it does
        rid_response = RIDFlightResponse(timestamp=now, flights=[])

        return JsonResponse(json.loads(json.dumps(asdict(rid_response))),
                            status=200)
예제 #5
0
def get_display_data(request):
    ''' This is the end point for the rid_qualifier test DSS network call once a subscription is updated '''

    # get the view bounding box
    # get the existing subscription id , if no subscription exists, then reject
    request_id = str(uuid.uuid4())
    my_rid_output_helper = RIDOutputHelper()
    try:
        view = request.query_params['view']
        view_port = [float(i) for i in view.split(",")]
    except Exception as ke:
        incorrect_parameters = {
            "message":
            "A view bbox is necessary with four values: minx, miny, maxx and maxy"
        }
        return HttpResponse(json.dumps(incorrect_parameters),
                            status=400,
                            content_type='application/json')
    view_port_valid = view_port_ops.check_view_port(view_port=view_port)

    b = shapely.geometry.box(view_port[1], view_port[0], view_port[3],
                             view_port[2])
    co_ordinates = list(zip(*b.exterior.coords.xy))
    # Convert bounds vertex list
    vertex_list = []
    for cur_co_ordinate in co_ordinates:
        lat_lng = {"lng": 0, "lat": 0}
        lat_lng["lng"] = cur_co_ordinate[0]
        lat_lng["lat"] = cur_co_ordinate[1]
        vertex_list.append(lat_lng)
    # remove the final point
    vertex_list.pop()

    if view_port_valid:
        # stream_id = hashlib.md5(view.encode('utf-8')).hexdigest()
        # create a subscription
        my_subscription_helper = SubscriptionHelper()
        subscription_exists = my_subscription_helper.check_subscription_exists(
            view)
        if not subscription_exists:
            logger.info("Creating Subscription..")
            subscription_response = my_subscription_helper.create_new_subscription(
                request_id=request_id, vertex_list=vertex_list, view=view)

            logger.info("Sleeping 2 seconds..")
            time.sleep(2)

            logger.debug(subscription_response)

        # TODO: Get existing flight details from subscription
        stream_ops = flight_stream_helper.StreamHelperOps()
        pull_cg = stream_ops.get_pull_cg()
        all_streams_messages = pull_cg.read()
        print(all_streams_messages)
        unique_flights = []
        # Keep only the latest message
        try:
            for message in all_streams_messages:
                print(message)
                unique_flights.append({
                    'timestamp': message.timestamp,
                    'seq': message.sequence,
                    'msg_data': message.data,
                    'address': message.data['icao_address']
                })
            # sort by date
            unique_flights.sort(key=lambda item: item['timestamp'],
                                reverse=True)
            # Keep only the latest message
            distinct_messages = {
                i['address']: i
                for i in reversed(unique_flights)
            }.values()

        except KeyError as ke:
            logger.error(
                "Error in sorting distinct messages, ICAO name not defined %s"
                % ke)
            distinct_messages = []
        rid_flights = []

        for all_observations_messages in distinct_messages:
            all_recent_positions = []
            recent_paths = []
            try:
                observation_data = all_observations_messages['msg_data']
            except KeyError as ke:
                logger.error("Error in data in the stream %s" % ke)
            else:
                try:
                    observation_metadata = observation_data['metadata']
                    observation_metadata_dict = json.loads(
                        observation_metadata)
                    recent_positions = observation_metadata_dict[
                        'recent_positions']

                    for recent_position in recent_positions:
                        all_recent_positions.append(
                            Position(lat=recent_position['position']['lat'],
                                     lng=recent_position['position']['lng'],
                                     alt=recent_position['position']['alt']))

                    recent_paths.append(
                        RIDPositions(positions=all_recent_positions))

                except KeyError as ke:
                    logger.error("Error in metadata data in the stream %s" %
                                 ke)

            most_recent_position = Position(
                lat=observation_data['lat_dd'],
                lng=observation_data['lon_dd'],
                alt=observation_data['altitude_mm'])

            current_flight = RIDFlight(
                id=observation_data['icao_address'],
                most_recent_position=most_recent_position,
                recent_paths=recent_paths)

            rid_flights.append(current_flight)

        rid_display_data = RIDDisplayDataResponse(flights=rid_flights,
                                                  clusters=[])

        rid_flights_dict = my_rid_output_helper.make_json_compatible(
            rid_display_data)

        return JsonResponse(json.dumps({
            "flights": rid_flights_dict['flights'],
            "clusters": rid_flights_dict['clusters']
        }),
                            status=200,
                            content_type='application/json')
    else:
        view_port_error = {
            "message": "A incorrect view port bbox was provided"
        }
        return JsonResponse(json.dumps(view_port_error),
                            status=400,
                            content_type='application/json')
예제 #6
0
 def handle(self, *args, **options):
     my_stream_ops = flight_stream_helper.StreamHelperOps()
     
     my_stream_ops.create_pull_cg()     
     my_stream_ops.create_push_cg()