-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Replicate lufdetan feinstaub v1 routes (#49)
* /v1/sensors/<sensor_id> all raw measurements of the last 5 minutes for one sensor * Update pytest * /v1/filter?city=&country=&type= 5 minutes filtered by query + Tests * Fix formatting * /static/v2/*.json routes * /static/v2/data.dust|temp.min.json routes * Fix tests + cleanup settings
- Loading branch information
1 parent
255b49d
commit 7903dbf
Showing
12 changed files
with
295 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -400,3 +400,4 @@ celerybeat.pid | |
logs/ | ||
|
||
/static | ||
/sensorsafrica/static/**/*.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
from rest_framework import serializers | ||
from feinstaub.sensors.models import ( | ||
SensorData, | ||
SensorDataValue | ||
) | ||
|
||
|
||
class SensorDataValueSerializer(serializers.ModelSerializer): | ||
class Meta: | ||
model = SensorDataValue | ||
fields = ['value_type', 'value'] | ||
|
||
|
||
class SensorDataSerializer(serializers.ModelSerializer): | ||
sensordatavalues = SensorDataValueSerializer(many=True) | ||
|
||
class Meta: | ||
model = SensorData | ||
fields = ['timestamp', 'sensordatavalues'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import datetime | ||
import pytz | ||
import json | ||
|
||
from rest_framework.exceptions import ValidationError | ||
|
||
from django.conf import settings | ||
from django.utils import timezone | ||
from dateutil.relativedelta import relativedelta | ||
from django.db.models import ExpressionWrapper, F, FloatField, Max, Min, Sum, Avg, Q | ||
from django.db.models.functions import Cast, TruncDate | ||
from rest_framework import mixins, pagination, viewsets | ||
|
||
from .serializers import SensorDataSerializer | ||
from feinstaub.sensors.models import SensorData | ||
|
||
|
||
class SensorDataView(mixins.ListModelMixin, viewsets.GenericViewSet): | ||
serializer_class = SensorDataSerializer | ||
|
||
def get_queryset(self): | ||
return ( | ||
SensorData.objects | ||
.filter( | ||
timestamp__gte=timezone.now() - datetime.timedelta(minutes=5), | ||
sensor=self.kwargs["sensor_id"] | ||
) | ||
.only('sensor', 'timestamp') | ||
.prefetch_related('sensordatavalues') | ||
) | ||
|
||
|
||
class FilterView(mixins.ListModelMixin, viewsets.GenericViewSet): | ||
serializer_class = SensorDataSerializer | ||
|
||
def get_queryset(self): | ||
sensor_type = self.request.GET.get('type', r'\w+') | ||
country = self.request.GET.get('country', r'\w+') | ||
city = self.request.GET.get('city', r'\w+') | ||
return ( | ||
SensorData.objects | ||
.filter( | ||
timestamp__gte=timezone.now() - datetime.timedelta(minutes=5), | ||
sensor__sensor_type__uid__iregex=sensor_type, | ||
location__country__iregex=country, | ||
location__city__iregex=city | ||
) | ||
.only('sensor', 'timestamp') | ||
.prefetch_related('sensordatavalues') | ||
) |
101 changes: 101 additions & 0 deletions
101
sensorsafrica/management/commands/cache_static_json_data.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
from django.core.management import BaseCommand | ||
from django.core.cache import cache | ||
|
||
from django.conf import settings | ||
|
||
from django.forms.models import model_to_dict | ||
|
||
from feinstaub.sensors.models import SensorLocation, Sensor, SensorType | ||
|
||
import os | ||
import json | ||
import datetime | ||
from django.utils import timezone | ||
|
||
from django.db import connection | ||
|
||
from rest_framework import serializers | ||
|
||
|
||
class SensorTypeSerializer(serializers.ModelSerializer): | ||
class Meta: | ||
model = SensorType | ||
fields = "__all__" | ||
|
||
|
||
class SensorSerializer(serializers.ModelSerializer): | ||
sensor_type = SensorTypeSerializer() | ||
|
||
class Meta: | ||
model = Sensor | ||
fields = "__all__" | ||
|
||
|
||
class SensorLocationSerializer(serializers.ModelSerializer): | ||
class Meta: | ||
model = SensorLocation | ||
fields = "__all__" | ||
|
||
|
||
class Command(BaseCommand): | ||
help = "" | ||
|
||
def add_arguments(self, parser): | ||
parser.add_argument('--interval', type=str) | ||
|
||
def handle(self, *args, **options): | ||
intervals = {'5m': '5 minutes', '1h': '1 hour', '24h': '24 hours'} | ||
paths = { | ||
'5m': [ | ||
'../../../static/v2/data.json', | ||
'../../../static/v2/data.dust.min.json', | ||
'../../../static/v2/data.temp.min.json' | ||
], | ||
'1h': ['../../../static/v2/data.1h.json'], | ||
'24h': ['../../../static/v2/data.24h.json'] | ||
} | ||
cursor = connection.cursor() | ||
cursor.execute(''' | ||
SELECT sd.sensor_id, sdv.value_type, AVG(CAST(sdv."value" AS FLOAT)) as "value", COUNT("value"), sd.location_id | ||
FROM sensors_sensordata sd | ||
INNER JOIN sensors_sensordatavalue sdv | ||
ON sd.id = sdv.sensordata_id WHERE "timestamp" >= (NOW() - interval %s) | ||
GROUP BY sd.sensor_id, sdv.value_type, sd.location_id | ||
''', [intervals[options['interval']]]) | ||
|
||
data = {} | ||
while True: | ||
row = cursor.fetchone() | ||
if row is None: | ||
break | ||
|
||
if row[0] in data: | ||
data[row[0]]['sensordatavalues'].append(dict({ | ||
'samples': row[3], | ||
'value': row[2], | ||
'value_type': row[1] | ||
})) | ||
else: | ||
data[row[0]] = dict({ | ||
'location': SensorLocationSerializer(SensorLocation.objects.get(pk=row[4])).data, | ||
'sensor': SensorSerializer(Sensor.objects.get(pk=row[0])).data, | ||
'sensordatavalues': [{ | ||
'samples': row[3], | ||
'value': row[2], | ||
'value_type': row[1] | ||
}] | ||
}) | ||
|
||
for path in paths[options['interval']]: | ||
with open( | ||
os.path.join(os.path.dirname( | ||
os.path.abspath(__file__)), path), 'w' | ||
) as f: | ||
if 'dust' in path: | ||
json.dump(list(filter( | ||
lambda d: d['sensor']['sensor_type']['uid'] == 'sds011', data.values())), f) | ||
elif 'temp' in path: | ||
json.dump(list(filter( | ||
lambda d: d['sensor']['sensor_type']['uid'] == 'dht22', data.values())), f) | ||
else: | ||
json.dump(list(data.values()), f) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.