from collections import OrderedDict import coreapi import coreschema from django.db.models import Count from rest_framework.schemas import ManualSchema from rest_framework.views import APIView from rest_framework import status from lofar.maintenance.monitoringdb.models.station_test import StationTest from lofar.maintenance.monitoringdb.models.station import Station from rest_framework.response import Response from lofar.maintenance.monitoringdb.models.rtsm import RTSMObservationSummary class ControllerStationOverview(APIView): """ Overview of the latest tests performed on the stations """ DEFAULT_STATION_GROUP = 'A' DEFAULT_ONLY_ERRORS = False DEFAULT_N_STATION_TESTS = 4 DEFAULT_N_RTSM = 4 queryset = StationTest.objects.all() schema = ManualSchema(fields=[ coreapi.Field( "station_group", required=False, location='query', schema=coreschema.Enum(['C', 'R', 'I', 'A'], description= 'Station group to select for choices are [C|R|I|ALL]', ) ), coreapi.Field( "n_station_tests", required=False, location='query', schema=coreschema.Integer(description='number of station tests to select', minimum=1) ), coreapi.Field( "n_rtsm", required=False, location='query', schema=coreschema.Integer(description='number of station tests to select', minimum=1) ), coreapi.Field( "errors_only", required=False, location='query', schema=coreschema.Boolean( description='displays or not only the station with more than one error') ) ] ) def get(self, request, format=None): errors_only = request.query_params.get('errors_only', self.DEFAULT_ONLY_ERRORS) station_group = request.query_params.get('station_group', self.DEFAULT_STATION_GROUP) n_station_tests = int( request.query_params.get('n_station_tests', self.DEFAULT_N_STATION_TESTS)) n_rtsm = int(request.query_params.get('n_rtsm', self.DEFAULT_N_RTSM)) station_entities = Station.objects.all() for group in station_group: if group is not 'A': station_entities = station_entities.filter(type=group) # Since django preferes a ordered dict over a dict we make it happy... for now response_payload = list() for station_entity in station_entities: station_payload = OrderedDict() station_payload['station_name'] = station_entity.name station_test_list = StationTest.objects.filter( station__name=station_entity.name).order_by('-end_datetime')[:n_station_tests - 1] rtsm_list = RTSMObservationSummary.objects.filter( station__name=station_entity.name).order_by('-end_time')[:n_rtsm - 1] station_payload['station_tests'] = list() for station_test in station_test_list: station_test_payload = OrderedDict() component_errors = station_test.component_errors station_test_payload[ 'total_component_errors'] = station_test.component_errors.count() station_test_payload['start_datetime'] = station_test.start_datetime station_test_payload['end_datetime'] = station_test.end_datetime station_test_payload['checks'] = station_test.checks component_errors_summary = component_errors. \ values('component__type', 'type').annotate( total=Count('type')).order_by('-total') component_errors_summary_dict = OrderedDict() for item in component_errors_summary: item_component_type = item['component__type'] item_error_type = item['type'] item_error_total = item['total'] if item_component_type not in component_errors_summary_dict: component_errors_summary_dict[item_component_type] = OrderedDict() component_errors_summary_dict[item_component_type][item_error_type] = \ item_error_total station_test_payload['component_error_summary'] = component_errors_summary_dict station_payload['station_tests'].append(station_test_payload) station_payload['rtsm'] = list() for rtsm in rtsm_list: rtsm_payload = OrderedDict() rtsm_payload['observation_id'] = rtsm.observation_id rtsm_payload['start_datetime'] = rtsm.start_time rtsm_payload['end_datetime'] = rtsm.end_time unique_modes = [item['mode'] for item in rtsm.errors.values('mode').distinct()] rtsm_payload['mode'] = unique_modes rtsm_payload['total_component_error'] = rtsm.errors_found.count() from django.db.models import Window, F errors_summary = OrderedDict() errors_summary_query = rtsm.errors_found.annotate(total= Window(expression=Count('rcu'), partition_by=[F( 'error_type')])).values( 'error_type', 'total').distinct() for error_summary in errors_summary_query: errors_summary[error_summary['error_type']] = error_summary['total'] rtsm_payload['error_summary'] = errors_summary station_payload['rtsm'].append(rtsm_payload) response_payload.append(station_payload) if errors_only: response_payload = filter( lambda station_entry: len(station_entry['station_tests']) + len(station_entry['rtsm']) > 0, response_payload) response_payload = sorted(response_payload, key=lambda item: item['station_name']) return Response(status=status.HTTP_200_OK, data=response_payload)