refactor the code to abstract from the weather provider

This commit is contained in:
Sven Czarnian
2021-09-24 22:10:46 +02:00
parent b54f7dfc50
commit 11e76a3f24
2 changed files with 77 additions and 14 deletions

View File

@@ -6,7 +6,6 @@ import urllib.request
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from datetime import datetime as dt from datetime import datetime as dt
from threading import Thread
# @brief Checks the DWD pages for wind information # @brief Checks the DWD pages for wind information
# Format: # Format:
@@ -18,12 +17,10 @@ from threading import Thread
# - first element of wind data tuple: minimum altitude AMSL for this wind information # - first element of wind data tuple: minimum altitude AMSL for this wind information
# - second element of wind data tuple: wind direction # - second element of wind data tuple: wind direction
# - third element of wind data tuple: wind speed (KT) # - third element of wind data tuple: wind speed (KT)
class DwdCrawler(Thread): class DwdCrawler():
def __init__(self): def __init__(self):
Thread.__init__(self) self.updateTime = None
self.dataAvailable = False self.windData = None
self.executing = True
self.start()
def parseGaforAreas(areas : str): def parseGaforAreas(areas : str):
areas = areas.replace(':', '') areas = areas.replace(':', '')
@@ -102,7 +99,7 @@ class DwdCrawler(Thread):
# analyze the received data # analyze the received data
if None != content: if None != content:
windInformation = [] windInformation = []
udpdateTime = None nextUpdate = None
windTable = [] windTable = []
areaIds = None areaIds = None
@@ -119,15 +116,18 @@ class DwdCrawler(Thread):
elif None != areaIds: elif None != areaIds:
windTable = DwdCrawler.parseWindTableRow(line, windTable) windTable = DwdCrawler.parseWindTableRow(line, windTable)
elif 'Aktualisierung erfolgt um ' in line: elif 'Aktualisierung erfolgt um ' in line:
updateTime = DwdCrawler.parseNextUpdateTime(line) nextUpdate = DwdCrawler.parseNextUpdateTime(line)
# return the collected information # return the collected information
if 0 != len(windInformation) and None != updateTime: if 0 == len(windInformation) or None == nextUpdate:
return updateTime, windInformation return None, None
else: else:
return None return nextUpdate, windInformation
def receiveWindData(self):
self.updateTime = None
self.windData = None
def run(self):
with urllib.request.urlopen('https://www.dwd.de/DE/fachnutzer/luftfahrt/teaser/luftsportberichte/luftsportberichte_node.html') as site: with urllib.request.urlopen('https://www.dwd.de/DE/fachnutzer/luftfahrt/teaser/luftsportberichte/luftsportberichte_node.html') as site:
data = site.read().decode('utf-8') data = site.read().decode('utf-8')
site.close() site.close()
@@ -152,6 +152,8 @@ class DwdCrawler(Thread):
# indicate that new wind data is available # indicate that new wind data is available
if None != self.updateTime: if None != self.updateTime:
self.dataAvailable = True return True
else:
return False
self.executing = False return False

61
aman/com/Weather.py Normal file
View File

@@ -0,0 +1,61 @@
#!/usr/bin/env python
import datetime
import pytz
import sys
import time
from datetime import datetime as dt
from threading import Thread
from aman.com.DwdCrawler import DwdCrawler
import aman.config.Weather
class Weather(Thread):
def __init__(self, config : aman.config.Weather.Weather):
Thread.__init__(self)
self.nextUpdate = dt.utcfromtimestamp(int(time.time()))
self.lastUpdateTried = None
self.stopThread = False
self.provider = None
if 'DWD' == config.Provider.upper():
self.provider = DwdCrawler()
else:
sys.stderr.write('Invalid or unknown weather-provider defined')
sys.exit(-1)
self.start()
def stop(self):
self.stopThread = True
def currentClock():
clock = dt.utcfromtimestamp(int(time.time()))
clock = datetime.datetime(
year = clock.year,
month = clock.month,
day = clock.day,
hour = clock.hour,
minute = clock.minute,
second = clock.second,
tzinfo = pytz.UTC
)
return clock
def run(self):
while False == self.stopThread and None != self.provider:
now = Weather.currentClock()
# check if an update is required
if None != self.provider.updateTime and self.provider.updateTime > now:
time.sleep(1)
continue
# calculate the theoretical next try for an update
if None != self.lastUpdateTried:
earliestUpdate = self.lastUpdateTried + datetime.timedelta(minutes=2)
if None == self.lastUpdateTried or self.lastUpdateTried <= now:
if True == self.provider.receiveWindData():
self.nextUpdate = self.provider.updateTime