Example #1
0
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]
Example #2
0
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]
Example #3
0
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]
Example #4
0
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
Example #5
0
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
Example #6
0
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]
Example #7
0
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
        ]