예제 #1
0
        def process_update(update, current):

            # calculate orientation?
            if ('orientation' not in update and
                    'location' in update and
                    update['location'] != current['location']):

                    current['orientation'] = calculate_orientation(current['location'], update['location'])

            # clear timestamp
            # if update has no timestamp, save should create one
            current.pop('timestamp', None)

            # update data
            current.update(**update)

            return current
예제 #2
0
    def save(self, *args, **kwargs):

        # creation?
        created = self.pk is None

        # loaded_values?
        loaded_values = self._loaded_values is not None

        # create equipment holder?
        try:
            if created or self.equipmentholder is None:
                self.equipmentholder = EquipmentHolder.objects.create()
        except EquipmentHolder.DoesNotExist:
            self.equipmentholder = EquipmentHolder.objects.create()

        # has location changed?
        has_moved = False
        if (not loaded_values) or \
                calculate_distance(self._loaded_values['location'], self.location) > stationary_radius:
            has_moved = True

        # calculate orientation only if location has changed and orientation has not changed
        if has_moved and loaded_values and self._loaded_values['orientation'] == self.orientation:
            # TODO: should we allow for a small radius before updating direction?
            self.orientation = calculate_orientation(self._loaded_values['location'], self.location)
            # logger.debug('< {} - {} = {}'.format(self._loaded_values['location'],
            #                                      self.location,
            #                                      self.orientation))

        # logger.debug('loaded_values: {}'.format(loaded_values))
        # logger.debug('_loaded_values: {}'.format(self._loaded_values))

        # if comment, capability, status or location changed
        # model_changed = False
        if has_moved or \
                self._loaded_values['status'] != self.status or \
                self._loaded_values['capability'] != self.capability or \
                self._loaded_values['comment'] != self.comment:

            # save to Ambulance
            super().save(*args, **kwargs)

            # logger.debug('SAVED')

            # save to AmbulanceUpdate
            data = {k: getattr(self, k)
                    for k in ('capability', 'status', 'orientation',
                              'location', 'timestamp',
                              'comment', 'updated_by', 'updated_on')}
            data['ambulance'] = self
            obj = AmbulanceUpdate(**data)
            obj.save()

            # logger.debug('UPDATE SAVED')

            # # model changed
            # model_changed = True

        # if identifier changed
        # NOTE: self._loaded_values is NEVER None because has_moved is True
        elif self._loaded_values['identifier'] != self.identifier:

            # save only to Ambulance
            super().save(*args, **kwargs)

            # logger.debug('SAVED')

            # # model changed
            # model_changed = True

        # # Did the model change?
        # if model_changed:
        #
        #     # publish to mqtt
        #
        #     from mqtt.publish import SingletonPublishClient
        #     SingletonPublishClient().publish_ambulance(self)
        #
        #     # logger.debug('PUBLISHED ON MQTT')

        # just created?
        if created:
            # invalidate permissions cache
            from mqtt.cache_clear import mqtt_cache_clear
            mqtt_cache_clear()
    def test(self):

        # Bulk update ambulance a1
        a = self.a1
        user = self.u1

        location0 = {'latitude': -3., 'longitude': 6.}
        location = {'latitude': -2., 'longitude': 7.}
        orientation = calculate_orientation(dict2point(location0),
                                            dict2point(location))
        data = [{
            'status': AmbulanceStatus.AH.name,
            'location': location0,
        }, {
            'location': location,
            'timestamp': timezone.now()
        }, {
            'status': AmbulanceStatus.OS.name
        }]

        serializer = AmbulanceUpdateSerializer(data=data,
                                               many=True,
                                               partial=True)
        serializer.is_valid(raise_exception=True)
        serializer.save(ambulance=Ambulance.objects.get(id=a.id),
                        updated_by=user)

        # test AmbulanceUpdateSerializer
        queryset = AmbulanceUpdate.objects.filter(ambulance=a)
        answer1 = []
        for u in queryset:
            serializer = AmbulanceUpdateSerializer(u)
            result = {
                'id': u.id,
                'ambulance_id': u.ambulance.id,
                'ambulance_identifier': u.ambulance.identifier,
                'comment': u.comment,
                'capability': u.capability,
                'status': u.status,
                'orientation': u.orientation,
                'location': point2str(u.location),
                'timestamp': date2iso(u.timestamp),
                'updated_by_username': u.updated_by.username,
                'updated_on': date2iso(u.updated_on)
            }
            answer1.append(serializer.data)
            self.assertDictEqual(serializer.data, result)

        # make sure last update is reflected in ambulance
        a = Ambulance.objects.get(id=a.id)
        serializer = AmbulanceSerializer(a)
        self.assertEqual(math.fabs(orientation - a.orientation) < 1e-4, True)
        orientation = a.orientation
        result = {
            'id': a.id,
            'identifier': a.identifier,
            'comment': a.comment,
            'capability': a.capability,
            'status': AmbulanceStatus.OS.name,
            'orientation': orientation,
            'location': point2str(location),
            'timestamp': date2iso(a.timestamp),
            'client_id': None,
            'updated_by': a.updated_by.id,
            'updated_on': date2iso(a.updated_on)
        }
        self.assertDictEqual(serializer.data, result)

        # Bulk update ambulance a2
        a = self.a3
        user = self.u3

        data = [{
            'status': AmbulanceStatus.AH.name,
            'location': location0
        }, {
            'status': AmbulanceStatus.OS.name
        }, {
            'location': location,
            'timestamp': timezone.now()
        }]

        serializer = AmbulanceUpdateSerializer(data=data,
                                               many=True,
                                               partial=True)
        serializer.is_valid(raise_exception=True)
        serializer.save(ambulance=Ambulance.objects.get(id=a.id),
                        updated_by=user)

        # test AmbulanceUpdateSerializer
        queryset = AmbulanceUpdate.objects.filter(ambulance=a)
        answer3 = []
        for u in queryset:
            serializer = AmbulanceUpdateSerializer(u)
            result = {
                'id': u.id,
                'ambulance_id': a.id,
                'ambulance_identifier': a.identifier,
                'comment': u.comment,
                'capability': u.capability,
                'status': u.status,
                'orientation': u.orientation,
                'location': point2str(u.location),
                'timestamp': date2iso(u.timestamp),
                'updated_by_username': u.updated_by.username,
                'updated_on': date2iso(u.updated_on)
            }
            answer3.append(serializer.data)
            self.assertDictEqual(serializer.data, result)

        # make sure last update is reflected in ambulance
        a = Ambulance.objects.get(id=a.id)
        serializer = AmbulanceSerializer(a)
        self.assertEqual(math.fabs(orientation - a.orientation) < 1e-4, True)
        orientation = a.orientation
        result = {
            'id': a.id,
            'identifier': a.identifier,
            'comment': a.comment,
            'capability': a.capability,
            'status': AmbulanceStatus.OS.name,
            'orientation': orientation,
            'location': point2str(location),
            'timestamp': date2iso(a.timestamp),
            'client_id': None,
            'updated_by': a.updated_by.id,
            'updated_on': date2iso(a.updated_on)
        }
        self.assertDictEqual(serializer.data, result)

        # Test api

        # instantiate client
        client = Client()

        # login as admin
        client.login(username=settings.MQTT['USERNAME'],
                     password=settings.MQTT['PASSWORD'])

        # retrieve ambulances updates
        response = client.get('/en/api/ambulance/{}/updates/'.format(
            self.a1.id),
                              follow=True)
        self.assertEqual(response.status_code, 200)
        result = JSONParser().parse(BytesIO(response.content))
        self.assertCountEqual(result, answer1)
        self.assertEqual(len(result), 4)

        # retrieve ambulances updates
        response = client.get('/en/api/ambulance/{}/updates/'.format(
            self.a3.id),
                              follow=True)
        self.assertEqual(response.status_code, 200)
        result = JSONParser().parse(BytesIO(response.content))
        self.assertCountEqual(result, answer3)
        self.assertEqual(len(result), 4)

        # logout
        client.logout()

        # login as testuser1
        client.login(username='******', password='******')

        # retrieve ambulances
        response = client.get('/en/api/ambulance/{}/updates/'.format(
            self.a1.id),
                              follow=True)
        self.assertEqual(response.status_code, 404)

        # retrieve ambulances
        response = client.get('/en/api/ambulance/{}/updates/'.format(
            self.a3.id),
                              follow=True)
        self.assertEqual(response.status_code, 404)

        # logout
        client.logout()

        # login as testuser2
        client.login(username='******', password='******')

        # retrieve ambulances
        response = client.get('/en/api/ambulance/{}/updates/'.format(
            self.a1.id),
                              follow=True)
        self.assertEqual(response.status_code, 404)

        # retrieve ambulances updates
        response = client.get('/en/api/ambulance/{}/updates/'.format(
            self.a3.id),
                              follow=True)
        self.assertEqual(response.status_code, 200)
        result = JSONParser().parse(BytesIO(response.content))
        self.assertCountEqual(result, answer3)
        self.assertEqual(len(result), 4)

        # logout
        client.logout()