Ejemplo n.º 1
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]
Ejemplo n.º 2
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]
Ejemplo n.º 3
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]
Ejemplo n.º 4
0
class MixedSensorResource(Resource):

    model = ScalarSensor
    display_field = 'metric'
    resource_name = 'sensors'
    resource_type = 'sensor'

    # for now, name is hardcoded as the only attribute of metric and unit
    stub_fields = {'metric': 'name'}

    queryset = ScalarSensor.objects

    available_sensor_types = {
        'scalar': {
            'model': ScalarSensor,
            'resource': ScalarSensorResource
        },
        'presence': {
            'model': PresenceSensor,
            'resource': PresenceSensorResource
        }
    }

    related_fields = {
        'ch:device': ResourceField('chain.core.resources.DeviceResource',
                                   'device')
    }

    @classmethod
    def get_schema(cls, filters=None):
        schema = {
            'required': ['sensor-type'],
            'type': 'object',
            'properties': {
                'sensor-type': {
                    'type': 'string',
                    'title': 'sensor-type',
                    'enum': cls.available_sensor_types.keys()
                }
            },
            'title': 'Create Sensor'
        }
        for sensor_type in cls.available_sensor_types:
            sub_schema = cls.available_sensor_types[sensor_type][
                'resource'].get_schema(filters)
            schema = json_merge(schema, sub_schema)
        return schema

    @classmethod
    def create_list(cls, data, req):
        raise Exception("Not yet implemented.")

    @classmethod
    def create_single(cls, data, req):
        if u'sensor-type' not in data:
            # raise Exception("'type' property not found")
            # For temporary back-compatability, assume it
            #   is a ScalarSensor:
            return ScalarSensorResource.create_single(data, req)
        for sensor_type in cls.available_sensor_types:
            if data['sensor-type'] == sensor_type:
                del data['sensor-type']
                return cls.available_sensor_types[sensor_type][
                    'resource'].create_single(data, req)
        # TODO:  Return 400 rather than raising an exception
        raise Exception("Unrecognized sensor type.")

    def serialize_single(self, embed, cache, *args, **kwargs):
        data = super(MixedSensorResource,
                     self).serialize_single(embed, cache, *args, **kwargs)
        if embed:
            pass
        if '_links' in data:
            data['_links'].update(self.get_links())
            data['totalCount'] = len(data['_links']['items'])
        return data

    def serialize_list(self, embed, cache, *args, **kwargs):
        data = super(MixedSensorResource, self).serialize_list(embed=embed,
                                                               cache=cache,
                                                               *args,
                                                               **kwargs)
        if embed:
            pass
        if '_links' in data:
            data['_links'].update(self.get_links())
            data['totalCount'] = len(data['_links']['items'])
        return data

    def get_links(self):
        mapped_model_to_res = self.map_model_to_resource()
        sensors = self.query_models()
        items = []
        for sensor in sensors:
            items.append({
                'href': (mapped_model_to_res[type(sensor)](
                    obj=sensor, request=self._request)).get_single_href(),
                'title':
                "%s" % sensor
            })
        return {'items': items}

    def map_model_to_resource(self):
        mapped = {}
        for sensor_type in self.available_sensor_types:
            sensor_details = self.available_sensor_types[sensor_type]
            mapped[sensor_details['model']] = sensor_details['resource']
        return mapped

    def query_models(self):
        results = []
        for sensor_type in self.available_sensor_types:
            modelResults = self.available_sensor_types[sensor_type][
                'model'].objects.filter(**self._filters)
            results.extend(modelResults)
        return results

    def get_tags(self):
        return [
            'sensor-%s' % self._obj.id,
            'device-%s' % self._obj.device_id,
            'site-%s' % self._obj.device.site_id
        ]
Ejemplo n.º 5
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]
Ejemplo n.º 6
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
        ]