From 9bd50e8bc54dedae84b3eb424d5eba54bfa870f3 Mon Sep 17 00:00:00 2001 From: Matt Kohls Date: Sat, 2 Dec 2023 00:23:02 -0500 Subject: Expanding api for getting json data --- snag/data.py | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 104 insertions(+), 6 deletions(-) (limited to 'snag/data.py') diff --git a/snag/data.py b/snag/data.py index 69f9849..7e65186 100644 --- a/snag/data.py +++ b/snag/data.py @@ -12,12 +12,15 @@ import time bp = Blueprint('data', __name__, url_prefix='/data') -# Temp dst function, should add this to database to track instead +# Check if device is aware of daylight savings, we may need to adjust their reported time def is_dst_aware(deviceId): - if (deviceId in [2]): + db = get_db() + sql = "SELECT dstAware FROM devices WHERE deviceId = ?" + data = db.execute(sql, deviceId) + if data is None: return False else: - return True + return data.fetchone()['dstAware'] != 0 # Process json data # @@ -46,13 +49,14 @@ def unpack_json_scheme_1(req): try: deviceId = req['deviceId'] db = get_db() + dstAware = is_dst_aware(deviceId) # Status only has one object in it, and is optional if 'status' in req: if 'timeStamp' in req['status'][0]: now = req['status'][0]['timeStamp'] now = datetime.strptime(now, "%Y-%m-%dT%H:%M:%SZ") - if not is_dst_aware(deviceId) and time.daylight: + if not dstAware and time.daylight: now = now + timedelta(hours=1) now = now.strftime("%Y-%m-%d %H:%M:%S") else: @@ -68,7 +72,7 @@ def unpack_json_scheme_1(req): pressure = environment['pressure'] now = environment['timeStamp'] now = datetime.strptime(now, "%Y-%m-%dT%H:%M:%SZ") - if not is_dst_aware(deviceId) and time.daylight: + if not dstAware and time.daylight: now = now + timedelta(hours=1) now = now.strftime("%Y-%m-%d %H:%M:%S") if env == 'outdoor': @@ -118,7 +122,7 @@ def get_devices(): for env in envs: envDict = { "environment" : env["environment"], - "environmentDesc" : env["environmentDescription"] + #"environmentDesc" : env["environmentDescription"] } envList.append(envDict) deviceLine = { @@ -130,3 +134,97 @@ def get_devices(): out.append(deviceLine) return out +def parse_measuremet_req(req): + req = req.lower() + if req == "": + req = "thp" + measurements = "date" + if 't' in req: + measurements = measurements + ", temperature" + if 'h' in req: + measurements = measurements + ", humidity" + if 'p' in req: + measurements = measurements + ", pressure" + + return measurements + +## Grabs data from db, or None if not +def get_data_selection(device_id, start_time, end_time, columns, environment): + if end_time is None: + end_time = datetime.now() + if start_time is None: + start_time = end_time - timedelta(days=1) + if end_time < start_time: + start_time, end_time = end_time, start_time + + db = get_db() + if environment is not None: + sql = (f"SELECT {columns} " + f"FROM {environment} " + "WHERE (date BETWEEN ? AND ?) AND deviceId = ?") + subset = db.execute(sql, [start_time.isoformat(" ", "seconds"), end_time.isoformat(" ", "seconds"), device_id]).fetchall() + else: + subset = None + + return subset + +## Get data by deviceId +# +# Expected json payload +# { +# "environment" : "", ; Required +# "startTime" : "", ; Optional +# "endTime" : "", ; Optional +# "measurements" : [ "", "", ..] ; Required +# } +# +# Returns a json payload like this +# [ +# {"timeStamp":"2112-09-21T09:21:00", "":"", ..}, .. +# ] +# +@bp.route('/', methods=['GET']) +def get_device_data(device_id): + if request.is_json: + payload = request.get_json() + if 'environment' in payload and 'measurements' in payload: + env = payload['environment'] + end_time = datetime.now() + start_time = end_time - timedelta(hours=1) + if 'startTime' in payload: + start_time = payload['startTime'] + start_time = datetime.strptime(start_time, "%Y-%m-%dT%H:%M:%SZ") + if 'endTime' in payload: + end_time = payload['endTime'] + end_time = datetime.strptime(end_time, "%Y-%m-%dT%H:%M:%SZ") + selected_columns = "date" + for measurement in payload['measurements']: + selected_columns = selected_columns + ", " + measurement + if selected_columns == "date": + abort(400, "Bad json payload - missing measurements") + else: + data = get_data_selection(device_id, start_time, end_time, selected_columns, env) + if data is None: + abort(404, "No data found") + + outlist = [] + for row in data: + reading = { "timeStamp":row["date"].strftime('%Y-%m-%dT%H:%M:%SZ') } + for measurement in payload['measurements']: + reading[measurement] = row[measurement] + outlist.append(reading) + return outlist + else: + abort(400, "Bad json payload") + else: + abort(400, "Missing request data") + +# Get data by environment type +@bp.route('/environment', methods=['GET']) +def get_env_data(): + if request.args['type'] is not None: + return "todo" + else: + abort(400, "Unknown environment type") + + -- cgit v1.2.3