Implement grouping of openweathermapdata.
authorPhilipp Spitzer <philipp@spitzer.priv.at>
Wed, 22 Aug 2018 21:10:58 +0000 (23:10 +0200)
committerPhilipp Spitzer <philipp@spitzer.priv.at>
Wed, 22 Aug 2018 21:10:58 +0000 (23:10 +0200)
web/seepark_web.py

index cbe55f85f174ecc253868e52aa36c30d76ffc56d..42bbf30740db0f42292f89901d432b5611f382e6 100644 (file)
@@ -72,8 +72,8 @@ def select_sensordata(sensor_id, sensor_type, begin, end):
     return query.all()
 
 
     return query.all()
 
 
-def select_sensordata_grouped(sensor_id, sensor_type, begin, end):
-    # determine resolution (interval in seconds for data points)
+def calc_grouping_resolution(begin, end):
+    """How many data points should be between the timestamps begin and end?"""
     # copied from munin/master/_bin/munin-cgi-graph.in
     resolutions = dict(
         day   =   300,
     # copied from munin/master/_bin/munin-cgi-graph.in
     resolutions = dict(
         day   =   300,
@@ -91,6 +91,12 @@ def select_sensordata_grouped(sensor_id, sensor_type, begin, end):
         resolution = resolutions['month']
     else:
         resolution = resolutions['year']
         resolution = resolutions['month']
     else:
         resolution = resolutions['year']
+    return resolution
+
+
+def select_sensordata_grouped(sensor_id, sensor_type, begin, end):
+    # determine resolution (interval in seconds for data points)
+    resolution = calc_grouping_resolution(begin, end)
 
     # Let the database do the grouping. Example in SQL (MySQL):
     # select to_seconds(datetime) DIV (60*60*24) as interval_id, min(datetime), max(datetime), min(temp), avg(temp), max(temp), count(temp) from openweathermap group by interval_id order by interval_id;
 
     # Let the database do the grouping. Example in SQL (MySQL):
     # select to_seconds(datetime) DIV (60*60*24) as interval_id, min(datetime), max(datetime), min(temp), avg(temp), max(temp), count(temp) from openweathermap group by interval_id order by interval_id;
@@ -108,34 +114,29 @@ def select_sensordata_grouped(sensor_id, sensor_type, begin, end):
     return query.all()
 
 
     return query.all()
 
 
-def select_openweatherdata(cityid, begin, end, mode):
+def select_openweatherdata(cityid, begin, end):
     query = OpenWeatherMap.query.filter(OpenWeatherMap.cityid == cityid)
     if begin is not None:
         query = query.filter(OpenWeatherMap.datetime >= begin)
     if end is not None:
         query = query.filter(OpenWeatherMap.datetime <= end)
     query = OpenWeatherMap.query.filter(OpenWeatherMap.cityid == cityid)
     if begin is not None:
         query = query.filter(OpenWeatherMap.datetime >= begin)
     if end is not None:
         query = query.filter(OpenWeatherMap.datetime <= end)
-    if mode == 'consolidated' and begin is not None and end is not None:
-        # copied from munin/master/_bin/munin-cgi-graph.in
-        # interval in seconds for data points
-        resolutions = dict(
-            day   =   300,
-            week  =  1800,
-            month =  7200,
-            year  = 86400,
-        )
-        duration = (end - begin).total_seconds()
-        day = 60 * 60 * 24
-        if duration < day:
-            resolution = resolutions['day']
-        elif duration < 7 * day:
-            resolution = resolutions['week']
-        elif duration < 31 * day:
-            resolution = resolutions['month']
-        else:
-            resolution = resolutions['year']
-        # TODO: filter out samples from 'result'
-        # something like 
-        # select to_seconds(datetime) DIV (60*60*24) as interval_id, min(datetime), max(datetime), min(temp), avg(temp), max(temp), count(temp) from openweathermap group by interval_id order by interval_id;
+    return query.all()
+
+
+def select_openweatherdata_grouped(cityid, begin, end):
+    # determine resolution (interval in seconds for data points)
+    resolution = calc_grouping_resolution(begin, end)
+
+    # Let the database do the grouping. Example in SQL (MySQL):
+    # select to_seconds(datetime) DIV (60*60*24) as interval_id, min(datetime), max(datetime), min(temp), avg(temp), max(temp), count(temp) from openweathermap group by interval_id order by interval_id;
+    query = db.session.query(func.to_seconds(OpenWeatherMap.datetime).op('div')(resolution).label('g'),
+            func.min(OpenWeatherMap.datetime).label('datetime'),
+            func.avg(OpenWeatherMap.temp).label('temp'),
+            OpenWeatherMap.cityid)
+    OpenWeatherMap.query.filter(OpenWeatherMap.cityid == cityid)
+    query = query.filter(Sensors.timestamp >= begin)
+    query = query.filter(Sensors.timestamp <= end)
+    query = query.group_by('g', OpenWeatherMap.cityid)
     return query.all()
 
 
     return query.all()
 
 
@@ -188,7 +189,14 @@ def openweathermapdata(cityid):
     mode = request.args.get('mode', 'full')
     format = request.args.get('format', 'default')
 
     mode = request.args.get('mode', 'full')
     format = request.args.get('format', 'default')
 
-    result = select_openweatherdata(cityid, begin, end, mode)
+    if mode == 'full':
+        result = select_openweatherdata(cityid, begin, end)
+    elif mode == 'consolidated':
+        if begin is None or end is None:
+            abort(Response('begin and end have to be set for mode==consolidated', 400))
+        result = select_openweatherdata_grouped(cityid, begin, end)
+    else:
+        abort(Response('unknown value for mode', 400))
 
     if format == 'c3':
         return convert_to_c3(result, 'cityid', 'datetime', 'temp')
 
     if format == 'c3':
         return convert_to_c3(result, 'cityid', 'datetime', 'temp')