diff --git a/.gitattributes b/.gitattributes index 9901d6d308457039f6877b7e1fc3aeebe7a5ea97..1584e2d7b6616c770ddfb060b5835f440a6042eb 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1836,6 +1836,7 @@ LCU/Maintenance/DBInterface/monitoringdb/admin.py -text LCU/Maintenance/DBInterface/monitoringdb/apps.py -text LCU/Maintenance/DBInterface/monitoringdb/exceptions.py -text LCU/Maintenance/DBInterface/monitoringdb/migrations/0001_initial.py -text +LCU/Maintenance/DBInterface/monitoringdb/migrations/0002_winccantennastatuses.py -text LCU/Maintenance/DBInterface/monitoringdb/migrations/__init__.py -text LCU/Maintenance/DBInterface/monitoringdb/models/__init__.py -text LCU/Maintenance/DBInterface/monitoringdb/models/component.py -text @@ -1847,6 +1848,7 @@ LCU/Maintenance/DBInterface/monitoringdb/models/log.py -text LCU/Maintenance/DBInterface/monitoringdb/models/rtsm.py -text LCU/Maintenance/DBInterface/monitoringdb/models/station.py -text LCU/Maintenance/DBInterface/monitoringdb/models/station_test.py -text +LCU/Maintenance/DBInterface/monitoringdb/models/wincc.py -text LCU/Maintenance/DBInterface/monitoringdb/pagination.py -text LCU/Maintenance/DBInterface/monitoringdb/rtsm_test_raw_parser.py -text LCU/Maintenance/DBInterface/monitoringdb/serializers/__init__.py -text @@ -1859,6 +1861,7 @@ LCU/Maintenance/DBInterface/monitoringdb/serializers/rtsm.py -text LCU/Maintenance/DBInterface/monitoringdb/serializers/station.py -text LCU/Maintenance/DBInterface/monitoringdb/serializers/station_tests.py -text LCU/Maintenance/DBInterface/monitoringdb/serializers/utils.py -text +LCU/Maintenance/DBInterface/monitoringdb/serializers/wincc.py -text LCU/Maintenance/DBInterface/monitoringdb/station_test_raw_parser.py -text LCU/Maintenance/DBInterface/monitoringdb/tasks.py -text LCU/Maintenance/DBInterface/monitoringdb/tests/__init__.py -text @@ -1876,6 +1879,7 @@ LCU/Maintenance/DBInterface/monitoringdb/views/controllers.py -text LCU/Maintenance/DBInterface/monitoringdb/views/logs_view.py -text LCU/Maintenance/DBInterface/monitoringdb/views/rtsm_views.py -text LCU/Maintenance/DBInterface/monitoringdb/views/station_test_views.py -text +LCU/Maintenance/DBInterface/monitoringdb/views/wincc_view.py -text LCU/Maintenance/DBInterface/test/CMakeLists.txt -text LCU/Maintenance/DBInterface/test/__init__.py -text LCU/Maintenance/DBInterface/test/controllers/CMakeLists.txt -text diff --git a/LCU/Maintenance/DBInterface/monitoringdb/migrations/0002_winccantennastatuses.py b/LCU/Maintenance/DBInterface/monitoringdb/migrations/0002_winccantennastatuses.py new file mode 100644 index 0000000000000000000000000000000000000000..d75d4485685f9fa63b564a244d09b6c2d4086b35 --- /dev/null +++ b/LCU/Maintenance/DBInterface/monitoringdb/migrations/0002_winccantennastatuses.py @@ -0,0 +1,86 @@ +# Generated by Django 2.0.7 on 2019-03-07 16:11 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('monitoringdb', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='WinCCAntennaStatus', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('timestamp', models.DateTimeField(auto_now_add=True)), + ('station', models.CharField(max_length=10)), + ('antenna_type', models.CharField(max_length=4)), + ('antenna_id', models.IntegerField()), + ('status_code', models.IntegerField()), + ('status_code_reason', models.CharField(max_length=1000)), + ('status_code_modified_at', models.CharField(max_length=100)), + ('element_00', models.IntegerField(null=True)), + ('element_00_reason', models.CharField(max_length=1000, null=True)), + ('element_00_modified_at', models.CharField(max_length=100, null=True)), + ('element_01', models.IntegerField(null=True)), + ('element_01_reason', models.CharField(max_length=1000, null=True)), + ('element_01_modified_at', models.CharField(max_length=100, null=True)), + ('element_02', models.IntegerField(null=True)), + ('element_02_reason', models.CharField(max_length=1000, null=True)), + ('element_02_modified_at', models.CharField(max_length=100, null=True)), + ('element_03', models.IntegerField(null=True)), + ('element_03_reason', models.CharField(max_length=1000, null=True)), + ('element_03_modified_at', models.CharField(max_length=100, null=True)), + ('element_04', models.IntegerField(null=True)), + ('element_04_reason', models.CharField(max_length=1000, null=True)), + ('element_04_modified_at', models.CharField(max_length=100, null=True)), + ('element_05', models.IntegerField(null=True)), + ('element_05_reason', models.CharField(max_length=1000, null=True)), + ('element_05_modified_at', models.CharField(max_length=100, null=True)), + ('element_06', models.IntegerField(null=True)), + ('element_06_reason', models.CharField(max_length=1000, null=True)), + ('element_06_modified_at', models.CharField(max_length=100, null=True)), + ('element_07', models.IntegerField(null=True)), + ('element_07_reason', models.CharField(max_length=1000, null=True)), + ('element_07_modified_at', models.CharField(max_length=100, null=True)), + ('element_08', models.IntegerField(null=True)), + ('element_08_reason', models.CharField(max_length=1000, null=True)), + ('element_08_modified_at', models.CharField(max_length=100, null=True)), + ('element_09', models.IntegerField(null=True)), + ('element_09_reason', models.CharField(max_length=1000, null=True)), + ('element_09_modified_at', models.CharField(max_length=100, null=True)), + ('element_10', models.IntegerField(null=True)), + ('element_10_reason', models.CharField(max_length=1000, null=True)), + ('element_10_modified_at', models.CharField(max_length=100, null=True)), + ('element_11', models.IntegerField(null=True)), + ('element_11_reason', models.CharField(max_length=1000, null=True)), + ('element_11_modified_at', models.CharField(max_length=100, null=True)), + ('element_12', models.IntegerField(null=True)), + ('element_12_reason', models.CharField(max_length=1000, null=True)), + ('element_12_modified_at', models.CharField(max_length=100, null=True)), + ('element_13', models.IntegerField(null=True)), + ('element_13_reason', models.CharField(max_length=1000, null=True)), + ('element_13_modified_at', models.CharField(max_length=100, null=True)), + ('element_14', models.IntegerField(null=True)), + ('element_14_reason', models.CharField(max_length=1000, null=True)), + ('element_14_modified_at', models.CharField(max_length=100, null=True)), + ('element_15', models.IntegerField(null=True)), + ('element_15_reason', models.CharField(max_length=1000, null=True)), + ('element_15_modified_at', models.CharField(max_length=100, null=True)), + ], + options={ + 'db_table': 'antenna_statuses', + 'ordering': ['-timestamp', 'station', 'antenna_type', 'antenna_id'], + }, + ), + migrations.AddIndex( + model_name='winccantennastatus', + index=models.Index(fields=['station', 'antenna_type', 'antenna_id', 'timestamp'], name='antenna_sta_station_2632f8_idx'), + ), + migrations.RunSQL( + sql="ALTER TABLE antenna_statuses ALTER COLUMN timestamp SET DEFAULT now()", + reverse_sql="" + ) + ] diff --git a/LCU/Maintenance/DBInterface/monitoringdb/models/rtsm.py b/LCU/Maintenance/DBInterface/monitoringdb/models/rtsm.py index 16c28c62ad3ec6fae15d014798f80bbc696ab050..7800afb4696f3deacfffe43910701a5c2000b98d 100644 --- a/LCU/Maintenance/DBInterface/monitoringdb/models/rtsm.py +++ b/LCU/Maintenance/DBInterface/monitoringdb/models/rtsm.py @@ -5,8 +5,6 @@ from django.db import models from django.contrib.postgres.fields import ArrayField from .station import Station -from .fixed_types import STATION_TYPES - MODE_TO_COMPONENT = { 1: 'LBL', 2: 'LBL', @@ -23,6 +21,7 @@ COMPONENT_TO_MODE = { 'HBA': [5, 6, 7] } + class RTSMObservation(models.Model): observation_id = models.PositiveIntegerField(default=0) diff --git a/LCU/Maintenance/DBInterface/monitoringdb/models/wincc.py b/LCU/Maintenance/DBInterface/monitoringdb/models/wincc.py new file mode 100644 index 0000000000000000000000000000000000000000..a8d28b4ebdb395f1396270c6b301a3d17cfbcb9a --- /dev/null +++ b/LCU/Maintenance/DBInterface/monitoringdb/models/wincc.py @@ -0,0 +1,188 @@ +import django.db.models as models +from collections import OrderedDict + + +COMPONENT_TYPE_TO_ANTENNA_TYPE = dict(HBA='HBA', LBH='LBA', LBL='LBA') +STATUS_CODE_TO_STATUS = {0:'OFF', + 10:'OPERATIONAL', + 20:'MAINTENANCE', + 30:'TEST', + 40:'SUSPICIOUS', + 50:'BROKEN', + 60:'BEYOND REPAIR', + 70:'MISSING DATAPOINT'} + + +def to_antenna_type(component_type): + return COMPONENT_TYPE_TO_ANTENNA_TYPE.get(component_type, None) + + +def to_status(status_code): + return STATUS_CODE_TO_STATUS.get(status_code, 'UNKNOWN') + + +class WinCCAntannaStatusManager(models.Manager): + def latest_status_per_station_and_component_type(self, station, + component_type, + to_date): + antenna_type = to_antenna_type(component_type) + if antenna_type: + return self.latest_status_per_station_and_antenna_type(station, antenna_type, + to_date) + else: + return OrderedDict() + + @staticmethod + def format_result(raw_query_result, antenna_type): + results = OrderedDict() + for row in raw_query_result: + status_description = OrderedDict() + results[str(row.antenna_id)] = status_description + status_description['status'] = to_status(row.status_code) + status_description['status_code'] = row.status_code + status_description['reason'] = row.status_code_reason + status_description['last_modified'] = row.status_code_modified_at + + if antenna_type is 'HBA': + elements = OrderedDict() + status_description['elements'] = elements + + for i in range(16): + element_status = OrderedDict() + elements[str(i)] = element_status + + element_status['status_code'] = getattr(row, "element_%.02d" % i, ) + element_status['status'] = to_status(element_status['status_code']) + + element_status['reason'] = getattr(row, "element_%.02d_reason" % i, ) + element_status['last_modified'] = getattr(row, + "element_%.02d_modified_at" % i, ) + return results + + def latest_status_per_station_and_antenna_type(self, station, antenna_type, to_date): + raw_results = super().raw(''' + SELECT * + FROM antenna_statuses master + INNER JOIN ( + SELECT station, antenna_type, antenna_id, MAX("timestamp") last_entry_timestamp + FROM antenna_statuses + WHERE timestamp <= %s + GROUP BY station, antenna_type, antenna_id + ) slave ON master.station=slave.station AND master.antenna_type=slave.antenna_type AND master.antenna_id = slave.antenna_id AND last_entry_timestamp=master.timestamp + WHERE master.station=%s AND master.antenna_type=%s + ''', [to_date, station.rstrip('C'), antenna_type]) + + return WinCCAntannaStatusManager.format_result(raw_results, antenna_type) + + def latest_status_per_station_and_component_type_antenna_id(self, station, + component_type, + component_id, + to_date): + antenna_type = to_antenna_type(component_type) + if antenna_type: + return self.latest_status_per_station_and_antenna_type_antenna_id(station, antenna_type, + component_id, + to_date) + else: + return OrderedDict() + + def latest_status_per_station_and_antenna_type_antenna_id(self, station, + antenna_type, + antenna_id, + to_date): + raw_results = super().raw(''' + SELECT * + FROM antenna_statuses master + INNER JOIN ( + SELECT station, antenna_type, antenna_id, MAX("timestamp") last_entry_timestamp + FROM antenna_statuses + WHERE timestamp <= %s + GROUP BY station, antenna_type, antenna_id + ) slave ON master.station=slave.station AND master.antenna_type=slave.antenna_type AND master.antenna_id = slave.antenna_id AND last_entry_timestamp=master.timestamp + WHERE master.station=%s AND master.antenna_type=%s AND master.antenna_id=%s + ''', [to_date, station.rstrip('C'), antenna_type, antenna_id]) + return WinCCAntannaStatusManager.format_result(raw_results, antenna_type) + + +class WinCCAntennaStatus(models.Model): + class Meta: + db_table = "antenna_statuses" + ordering = ['-timestamp', 'station', 'antenna_type', 'antenna_id'] + indexes = [ + models.Index(fields=['station', 'antenna_type', 'antenna_id', 'timestamp']) + ] + objects = WinCCAntannaStatusManager() + + timestamp = models.DateTimeField(auto_now_add=True) + station = models.CharField(max_length=10) + antenna_type = models.CharField(max_length=4) + antenna_id = models.IntegerField() + + status_code = models.IntegerField() + status_code_reason = models.CharField(max_length=1000) + status_code_modified_at = models.CharField(max_length=100) + + element_00 = models.IntegerField(null=True) + element_00_reason = models.CharField(max_length=1000, null=True) + element_00_modified_at = models.CharField(max_length=100, null=True) + + element_01 = models.IntegerField(null=True) + element_01_reason = models.CharField(max_length=1000, null=True) + element_01_modified_at = models.CharField(max_length=100, null=True) + + element_02 = models.IntegerField(null=True) + element_02_reason = models.CharField(max_length=1000, null=True) + element_02_modified_at = models.CharField(max_length=100, null=True) + + element_03 = models.IntegerField(null=True) + element_03_reason = models.CharField(max_length=1000, null=True) + element_03_modified_at = models.CharField(max_length=100, null=True) + + element_04 = models.IntegerField(null=True) + element_04_reason = models.CharField(max_length=1000, null=True) + element_04_modified_at = models.CharField(max_length=100, null=True) + + element_05 = models.IntegerField(null=True) + element_05_reason = models.CharField(max_length=1000, null=True) + element_05_modified_at = models.CharField(max_length=100, null=True) + + element_06 = models.IntegerField(null=True) + element_06_reason = models.CharField(max_length=1000, null=True) + element_06_modified_at = models.CharField(max_length=100, null=True) + + element_07 = models.IntegerField(null=True) + element_07_reason = models.CharField(max_length=1000, null=True) + element_07_modified_at = models.CharField(max_length=100, null=True) + + element_08 = models.IntegerField(null=True) + element_08_reason = models.CharField(max_length=1000, null=True) + element_08_modified_at = models.CharField(max_length=100, null=True) + + element_09 = models.IntegerField(null=True) + element_09_reason = models.CharField(max_length=1000, null=True) + element_09_modified_at = models.CharField(max_length=100, null=True) + + element_10 = models.IntegerField(null=True) + element_10_reason = models.CharField(max_length=1000, null=True) + element_10_modified_at = models.CharField(max_length=100, null=True) + + element_11 = models.IntegerField(null=True) + element_11_reason = models.CharField(max_length=1000, null=True) + element_11_modified_at = models.CharField(max_length=100, null=True) + + element_12 = models.IntegerField(null=True) + element_12_reason = models.CharField(max_length=1000, null=True) + element_12_modified_at = models.CharField(max_length=100, null=True) + + element_13 = models.IntegerField(null=True) + element_13_reason = models.CharField(max_length=1000, null=True) + element_13_modified_at = models.CharField(max_length=100, null=True) + + element_14 = models.IntegerField(null=True) + element_14_reason = models.CharField(max_length=1000, null=True) + element_14_modified_at = models.CharField(max_length=100, null=True) + + element_15 = models.IntegerField(null=True) + element_15_reason = models.CharField(max_length=1000, null=True) + element_15_modified_at = models.CharField(max_length=100, null=True) + diff --git a/LCU/Maintenance/DBInterface/monitoringdb/serializers/wincc.py b/LCU/Maintenance/DBInterface/monitoringdb/serializers/wincc.py new file mode 100644 index 0000000000000000000000000000000000000000..cef8b708b4b1e95830c5df82ff06f46b0801921b --- /dev/null +++ b/LCU/Maintenance/DBInterface/monitoringdb/serializers/wincc.py @@ -0,0 +1,8 @@ +from ..models.wincc import WinCCAntennaStatus +from .utils import NotNullModelSerializer + + +class WinCCAntennaStatusSerializer(NotNullModelSerializer): + class Meta: + model = WinCCAntennaStatus + fields = '__all__' diff --git a/LCU/Maintenance/DBInterface/monitoringdb/urls.py b/LCU/Maintenance/DBInterface/monitoringdb/urls.py index 3286959e501e1a4ad692dbb867a5736eb56789fa..d2a37ed245fd00ae3d96307b5a84efb0b7d3085d 100644 --- a/LCU/Maintenance/DBInterface/monitoringdb/urls.py +++ b/LCU/Maintenance/DBInterface/monitoringdb/urls.py @@ -2,6 +2,7 @@ from django.conf.urls import url, include from rest_framework import routers from rest_framework.documentation import include_docs_urls +from .views.wincc_view import * from .views.controllers import * from .views.logs_view import * from .views.rtsm_views import * @@ -10,9 +11,13 @@ from .views.station_test_views import * log_router = routers.DefaultRouter() log_router.register(r'action_log', ActionLogViewSet) -station_test_router = routers.DefaultRouter() +# WinCC +wincc_router = routers.DefaultRouter() +wincc_router.register(r'antenna_status', WinCCAntennaStatusViewSet) # Station test +station_test_router = routers.DefaultRouter() + station_test_router.register(r'element_error', ElementErrorViewSet) station_test_router.register(r'element', ElementViewSet) station_test_router.register(r'component_error', ComponentErrorViewSet) @@ -21,9 +26,10 @@ station_test_router.register(r'component', ComponentViewSet) station_test_router.register(r'station', StationViewSet) station_test_router.register(r'', StationTestViewSet) -rtsm_router = routers.DefaultRouter() # RTSM +rtsm_router = routers.DefaultRouter() + rtsm_router.register(r'errors', RTSMErrorsViewSet) rtsm_router.register(r'spectra', RTSMSpectrumViewSet) rtsm_router.register(r'error_summary_plot', RTSMSummaryPlot, base_name='rtsm-summary-plot') @@ -34,6 +40,8 @@ urlpatterns = [ url(r'^api/stationtests/', include(station_test_router.urls)), url(r'^api/rtsm/', include(rtsm_router.urls)), + url(r'^api/wincc/', include(wincc_router.urls)), + url(r'^api/log/', include(log_router.urls)), url(r'^api/api-auth', include('rest_framework.urls', namespace='rest_framework')), diff --git a/LCU/Maintenance/DBInterface/monitoringdb/views/controllers.py b/LCU/Maintenance/DBInterface/monitoringdb/views/controllers.py index e5a172285c30d2db298c51c3b80d48588a821fb3..765c82c39c955e80715e3f2d340b3ef0b79221cc 100644 --- a/LCU/Maintenance/DBInterface/monitoringdb/views/controllers.py +++ b/LCU/Maintenance/DBInterface/monitoringdb/views/controllers.py @@ -13,6 +13,7 @@ from lofar.maintenance.monitoringdb.models.rtsm import RTSMErrorSummary, MODE_TO from lofar.maintenance.monitoringdb.models.rtsm import RTSMObservation from lofar.maintenance.monitoringdb.models.station import Station from lofar.maintenance.monitoringdb.models.station_test import StationTest +from lofar.maintenance.monitoringdb.models.wincc import WinCCAntennaStatus from rest_framework import status from rest_framework.response import Response from rest_framework.reverse import reverse @@ -258,7 +259,7 @@ class ControllerStationOverview(ValidableReadOnlyView): station_test_payload = OrderedDict() component_errors = station_test.component_errors selected_component_errors = component_errors - if (self.error_types): + if self.error_types: selected_component_errors = component_errors.filter(type__in=self.error_types) station_test_payload[ 'total_component_errors'] = selected_component_errors.count() @@ -296,7 +297,7 @@ class ControllerStationOverview(ValidableReadOnlyView): rtsm_payload['mode'] = unique_modes selected_rtsm_errors = rtsm.errors_summary - if (self.error_types): + if self.error_types: selected_rtsm_errors = rtsm.errors_summary.filter( error_type__in=self.error_types) @@ -813,6 +814,12 @@ class ControllerStationComponentErrors(ValidableReadOnlyView): test_summary['start_date'] = station_test.start_datetime test_summary['end_date'] = station_test.end_datetime component_errors_dict = OrderedDict() + antenna_statuses = \ + WinCCAntennaStatus.objects. \ + latest_status_per_station_and_component_type(self.station_name, + failing_component_type, + to_date=station_test.end_datetime) + test_summary['status'] = antenna_statuses test_summary['component_errors'] = component_errors_dict component_errors = station_test.component_errors \ .filter(component__type=failing_component_type) @@ -855,6 +862,12 @@ class ControllerStationComponentErrors(ValidableReadOnlyView): rtsm_summary['start_date'] = rtsm_observation.start_datetime rtsm_summary['end_date'] = rtsm_observation.end_datetime rtsm_summary['observation_id'] = rtsm_observation.observation_id + antenna_statuses = \ + WinCCAntennaStatus.objects. \ + latest_status_per_station_and_component_type(self.station_name, + component_name, + to_date=rtsm_observation.end_datetime) + rtsm_summary['status'] = antenna_statuses component_errors_dict = OrderedDict() rtsm_summary['component_errors'] = component_errors_dict @@ -922,6 +935,7 @@ class ControllerStationComponentErrors(ValidableReadOnlyView): rtsm_errors = self.collect_rtsm_errors() payload = OrderedDict() + payload['current_status'] = OrderedDict() for component_type in set(rtsm_errors.keys() | station_test_errors.keys()): station_test_errors_per_type = station_test_errors.get(component_type, []) rtsm_errors_per_type = rtsm_errors.get(component_type, []) @@ -929,6 +943,10 @@ class ControllerStationComponentErrors(ValidableReadOnlyView): payload[component_type] = sorted(station_test_errors_per_type + rtsm_errors_per_type, key=lambda item: item['start_date'], reverse=True) + payload['current_status'][component_type] = WinCCAntennaStatus.objects. \ + latest_status_per_station_and_component_type(self.station_name, + component_type, + to_date=datetime.datetime.now()) return Response(status=status.HTTP_200_OK, data=payload) @@ -1010,6 +1028,16 @@ class ControllerStationComponentElementErrors(ValidableReadOnlyView): end_date=observation['end_datetime'], test_type='R', component_errors=dict()) + antenna_statuses = \ + WinCCAntennaStatus.objects. \ + latest_status_per_station_and_component_type_antenna_id(self.station_name, + self.component_type, + self.antenna_id, + to_date=observation[ + 'end_datetime']) + + entry['status'] = antenna_statuses + result.append(entry) return result @@ -1027,6 +1055,13 @@ class ControllerStationComponentElementErrors(ValidableReadOnlyView): end_date=station_test['end_datetime'], test_type='S', component_errors=dict()) + antenna_statuses = WinCCAntennaStatus.objects. \ + latest_status_per_station_and_component_type_antenna_id(self.station_name, + self.component_type, + self.antenna_id, + to_date=station_test['end_datetime']) + + entry['status'] = antenna_statuses result.append(entry) return result @@ -1052,6 +1087,7 @@ class ControllerStationComponentElementErrors(ValidableReadOnlyView): observation__station__name=self.station_name, mode__in=COMPONENT_TO_MODE[self.component_type], rcu__in=list(rcus_per_polarization.keys())).order_by('-observation__start_datetime') + for item in rtsm_errors: observation_pk = item['observation__pk'] if observation_pk not in errors.keys(): @@ -1063,6 +1099,17 @@ class ControllerStationComponentElementErrors(ValidableReadOnlyView): 'observation__end_datetime'], test_type='R', component_errors=dict()) + + antenna_statuses = \ + WinCCAntennaStatus.objects. \ + latest_status_per_station_and_component_type_antenna_id(self.station_name, + self.component_type, + self.antenna_id, + to_date=item[ + 'observation__end_datetime']) + + errors[observation_pk]['status'] = antenna_statuses + rcu = item['rcu'] polarization = rcus_per_polarization[rcu] @@ -1102,6 +1149,14 @@ class ControllerStationComponentElementErrors(ValidableReadOnlyView): end_date=component_error.station_test.end_datetime, test_type='S', component_errors=dict()) + antenna_statuses = WinCCAntennaStatus.objects.\ + latest_status_per_station_and_component_type_antenna_id(self.station_name, + self.component_type, + self.antenna_id, + to_date=component_error.station_test.end_datetime) + + errors[station_test_pk]['status'] = antenna_statuses + error_type = component_error.type details = component_error.details errors[station_test_pk]['component_errors'][error_type] = dict(details=details, @@ -1130,4 +1185,13 @@ class ControllerStationComponentElementErrors(ValidableReadOnlyView): combined = rtsm_errors_list + station_test_list combined_and_sorted = sorted(combined, key=lambda test: test['start_date'], reverse=True) - return Response(status=status.HTTP_200_OK, data=dict(errors=combined_and_sorted)) + data = OrderedDict() + data['errors'] = combined_and_sorted + + data['current_status'] = WinCCAntennaStatus.objects.\ + latest_status_per_station_and_component_type_antenna_id(self.station_name, + self.component_type, + self.antenna_id, + to_date=datetime.datetime.now()) + return Response(status=status.HTTP_200_OK, data=data) + diff --git a/LCU/Maintenance/DBInterface/monitoringdb/views/wincc_view.py b/LCU/Maintenance/DBInterface/monitoringdb/views/wincc_view.py new file mode 100644 index 0000000000000000000000000000000000000000..9749157bd50baaf2603ac413f3df6a972eb9547b --- /dev/null +++ b/LCU/Maintenance/DBInterface/monitoringdb/views/wincc_view.py @@ -0,0 +1,9 @@ +from rest_framework import viewsets +from lofar.maintenance.monitoringdb.models.wincc import WinCCAntennaStatus +from lofar.maintenance.monitoringdb.serializers.wincc import WinCCAntennaStatusSerializer + + +class WinCCAntennaStatusViewSet(viewsets.ReadOnlyModelViewSet): + queryset = WinCCAntennaStatus.objects.all() + serializer_class = WinCCAntennaStatusSerializer + filter_fields = '__all__'