mirror of
https://github.com/bbilly1/aqi_monitor.git
synced 2024-08-02 16:03:33 +00:00
added secondary call to openweathermap api for additional weather data to be return from main route
This commit is contained in:
parent
39740276ec
commit
58406828ee
@ -2,28 +2,39 @@ import json
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
def input_process(data):
|
def input_process(data):
|
||||||
# parse string
|
"""
|
||||||
# print(data)
|
parsing aqi post data and combine it with weather data
|
||||||
# print('type' + type(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
|
json_dict = data
|
||||||
|
|
||||||
pm25 = json_dict['pm25']
|
pm25 = json_dict['pm25']
|
||||||
|
|
||||||
aqi, aqi_category = get_AQI(pm25)
|
aqi, aqi_category = get_AQI(pm25)
|
||||||
json_dict['aqi_value'] = float(aqi)
|
json_dict['aqi_value'] = float(aqi)
|
||||||
json_dict['aqi_category'] = aqi_category
|
json_dict['aqi_category'] = aqi_category
|
||||||
|
# set timestamp
|
||||||
now = datetime.now()
|
now = datetime.now()
|
||||||
timestamp = now.strftime("%Y-%m-%d %H:%M:%S")
|
timestamp = now.strftime("%Y-%m-%d %H:%M:%S")
|
||||||
epoch_time = int(now.strftime('%s'))
|
epoch_time = int(now.strftime('%s'))
|
||||||
|
|
||||||
json_dict['timestamp'] = timestamp
|
json_dict['timestamp'] = timestamp
|
||||||
json_dict['epoch_time'] = epoch_time
|
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):
|
def get_AQI(pm25):
|
||||||
|
@ -3,9 +3,12 @@ import configparser
|
|||||||
from flask_cors import CORS
|
from flask_cors import CORS
|
||||||
from flask import request
|
from flask import request
|
||||||
from flask_httpauth import HTTPBasicAuth
|
from flask_httpauth import HTTPBasicAuth
|
||||||
|
from apscheduler.schedulers.background import BackgroundScheduler
|
||||||
|
|
||||||
|
|
||||||
from app import app
|
from app import app
|
||||||
from app import aqi_parser
|
from app import aqi_parser
|
||||||
|
from app import weather
|
||||||
|
|
||||||
cors = CORS(app, resources={r"/": {"origins": "*"}})
|
cors = CORS(app, resources={r"/": {"origins": "*"}})
|
||||||
auth = HTTPBasicAuth()
|
auth = HTTPBasicAuth()
|
||||||
@ -20,6 +23,9 @@ def get_config():
|
|||||||
config = {}
|
config = {}
|
||||||
config["authUsername"] = config_parser.get('aqi_monitor', "authUsername")
|
config["authUsername"] = config_parser.get('aqi_monitor', "authUsername")
|
||||||
config["authPassword"] = config_parser.get('aqi_monitor', "authPassword")
|
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
|
return config
|
||||||
|
|
||||||
|
|
||||||
@ -31,6 +37,14 @@ USER_DATA = {}
|
|||||||
USER_DATA[config['authUsername']] = config['authPassword']
|
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
|
@auth.verify_password
|
||||||
def verify(username, password):
|
def verify(username, password):
|
||||||
if not (username and password):
|
if not (username and password):
|
||||||
@ -45,7 +59,7 @@ def ingest():
|
|||||||
data = request.json
|
data = request.json
|
||||||
if data:
|
if data:
|
||||||
data = aqi_parser.input_process(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)
|
f.write(data)
|
||||||
print(data)
|
print(data)
|
||||||
return 'ingest'
|
return 'ingest'
|
||||||
@ -55,7 +69,7 @@ def ingest():
|
|||||||
@app.route('/')
|
@app.route('/')
|
||||||
def home():
|
def home():
|
||||||
try:
|
try:
|
||||||
with open('dyn/values.json', 'r') as f:
|
with open('dyn/air.json', 'r') as f:
|
||||||
data = f.read()
|
data = f.read()
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
# will get regeneratod on next run
|
# will get regeneratod on next run
|
||||||
|
48
backend/flask/app/weather.py
Executable file
48
backend/flask/app/weather.py
Executable file
@ -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}')
|
@ -1,3 +1,8 @@
|
|||||||
[aqi_monitor]
|
[aqi_monitor]
|
||||||
authUsername = username
|
authUsername = username
|
||||||
authPassword = password
|
authPassword = password
|
||||||
|
|
||||||
|
[openweathermap]
|
||||||
|
api_key = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
lat = 40.71
|
||||||
|
lon = -73.99
|
1
backend/flask/dyn/weather.json
Normal file
1
backend/flask/dyn/weather.json
Normal file
@ -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}
|
@ -1,5 +1,7 @@
|
|||||||
|
apscheduler
|
||||||
Flask
|
Flask
|
||||||
flask-cors
|
flask-cors
|
||||||
Flask-HTTPAuth
|
Flask-HTTPAuth
|
||||||
uWSGI
|
|
||||||
numpy
|
numpy
|
||||||
|
requests
|
||||||
|
uWSGI
|
||||||
|
@ -2,7 +2,9 @@
|
|||||||
# upload project to vps2
|
# upload project to vps2
|
||||||
|
|
||||||
rsync --progress -a docker-compose.yml vps2:docker/
|
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/
|
rsync --progress -a --delete-after frontend vps2:docker/
|
||||||
|
|
||||||
##
|
##
|
||||||
|
Loading…
Reference in New Issue
Block a user