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
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()