fix things
This commit is contained in:
parent
979381f365
commit
aa472d98cf
|
@ -4,7 +4,8 @@ This is an MQTT sensor to send NOAA space weather data to Home Assistant. Fetchi
|
||||||
|
|
||||||
1. Create an account at <https://urs.earthdata.nasa.gov>
|
1. Create an account at <https://urs.earthdata.nasa.gov>
|
||||||
2. `pip install -r requirements.txt`
|
2. `pip install -r requirements.txt`
|
||||||
3. `sudo apt install p7zip-full`
|
3. `sudo apt install p7zip-full redis-server`
|
||||||
|
4. `sudo systemctl enable --now redis-server`
|
||||||
|
|
||||||
### Google Chrome
|
### Google Chrome
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import io
|
import io
|
||||||
import logging
|
import logging
|
||||||
import pickle
|
import pickle
|
||||||
import sys
|
import time
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
|
import schedule
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from redis import Redis
|
from redis import Redis
|
||||||
|
|
||||||
|
@ -17,30 +18,40 @@ LAT_RANGE_MAX = 90
|
||||||
LON_RANGE_MIN = -180
|
LON_RANGE_MIN = -180
|
||||||
LON_RANGE_MAX = 180
|
LON_RANGE_MAX = 180
|
||||||
|
|
||||||
redis = Redis(host='localhost', port=6379, db=0)
|
|
||||||
|
|
||||||
utc_hr = datetime.utcnow().hour
|
def main():
|
||||||
logging.info(f'Generating plot for hour {utc_hr}')
|
redis = Redis(host='localhost', port=6379, db=0)
|
||||||
|
|
||||||
ionex_data: List = pickle.loads(redis.get('tecmap_data'))
|
while True:
|
||||||
if ionex_data is None:
|
utc_hr = datetime.utcnow().hour
|
||||||
logging.critical('Redis has not been populated yet. Is cache.py running?')
|
logging.info(f'Generating plot for hour {utc_hr}')
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
for tecmap, epoch in ionex_data:
|
ionex_data: List = pickle.loads(redis.get('tecmap_data'))
|
||||||
if epoch.hour == utc_hr:
|
while ionex_data is None:
|
||||||
plt = plot_tec_map(tecmap, [float(LON_RANGE_MIN), float(LON_RANGE_MAX)], [float(LAT_RANGE_MIN), float(LAT_RANGE_MAX)])[1]
|
logging.warning('Redis has not been populated yet. Is cache.py running? Sleeping 10s...')
|
||||||
|
time.sleep(10)
|
||||||
|
|
||||||
buf = io.BytesIO()
|
for tecmap, epoch in ionex_data:
|
||||||
plt.savefig(buf, format='png', bbox_inches='tight', pad_inches=0, dpi=110)
|
if epoch.hour == utc_hr:
|
||||||
plt.close()
|
plt = plot_tec_map(tecmap, [float(LON_RANGE_MIN), float(LON_RANGE_MAX)], [float(LAT_RANGE_MIN), float(LAT_RANGE_MAX)], timestamp=epoch)[1]
|
||||||
del plt
|
|
||||||
|
|
||||||
buf.seek(0)
|
buf = io.BytesIO()
|
||||||
img = Image.open(buf)
|
plt.savefig(buf, format='png', bbox_inches='tight', pad_inches=0, dpi=110)
|
||||||
# img = img.resize((img.size[0], 500), Image.LANCZOS)
|
plt.close()
|
||||||
buf = io.BytesIO()
|
del plt
|
||||||
img.save(buf, format='PNG')
|
|
||||||
|
|
||||||
redis.set('global_map', buf.getvalue())
|
buf.seek(0)
|
||||||
buf.close()
|
img = Image.open(buf)
|
||||||
|
buf = io.BytesIO()
|
||||||
|
img.save(buf, format='PNG')
|
||||||
|
|
||||||
|
redis.set('global_map', buf.getvalue())
|
||||||
|
buf.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
schedule.every().hour.at(":00").do(main)
|
||||||
|
while True:
|
||||||
|
schedule.run_pending()
|
||||||
|
time.sleep(1)
|
||||||
|
|
|
@ -32,7 +32,7 @@ def get_tecmaps(ionex: str):
|
||||||
yield parse_map(tecmap), epoch
|
yield parse_map(tecmap), epoch
|
||||||
|
|
||||||
|
|
||||||
def plot_tec_map(tecmap, lon_range: list, lat_range: list):
|
def plot_tec_map(tecmap, lon_range: list, lat_range: list, timestamp: datetime = None):
|
||||||
proj = ccrs.PlateCarree()
|
proj = ccrs.PlateCarree()
|
||||||
f, ax = plt.subplots(1, 1, subplot_kw=dict(projection=proj))
|
f, ax = plt.subplots(1, 1, subplot_kw=dict(projection=proj))
|
||||||
|
|
||||||
|
@ -54,7 +54,8 @@ def plot_tec_map(tecmap, lon_range: list, lat_range: list):
|
||||||
|
|
||||||
# Make graph pretty
|
# Make graph pretty
|
||||||
ax.coastlines()
|
ax.coastlines()
|
||||||
plt.title(datetime.now().strftime('%H:%M %d-%m-%Y'), fontsize=12, y=1.04)
|
if timestamp:
|
||||||
|
plt.title(timestamp.strftime('%H:%M %d-%m-%Y'), fontsize=12, y=1.04)
|
||||||
plt.suptitle('Vertical Total Electron Count', fontsize=16, y=0.87)
|
plt.suptitle('Vertical Total Electron Count', fontsize=16, y=0.87)
|
||||||
divider = make_axes_locatable(ax)
|
divider = make_axes_locatable(ax)
|
||||||
ax_cb = divider.new_horizontal(size='5%', pad=0.1, axes_class=plt.Axes)
|
ax_cb = divider.new_horizontal(size='5%', pad=0.1, axes_class=plt.Axes)
|
||||||
|
|
|
@ -3,7 +3,6 @@ import os
|
||||||
import pickle
|
import pickle
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import traceback
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
|
@ -61,27 +60,28 @@ def publish(topic: str, msg):
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
try:
|
redis = Redis(host='localhost', port=6379, db=0)
|
||||||
redis = Redis(host='localhost', port=6379, db=0)
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
utc_hr = datetime.utcnow().hour
|
utc_hr = datetime.utcnow().hour
|
||||||
logging.info('Fetching latest IONEX data')
|
logging.info('Fetching latest IONEX data')
|
||||||
logging.info(f'Using hour {utc_hr}')
|
logging.info(f'Using hour {utc_hr}')
|
||||||
ionex_data: List = pickle.loads(redis.get('tecmap_data'))
|
|
||||||
avg_tec = None
|
ionex_data: List = pickle.loads(redis.get('tecmap_data'))
|
||||||
for tecmap, epoch in ionex_data:
|
while ionex_data is None:
|
||||||
parsed_dt = parse_ionex_datetime(epoch)
|
logging.warning('Redis has not been populated yet. Is cache.py running? Sleeping 10s...')
|
||||||
if parsed_dt.hour == utc_hr:
|
time.sleep(10)
|
||||||
avg_tec = np.mean(plot_tec_map(tecmap, [float(LON_RANGE_MIN), float(LON_RANGE_MAX)], [float(LAT_RANGE_MIN), float(LAT_RANGE_MAX)])[0])
|
|
||||||
logging.info(f'Data timestamp: {parsed_dt.isoformat()}')
|
avg_tec = None
|
||||||
break
|
for tecmap, epoch in ionex_data:
|
||||||
latest = round(avg_tec, 1)
|
parsed_dt = parse_ionex_datetime(epoch)
|
||||||
publish('vtec', latest)
|
if parsed_dt.hour == utc_hr:
|
||||||
time.sleep(60)
|
avg_tec = np.mean(plot_tec_map(tecmap, [float(LON_RANGE_MIN), float(LON_RANGE_MAX)], [float(LAT_RANGE_MIN), float(LAT_RANGE_MAX)])[0])
|
||||||
except:
|
logging.info(f'Data timestamp: {parsed_dt.isoformat()}')
|
||||||
logging.critical(traceback.format_exc())
|
break
|
||||||
sys.exit(1)
|
latest = round(avg_tec, 1)
|
||||||
|
publish('vtec', latest)
|
||||||
|
time.sleep(60)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -8,4 +8,5 @@ numpy==2.0.1
|
||||||
redis==5.0.8
|
redis==5.0.8
|
||||||
async-timeout==4.0.3
|
async-timeout==4.0.3
|
||||||
Pillow
|
Pillow
|
||||||
flask==3.0.3
|
flask==3.0.3
|
||||||
|
schedule==1.2.2
|
|
@ -11,7 +11,7 @@ redis_client = redis.Redis(host='localhost', port=6379)
|
||||||
def serve_global_map():
|
def serve_global_map():
|
||||||
global_map_data = redis_client.get('global_map')
|
global_map_data = redis_client.get('global_map')
|
||||||
if global_map_data is None:
|
if global_map_data is None:
|
||||||
return "No global map available", 404
|
return "No global map available", 400
|
||||||
|
|
||||||
buf = io.BytesIO(global_map_data)
|
buf = io.BytesIO(global_map_data)
|
||||||
buf.seek(0)
|
buf.seek(0)
|
||||||
|
|
Loading…
Reference in New Issue