diff --git a/backend/flask/app/aqi_parser.py b/backend/flask/app/aqi_parser.py index 17a2b59..e023a64 100644 --- a/backend/flask/app/aqi_parser.py +++ b/backend/flask/app/aqi_parser.py @@ -2,28 +2,39 @@ import json from datetime import datetime import numpy as np + def input_process(data): - # parse string - # print(data) - # print('type' + type(data)) + """ + parsing aqi post data and combine it with weather data + """ + # get weather data + try: + with open('dyn/weather.json', 'r') as f: + weather_data = f.read() + weather_data_json = json.loads(weather_data) + del weather_data_json['timestamp'] + del weather_data_json['epoch_time'] + except FileNotFoundError: + # will get recreated on next run + weather_data_json = {} + # parse aqi data json_dict = data - pm25 = json_dict['pm25'] - aqi, aqi_category = get_AQI(pm25) json_dict['aqi_value'] = float(aqi) json_dict['aqi_category'] = aqi_category - + # set timestamp now = datetime.now() timestamp = now.strftime("%Y-%m-%d %H:%M:%S") epoch_time = int(now.strftime('%s')) - json_dict['timestamp'] = timestamp json_dict['epoch_time'] = epoch_time + # combine the two + json_dict.update(weather_data_json) - new_string = json.dumps(json_dict) + aqi_string = json.dumps(json_dict) - return new_string + return aqi_string def get_AQI(pm25): diff --git a/backend/flask/app/views.py b/backend/flask/app/views.py index df1402c..78847e3 100644 --- a/backend/flask/app/views.py +++ b/backend/flask/app/views.py @@ -3,9 +3,12 @@ import configparser from flask_cors import CORS from flask import request from flask_httpauth import HTTPBasicAuth +from apscheduler.schedulers.background import BackgroundScheduler + from app import app from app import aqi_parser +from app import weather cors = CORS(app, resources={r"/": {"origins": "*"}}) auth = HTTPBasicAuth() @@ -20,6 +23,9 @@ def get_config(): config = {} config["authUsername"] = config_parser.get('aqi_monitor', "authUsername") config["authPassword"] = config_parser.get('aqi_monitor', "authPassword") + config["api_key"] = config_parser.get('openweathermap', "api_key") + config["lat"] = config_parser.get('openweathermap', "lat") + config["lon"] = config_parser.get('openweathermap', "lon") return config @@ -31,6 +37,14 @@ USER_DATA = {} USER_DATA[config['authUsername']] = config['authPassword'] +# start scheduler +scheduler = BackgroundScheduler() +scheduler.start() +scheduler.add_job( + weather.handle_weather, args=[config], trigger="interval", name='weather_api', seconds=300 +) + + @auth.verify_password def verify(username, password): if not (username and password): @@ -45,7 +59,7 @@ def ingest(): data = request.json if data: data = aqi_parser.input_process(data) - with open('dyn/values.json', 'w') as f: + with open('dyn/air.json', 'w') as f: f.write(data) print(data) return 'ingest' @@ -55,7 +69,7 @@ def ingest(): @app.route('/') def home(): try: - with open('dyn/values.json', 'r') as f: + with open('dyn/air.json', 'r') as f: data = f.read() except FileNotFoundError: # will get regeneratod on next run diff --git a/backend/flask/app/weather.py b/backend/flask/app/weather.py new file mode 100755 index 0000000..d02cc05 --- /dev/null +++ b/backend/flask/app/weather.py @@ -0,0 +1,48 @@ +""" get data from openweathermap.org """ + +from datetime import datetime +from time import sleep +import json + +import requests + + +def get_weather(config): + """ + gets the missing weather data from openweathermap + return: json string + """ + api_key = config['api_key'] + lat = config['lat'] + lon = config['lon'] + # get data + r = requests.get("https://api.openweathermap.org/data/2.5/weather?&units=metric&appid=" + api_key + "&lat=" + lat + "&lon=" + lon, timeout=20) + # format data + r_json = r.json() + weather_name = r_json['weather'][0]['main'] + weather_icon = r_json['weather'][0]['icon'] + wind_speed = r_json['wind']['speed'] + wind_direction = r_json['wind']['deg'] + # timestamp + now = datetime.now() + timestamp = now.strftime("%Y-%m-%d %H:%M:%S") + epoch_time = int(now.strftime('%s')) + # form dict + json_dict = {} + json_dict['weather_name'] = weather_name + json_dict['weather_icon'] = weather_icon + json_dict['wind_speed'] = wind_speed + json_dict['wind_direction'] = wind_direction + json_dict['timestamp'] = timestamp + json_dict['epoch_time'] = epoch_time + # return json string + weather_json = json.dumps(json_dict) + return weather_json, timestamp + + +def handle_weather(config): + """ sets infinite loop to collect api data """ + weather_json, timestamp = get_weather(config) + with open('dyn/weather.json', 'w') as f: + f.write(weather_json) + print(f'weather data updated: {timestamp}') diff --git a/backend/flask/config.sample b/backend/flask/config.sample index e664d09..658a6f3 100644 --- a/backend/flask/config.sample +++ b/backend/flask/config.sample @@ -1,3 +1,8 @@ [aqi_monitor] authUsername = username -authPassword = password \ No newline at end of file +authPassword = password + +[openweathermap] +api_key = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +lat = 40.71 +lon = -73.99 \ No newline at end of file diff --git a/backend/flask/dyn/weather.json b/backend/flask/dyn/weather.json new file mode 100644 index 0000000..0eb68a4 --- /dev/null +++ b/backend/flask/dyn/weather.json @@ -0,0 +1 @@ +{"weather_name": "Clouds", "weather_icon": "02d", "wind_speed": 2.06, "wind_direction": 180, "timestamp": "2021-02-16 14:32:52", "epoch_time": 1613460772} \ No newline at end of file diff --git a/backend/flask/requirements.txt b/backend/flask/requirements.txt index b30c269..99e3009 100644 --- a/backend/flask/requirements.txt +++ b/backend/flask/requirements.txt @@ -1,5 +1,7 @@ +apscheduler Flask flask-cors Flask-HTTPAuth -uWSGI numpy +requests +uWSGI diff --git a/deploy.sh b/deploy.sh index 244099c..a5c4326 100755 --- a/deploy.sh +++ b/deploy.sh @@ -2,7 +2,9 @@ # upload project to vps2 rsync --progress -a docker-compose.yml vps2:docker/ -rsync --progress -a --delete-after --exclude dyn --exclude config.sample backend vps2:docker/ +rsync --progress -a --delete-after \ + --exclude dyn --exclude config.sample --exclude __pychache__ \ + backend vps2:docker/ rsync --progress -a --delete-after frontend vps2:docker/ ##