Skip to content
Snippets Groups Projects
controllers.py 6.25 KiB
Newer Older
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)