class ScalarSensorResource(Resource): model = ScalarSensor display_field = 'metric' resource_name = 'scalar_sensors' resource_type = 'scalar_sensor' required_fields = ['metric', 'unit'] model_fields = ['active'] # for now, name is hardcoded as the only attribute of metric and unit stub_fields = {'metric': 'name', 'unit': 'name'} queryset = ScalarSensor.objects related_fields = { 'ch:dataHistory': CollectionField(ScalarSensorDataResource, reverse_name='sensor'), 'ch:aggregateData': CollectionField(AggregateScalarSensorDataResource, reverse_name='sensor'), 'ch:device': ResourceField('chain.core.resources.DeviceResource', 'device'), 'ch:metadata': MetadataCollectionField(MetadataResource) } def serialize_single(self, embed, cache, *args, **kwargs): data = super( ScalarSensorResource, self).serialize_single( embed, cache, *args, **kwargs) data['sensor-type'] = "scalar" if embed: data['dataType'] = 'float' # this is hammering the influx server, we should switch it # over to doing a single bulk query. For now disabling the # data to get things up and running if not kwargs.get('include_data', True): return data else: last_data = influx_client.get_last_sensor_data(self._obj.id) if last_data: # column name returned by last() selector is last data['value'] = last_data[0]['last'] data['updated'] = last_data[0]['time'] return data def get_tags(self): return ['sensor-%s' % self._obj.id, 'scalar_sensor-%s' % self._obj.id, 'device-%s' % self._obj.device_id, 'site-%s' % self._obj.device.site_id]
class SensorResource(Resource): model = Sensor display_field = 'metric' resource_name = 'sensors' resource_type = 'sensor' required_fields = ['metric', 'unit'] # for now, name is hardcoded as the only attribute of metric and unit stub_fields = {'metric': 'name', 'unit': 'name'} queryset = Sensor.objects related_fields = { 'ch:dataHistory': CollectionField(SensorDataResource, reverse_name='sensor'), 'ch:device': ResourceField('chain.core.resources.DeviceResource', 'device') } def serialize_single(self, embed, cache, *args, **kwargs): data = super(SensorResource, self).serialize_single(embed, cache, *args, **kwargs) if embed: data['dataType'] = 'float' last_data = self._obj.scalar_data.order_by( 'timestamp').reverse()[:1] if last_data: data['value'] = last_data[0].value data['updated'] = last_data[0].timestamp.isoformat() return data def get_tags(self): return ['sensor-%s' % self._obj.id, 'device-%s' % self._obj.device_id, 'site-%s' % self._obj.device.site_id]
class DeviceResource(Resource): model = Device display_field = 'name' resource_name = 'devices' resource_type = 'device' required_fields = ['name'] model_fields = [ 'name', 'description', 'building', 'floor', 'room', 'active' ] ''''ch:sensors': CollectionField(ScalarSensorResource, reverse_name='device'), 'ch:sensors': CollectionField(PresenceSensorResource, reverse_name='device'),''' related_fields = { 'ch:sensors': CollectionField(MixedSensorResource, reverse_name='device'), 'ch:site': ResourceField('chain.core.resources.SiteResource', 'site'), 'ch:metadata': MetadataCollectionField(MetadataResource) } queryset = Device.objects def get_tags(self): # sometimes the site_id field is unicode? weird return ['device-%d' % self._obj.id, 'site-%s' % self._obj.site_id]
class SiteResource(Resource): model = Site # TODO _href should be the external URL if present resource_name = 'sites' resource_type = 'site' display_field = 'name' model_fields = ['name'] required_fields = ['name'] related_fields = { 'ch:devices': CollectionField(DeviceResource, reverse_name='site') } queryset = Site.objects def serialize_single(self, embed, cache): data = super(SiteResource, self).serialize_single(embed, cache) if embed: stream = self._obj.raw_zmq_stream if stream: data['_links']['rawZMQStream'] = { 'href': stream, 'title': 'Raw ZMQ Stream'} data['_links']['ch:siteSummary'] = { 'title': 'Summary', 'href': full_reverse('site-summary', self._request, args=(self._obj.id,)) } return data def get_filled_schema(self): schema = super(SiteResource, self).get_filled_schema() schema['properties']['rawZMQStream']['default'] = \ self._obj.raw_zmq_stream return schema def deserialize(self): super(SiteResource, self).deserialize() if 'rawZMQStream' in self._data: self._obj.raw_zmq_stream = self._data['rawZMQStream'] return self._obj def update(self, data): super(SiteResource, self).update(data) if 'rawZMQStream' in data: self._obj.raw_zmq_stream = data['rawZMQStream'] self._obj.save() def get_tags(self): return ['site-%d' % self._obj.id] @classmethod def get_schema(cls): schema = super(SiteResource, cls).get_schema() schema['properties']['rawZMQStream'] = { 'type': 'string', 'format': 'uri', 'title': 'rawZMQStream' } return schema @classmethod def site_summary_view(cls, request, id): time_begin = timezone.now() - timedelta(hours=2) #filters = request.GET.dict() devices = Device.objects.filter(site_id=id).select_related( 'sensors', 'sensors__metric', 'sensors__unit') db_sensor_data = ScalarData.objects.filter(sensor__device__site_id=id, timestamp__gt=time_begin) response = { '_links': { 'self': {'href': full_reverse('site-summary', request, args=(id,))}, }, 'devices': [] } sensor_hash = {} for device in devices: dev_resource = DeviceResource(obj=device, request=request) dev_data = dev_resource.serialize(rels=False) dev_data['href'] = dev_resource.get_single_href() response['devices'].append(dev_data) dev_data['sensors'] = [] for sensor in device.sensors.all(): sensor_resource = SensorResource(obj=sensor, request=request) sensor_data = sensor_resource.serialize(rels=False) sensor_data['href'] = sensor_resource.get_single_href() dev_data['sensors'].append(sensor_data) sensor_data['data'] = [] sensor_hash[sensor.id] = sensor_data #import pdb; pdb.set_trace() for data in db_sensor_data: data_data = SensorDataResource( obj=data, request=request).serialize(rels=False) sensor_hash[data.sensor_id]['data'].append(data_data) return cls.render_response(response, request) @classmethod def urls(cls): base_patterns = super(SiteResource, cls).urls() base_patterns.append( url(r'^(\d+)/summary$', cls.site_summary_view, name='site-summary')) return base_patterns
class SiteResource(Resource): model = Site # TODO _href should be the external URL if present resource_name = 'sites' resource_type = 'site' display_field = 'name' model_fields = ['name'] required_fields = ['name'] related_fields = { 'ch:devices': CollectionField(DeviceResource, reverse_name='site'), 'ch:people': CollectionField(PersonResource, reverse_name='site') } queryset = Site.objects def serialize_single(self, embed, cache): data = super(SiteResource, self).serialize_single(embed, cache) if embed: stream = self._obj.raw_zmq_stream if stream: data['_links']['rawZMQStream'] = { 'href': stream, 'title': 'Raw ZMQ Stream' } data['_links']['ch:siteSummary'] = { 'title': 'Summary', 'href': full_reverse('site-summary', self._request, args=(self._obj.id, )) } return data def get_filled_schema(self): schema = super(SiteResource, self).get_filled_schema() schema['properties']['rawZMQStream']['default'] = \ self._obj.raw_zmq_stream return schema def deserialize(self): super(SiteResource, self).deserialize() if 'rawZMQStream' in self._data: self._obj.raw_zmq_stream = self._data['rawZMQStream'] return self._obj def update(self, data): super(SiteResource, self).update(data) if 'rawZMQStream' in data: self._obj.raw_zmq_stream = data['rawZMQStream'] self._obj.save() def get_tags(self): return ['site-%d' % self._obj.id] @classmethod def get_schema(cls, filters=None): schema = super(SiteResource, cls).get_schema(filters) schema['properties']['rawZMQStream'] = { 'type': 'string', 'format': 'uri', 'title': 'rawZMQStream' } return schema @classmethod def site_summary_view(cls, request, id): #filters = request.GET.dict() devices = Device.objects.filter(site_id=id).select_related( 'sensors', 'sensors__metric', 'sensors__unit') response = { '_links': { 'self': { 'href': full_reverse('site-summary', request, args=(id, )) }, }, 'devices': [] } sensor_data_list = influx_client.get_last_data_from_all_sensors(id) sensor_data_dict = {} for data_point in sensor_data_list: sensor_data_dict[int( data_point['sensor_id'])] = (data_point['last_value'], data_point['time']) for device in devices: dev_resource = DeviceResource(obj=device, request=request) dev_data = dev_resource.serialize(rels=False) dev_data['href'] = dev_resource.get_single_href() response['devices'].append(dev_data) dev_data['sensors'] = [] for sensor in device.sensors.all(): sensor_resource = ScalarSensorResource(obj=sensor, request=request) sensor_data = sensor_resource.serialize(rels=False, include_data=False) try: sensor_data['value'] = sensor_data_dict[sensor.id][0] sensor_data['updated'] = sensor_data_dict[sensor.id][1] except KeyError: # looks like we don't have any data for this sensor pass sensor_data['href'] = sensor_resource.get_single_href() dev_data['sensors'].append(sensor_data) sensor_data['data'] = [] return cls.render_response(response, request) @classmethod def urls(cls): base_patterns = super(SiteResource, cls).urls() base_patterns.append( url(r'^(\d+)/summary$', cls.site_summary_view, name='site-summary')) return base_patterns
class PersonResource(Resource): model = Person display_field = 'last_name' resource_name = 'people' resource_type = 'person' required_fields = ['first_name', 'last_name'] model_fields = ['first_name', 'last_name', 'twitter_handle', 'rfid'] related_fields = { 'ch:presence-data': CollectionField(PresenceDataResource, reverse_name='person'), 'ch:site': ResourceField('chain.core.resources.SiteResource', 'site') } queryset = Person.objects def serialize_single(self, embed, cache, *args, **kwargs): data = super(PersonResource, self).serialize_single(embed, cache, *args, **kwargs) if embed: if '_embedded' not in data: data['_embedded'] = {} data['_embedded'].update(self.get_additional_embedded()) if '_links' in data: data['_links'].update(self.get_additional_links()) return data def get_presence_data(self): filters = {'person': self._obj} return PresenceData.objects.filter(**filters).order_by('timestamp')[:1] def get_additional_links(self): links = {} last_data = self.get_presence_data() if last_data: links['last-visit'] = { 'href': self.get_presense_data_url(last_data[0]), 'title': "at %s->%s at time %s" % (last_data[0].sensor.device, last_data[0].sensor.metric, last_data[0].timestamp.isoformat()) } if self._obj.picture_url: links['picture'] = { 'href': self._obj.picture_url, 'title': 'Picture URL (external)' } return links def get_additional_embedded(self): embedded = {} last_data = self.get_presence_data() if last_data: embedded['last-visit'] = PresenceDataResource(obj=last_data[0], request=self._request)\ .serialize_single(False, {}) return embedded def get_presense_data_url(self, obj): if self._request is None: # No way to form URL, just return the person's ID return obj.id pdata_resource = PresenceDataResource(obj=obj, request=self._request) return pdata_resource.get_single_href() def get_tags(self): # sometimes the site_id field is unicode? weird return ['person-%d' % self._obj.id, 'site-%s' % self._obj.site_id]
class PresenceSensorResource(Resource): model = PresenceSensor display_field = 'metric' resource_name = 'presence_sensors' resource_type = 'presence_sensor' required_fields = ['metric'] # for now, name is hardcoded as the only attribute of metric and unit stub_fields = {'metric': 'name'} queryset = PresenceSensor.objects related_fields = { 'ch:dataHistory': CollectionField(PresenceDataResource, reverse_name='sensor'), 'ch:device': ResourceField('chain.core.resources.DeviceResource', 'device') } def serialize_single(self, embed, cache, *args, **kwargs): data = super(PresenceSensorResource, self).serialize_single(embed, cache, *args, **kwargs) data['sensor-type'] = "presence" data['dataType'] = "presence" if embed: if '_embedded' not in data: data['_embedded'] = {} data['_embedded'].update(self.get_additional_embedded()) if '_links' not in data: data['_links'] = {} data['_links'].update(self.get_additional_links()) return data def get_additional_links(self): links = {} last_data = self._obj.presence_data.order_by('timestamp').reverse()[:1] if last_data: links['last-visit'] = { 'href': self.get_presense_data_url(last_data[0]), 'title': "%s at %s" % (last_data[0].person, last_data[0].timestamp.isoformat()) } return links def get_additional_embedded(self): embedded = {} last_data = self._obj.presence_data.order_by('timestamp').reverse()[:1] if last_data: embedded['last-visit'] = PresenceDataResource(obj=last_data[0], request=self._request)\ .serialize_single(False, {}) return embedded def get_person_url(self, obj): if self._request is None: # No way to form URL, just return the person's ID return obj.id person_resource = PersonResource(obj=obj, request=self._request) return person_resource.get_single_href() def get_presense_data_url(self, obj): if self._request is None: # No way to form URL, just return the person's ID return obj.id pdata_resource = PresenceDataResource(obj=obj, request=self._request) return pdata_resource.get_single_href() def get_sensor_url(self, obj): if self._request is None: # No way to form URL, just return the person's ID return obj.id psensor_resource = PresenceSensorResource(obj=obj, request=self._request) return psensor_resource.get_single_href() def get_tags(self): return [ 'sensor-%s' % self._obj.id, 'presense_sensor-%s' % self._obj.id, 'device-%s' % self._obj.device_id, 'site-%s' % self._obj.device.site_id ]