mirror of
https://github.com/mewtek/i2ME-Legacy.git
synced 2025-05-11 17:00:23 -05:00
Merge pull request #6 from Open-Telecom/collectorsToAsync
Convert data collectors to async
This commit is contained in:
commit
66a769fe9f
97
RecordTasks.py
Normal file
97
RecordTasks.py
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
import asyncio
|
||||||
|
from recordGenerators import Alerts,CurrentObservations,HourlyForecast,DailyForecast, AirQuality, AirportDelays, AchesAndPains, Breathing, HeatingAndCooling, MosquitoActivity, PollenForecast, TideForecast, WateringNeeds
|
||||||
|
from radar import TWCRadarCollector
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
|
""" This houses the tasks needed to update the data records concurrently
|
||||||
|
I have no idea if this is a messy way to do things, but it will be worked upon if it is.
|
||||||
|
"""
|
||||||
|
|
||||||
|
async def updateMosaicTask():
|
||||||
|
mosaicUpdateIntervals = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55]
|
||||||
|
|
||||||
|
while True:
|
||||||
|
# Server takes ~15 - 35 seconds to fully generate a frame, so use 40 seconds to ensure it's fully generated.
|
||||||
|
if datetime.now().minute in mosaicUpdateIntervals and datetime.now().second == 40:
|
||||||
|
await TWCRadarCollector.collect("radarmosaic")
|
||||||
|
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
|
async def updateSatradTask():
|
||||||
|
satradUpdateIntervals = [0, 10, 20, 30, 40, 50]
|
||||||
|
|
||||||
|
while True:
|
||||||
|
# Server takes ~15 - 35 seconds to fully generate a frame, so use 40 seconds to ensure it's fully generated.
|
||||||
|
if datetime.now().minute in satradUpdateIntervals and datetime.now().second == 40:
|
||||||
|
await TWCRadarCollector.collect("satrad")
|
||||||
|
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
async def alertsTask():
|
||||||
|
while True:
|
||||||
|
await Alerts.makeRecord()
|
||||||
|
await asyncio.sleep(60)
|
||||||
|
|
||||||
|
async def coTask():
|
||||||
|
while True:
|
||||||
|
await CurrentObservations.makeDataFile()
|
||||||
|
await asyncio.sleep(5 * 60)
|
||||||
|
|
||||||
|
# These tasks should be updated every hour
|
||||||
|
|
||||||
|
async def hfTask():
|
||||||
|
while True:
|
||||||
|
await HourlyForecast.makeDataFile()
|
||||||
|
await asyncio.sleep(60 * 60)
|
||||||
|
|
||||||
|
async def dfTask():
|
||||||
|
while True:
|
||||||
|
await DailyForecast.makeDataFile()
|
||||||
|
await asyncio.sleep(60 * 60)
|
||||||
|
|
||||||
|
async def aqTask():
|
||||||
|
while True:
|
||||||
|
await AirQuality.writeData()
|
||||||
|
await asyncio.sleep(60 * 60)
|
||||||
|
|
||||||
|
async def aptTask():
|
||||||
|
while True:
|
||||||
|
await AirportDelays.writeData()
|
||||||
|
await asyncio.sleep(60 * 60)
|
||||||
|
|
||||||
|
async def apTask():
|
||||||
|
while True:
|
||||||
|
await AchesAndPains.makeRecord()
|
||||||
|
await asyncio.sleep(60 * 60)
|
||||||
|
|
||||||
|
async def brTask():
|
||||||
|
while True:
|
||||||
|
await Breathing.makeDataFile()
|
||||||
|
await asyncio.sleep(60 * 60)
|
||||||
|
|
||||||
|
async def hcTask():
|
||||||
|
while True:
|
||||||
|
await HeatingAndCooling.makeRecord()
|
||||||
|
await asyncio.sleep(60 * 60)
|
||||||
|
|
||||||
|
async def maTask():
|
||||||
|
while True:
|
||||||
|
await MosquitoActivity.makeRecord()
|
||||||
|
await asyncio.sleep(60 * 60)
|
||||||
|
|
||||||
|
async def pTask():
|
||||||
|
while True:
|
||||||
|
await PollenForecast.makeDataFile()
|
||||||
|
await asyncio.sleep(60 * 60)
|
||||||
|
|
||||||
|
async def tTask():
|
||||||
|
while True:
|
||||||
|
await TideForecast.makeRecord()
|
||||||
|
await asyncio.sleep(60 * 60)
|
||||||
|
|
||||||
|
async def wnTask():
|
||||||
|
while True:
|
||||||
|
await WateringNeeds.makeRecord()
|
||||||
|
await asyncio.sleep(60 * 60)
|
@ -50,9 +50,90 @@ def getTideStations():
|
|||||||
|
|
||||||
def getAirportCodes():
|
def getAirportCodes():
|
||||||
""" Returns all of the airport identifiers present in the MachineProductCfg """
|
""" Returns all of the airport identifiers present in the MachineProductCfg """
|
||||||
airports = []
|
airports = [
|
||||||
|
'ATL',
|
||||||
|
'LAX',
|
||||||
|
'ORD',
|
||||||
|
'DFW',
|
||||||
|
'JFK',
|
||||||
|
'DEN',
|
||||||
|
'SFO',
|
||||||
|
'CLT',
|
||||||
|
'LAS',
|
||||||
|
'PHX',
|
||||||
|
'IAH',
|
||||||
|
'MIA',
|
||||||
|
'SEA',
|
||||||
|
'EWR',
|
||||||
|
'MCO',
|
||||||
|
'MSP',
|
||||||
|
'DTW',
|
||||||
|
'BOS',
|
||||||
|
'PHL',
|
||||||
|
'LGA',
|
||||||
|
'FLL',
|
||||||
|
'BWI',
|
||||||
|
'IAD',
|
||||||
|
'MDW',
|
||||||
|
'SLC',
|
||||||
|
'DCA',
|
||||||
|
'HNL',
|
||||||
|
'SAN',
|
||||||
|
'TPA',
|
||||||
|
'PDX',
|
||||||
|
'STL',
|
||||||
|
'HOU',
|
||||||
|
'BNA',
|
||||||
|
'AUS',
|
||||||
|
'OAK',
|
||||||
|
'MSY',
|
||||||
|
'RDU',
|
||||||
|
'SJC',
|
||||||
|
'SNA',
|
||||||
|
'DAL',
|
||||||
|
'SMF',
|
||||||
|
'SAT',
|
||||||
|
'RSW',
|
||||||
|
'PIT',
|
||||||
|
'CLE',
|
||||||
|
'IND',
|
||||||
|
'MKE',
|
||||||
|
'CMH',
|
||||||
|
'OGG',
|
||||||
|
'PBI',
|
||||||
|
'BDL',
|
||||||
|
'CVG',
|
||||||
|
'JAX',
|
||||||
|
'ANC',
|
||||||
|
'BUF',
|
||||||
|
'ABQ',
|
||||||
|
'ONT',
|
||||||
|
'OMA',
|
||||||
|
'BUR',
|
||||||
|
'OKC',
|
||||||
|
'MEM',
|
||||||
|
'PVD',
|
||||||
|
'RIC',
|
||||||
|
'SDF',
|
||||||
|
'RNO',
|
||||||
|
'TUS',
|
||||||
|
'CHS',
|
||||||
|
'ORF',
|
||||||
|
'PWM',
|
||||||
|
'GRR',
|
||||||
|
'BHM',
|
||||||
|
'LIT',
|
||||||
|
'DSM',
|
||||||
|
'FAR',
|
||||||
|
'FSD',
|
||||||
|
'ICT',
|
||||||
|
'LBB',
|
||||||
|
'BIL',
|
||||||
|
'BOI',
|
||||||
|
'GEG'
|
||||||
|
]
|
||||||
for i in data['Config']['ConfigDef']['ConfigItems']['ConfigItem']:
|
for i in data['Config']['ConfigDef']['ConfigItems']['ConfigItem']:
|
||||||
if "Airport" in i['@key'] and i['@value'] != "":
|
if "Airport" in i['@key'] and i['@value'] != "" and not i['@value'] in airports:
|
||||||
# Split the string up
|
# Split the string up
|
||||||
airports.append(i['@value'].split("_")[2])
|
airports.append(i['@value'].split("_")[2])
|
||||||
|
|
||||||
|
136
main.py
136
main.py
@ -1,93 +1,81 @@
|
|||||||
import asyncio
|
import asyncio, aiofiles
|
||||||
from asyncio.log import logger
|
from asyncio.log import logger
|
||||||
from asyncore import loop
|
from asyncore import loop
|
||||||
import logging,coloredlogs
|
import logging,coloredlogs
|
||||||
from recordGenerators import Alerts,CurrentObservations,DailyForecast,HourlyForecast,AirportDelays,AirQuality,HeatingAndCooling,PollenForecast,Breathing, AchesAndPains, MosquitoActivity, WateringNeeds, TideForecast
|
|
||||||
from radar import TWCRadarCollector
|
from radar import TWCRadarCollector
|
||||||
import os
|
import os
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
import RecordTasks
|
||||||
|
|
||||||
l = logging.getLogger(__name__)
|
l = logging.getLogger(__name__)
|
||||||
coloredlogs.install(logger=l)
|
coloredlogs.install(logger=l)
|
||||||
|
|
||||||
useRadarServer = True
|
useRadarServer = True
|
||||||
|
|
||||||
# Create dirs and files
|
|
||||||
if not os.path.exists('.temp/'):
|
|
||||||
os.makedirs('.temp/')
|
|
||||||
|
|
||||||
if not os.path.exists('.temp/tiles/'):
|
|
||||||
os.makedirs('.temp/tiles/')
|
|
||||||
|
|
||||||
if not os.path.exists('.temp/tiles/output/'):
|
|
||||||
os.makedirs('.temp/tiles/output/')
|
|
||||||
|
|
||||||
if not os.path.exists('.temp/msgId.txt'):
|
|
||||||
print("Creating initial msgId file")
|
|
||||||
with open('.temp/msgId.txt', "w") as f:
|
|
||||||
f.write("410080515")
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
CurrentConditions: Every 5 minutes
|
|
||||||
Daily Forecasts, Hourlies, etc: 60 minutes
|
|
||||||
Alerts: 5 minutes
|
|
||||||
"""
|
|
||||||
l.info("Starting i2RecordCollector")
|
l.info("Starting i2RecordCollector")
|
||||||
l.info("Developed by mewtek32, Floppaa, Goldblaze, and needlenose")
|
l.info("Developed by mewtek32, Floppaa, Goldblaze, and needlenose")
|
||||||
|
|
||||||
async def grabAlertsLoop():
|
async def createTemp():
|
||||||
while True:
|
""" Used on a first time run, creates necessary files & directories for the message encoder to work properly. """
|
||||||
Alerts.makeRecord()
|
if not (os.path.exists('./.temp/')):
|
||||||
await asyncio.sleep(60)
|
l.info("Creating necessary directories & files..")
|
||||||
|
os.mkdir('./.temp')
|
||||||
async def FiveMinUpdaters():
|
|
||||||
while True:
|
|
||||||
CurrentObservations.makeDataFile()
|
|
||||||
l.debug("Sleeping for 5 minutes...")
|
|
||||||
await asyncio.sleep(5 * 60)
|
|
||||||
|
|
||||||
async def HourUpdaters():
|
|
||||||
while True:
|
|
||||||
DailyForecast.makeDataFile()
|
|
||||||
HourlyForecast.makeDataFile()
|
|
||||||
AirQuality.writeData()
|
|
||||||
PollenForecast.makeDataFile()
|
|
||||||
AirportDelays.writeData()
|
|
||||||
Breathing.makeDataFile()
|
|
||||||
HeatingAndCooling.makeRecord()
|
|
||||||
WateringNeeds.makeRecord()
|
|
||||||
MosquitoActivity.makeRecord()
|
|
||||||
AchesAndPains.makeRecord()
|
|
||||||
TideForecast.makeRecord()
|
|
||||||
l.debug("Sleeping for an hour...")
|
|
||||||
await asyncio.sleep(60 * 60)
|
|
||||||
|
|
||||||
async def radarCollector():
|
|
||||||
mosaicUpdateIntervals = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55]
|
|
||||||
satradUpdateIntervals = [0, 10, 20, 30, 40, 50]
|
|
||||||
|
|
||||||
while True:
|
|
||||||
# Server takes ~15 - 35 seconds on average to fully generate a frame, use 40 seconds
|
|
||||||
# to make sure the radar frame is fully good to go
|
|
||||||
if datetime.now().minute in mosaicUpdateIntervals and datetime.now().second == 40:
|
|
||||||
await TWCRadarCollector.collect("radarmosaic")
|
|
||||||
|
|
||||||
if datetime.now().minute in satradUpdateIntervals and datetime.now().second == 45:
|
|
||||||
await TWCRadarCollector.collect("satrad")
|
|
||||||
|
|
||||||
await asyncio.sleep(1)
|
# Used for the record generator
|
||||||
|
os.mkdir('./.temp/tiles/')
|
||||||
|
os.mkdir('./.temp/tiles/output/')
|
||||||
|
|
||||||
loop = asyncio.get_event_loop()
|
# Used for radar server downloads
|
||||||
alertTask = loop.create_task(grabAlertsLoop())
|
os.mkdir('./.temp/output')
|
||||||
CCtask = loop.create_task(FiveMinUpdaters())
|
os.mkdir('./.temp/output/radarmosaic')
|
||||||
ForecastsTask = loop.create_task(HourUpdaters())
|
os.mkdir('./.temp/output/satrad')
|
||||||
|
|
||||||
if useRadarServer: radarTask = loop.create_task(radarCollector())
|
# Create msgId file for bit.py
|
||||||
|
async with aiofiles.open('./.temp/msgId.txt', 'w') as msgId:
|
||||||
|
await msgId.write('410080515')
|
||||||
|
await msgId.close()
|
||||||
|
else:
|
||||||
|
l.debug(".temp file exists")
|
||||||
|
return
|
||||||
|
|
||||||
try:
|
|
||||||
loop.run_until_complete(alertTask)
|
async def main():
|
||||||
loop.run_until_complete(CCtask)
|
await createTemp()
|
||||||
loop.run_until_complete(ForecastsTask)
|
|
||||||
if useRadarServer: loop.run_until_complete(radarTask)
|
mosaicTask = asyncio.create_task(RecordTasks.updateMosaicTask())
|
||||||
except asyncio.CancelledError: pass
|
satradTask = asyncio.create_task(RecordTasks.updateSatradTask())
|
||||||
|
alertsTask = asyncio.create_task(RecordTasks.alertsTask())
|
||||||
|
coTask = asyncio.create_task(RecordTasks.coTask())
|
||||||
|
hfTask = asyncio.create_task(RecordTasks.hfTask())
|
||||||
|
dfTask = asyncio.create_task(RecordTasks.dfTask())
|
||||||
|
aqTask = asyncio.create_task(RecordTasks.aqTask())
|
||||||
|
aptTask = asyncio.create_task(RecordTasks.aptTask())
|
||||||
|
apTask = asyncio.create_task(RecordTasks.apTask())
|
||||||
|
brTask = asyncio.create_task(RecordTasks.brTask())
|
||||||
|
hcTask = asyncio.create_task(RecordTasks.hcTask())
|
||||||
|
maTask = asyncio.create_task(RecordTasks.maTask())
|
||||||
|
pTask = asyncio.create_task(RecordTasks.pTask())
|
||||||
|
tTask = asyncio.create_task(RecordTasks.tTask())
|
||||||
|
wnTask = asyncio.create_task(RecordTasks.wnTask())
|
||||||
|
|
||||||
|
# In theory, these should all run concurrently without problems
|
||||||
|
await alertsTask
|
||||||
|
await coTask
|
||||||
|
await hfTask
|
||||||
|
await dfTask
|
||||||
|
await aqTask
|
||||||
|
await aptTask
|
||||||
|
await apTask
|
||||||
|
await brTask
|
||||||
|
await hcTask
|
||||||
|
await maTask
|
||||||
|
await pTask
|
||||||
|
await tTask
|
||||||
|
await wnTask
|
||||||
|
|
||||||
|
if useRadarServer:
|
||||||
|
await mosaicTask
|
||||||
|
await satradTask
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
asyncio.run(main())
|
@ -42,4 +42,4 @@ def makeStarBundle(Directory, Type, flag, Version, date, sendAfter):
|
|||||||
|
|
||||||
|
|
||||||
#Directory which contains Files to be bundled Type Flags Version Date SendImmediately(Does not apply to this script)
|
#Directory which contains Files to be bundled Type Flags Version Date SendImmediately(Does not apply to this script)
|
||||||
makeStarBundle('./.temp/i2State/SD/Managed/Events', 'Managed', 'Domestic_SD_Universe', '637898877227230030', '09/28/2022', 0)
|
# makeStarBundle('./.temp/i2State/SD/Managed/Events', 'Managed', 'Domestic_SD_Universe', '637898877227230030', '09/28/2022', 0)
|
@ -55,8 +55,8 @@ def WorldCoordinateToTile(coord: Point) -> Point:
|
|||||||
scale = 1 << 6
|
scale = 1 << 6
|
||||||
|
|
||||||
return Point(
|
return Point(
|
||||||
x = math.floor(coord.x * scale / 256),
|
x = math.floor(coord.x * scale / 255),
|
||||||
y = math.floor(coord.y * scale / 256)
|
y = math.floor(coord.y * scale / 255)
|
||||||
)
|
)
|
||||||
|
|
||||||
def WorldCoordinateToPixel(coord: Point) -> Point:
|
def WorldCoordinateToPixel(coord: Point) -> Point:
|
||||||
@ -68,10 +68,10 @@ def WorldCoordinateToPixel(coord: Point) -> Point:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def LatLongProject(lat, long) -> Point:
|
def LatLongProject(lat, long) -> Point:
|
||||||
siny = math.sin(lat * math.pi / 185)
|
siny = math.sin(lat * math.pi / 180)
|
||||||
siny = min(max(siny, -0.9999), 0.9999)
|
siny = min(max(siny, -0.9999), 0.9999)
|
||||||
|
|
||||||
return Point(
|
return Point(
|
||||||
x = 256 * (0.5 + long / 360),
|
x = 256 * (0.5 + long / 360),
|
||||||
y = 256 * (0.5 - math.log((1 + siny) / (1 - siny)) / (4 * math.pi))
|
y = 256 * (0.5 - math.log((1 + siny) / (1 - siny)) / (4 * math.pi))
|
||||||
)
|
)
|
@ -88,6 +88,7 @@ def getTime(timestamp) -> str:
|
|||||||
return str(time)
|
return str(time)
|
||||||
|
|
||||||
async def collect(radarType: str):
|
async def collect(radarType: str):
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
ts = await getValidTimestamps(radarType)
|
ts = await getValidTimestamps(radarType)
|
||||||
frames = await downloadRadarFrames(radarType, ts)
|
frames = await downloadRadarFrames(radarType, ts)
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import records.LFRecord as LFR
|
|||||||
import gzip
|
import gzip
|
||||||
from os import remove
|
from os import remove
|
||||||
import xml.dom.minidom
|
import xml.dom.minidom
|
||||||
|
import aiohttp, aiofiles, asyncio
|
||||||
|
|
||||||
l = logging.getLogger(__name__)
|
l = logging.getLogger(__name__)
|
||||||
coloredlogs.install()
|
coloredlogs.install()
|
||||||
@ -20,46 +21,49 @@ for i in MPC.getPrimaryLocations():
|
|||||||
|
|
||||||
apiKey = "21d8a80b3d6b444998a80b3d6b1449d3"
|
apiKey = "21d8a80b3d6b444998a80b3d6b1449d3"
|
||||||
|
|
||||||
def getData(coopId, geocode):
|
async def getData(coopId, geocode):
|
||||||
fetchUrl = f"https://api.weather.com/v2/indices/achePain/daypart/7day?geocode={geocode}&language=en-US&format=xml&apiKey={apiKey}"
|
fetchUrl = f"https://api.weather.com/v2/indices/achePain/daypart/7day?geocode={geocode}&language=en-US&format=xml&apiKey={apiKey}"
|
||||||
|
data = ""
|
||||||
|
|
||||||
|
async with aiohttp.ClientSession() as s:
|
||||||
|
async with s.get(fetchUrl) as r:
|
||||||
|
if r.status != 200:
|
||||||
|
l.error(f"Failed to write AchesAndPains record -- status code {r.status}")
|
||||||
|
return
|
||||||
|
|
||||||
|
data = await r.text()
|
||||||
|
|
||||||
res = requests.get(fetchUrl)
|
|
||||||
|
|
||||||
if res.status_code != 200:
|
|
||||||
l.error("DO NOT REPORT THE ERROR BELOW")
|
|
||||||
l.error(f"Failed to write AchesAndPains record -- Status code {res.status_code}")
|
|
||||||
return
|
|
||||||
|
|
||||||
data = res.text
|
|
||||||
newData = data[63:-26]
|
newData = data[63:-26]
|
||||||
|
|
||||||
i2Doc = f'\n <AchesAndPains id="000000000" locationKey="{coopId}" isWxScan="0">\n {newData}\n <clientKey>{coopId}</clientKey>\n </AchesAndPains>'
|
i2Doc = f'\n <AchesAndPains id="000000000" locationKey="{coopId}" isWxScan="0">\n {newData}\n <clientKey>{coopId}</clientKey>\n </AchesAndPains>'
|
||||||
|
|
||||||
f = open('./.temp/AchesAndPains.i2m', 'a')
|
async with aiofiles.open('./.temp/AchesAndPains.i2m', 'a') as f:
|
||||||
f.write(i2Doc)
|
await f.write(i2Doc)
|
||||||
f.close()
|
await f.close()
|
||||||
|
|
||||||
def makeRecord():
|
async def makeRecord():
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
l.info("Writing AchesAndPains record.")
|
l.info("Writing AchesAndPains record.")
|
||||||
|
|
||||||
header = '<Data type="AchesAndPains">'
|
header = '<Data type="AchesAndPains">'
|
||||||
footer = '</Data>'
|
footer = '</Data>'
|
||||||
|
|
||||||
with open('./.temp/AchesAndPains.i2m', 'a') as doc:
|
async with aiofiles.open('./.temp/AchesAndPains.i2m', 'a') as doc:
|
||||||
doc.write(header)
|
await doc.write(header)
|
||||||
|
|
||||||
for (x, y) in zip(coopIds, geocodes):
|
for (x, y) in zip(coopIds, geocodes):
|
||||||
getData(x,y)
|
await getData(x,y)
|
||||||
|
|
||||||
with open('./.temp/AchesAndPains.i2m', 'a') as end:
|
async with aiofiles.open('./.temp/AchesAndPains.i2m', 'a') as end:
|
||||||
end.write(footer)
|
await end.write(footer)
|
||||||
|
|
||||||
dom = xml.dom.minidom.parse('./.temp/AchesAndPains.i2m')
|
dom = xml.dom.minidom.parse('./.temp/AchesAndPains.i2m')
|
||||||
xmlPretty = dom.toprettyxml(indent= " ")
|
xmlPretty = dom.toprettyxml(indent= " ")
|
||||||
|
|
||||||
with open('./.temp/AchesAndPains.i2m', 'w') as g:
|
async with aiofiles.open('./.temp/AchesAndPains.i2m', 'w') as g:
|
||||||
g.write(xmlPretty[23:])
|
await g.write(xmlPretty[23:])
|
||||||
g.close()
|
await g.close()
|
||||||
|
|
||||||
|
|
||||||
# Compresss i2m to gzip
|
# Compresss i2m to gzip
|
||||||
|
@ -4,6 +4,7 @@ import os
|
|||||||
import shutil
|
import shutil
|
||||||
import xml.dom.minidom
|
import xml.dom.minidom
|
||||||
import logging,coloredlogs
|
import logging,coloredlogs
|
||||||
|
import aiohttp, aiofiles, asyncio
|
||||||
|
|
||||||
l = logging.getLogger(__name__)
|
l = logging.getLogger(__name__)
|
||||||
coloredlogs.install()
|
coloredlogs.install()
|
||||||
@ -27,22 +28,25 @@ for i in MPC.getPrimaryLocations():
|
|||||||
|
|
||||||
apiKey = '21d8a80b3d6b444998a80b3d6b1449d3'
|
apiKey = '21d8a80b3d6b444998a80b3d6b1449d3'
|
||||||
|
|
||||||
def getData(epaId, zipcode):
|
async def getData(epaId, zipcode):
|
||||||
url = f"https://api.weather.com/v1/location/{zipcode}:4:US/airquality.xml?language=en-US&apiKey={apiKey}"
|
url = f"https://api.weather.com/v1/location/{zipcode}:4:US/airquality.xml?language=en-US&apiKey={apiKey}"
|
||||||
|
data = ""
|
||||||
|
|
||||||
res = requests.get(url=url)
|
async with aiohttp.ClientSession() as s:
|
||||||
|
async with s.get(url) as r:
|
||||||
data = res.text
|
data = await r.text()
|
||||||
|
|
||||||
newData = data[57:-11]
|
newData = data[57:-11]
|
||||||
|
|
||||||
# Write to i2doc file
|
# Write to i2doc file
|
||||||
i2Doc = f'<AirQuality id="000000000" locationKey="{epaId}" isWxScan="0">' + '' + newData + f'<clientKey>{epaId}</clientKey></AirQuality>'
|
i2Doc = f'<AirQuality id="000000000" locationKey="{epaId}" isWxScan="0">' + '' + newData + f'<clientKey>{epaId}</clientKey></AirQuality>'
|
||||||
|
|
||||||
f = open("./.temp/AirQuality.i2m", 'a')
|
async with aiofiles.open("./.temp/AirQuality.i2m", 'a') as f:
|
||||||
f.write(i2Doc)
|
await f.write(i2Doc)
|
||||||
f.close()
|
await f.close()
|
||||||
|
|
||||||
def writeData():
|
async def writeData():
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
useData = False
|
useData = False
|
||||||
workingEpaIds = []
|
workingEpaIds = []
|
||||||
|
|
||||||
@ -62,21 +66,21 @@ def writeData():
|
|||||||
header = '<Data type="AirQuality">'
|
header = '<Data type="AirQuality">'
|
||||||
footer = "</Data>"
|
footer = "</Data>"
|
||||||
|
|
||||||
with open("./.temp/AirQuality.i2m", 'w') as doc:
|
async with aiofiles.open("./.temp/AirQuality.i2m", 'w') as doc:
|
||||||
doc.write(header)
|
await doc.write(header)
|
||||||
|
|
||||||
for (x, y) in zip(workingEpaIds, zipCodes):
|
for (x, y) in zip(workingEpaIds, zipCodes):
|
||||||
getData(x, y)
|
await getData(x, y)
|
||||||
|
|
||||||
with open("./.temp/AirQuality.i2m", 'a') as end:
|
async with aiofiles.open("./.temp/AirQuality.i2m", 'a') as end:
|
||||||
end.write(footer)
|
await end.write(footer)
|
||||||
|
|
||||||
dom = xml.dom.minidom.parse("./.temp/AirQuality.i2m")
|
dom = xml.dom.minidom.parse("./.temp/AirQuality.i2m")
|
||||||
xmlPretty = dom.toprettyxml(indent = " ")
|
xmlPretty = dom.toprettyxml(indent = " ")
|
||||||
|
|
||||||
with open("./.temp/AirQuality.i2m", 'w') as g:
|
async with aiofiles.open("./.temp/AirQuality.i2m", 'w') as g:
|
||||||
g.write(xmlPretty[23:])
|
await g.write(xmlPretty[23:])
|
||||||
g.close()
|
await g.close()
|
||||||
|
|
||||||
files = []
|
files = []
|
||||||
commands = []
|
commands = []
|
||||||
|
@ -4,6 +4,7 @@ import os
|
|||||||
import shutil
|
import shutil
|
||||||
import xml.dom.minidom
|
import xml.dom.minidom
|
||||||
import logging,coloredlogs
|
import logging,coloredlogs
|
||||||
|
import aiohttp, aiofiles, asyncio
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
sys.path.append("./py2lib")
|
sys.path.append("./py2lib")
|
||||||
@ -29,56 +30,57 @@ l.debug(airports)
|
|||||||
|
|
||||||
apiKey = '21d8a80b3d6b444998a80b3d6b1449d3'
|
apiKey = '21d8a80b3d6b444998a80b3d6b1449d3'
|
||||||
|
|
||||||
def getData(airport):
|
async def getData(airport):
|
||||||
url = f"https://api.weather.com/v1/airportcode/{airport}/airport/delays.xml?language=en-US&apiKey={apiKey}"
|
url = f"https://api.weather.com/v1/airportcode/{airport}/airport/delays.xml?language=en-US&apiKey={apiKey}"
|
||||||
|
data = ""
|
||||||
|
|
||||||
res = requests.get(url=url)
|
async with aiohttp.ClientSession() as s:
|
||||||
|
async with s.get(url) as r:
|
||||||
|
data = await r.text()
|
||||||
|
|
||||||
data = res.text
|
newData = data[48:-11].replace('¿', '-')
|
||||||
newData = data[48:-11]
|
|
||||||
|
|
||||||
# Write to i2doc file
|
# Write to i2doc file
|
||||||
i2Doc = f'<AirportDelays id="000000000" locationKey="{airport}" isWxScan="0">' + '' + newData + f'<clientKey>{airport}</clientKey></AirportDelays>'
|
i2Doc = f'<AirportDelays id="000000000" locationKey="{airport}" isWxScan="0">' + '' + newData + f'<clientKey>{airport}</clientKey></AirportDelays>'
|
||||||
|
|
||||||
f = open("./.temp/AirportDelays.i2m", 'a')
|
async with aiofiles.open("./.temp/AirportDelays.i2m", 'a') as f:
|
||||||
f.write(i2Doc)
|
await f.write(i2Doc)
|
||||||
f.close()
|
await f.close()
|
||||||
|
|
||||||
def writeData():
|
async def writeData():
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
useData = False
|
useData = False
|
||||||
airportsWithDelays = []
|
airportsWithDelays = []
|
||||||
|
|
||||||
for x in airports:
|
for x in airports:
|
||||||
# Do a quick check to see if the airport in question has a delay or not
|
async with aiohttp.ClientSession() as s:
|
||||||
res = requests.get(f"https://api.weather.com/v1/airportcode/{x}/airport/delays.xml?language=en-US&apiKey={apiKey}")
|
async with s.get(f"https://api.weather.com/v1/airportcode/{x}/airport/delays.xml?language=en-US&apiKey={apiKey}") as r:
|
||||||
|
if r.status != 200:
|
||||||
if (res.status_code != 200):
|
l.debug(f"No delay for {x} found, skipping..")
|
||||||
l.debug(f"[AIRPORT DELAYS] No delays for {x} found, skipping..")
|
else:
|
||||||
else:
|
airportsWithDelays.append(x)
|
||||||
airportsWithDelays.append(x)
|
useData = True
|
||||||
l.debug(f"[AIRPORT DELAYS] {x} has a delay! Writing a file..")
|
|
||||||
useData = True
|
|
||||||
|
|
||||||
if (useData):
|
if (useData):
|
||||||
l.info("Writing an AirportDelays record.")
|
l.info("Writing an AirportDelays record.")
|
||||||
header = '<Data type="AirportDelays">'
|
header = '<Data type="AirportDelays">'
|
||||||
footer = "</Data>"
|
footer = "</Data>"
|
||||||
|
|
||||||
with open("./.temp/AirportDelays.i2m", 'w') as doc:
|
async with aiofiles.open("./.temp/AirportDelays.i2m", 'w') as doc:
|
||||||
doc.write(header)
|
await doc.write(header)
|
||||||
|
|
||||||
for x in airportsWithDelays:
|
for x in airportsWithDelays:
|
||||||
getData(x)
|
await getData(x)
|
||||||
|
|
||||||
with open("./.temp/AirportDelays.i2m", 'a') as end:
|
async with aiofiles.open("./.temp/AirportDelays.i2m", 'a') as end:
|
||||||
end.write(footer)
|
await end.write(footer)
|
||||||
|
|
||||||
dom = xml.dom.minidom.parse("./.temp/AirportDelays.i2m")
|
dom = xml.dom.minidom.parse("./.temp/AirportDelays.i2m")
|
||||||
prettyXml = dom.toprettyxml(indent=" ")
|
prettyXml = dom.toprettyxml(indent=" ")
|
||||||
|
|
||||||
with open("./.temp/AirportDelays.i2m", 'w') as g:
|
async with aiofiles.open("./.temp/AirportDelays.i2m", 'w') as g:
|
||||||
g.write(prettyXml)
|
await g.write(prettyXml)
|
||||||
g.close()
|
await g.close()
|
||||||
|
|
||||||
files = []
|
files = []
|
||||||
commands = []
|
commands = []
|
||||||
|
@ -9,6 +9,7 @@ import xml.dom.minidom
|
|||||||
import shutil
|
import shutil
|
||||||
import gzip
|
import gzip
|
||||||
import logging,coloredlogs
|
import logging,coloredlogs
|
||||||
|
import aiohttp, aiofiles, asyncio
|
||||||
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
@ -26,321 +27,326 @@ headlineApiKey = '21d8a80b3d6b444998a80b3d6b1449d3'
|
|||||||
detailsApiKey = '21d8a80b3d6b444998a80b3d6b1449d3'
|
detailsApiKey = '21d8a80b3d6b444998a80b3d6b1449d3'
|
||||||
|
|
||||||
k = 0
|
k = 0
|
||||||
def getAlerts(location):
|
async def getAlerts(location):
|
||||||
global k
|
global k
|
||||||
fetchUrl = 'https://api.weather.com/v3/alerts/headlines?areaId=' + location + ':US&format=json&language=en-US&apiKey=' + headlineApiKey
|
fetchUrl = 'https://api.weather.com/v3/alerts/headlines?areaId=' + location + ':US&format=json&language=en-US&apiKey=' + headlineApiKey
|
||||||
response = requests.get(fetchUrl)
|
# response = requests.get(fetchUrl)
|
||||||
|
|
||||||
theCode = response.status_code
|
# theCode = response.status_code
|
||||||
|
|
||||||
#Our global variables
|
|
||||||
|
|
||||||
|
|
||||||
#Set the actions based on response code
|
|
||||||
if theCode == 204:
|
|
||||||
l.info('No alerts for area ' + location + '.\n')
|
|
||||||
return
|
|
||||||
elif theCode == 403:
|
|
||||||
l.critical("Uh oh! Your API key may not be authorized for alerts. Tsk Tsk. Maybe you shouldn't pirate IBM data :)\n")
|
|
||||||
return
|
|
||||||
elif theCode == 401:
|
|
||||||
l.critical("Uh oh! This request requires authentication. Maybe you shouldn't try to access resources for IBM employee's only :)\n")
|
|
||||||
return
|
|
||||||
elif theCode == 404:
|
|
||||||
l.error("Uh oh! The requested resource cannot be found. This means either the URL is wrong or IBM is having technical difficulties :(\n Or.... They deleted the API :O\n")
|
|
||||||
return
|
|
||||||
elif theCode == 405:
|
|
||||||
l.error("Uh oh! Got a 405! This means that somehow.... someway..... this script made an invalid request. So sad..... So terrible..... :(\n")
|
|
||||||
return
|
|
||||||
elif theCode == 406:
|
|
||||||
l.critical("Uh oh! Got a 406! This means that IBM doesn't like us. :(\n")
|
|
||||||
return
|
|
||||||
elif theCode == 408:
|
|
||||||
l.error("Uh oh! We were too slow in providing IBM our alert request. Although I prefer to say we were Slowly Capable! :)\n")
|
|
||||||
return
|
|
||||||
elif theCode == 500:
|
|
||||||
l.error("Uh oh! Seems IBM's on call IT Tech spilled coffee on the server! Looks like no alerts for a while. Please check back later :)\n")
|
|
||||||
return
|
|
||||||
elif theCode == 502 or theCode == 503 or theCode == 504:
|
|
||||||
l.error("Uh oh! This is why you don't have interns messing with the server configuration. Please stand by while IBM's on call IT Tech resolves the issue :)\n")
|
|
||||||
return
|
|
||||||
elif theCode == 200:
|
|
||||||
pass
|
|
||||||
|
|
||||||
#Alright lets map our headline variables.
|
theCode = 0
|
||||||
l.debug('Found Alert for ' + location + '\n')
|
|
||||||
dataH = response.json()
|
|
||||||
alertsRoot = dataH['alerts']
|
|
||||||
|
|
||||||
for x in alertsRoot:
|
async with aiohttp.ClientSession() as s:
|
||||||
detailKey = x['detailKey']
|
async with s.get(fetchUrl) as r:
|
||||||
#Lets get map our detail variables.
|
theCode = await r.status
|
||||||
detailsUrl = 'https://api.weather.com/v3/alerts/detail?alertId=' + detailKey + '&format=json&language=en-US&apiKey=' + detailsApiKey
|
|
||||||
detailsResponse = requests.get(detailsUrl)
|
#Set the actions based on response code
|
||||||
dataD = detailsResponse.json()
|
if theCode == 204:
|
||||||
detailsRoot = dataD['alertDetail']
|
l.info('No alerts for area ' + location + '.\n')
|
||||||
theDetailsText = detailsRoot['texts']
|
return
|
||||||
detailsText = theDetailsText[0]
|
elif theCode == 403:
|
||||||
descriptionRaw = detailsText['description']
|
l.critical("Uh oh! Your API key may not be authorized for alerts. Tsk Tsk. Maybe you shouldn't pirate IBM data :)\n")
|
||||||
language = detailsText['languageCode']
|
return
|
||||||
Identifier = location + '_' + x['phenomena'] + '_' + x['significance'] + '_' + str(x['processTimeUTC'])
|
elif theCode == 401:
|
||||||
|
l.critical("Uh oh! This request requires authentication. Maybe you shouldn't try to access resources for IBM employee's only :)\n")
|
||||||
#Is this for a NWS Zone or County?
|
return
|
||||||
last4 = location[2:]
|
elif theCode == 404:
|
||||||
locationType = None
|
l.error("Uh oh! The requested resource cannot be found. This means either the URL is wrong or IBM is having technical difficulties :(\n Or.... They deleted the API :O\n")
|
||||||
if 'C' in last4:
|
return
|
||||||
locationType = 'C'
|
elif theCode == 405:
|
||||||
elif 'Z' in last4:
|
l.error("Uh oh! Got a 405! This means that somehow.... someway..... this script made an invalid request. So sad..... So terrible..... :(\n")
|
||||||
locationType = 'Z'
|
return
|
||||||
|
elif theCode == 406:
|
||||||
|
l.critical("Uh oh! Got a 406! This means that IBM doesn't like us. :(\n")
|
||||||
|
return
|
||||||
|
elif theCode == 408:
|
||||||
|
l.error("Uh oh! We were too slow in providing IBM our alert request. Although I prefer to say we were Slowly Capable! :)\n")
|
||||||
|
return
|
||||||
|
elif theCode == 500:
|
||||||
|
l.error("Uh oh! Seems IBM's on call IT Tech spilled coffee on the server! Looks like no alerts for a while. Please check back later :)\n")
|
||||||
|
return
|
||||||
|
elif theCode == 502 or theCode == 503 or theCode == 504:
|
||||||
|
l.error("Uh oh! This is why you don't have interns messing with the server configuration. Please stand by while IBM's on call IT Tech resolves the issue :)\n")
|
||||||
|
return
|
||||||
|
elif theCode == 200:
|
||||||
|
pass
|
||||||
|
|
||||||
#theIdent = str(Identifier)
|
# Map headline variables
|
||||||
try:
|
l.debug('Found Alert for ' + location + '\n')
|
||||||
thecheck = open('./.temp/alertmanifest.txt', "r")
|
dataH = await r.json()
|
||||||
check = thecheck.read()
|
alertsRoot = dataH['alerts']
|
||||||
|
|
||||||
|
for x in alertsRoot:
|
||||||
|
detailKey = x['detailKey']
|
||||||
|
#Lets get map our detail variables.
|
||||||
|
detailsUrl = 'https://api.weather.com/v3/alerts/detail?alertId=' + detailKey + '&format=json&language=en-US&apiKey=' + detailsApiKey
|
||||||
|
detailsResponse = requests.get(detailsUrl)
|
||||||
|
dataD = detailsResponse.json()
|
||||||
|
detailsRoot = dataD['alertDetail']
|
||||||
|
theDetailsText = detailsRoot['texts']
|
||||||
|
detailsText = theDetailsText[0]
|
||||||
|
descriptionRaw = detailsText['description']
|
||||||
|
language = detailsText['languageCode']
|
||||||
|
Identifier = location + '_' + x['phenomena'] + '_' + x['significance'] + '_' + str(x['processTimeUTC'])
|
||||||
|
|
||||||
if check.find(Identifier) != -1:
|
#Is this for a NWS Zone or County?
|
||||||
l.debug("Alert already sent...")
|
last4 = location[2:]
|
||||||
return
|
locationType = None
|
||||||
except FileNotFoundError:
|
if 'C' in last4:
|
||||||
l.warning("alert manifest does not exist (yet)")
|
locationType = 'C'
|
||||||
k += 1 #We have an alert to send!
|
elif 'Z' in last4:
|
||||||
|
locationType = 'Z'
|
||||||
|
|
||||||
|
#theIdent = str(Identifier)
|
||||||
|
try:
|
||||||
|
async with aiofiles.open('./.temp/alertmanifest.txt', 'r' ) as checkFile:
|
||||||
|
c = await checkFile.read()
|
||||||
|
|
||||||
|
if c.find(Identifier) != -1:
|
||||||
|
l.debug(f"{Identifier} was sent already, skipping..")
|
||||||
|
return
|
||||||
|
except FileNotFoundError:
|
||||||
|
l.warning("alert manifest does not exist (yet)")
|
||||||
|
|
||||||
|
k += 1 #We have an alert to send!
|
||||||
|
|
||||||
|
#Lets Map Our Vocal Codes!
|
||||||
|
vocalCheck = x['phenomena'] + '_' + x['significance']
|
||||||
|
vocalCode = None
|
||||||
|
|
||||||
#Lets Map Our Vocal Codes!
|
if vocalCheck == 'HU_W':
|
||||||
vocalCheck = x['phenomena'] + '_' + x['significance']
|
vocalCode = '<bVocHdlnCd>HE001</bVocHdlnCd>'
|
||||||
vocalCode = None
|
elif vocalCheck == 'TY_W':
|
||||||
|
vocalCode = '<bVocHdlnCd>HE002</bVocHdlnCd>'
|
||||||
if vocalCheck == 'HU_W':
|
elif vocalCheck == 'HI_W':
|
||||||
vocalCode = '<bVocHdlnCd>HE001</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE003</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'TY_W':
|
elif vocalCheck == 'TO_A':
|
||||||
vocalCode = '<bVocHdlnCd>HE002</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE004</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'HI_W':
|
elif vocalCheck == 'SV_A':
|
||||||
vocalCode = '<bVocHdlnCd>HE003</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE005</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'TO_A':
|
elif vocalCheck == 'HU_A':
|
||||||
vocalCode = '<bVocHdlnCd>HE004</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE006</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'SV_A':
|
elif vocalCheck == 'TY_A':
|
||||||
vocalCode = '<bVocHdlnCd>HE005</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE007</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'HU_A':
|
elif vocalCheck == 'TR_W':
|
||||||
vocalCode = '<bVocHdlnCd>HE006</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE008</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'TY_A':
|
elif vocalCheck == 'TR_A':
|
||||||
vocalCode = '<bVocHdlnCd>HE007</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE009</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'TR_W':
|
elif vocalCheck == 'TI_W':
|
||||||
vocalCode = '<bVocHdlnCd>HE008</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE010</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'TR_A':
|
elif vocalCheck == 'HI_A':
|
||||||
vocalCode = '<bVocHdlnCd>HE009</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE011</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'TI_W':
|
elif vocalCheck == 'TI_A':
|
||||||
vocalCode = '<bVocHdlnCd>HE010</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE012</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'HI_A':
|
elif vocalCheck == 'BZ_W':
|
||||||
vocalCode = '<bVocHdlnCd>HE011</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE013</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'TI_A':
|
elif vocalCheck == 'IS_W':
|
||||||
vocalCode = '<bVocHdlnCd>HE012</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE014</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'BZ_W':
|
elif vocalCheck == 'WS_W':
|
||||||
vocalCode = '<bVocHdlnCd>HE013</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE015</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'IS_W':
|
elif vocalCheck == 'HW_W':
|
||||||
vocalCode = '<bVocHdlnCd>HE014</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE016</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'WS_W':
|
elif vocalCheck == 'LE_W':
|
||||||
vocalCode = '<bVocHdlnCd>HE015</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE017</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'HW_W':
|
elif vocalCheck == 'ZR_Y':
|
||||||
vocalCode = '<bVocHdlnCd>HE016</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE018</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'LE_W':
|
elif vocalCheck == 'CF_W':
|
||||||
vocalCode = '<bVocHdlnCd>HE017</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE019</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'ZR_Y':
|
elif vocalCheck == 'LS_W':
|
||||||
vocalCode = '<bVocHdlnCd>HE018</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE020</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'CF_W':
|
elif vocalCheck == 'WW_Y':
|
||||||
vocalCode = '<bVocHdlnCd>HE019</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE021</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'LS_W':
|
elif vocalCheck == 'LB_Y':
|
||||||
vocalCode = '<bVocHdlnCd>HE020</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE022</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'WW_Y':
|
elif vocalCheck == 'LE_Y':
|
||||||
vocalCode = '<bVocHdlnCd>HE021</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE023</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'LB_Y':
|
elif vocalCheck == 'BZ_A':
|
||||||
vocalCode = '<bVocHdlnCd>HE022</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE024</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'LE_Y':
|
elif vocalCheck == 'WS_A':
|
||||||
vocalCode = '<bVocHdlnCd>HE023</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE025</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'BZ_A':
|
elif vocalCheck == 'FF_A':
|
||||||
vocalCode = '<bVocHdlnCd>HE024</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE026</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'WS_A':
|
elif vocalCheck == 'FA_A':
|
||||||
vocalCode = '<bVocHdlnCd>HE025</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE027</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'FF_A':
|
elif vocalCheck == 'FA_Y':
|
||||||
vocalCode = '<bVocHdlnCd>HE026</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE028</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'FA_A':
|
elif vocalCheck == 'HW_A':
|
||||||
vocalCode = '<bVocHdlnCd>HE027</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE029</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'FA_Y':
|
elif vocalCheck == 'LE_A':
|
||||||
vocalCode = '<bVocHdlnCd>HE028</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE030</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'HW_A':
|
elif vocalCheck == 'SU_W':
|
||||||
vocalCode = '<bVocHdlnCd>HE029</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE031</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'LE_A':
|
elif vocalCheck == 'LS_Y':
|
||||||
vocalCode = '<bVocHdlnCd>HE030</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE032</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'SU_W':
|
elif vocalCheck == 'CF_A':
|
||||||
vocalCode = '<bVocHdlnCd>HE031</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE033</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'LS_Y':
|
elif vocalCheck == 'ZF_Y':
|
||||||
vocalCode = '<bVocHdlnCd>HE032</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE034</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'CF_A':
|
elif vocalCheck == 'FG_Y':
|
||||||
vocalCode = '<bVocHdlnCd>HE033</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE035</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'ZF_Y':
|
elif vocalCheck == 'SM_Y':
|
||||||
vocalCode = '<bVocHdlnCd>HE034</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE036</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'FG_Y':
|
elif vocalCheck == 'EC_W':
|
||||||
vocalCode = '<bVocHdlnCd>HE035</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE037</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'SM_Y':
|
elif vocalCheck == 'EH_W':
|
||||||
vocalCode = '<bVocHdlnCd>HE036</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE038</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'EC_W':
|
elif vocalCheck == 'HZ_W':
|
||||||
vocalCode = '<bVocHdlnCd>HE037</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE039</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'EH_W':
|
elif vocalCheck == 'FZ_W':
|
||||||
vocalCode = '<bVocHdlnCd>HE038</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE040</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'HZ_W':
|
elif vocalCheck == 'HT_Y':
|
||||||
vocalCode = '<bVocHdlnCd>HE039</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE041</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'FZ_W':
|
elif vocalCheck == 'WC_Y':
|
||||||
vocalCode = '<bVocHdlnCd>HE040</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE042</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'HT_Y':
|
elif vocalCheck == 'FR_Y':
|
||||||
vocalCode = '<bVocHdlnCd>HE041</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE043</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'WC_Y':
|
elif vocalCheck == 'EC_A':
|
||||||
vocalCode = '<bVocHdlnCd>HE042</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE044</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'FR_Y':
|
elif vocalCheck == 'EH_A':
|
||||||
vocalCode = '<bVocHdlnCd>HE043</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE045</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'EC_A':
|
elif vocalCheck == 'HZ_A':
|
||||||
vocalCode = '<bVocHdlnCd>HE044</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE046</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'EH_A':
|
elif vocalCheck == 'DS_W':
|
||||||
vocalCode = '<bVocHdlnCd>HE045</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE047</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'HZ_A':
|
elif vocalCheck == 'WI_Y':
|
||||||
vocalCode = '<bVocHdlnCd>HE046</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE048</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'DS_W':
|
elif vocalCheck == 'SU_Y':
|
||||||
vocalCode = '<bVocHdlnCd>HE047</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE049</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'WI_Y':
|
elif vocalCheck == 'AS_Y':
|
||||||
vocalCode = '<bVocHdlnCd>HE048</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE050</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'SU_Y':
|
elif vocalCheck == 'WC_W':
|
||||||
vocalCode = '<bVocHdlnCd>HE049</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE051</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'AS_Y':
|
elif vocalCheck == 'FZ_A':
|
||||||
vocalCode = '<bVocHdlnCd>HE050</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE052</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'WC_W':
|
elif vocalCheck == 'WC_A':
|
||||||
vocalCode = '<bVocHdlnCd>HE051</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE053</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'FZ_A':
|
elif vocalCheck == 'AF_W':
|
||||||
vocalCode = '<bVocHdlnCd>HE052</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE054</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'WC_A':
|
elif vocalCheck == 'AF_Y':
|
||||||
vocalCode = '<bVocHdlnCd>HE053</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE055</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'AF_W':
|
elif vocalCheck == 'DU_Y':
|
||||||
vocalCode = '<bVocHdlnCd>HE054</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE056</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'AF_Y':
|
elif vocalCheck == 'LW_Y':
|
||||||
vocalCode = '<bVocHdlnCd>HE055</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE057</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'DU_Y':
|
elif vocalCheck == 'LS_A':
|
||||||
vocalCode = '<bVocHdlnCd>HE056</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE058</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'LW_Y':
|
elif vocalCheck == 'HF_W':
|
||||||
vocalCode = '<bVocHdlnCd>HE057</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE059</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'LS_A':
|
elif vocalCheck == 'SR_W':
|
||||||
vocalCode = '<bVocHdlnCd>HE058</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE060</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'HF_W':
|
elif vocalCheck == 'GL_W':
|
||||||
vocalCode = '<bVocHdlnCd>HE059</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE061</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'SR_W':
|
elif vocalCheck == 'HF_A':
|
||||||
vocalCode = '<bVocHdlnCd>HE060</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE062</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'GL_W':
|
elif vocalCheck == 'UP_W':
|
||||||
vocalCode = '<bVocHdlnCd>HE061</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE063</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'HF_A':
|
elif vocalCheck == 'SE_W':
|
||||||
vocalCode = '<bVocHdlnCd>HE062</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE064</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'UP_W':
|
elif vocalCheck == 'SR_A':
|
||||||
vocalCode = '<bVocHdlnCd>HE063</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE065</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'SE_W':
|
elif vocalCheck == 'GL_A':
|
||||||
vocalCode = '<bVocHdlnCd>HE064</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE066</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'SR_A':
|
elif vocalCheck == 'MF_Y':
|
||||||
vocalCode = '<bVocHdlnCd>HE065</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE067</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'GL_A':
|
elif vocalCheck == 'MS_Y':
|
||||||
vocalCode = '<bVocHdlnCd>HE066</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE068</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'MF_Y':
|
elif vocalCheck == 'SC_Y':
|
||||||
vocalCode = '<bVocHdlnCd>HE067</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE069</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'MS_Y':
|
elif vocalCheck == 'UP_Y':
|
||||||
vocalCode = '<bVocHdlnCd>HE068</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE073</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'SC_Y':
|
elif vocalCheck == 'LO_Y':
|
||||||
vocalCode = '<bVocHdlnCd>HE069</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE074</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'UP_Y':
|
elif vocalCheck == 'AF_V':
|
||||||
vocalCode = '<bVocHdlnCd>HE073</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE075</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'LO_Y':
|
elif vocalCheck == 'UP_A':
|
||||||
vocalCode = '<bVocHdlnCd>HE074</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE076</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'AF_V':
|
elif vocalCheck == 'TAV_W':
|
||||||
vocalCode = '<bVocHdlnCd>HE075</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE077</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'UP_A':
|
elif vocalCheck == 'TAV_A':
|
||||||
vocalCode = '<bVocHdlnCd>HE076</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE078</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'TAV_W':
|
elif vocalCheck == 'TO_W':
|
||||||
vocalCode = '<bVocHdlnCd>HE077</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd>HE110</bVocHdlnCd>'
|
||||||
elif vocalCheck == 'TAV_A':
|
else:
|
||||||
vocalCode = '<bVocHdlnCd>HE078</bVocHdlnCd>'
|
vocalCode = '<bVocHdlnCd />'
|
||||||
elif vocalCheck == 'TO_W':
|
|
||||||
vocalCode = '<bVocHdlnCd>HE110</bVocHdlnCd>'
|
|
||||||
else:
|
|
||||||
vocalCode = '<bVocHdlnCd />'
|
|
||||||
|
|
||||||
#Do some date/time conversions
|
#Do some date/time conversions
|
||||||
EndTimeUTCEpoch = x['expireTimeUTC']
|
EndTimeUTCEpoch = x['expireTimeUTC']
|
||||||
EndTimeUTC = datetime.utcfromtimestamp(EndTimeUTCEpoch).strftime('%Y%m%d%H%M')
|
EndTimeUTC = datetime.utcfromtimestamp(EndTimeUTCEpoch).strftime('%Y%m%d%H%M')
|
||||||
#EndTimeUTC = EndTimeUTCString.astimezone(pytz.UTC)
|
#EndTimeUTC = EndTimeUTCString.astimezone(pytz.UTC)
|
||||||
|
|
||||||
|
expireTimeEpoch = x['expireTimeUTC']
|
||||||
|
expireTimeUTC = datetime.utcfromtimestamp(expireTimeEpoch).strftime('%Y%m%d%H%M')
|
||||||
|
|
||||||
|
#V3 Alert API doesn't give us issueTime in UTC. So we have to convert ourselves. Ughhh!!
|
||||||
|
iTLDTS = x['issueTimeLocal']
|
||||||
|
iTLDTO = datetime.strptime(iTLDTS, '%Y-%m-%dT%H:%M:%S%z')
|
||||||
|
issueTimeToUTC = iTLDTO.astimezone(pytz.UTC)
|
||||||
|
issueTimeUtc = issueTimeToUTC.strftime('%Y%m%d%H%M')
|
||||||
|
|
||||||
|
processTimeEpoch = x['processTimeUTC']
|
||||||
|
processTime = datetime.fromtimestamp(processTimeEpoch).strftime('%Y%m%d%H%M%S')
|
||||||
|
|
||||||
|
#What is the action of this alert?
|
||||||
|
Action = None
|
||||||
|
if x['messageType'] == 'Update':
|
||||||
|
Action = 'CON'
|
||||||
|
elif x['messageType'] == 'New':
|
||||||
|
Action = 'NEW'
|
||||||
|
|
||||||
expireTimeEpoch = x['expireTimeUTC']
|
#Fix description to replace new lines with space and add XML escape Chars. when needed
|
||||||
expireTimeUTC = datetime.utcfromtimestamp(expireTimeEpoch).strftime('%Y%m%d%H%M')
|
|
||||||
|
description = ' '.join(descriptionRaw.splitlines())
|
||||||
|
description = description.replace('&', '&')
|
||||||
|
description = description.replace('<', '<')
|
||||||
|
description = description.replace('>', '>')
|
||||||
|
description = description.replace('-', '')
|
||||||
|
description = description.replace(':', '')
|
||||||
|
|
||||||
|
#Is this alert urgent?
|
||||||
|
urgency ='piss'
|
||||||
|
if vocalCheck == 'TO_W' or vocalCheck == 'SV_W' or vocalCheck == 'FF_W':
|
||||||
|
urgency = 'BEUrgent'
|
||||||
|
else:
|
||||||
|
urgency = 'BERecord'
|
||||||
|
|
||||||
|
alertMsg = '<BERecord id="0000" locationKey="' + location + '_' + x['phenomena'] + '_' + x['significance'] + '_' + x['eventTrackingNumber'] + '_' + x['officeCode'] + '" isWxscan="0"><action>NOT_USED</action><BEHdr><bPIL>' + x['productIdentifier'] + '</bPIL><bWMOHdr>NOT_USED</bWMOHdr><bEvent><eActionCd eActionPriority="' + str(x['messageTypeCode']) + '">' + Action + '</eActionCd><eOfficeId eOfficeNm="' + x['officeName'] + '">' + x['officeCode'] + '</eOfficeId><ePhenom>' + x['phenomena'] + '</ePhenom><eSgnfcnc>' + x['significance'] + '</eSgnfcnc><eETN>' + x['eventTrackingNumber'] + '</eETN><eDesc>' + x['eventDescription'] + '</eDesc><eStTmUTC>NOT_USED</eStTmUTC><eEndTmUTC>' + EndTimeUTC + '</eEndTmUTC><eSvrty>' + str(x['severityCode']) + '</eSvrty><eTWCIId>NOT_USED</eTWCIId><eExpTmUTC>' + expireTimeUTC + '</eExpTmUTC></bEvent><bLocations><bLocCd bLoc="' + x['areaName'] + '" bLocTyp="' + locationType + '">' + location + '</bLocCd><bStCd bSt="' + x['adminDistrict'] + '">' + x['adminDistrictCode'] + '</bStCd><bUTCDiff>NOT_USED</bUTCDiff><bTzAbbrv>NOT_USED</bTzAbbrv><bCntryCd>NOT_USED</bCntryCd></bLocations><bSgmtChksum>' + x['identifier'] + '</bSgmtChksum><procTm>' + processTime + '</procTm></BEHdr><BEData><bIssueTmUTC>' + issueTimeUtc + '</bIssueTmUTC><bHdln><bHdlnTxt>' + x['headlineText'] + '</bHdlnTxt>' + vocalCode + '</bHdln><bParameter>NOT_USED</bParameter><bNarrTxt bNarrTxtLang="en-US"><bLn>' + description + '</bLn></bNarrTxt><bSrchRslt>NOT_USED</bSrchRslt></BEData><clientKey>' + location + '_' + x['phenomena'] + '_' + x['significance'] + '_' + x['eventTrackingNumber'] + '_' + x['officeCode'] + '</clientKey></BERecord>'
|
||||||
|
|
||||||
#V3 Alert API doesn't give us issueTime in UTC. So we have to convert ourselves. Ughhh!!
|
#Append BERecord
|
||||||
iTLDTS = x['issueTimeLocal']
|
async with aiofiles.open('./.temp/BERecord.xml', "a") as b:
|
||||||
iTLDTO = datetime.strptime(iTLDTS, '%Y-%m-%dT%H:%M:%S%z')
|
await b.write(alertMsg)
|
||||||
issueTimeToUTC = iTLDTO.astimezone(pytz.UTC)
|
await b.close()
|
||||||
issueTimeUtc = issueTimeToUTC.strftime('%Y%m%d%H%M')
|
|
||||||
|
#Add our alert to the manifest so we don't keep sending in the same alert every 60 seconds unless an update is issued.
|
||||||
processTimeEpoch = x['processTimeUTC']
|
async with aiofiles.open('./.temp/alertmanifest.txt', "a") as c:
|
||||||
processTime = datetime.fromtimestamp(processTimeEpoch).strftime('%Y%m%d%H%M%S')
|
await c.write('\n' + location + '_' + x['phenomena'] + '_' + x['significance'] + '_' + str(x['processTimeUTC']))
|
||||||
|
await c.close()
|
||||||
#What is the action of this alert?
|
|
||||||
Action = None
|
|
||||||
if x['messageType'] == 'Update':
|
|
||||||
Action = 'CON'
|
|
||||||
elif x['messageType'] == 'New':
|
|
||||||
Action = 'NEW'
|
|
||||||
|
|
||||||
#Fix description to replace new lines with space and add XML escape Chars. when needed
|
|
||||||
|
|
||||||
description = ' '.join(descriptionRaw.splitlines())
|
|
||||||
description = description.replace('&', '&')
|
|
||||||
description = description.replace('<', '<')
|
|
||||||
description = description.replace('>', '>')
|
|
||||||
description = description.replace('-', '')
|
|
||||||
description = description.replace(':', '')
|
|
||||||
|
|
||||||
#Is this alert urgent?
|
|
||||||
urgency ='piss'
|
|
||||||
if vocalCheck == 'TO_W' or vocalCheck == 'SV_W' or vocalCheck == 'FF_W':
|
|
||||||
urgency = 'BEUrgent'
|
|
||||||
else:
|
|
||||||
urgency = 'BERecord'
|
|
||||||
|
|
||||||
alertMsg = '<BERecord id="0000" locationKey="' + location + '_' + x['phenomena'] + '_' + x['significance'] + '_' + x['eventTrackingNumber'] + '_' + x['officeCode'] + '" isWxscan="0"><action>NOT_USED</action><BEHdr><bPIL>' + x['productIdentifier'] + '</bPIL><bWMOHdr>NOT_USED</bWMOHdr><bEvent><eActionCd eActionPriority="' + str(x['messageTypeCode']) + '">' + Action + '</eActionCd><eOfficeId eOfficeNm="' + x['officeName'] + '">' + x['officeCode'] + '</eOfficeId><ePhenom>' + x['phenomena'] + '</ePhenom><eSgnfcnc>' + x['significance'] + '</eSgnfcnc><eETN>' + x['eventTrackingNumber'] + '</eETN><eDesc>' + x['eventDescription'] + '</eDesc><eStTmUTC>NOT_USED</eStTmUTC><eEndTmUTC>' + EndTimeUTC + '</eEndTmUTC><eSvrty>' + str(x['severityCode']) + '</eSvrty><eTWCIId>NOT_USED</eTWCIId><eExpTmUTC>' + expireTimeUTC + '</eExpTmUTC></bEvent><bLocations><bLocCd bLoc="' + x['areaName'] + '" bLocTyp="' + locationType + '">' + location + '</bLocCd><bStCd bSt="' + x['adminDistrict'] + '">' + x['adminDistrictCode'] + '</bStCd><bUTCDiff>NOT_USED</bUTCDiff><bTzAbbrv>NOT_USED</bTzAbbrv><bCntryCd>NOT_USED</bCntryCd></bLocations><bSgmtChksum>' + x['identifier'] + '</bSgmtChksum><procTm>' + processTime + '</procTm></BEHdr><BEData><bIssueTmUTC>' + issueTimeUtc + '</bIssueTmUTC><bHdln><bHdlnTxt>' + x['headlineText'] + '</bHdlnTxt>' + vocalCode + '</bHdln><bParameter>NOT_USED</bParameter><bNarrTxt bNarrTxtLang="en-US"><bLn>' + description + '</bLn></bNarrTxt><bSrchRslt>NOT_USED</bSrchRslt></BEData><clientKey>' + location + '_' + x['phenomena'] + '_' + x['significance'] + '_' + x['eventTrackingNumber'] + '_' + x['officeCode'] + '</clientKey></BERecord>'
|
|
||||||
|
|
||||||
#Append BERecord
|
|
||||||
with open('./.temp/BERecord.xml', "a") as b:
|
|
||||||
b.write(alertMsg)
|
|
||||||
b.close()
|
|
||||||
|
|
||||||
#Add our alert to the manifest so we don't keep sending in the same alert every 60 seconds unless an update is issued.
|
|
||||||
with open('./.temp/alertmanifest.txt', "a") as c:
|
|
||||||
c.write('\n' + location + '_' + x['phenomena'] + '_' + x['significance'] + '_' + str(x['processTimeUTC']))
|
|
||||||
c.close()
|
|
||||||
|
|
||||||
|
|
||||||
# TODO: This should be converted into a function so it works better with async, that way we're not getting hung up on that time.sleep() call.
|
|
||||||
|
|
||||||
def makeRecord():
|
async def makeRecord():
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
global k
|
global k
|
||||||
with open("./.temp/BERecord.xml", 'a') as BERecord:
|
|
||||||
BERecord.write('<Data type="BERecord">')
|
|
||||||
BERecord.close()
|
|
||||||
|
|
||||||
for z in alertLocations:
|
|
||||||
getAlerts(z)
|
|
||||||
|
|
||||||
with open('./.temp/BERecord.xml', 'a') as BERecord:
|
# The BERecord XML doesn't need to be written if there's no alerts.
|
||||||
BERecord.write("</Data>")
|
|
||||||
BERecord.close()
|
|
||||||
|
|
||||||
dom = xml.dom.minidom.parse("./.temp/BERecord.xml")
|
|
||||||
pretty_xml_as_string = dom.toprettyxml(indent = " ")
|
|
||||||
|
|
||||||
with open("./.temp/BERecord.i2m", 'w') as h:
|
|
||||||
h.write(pretty_xml_as_string[23:])
|
|
||||||
h.close()
|
|
||||||
|
|
||||||
# If we don't need to send the i2 an alert, we don't need to gzip it.
|
|
||||||
if k > 0:
|
if k > 0:
|
||||||
|
async with aiofiles.open("./.temp/BERecord.xml", 'a') as BERecord:
|
||||||
|
await BERecord.write('<Data type="BERecord">')
|
||||||
|
await BERecord.close()
|
||||||
|
|
||||||
|
for z in alertLocations:
|
||||||
|
await getAlerts(z)
|
||||||
|
|
||||||
|
async with aiofiles.open('./.temp/BERecord.xml', 'a') as BERecord:
|
||||||
|
await BERecord.write("</Data>")
|
||||||
|
await BERecord.close()
|
||||||
|
|
||||||
|
dom = xml.dom.minidom.parse("./.temp/BERecord.xml")
|
||||||
|
pretty_xml_as_string = dom.toprettyxml(indent = " ")
|
||||||
|
|
||||||
|
async with aiofiles.open("./.temp/BERecord.i2m", 'w') as h:
|
||||||
|
await h.write(pretty_xml_as_string[23:])
|
||||||
|
await h.close()
|
||||||
|
|
||||||
l.info("Sending alert(s) to the IntelliStar 2!")
|
l.info("Sending alert(s) to the IntelliStar 2!")
|
||||||
with open("./.temp/BERecord.i2m", 'rb') as f_in:
|
with open("./.temp/BERecord.i2m", 'rb') as f_in:
|
||||||
with gzip.open("./.temp/BERecord.gz", 'wb') as f_out:
|
with gzip.open("./.temp/BERecord.gz", 'wb') as f_out:
|
||||||
@ -354,7 +360,7 @@ def makeRecord():
|
|||||||
bit.sendFile(files, commands, 1, 0)
|
bit.sendFile(files, commands, 1, 0)
|
||||||
os.remove(gZipFile)
|
os.remove(gZipFile)
|
||||||
k = 0
|
k = 0
|
||||||
|
|
||||||
os.remove("./.temp/BERecord.xml")
|
os.remove("./.temp/BERecord.xml")
|
||||||
os.remove("./.temp/BERecord.i2m")
|
os.remove("./.temp/BERecord.i2m")
|
||||||
|
|
@ -6,6 +6,7 @@ import os
|
|||||||
import shutil
|
import shutil
|
||||||
import xml.dom.minidom
|
import xml.dom.minidom
|
||||||
import logging,coloredlogs
|
import logging,coloredlogs
|
||||||
|
import aiohttp, aiofiles, asyncio
|
||||||
|
|
||||||
sys.path.append("./py2lib")
|
sys.path.append("./py2lib")
|
||||||
sys.path.append("./Util")
|
sys.path.append("./Util")
|
||||||
@ -30,14 +31,14 @@ l.debug(coopIds, geocodes)
|
|||||||
|
|
||||||
apiKey = '21d8a80b3d6b444998a80b3d6b1449d3'
|
apiKey = '21d8a80b3d6b444998a80b3d6b1449d3'
|
||||||
|
|
||||||
def getData(coopId, geocode):
|
async def getData(coopId, geocode):
|
||||||
fetchUrl = f"https://api.weather.com/v2/indices/breathing/daypart/7day?geocode={geocode}&language=en-US&format=xml&apiKey={apiKey}"
|
fetchUrl = f"https://api.weather.com/v2/indices/breathing/daypart/7day?geocode={geocode}&language=en-US&format=xml&apiKey={apiKey}"
|
||||||
|
data = ""
|
||||||
|
|
||||||
#Fetch data
|
#Fetch data
|
||||||
|
async with aiohttp.ClientSession() as s:
|
||||||
response = requests.get(fetchUrl)
|
async with s.get(fetchUrl) as r:
|
||||||
|
data = await r.text()
|
||||||
data = response.text
|
|
||||||
|
|
||||||
newData = data[63:-26]
|
newData = data[63:-26]
|
||||||
|
|
||||||
@ -45,32 +46,33 @@ def getData(coopId, geocode):
|
|||||||
#Write to .i2m file
|
#Write to .i2m file
|
||||||
i2Doc = '<Breathing id="000000000" locationKey="' + str(coopId) + '" isWxscan="0">' + '' + newData + '<clientKey>' + str(coopId) + '</clientKey></Breathing>'
|
i2Doc = '<Breathing id="000000000" locationKey="' + str(coopId) + '" isWxscan="0">' + '' + newData + '<clientKey>' + str(coopId) + '</clientKey></Breathing>'
|
||||||
|
|
||||||
f = open("./.temp/Breathing.i2m", "a")
|
async with aiofiles.open("./.temp/Breathing.i2m", "a") as f:
|
||||||
f.write(i2Doc)
|
await f.write(i2Doc)
|
||||||
f.close()
|
await f.close()
|
||||||
|
|
||||||
|
|
||||||
def makeDataFile():
|
async def makeDataFile():
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
l.info("Writing a Breathing forecast record.")
|
l.info("Writing a Breathing forecast record.")
|
||||||
header = '<Data type="Breathing">'
|
header = '<Data type="Breathing">'
|
||||||
footer = '</Data>'
|
footer = '</Data>'
|
||||||
|
|
||||||
with open("./.temp/Breathing.i2m", 'w') as doc:
|
async with aiofiles.open("./.temp/Breathing.i2m", 'w') as doc:
|
||||||
doc.write(header)
|
await doc.write(header)
|
||||||
|
|
||||||
for x, y in zip(coopIds, geocodes):
|
for x, y in zip(coopIds, geocodes):
|
||||||
getData(x, y)
|
await getData(x, y)
|
||||||
|
|
||||||
with open("./.temp/Breathing.i2m", 'a') as end:
|
async with aiofiles.open("./.temp/Breathing.i2m", 'a') as end:
|
||||||
end.write(footer)
|
await end.write(footer)
|
||||||
|
|
||||||
|
|
||||||
dom = xml.dom.minidom.parse("./.temp/Breathing.i2m")
|
dom = xml.dom.minidom.parse("./.temp/Breathing.i2m")
|
||||||
pretty_xml_as_string = dom.toprettyxml(indent = " ")
|
pretty_xml_as_string = dom.toprettyxml(indent = " ")
|
||||||
|
|
||||||
with open("./.temp/Breathing.i2m", "w") as g:
|
async with aiofiles.open("./.temp/Breathing.i2m", "w") as g:
|
||||||
g.write(pretty_xml_as_string[23:])
|
await g.write(pretty_xml_as_string[23:])
|
||||||
g.close()
|
await g.close()
|
||||||
|
|
||||||
files = []
|
files = []
|
||||||
commands = []
|
commands = []
|
||||||
|
@ -6,6 +6,7 @@ import os
|
|||||||
import shutil
|
import shutil
|
||||||
import xml.dom.minidom
|
import xml.dom.minidom
|
||||||
import logging,coloredlogs
|
import logging,coloredlogs
|
||||||
|
import aiohttp, aiofiles, asyncio
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
sys.path.append("./py2lib")
|
sys.path.append("./py2lib")
|
||||||
@ -34,50 +35,53 @@ for i in MPC.getMetroCities():
|
|||||||
|
|
||||||
apiKey = '21d8a80b3d6b444998a80b3d6b1449d3'
|
apiKey = '21d8a80b3d6b444998a80b3d6b1449d3'
|
||||||
|
|
||||||
def getData(tecci, zipCode):
|
async def getData(tecci, zipCode):
|
||||||
|
l.debug('Gathering data for location id ' + tecci)
|
||||||
fetchUrl = 'https://api.weather.com/v1/location/' + zipCode + ':4:US/observations/current.xml?language=en-US&units=e&apiKey=' + apiKey
|
fetchUrl = 'https://api.weather.com/v1/location/' + zipCode + ':4:US/observations/current.xml?language=en-US&units=e&apiKey=' + apiKey
|
||||||
|
data = ""
|
||||||
|
|
||||||
#Fetch data
|
async with aiohttp.ClientSession() as s:
|
||||||
|
async with s.get(fetchUrl) as r:
|
||||||
response = requests.get(fetchUrl)
|
data = await r.text()
|
||||||
|
|
||||||
data = response.text
|
|
||||||
|
|
||||||
newData = data[67:-30]
|
newData = data[67:-30]
|
||||||
|
|
||||||
l.debug('Gathering data for location id ' + tecci)
|
|
||||||
#Write to .i2m file
|
#Write to .i2m file
|
||||||
i2Doc = '<CurrentObservations id="000000000" locationKey="' + str(tecci) + '" isWxscan="0">' + '' + newData + '<clientKey>' + str(tecci) + '</clientKey></CurrentObservations>'
|
i2Doc = '<CurrentObservations id="000000000" locationKey="' + str(tecci) + '" isWxscan="0">' + '' + newData + '<clientKey>' + str(tecci) + '</clientKey></CurrentObservations>'
|
||||||
|
async with aiofiles.open("./.temp/CurrentObservations.i2m", 'a') as f:
|
||||||
|
await f.write(i2Doc)
|
||||||
|
await f.close()
|
||||||
|
|
||||||
|
|
||||||
f = open("./.temp/CurrentObservations.i2m", "a")
|
async def makeDataFile():
|
||||||
f.write(i2Doc)
|
loop = asyncio.get_running_loop()
|
||||||
f.close()
|
|
||||||
|
|
||||||
def makeDataFile():
|
|
||||||
l.info("Writing a CurrentObservations record.")
|
l.info("Writing a CurrentObservations record.")
|
||||||
header = '<Data type="CurrentObservations">'
|
header = '<Data type="CurrentObservations">'
|
||||||
footer = '</Data>'
|
footer = '</Data>'
|
||||||
|
|
||||||
with open("./.temp/CurrentObservations.i2m", 'w') as doc:
|
async with aiofiles.open("./.temp/CurrentObservations.i2m", 'w') as doc:
|
||||||
doc.write(header)
|
await doc.write(header)
|
||||||
|
|
||||||
for x, y in zip(tecciId, zipCodes):
|
for x, y in zip(tecciId, zipCodes):
|
||||||
getData(x, y)
|
await getData(x, y)
|
||||||
|
|
||||||
with open("./.temp/CurrentObservations.i2m", 'a') as end:
|
async with aiofiles.open("./.temp/CurrentObservations.i2m", 'a') as end:
|
||||||
end.write(footer)
|
await end.write(footer)
|
||||||
|
|
||||||
dom = xml.dom.minidom.parse("./.temp/CurrentObservations.i2m")
|
dom = xml.dom.minidom.parse("./.temp/CurrentObservations.i2m")
|
||||||
pretty_xml_as_string = dom.toprettyxml(indent = " ")
|
pretty_xml_as_string = dom.toprettyxml(indent = " ")
|
||||||
|
|
||||||
with open("./.temp/CurrentObservations.i2m", "w") as g:
|
async with aiofiles.open("./.temp/CurrentObservations.i2m", "w") as g:
|
||||||
g.write(pretty_xml_as_string[23:])
|
await g.write(pretty_xml_as_string[23:])
|
||||||
g.close()
|
await g.close()
|
||||||
|
|
||||||
files = []
|
files = []
|
||||||
commands = []
|
commands = []
|
||||||
|
|
||||||
|
"""
|
||||||
|
TODO: This can be ran in a seperate thread using loop.run_in_executor() according to the python discord.
|
||||||
|
! This should probably be implemented ASAP.
|
||||||
|
"""
|
||||||
with open("./.temp/CurrentObservations.i2m", 'rb') as f_in:
|
with open("./.temp/CurrentObservations.i2m", 'rb') as f_in:
|
||||||
with gzip.open("./.temp/CurrentObservations.gz", 'wb') as f_out:
|
with gzip.open("./.temp/CurrentObservations.gz", 'wb') as f_out:
|
||||||
shutil.copyfileobj(f_in, f_out)
|
shutil.copyfileobj(f_in, f_out)
|
||||||
@ -88,7 +92,7 @@ def makeDataFile():
|
|||||||
command = commands.append('<MSG><Exec workRequest="storeData(File={0},QGROUP=__CurrentObservations__,Feed=CurrentObservations)" /><GzipCompressedMsg fname="CurrentObservations" /></MSG>')
|
command = commands.append('<MSG><Exec workRequest="storeData(File={0},QGROUP=__CurrentObservations__,Feed=CurrentObservations)" /><GzipCompressedMsg fname="CurrentObservations" /></MSG>')
|
||||||
numFiles = len(files)
|
numFiles = len(files)
|
||||||
|
|
||||||
bit.sendFile(files, commands, numFiles, 0)
|
await loop.run_in_executor(bit.sendFile(files, commands, numFiles, 0))
|
||||||
|
|
||||||
os.remove("./.temp/CurrentObservations.i2m")
|
os.remove("./.temp/CurrentObservations.i2m")
|
||||||
os.remove("./.temp/CurrentObservations.gz")
|
os.remove("./.temp/CurrentObservations.gz")
|
||||||
|
@ -6,6 +6,7 @@ import os
|
|||||||
import shutil
|
import shutil
|
||||||
import xml.dom.minidom
|
import xml.dom.minidom
|
||||||
import logging,coloredlogs
|
import logging,coloredlogs
|
||||||
|
import aiohttp, aiofiles, asyncio
|
||||||
|
|
||||||
sys.path.append("./py2lib")
|
sys.path.append("./py2lib")
|
||||||
sys.path.append("./Util")
|
sys.path.append("./Util")
|
||||||
@ -32,14 +33,13 @@ for i in MPC.getMetroCities():
|
|||||||
|
|
||||||
apiKey = '21d8a80b3d6b444998a80b3d6b1449d3'
|
apiKey = '21d8a80b3d6b444998a80b3d6b1449d3'
|
||||||
|
|
||||||
def getData(tecci, zipCode):
|
async def getData(tecci, zipCode):
|
||||||
fetchUrl = 'https://api.weather.com/v1/location/' + zipCode + ':4:US/forecast/daily/7day.xml?language=en-US&units=e&apiKey=' + apiKey
|
fetchUrl = 'https://api.weather.com/v1/location/' + zipCode + ':4:US/forecast/daily/7day.xml?language=en-US&units=e&apiKey=' + apiKey
|
||||||
|
data = ""
|
||||||
|
|
||||||
#Fetch data
|
async with aiohttp.ClientSession() as s:
|
||||||
|
async with s.get(fetchUrl) as r:
|
||||||
response = requests.get(fetchUrl)
|
data = await r.text()
|
||||||
|
|
||||||
data = response.text
|
|
||||||
|
|
||||||
newData = data[61:-24]
|
newData = data[61:-24]
|
||||||
|
|
||||||
@ -47,32 +47,33 @@ def getData(tecci, zipCode):
|
|||||||
#Write to .i2m file
|
#Write to .i2m file
|
||||||
i2Doc = '<DailyForecast id="000000000" locationKey="' + str(tecci) + '" isWxscan="0">' + '' + newData + '<clientKey>' + str(tecci) + '</clientKey></DailyForecast>'
|
i2Doc = '<DailyForecast id="000000000" locationKey="' + str(tecci) + '" isWxscan="0">' + '' + newData + '<clientKey>' + str(tecci) + '</clientKey></DailyForecast>'
|
||||||
|
|
||||||
f = open("./.temp/DailyForecast.i2m", "a")
|
async with aiofiles.open('./.temp/DailyForecast.i2m', 'a') as f:
|
||||||
f.write(i2Doc)
|
await f.write(i2Doc)
|
||||||
f.close()
|
await f.close()
|
||||||
|
|
||||||
|
|
||||||
def makeDataFile():
|
async def makeDataFile():
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
l.info("Writing a DailyForecast record.")
|
l.info("Writing a DailyForecast record.")
|
||||||
header = '<Data type="DailyForecast">'
|
header = '<Data type="DailyForecast">'
|
||||||
footer = '</Data>'
|
footer = '</Data>'
|
||||||
|
|
||||||
with open("./.temp/DailyForecast.i2m", 'w') as doc:
|
async with aiofiles.open("./.temp/DailyForecast.i2m", 'w') as doc:
|
||||||
doc.write(header)
|
await doc.write(header)
|
||||||
|
|
||||||
for x, y in zip(tecciId, zipCodes):
|
for x, y in zip(tecciId, zipCodes):
|
||||||
getData(x, y)
|
await getData(x, y)
|
||||||
|
|
||||||
with open("./.temp/DailyForecast.i2m", 'a') as end:
|
async with aiofiles.open("./.temp/DailyForecast.i2m", 'a') as end:
|
||||||
end.write(footer)
|
await end.write(footer)
|
||||||
|
|
||||||
|
|
||||||
dom = xml.dom.minidom.parse("./.temp/DailyForecast.i2m")
|
dom = xml.dom.minidom.parse("./.temp/DailyForecast.i2m")
|
||||||
pretty_xml_as_string = dom.toprettyxml(indent = " ")
|
pretty_xml_as_string = dom.toprettyxml(indent = " ")
|
||||||
|
|
||||||
with open("./.temp/DailyForecast.i2m", "w") as g:
|
async with aiofiles.open("./.temp/DailyForecast.i2m", "w") as g:
|
||||||
g.write(pretty_xml_as_string[23:])
|
await g.write(pretty_xml_as_string[23:])
|
||||||
g.close()
|
await g.close()
|
||||||
|
|
||||||
files = []
|
files = []
|
||||||
commands = []
|
commands = []
|
||||||
|
@ -7,6 +7,7 @@ import records.LFRecord as LFR
|
|||||||
import gzip
|
import gzip
|
||||||
from os import remove
|
from os import remove
|
||||||
import xml.dom.minidom
|
import xml.dom.minidom
|
||||||
|
import aiohttp, aiofiles, asyncio
|
||||||
|
|
||||||
l = logging.getLogger(__name__)
|
l = logging.getLogger(__name__)
|
||||||
coloredlogs.install()
|
coloredlogs.install()
|
||||||
@ -20,46 +21,49 @@ for i in MPC.getPrimaryLocations():
|
|||||||
|
|
||||||
apiKey = "21d8a80b3d6b444998a80b3d6b1449d3"
|
apiKey = "21d8a80b3d6b444998a80b3d6b1449d3"
|
||||||
|
|
||||||
def getData(coopId, geocode):
|
async def getData(coopId, geocode):
|
||||||
fetchUrl = f"https://api.weather.com/v2/indices/heatCool/daypart/7day?geocode={geocode}&language=en-US&format=xml&apiKey={apiKey}"
|
fetchUrl = f"https://api.weather.com/v2/indices/heatCool/daypart/7day?geocode={geocode}&language=en-US&format=xml&apiKey={apiKey}"
|
||||||
|
data = ""
|
||||||
res = requests.get(fetchUrl)
|
|
||||||
|
|
||||||
if res.status_code != 200:
|
|
||||||
l.error("DO NOT REPORT THE ERROR BELOW")
|
|
||||||
l.error(f"Failed to write HeatingAndCooling record -- Status code {res.status_code}")
|
|
||||||
return
|
|
||||||
|
|
||||||
data = res.text
|
async with aiohttp.ClientSession() as s:
|
||||||
|
async with s.get(fetchUrl) as r:
|
||||||
|
if r.status != 200:
|
||||||
|
l.error(f"Failed to write HeatingAndCooling record -- Status code {r.status}")
|
||||||
|
return
|
||||||
|
|
||||||
|
data = await r.text()
|
||||||
|
|
||||||
|
# data = res.text
|
||||||
newData = data[63:-26]
|
newData = data[63:-26]
|
||||||
|
|
||||||
i2Doc = f'\n <HeatingAndCooling id="000000000" locationKey="{coopId}" isWxScan="0">\n {newData}\n <clientKey>{coopId}</clientKey>\n </HeatingAndCooling>'
|
i2Doc = f'\n <HeatingAndCooling id="000000000" locationKey="{coopId}" isWxScan="0">\n {newData}\n <clientKey>{coopId}</clientKey>\n </HeatingAndCooling>'
|
||||||
|
|
||||||
f = open('./.temp/HeatingAndCooling.i2m', 'a')
|
async with aiofiles.open('./.temp/HeatingAndCooling.i2m', 'a') as f:
|
||||||
f.write(i2Doc)
|
await f.write(i2Doc)
|
||||||
f.close()
|
await f.close()
|
||||||
|
|
||||||
def makeRecord():
|
async def makeRecord():
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
l.info("Writing HeatingAndCooling record.")
|
l.info("Writing HeatingAndCooling record.")
|
||||||
|
|
||||||
header = '<Data type="HeatingAndCooling">'
|
header = '<Data type="HeatingAndCooling">'
|
||||||
footer = '</Data>'
|
footer = '</Data>'
|
||||||
|
|
||||||
with open('./.temp/HeatingAndCooling.i2m', 'a') as doc:
|
async with aiofiles.open('./.temp/HeatingAndCooling.i2m', 'a') as doc:
|
||||||
doc.write(header)
|
await doc.write(header)
|
||||||
|
|
||||||
for (x, y) in zip(coopIds, geocodes):
|
for (x, y) in zip(coopIds, geocodes):
|
||||||
getData(x,y)
|
await getData(x,y)
|
||||||
|
|
||||||
with open('./.temp/HeatingAndCooling.i2m', 'a') as end:
|
async with aiofiles.open('./.temp/HeatingAndCooling.i2m', 'a') as end:
|
||||||
end.write(footer)
|
await end.write(footer)
|
||||||
|
|
||||||
dom = xml.dom.minidom.parse('./.temp/HeatingAndCooling.i2m')
|
dom = xml.dom.minidom.parse('./.temp/HeatingAndCooling.i2m')
|
||||||
xmlPretty = dom.toprettyxml(indent= " ")
|
xmlPretty = dom.toprettyxml(indent= " ")
|
||||||
|
|
||||||
with open('./.temp/HeatingAndCooling.i2m', 'w') as g:
|
async with aiofiles.open('./.temp/HeatingAndCooling.i2m', 'w') as g:
|
||||||
g.write(xmlPretty[23:])
|
await g.write(xmlPretty[23:])
|
||||||
g.close()
|
await g.close()
|
||||||
|
|
||||||
|
|
||||||
# Compresss i2m to gzip
|
# Compresss i2m to gzip
|
||||||
|
@ -5,6 +5,7 @@ import os
|
|||||||
import shutil
|
import shutil
|
||||||
import xml.dom.minidom
|
import xml.dom.minidom
|
||||||
import logging,coloredlogs
|
import logging,coloredlogs
|
||||||
|
import aiohttp, aiofiles, asyncio, asyncio
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
sys.path.append("./py2lib")
|
sys.path.append("./py2lib")
|
||||||
@ -32,46 +33,49 @@ for i in MPC.getMetroCities():
|
|||||||
|
|
||||||
apiKey = '21d8a80b3d6b444998a80b3d6b1449d3'
|
apiKey = '21d8a80b3d6b444998a80b3d6b1449d3'
|
||||||
|
|
||||||
def getData(tecci, zipCode):
|
async def getData(tecci, zipCode):
|
||||||
|
l.debug('Gathering data for location id ' + tecci)
|
||||||
fetchUrl = 'https://api.weather.com/v1/location/' + zipCode + ':4:US/forecast/hourly/360hour.xml?language=en-US&units=e&apiKey=' + apiKey
|
fetchUrl = 'https://api.weather.com/v1/location/' + zipCode + ':4:US/forecast/hourly/360hour.xml?language=en-US&units=e&apiKey=' + apiKey
|
||||||
|
data = ""
|
||||||
|
|
||||||
#Fetch data
|
#Fetch data
|
||||||
|
async with aiohttp.ClientSession() as s:
|
||||||
response = requests.get(fetchUrl)
|
async with s.get(fetchUrl) as r:
|
||||||
|
data = await r.text()
|
||||||
data = response.text
|
|
||||||
|
|
||||||
newData = data[48:-11]
|
newData = data[48:-11]
|
||||||
|
|
||||||
l.debug('Gathering data for location id ' + tecci)
|
|
||||||
#Write to .i2m file
|
#Write to .i2m file
|
||||||
i2Doc = '<HourlyForecast id="000000000" locationKey="' + str(tecci) + '" isWxscan="0">' + '' + newData + '<clientKey>' + str(tecci) + '</clientKey></HourlyForecast>'
|
i2Doc = '<HourlyForecast id="000000000" locationKey="' + str(tecci) + '" isWxscan="0">' + '' + newData + '<clientKey>' + str(tecci) + '</clientKey></HourlyForecast>'
|
||||||
|
|
||||||
f = open("./.temp/HourlyForecast.i2m", "a")
|
async with aiofiles.open('./.temp/HourlyForecast.i2m', 'a') as f:
|
||||||
f.write(i2Doc)
|
await f.write(i2Doc)
|
||||||
f.close()
|
await f.close()
|
||||||
|
|
||||||
def makeDataFile():
|
|
||||||
|
async def makeDataFile():
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
l.info("Writing an HourlyForecast record.")
|
l.info("Writing an HourlyForecast record.")
|
||||||
header = '<Data type="HourlyForecast">'
|
header = '<Data type="HourlyForecast">'
|
||||||
footer = '</Data>'
|
footer = '</Data>'
|
||||||
|
|
||||||
with open("./.temp/HourlyForecast.i2m", 'w') as doc:
|
async with aiofiles.open("./.temp/HourlyForecast.i2m", 'w') as doc:
|
||||||
doc.write(header)
|
await doc.write(header)
|
||||||
|
|
||||||
|
|
||||||
for x, y in zip(tecciId, zipCodes):
|
for x, y in zip(tecciId, zipCodes):
|
||||||
getData(x, y)
|
await getData(x, y)
|
||||||
|
|
||||||
with open("./.temp/HourlyForecast.i2m", 'a') as end:
|
async with aiofiles.open("./.temp/HourlyForecast.i2m", 'a') as end:
|
||||||
end.write(footer)
|
await end.write(footer)
|
||||||
|
|
||||||
|
|
||||||
dom = xml.dom.minidom.parse("./.temp/HourlyForecast.i2m")
|
dom = xml.dom.minidom.parse("./.temp/HourlyForecast.i2m")
|
||||||
pretty_xml_as_string = dom.toprettyxml(indent = " ")
|
pretty_xml_as_string = dom.toprettyxml(indent = " ")
|
||||||
|
|
||||||
with open("./.temp/HourlyForecast.i2m", "w") as g:
|
async with aiofiles.open("./.temp/HourlyForecast.i2m", "w") as g:
|
||||||
g.write(pretty_xml_as_string[23:])
|
await g.write(pretty_xml_as_string[23:])
|
||||||
g.close()
|
await g.close()
|
||||||
|
|
||||||
files = []
|
files = []
|
||||||
commands = []
|
commands = []
|
||||||
|
@ -7,6 +7,7 @@ import records.LFRecord as LFR
|
|||||||
import gzip
|
import gzip
|
||||||
from os import remove
|
from os import remove
|
||||||
import xml.dom.minidom
|
import xml.dom.minidom
|
||||||
|
import aiohttp, aiofiles, asyncio
|
||||||
|
|
||||||
l = logging.getLogger(__name__)
|
l = logging.getLogger(__name__)
|
||||||
coloredlogs.install()
|
coloredlogs.install()
|
||||||
@ -20,46 +21,49 @@ for i in MPC.getPrimaryLocations():
|
|||||||
|
|
||||||
apiKey = "21d8a80b3d6b444998a80b3d6b1449d3"
|
apiKey = "21d8a80b3d6b444998a80b3d6b1449d3"
|
||||||
|
|
||||||
def getData(coopId, geocode):
|
async def getData(coopId, geocode):
|
||||||
fetchUrl = f"https://api.weather.com/v2/indices/mosquito/daily/7day?geocode={geocode}&language=en-US&format=xml&apiKey={apiKey}"
|
fetchUrl = f"https://api.weather.com/v2/indices/mosquito/daily/7day?geocode={geocode}&language=en-US&format=xml&apiKey={apiKey}"
|
||||||
|
data = ""
|
||||||
|
|
||||||
|
async with aiohttp.ClientSession() as s:
|
||||||
|
async with s.get(fetchUrl) as r:
|
||||||
|
if r.status != 200:
|
||||||
|
l.error(f"Failed to write MosquitoActivity record -- status code {r.status}")
|
||||||
|
return
|
||||||
|
|
||||||
|
data = await r.text()
|
||||||
|
|
||||||
res = requests.get(fetchUrl)
|
|
||||||
|
|
||||||
if res.status_code != 200:
|
|
||||||
l.error("DO NOT REPORT THE ERROR BELOW")
|
|
||||||
l.error(f"Failed to write MosquitoActivity record -- Status code {res.status_code}")
|
|
||||||
return
|
|
||||||
|
|
||||||
data = res.text
|
|
||||||
newData = data[63:-26]
|
newData = data[63:-26]
|
||||||
|
|
||||||
i2Doc = f'\n <MosquitoActivity id="000000000" locationKey="{coopId}" isWxScan="0">\n {newData}\n <clientKey>{coopId}</clientKey>\n </MosquitoActivity>'
|
i2Doc = f'\n <MosquitoActivity id="000000000" locationKey="{coopId}" isWxScan="0">\n {newData}\n <clientKey>{coopId}</clientKey>\n </MosquitoActivity>'
|
||||||
|
|
||||||
f = open('./.temp/MosquitoActivity.i2m', 'a')
|
async with aiofiles.open('./.temp/MosquitoActivity.i2m', 'a') as f:
|
||||||
f.write(i2Doc)
|
await f.write(i2Doc)
|
||||||
f.close()
|
await f.close()
|
||||||
|
|
||||||
def makeRecord():
|
async def makeRecord():
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
l.info("Writing MosquitoActivity record.")
|
l.info("Writing MosquitoActivity record.")
|
||||||
|
|
||||||
header = '<Data type="MosquitoActivity">'
|
header = '<Data type="MosquitoActivity">'
|
||||||
footer = '</Data>'
|
footer = '</Data>'
|
||||||
|
|
||||||
with open('./.temp/MosquitoActivity.i2m', 'a') as doc:
|
async with aiofiles.open('./.temp/MosquitoActivity.i2m', 'a') as doc:
|
||||||
doc.write(header)
|
await doc.write(header)
|
||||||
|
|
||||||
for (x, y) in zip(coopIds, geocodes):
|
for (x, y) in zip(coopIds, geocodes):
|
||||||
getData(x,y)
|
await getData(x,y)
|
||||||
|
|
||||||
with open('./.temp/MosquitoActivity.i2m', 'a') as end:
|
async with aiofiles.open('./.temp/MosquitoActivity.i2m', 'a') as end:
|
||||||
end.write(footer)
|
await end.write(footer)
|
||||||
|
|
||||||
dom = xml.dom.minidom.parse('./.temp/MosquitoActivity.i2m')
|
dom = xml.dom.minidom.parse('./.temp/MosquitoActivity.i2m')
|
||||||
xmlPretty = dom.toprettyxml(indent= " ")
|
xmlPretty = dom.toprettyxml(indent= " ")
|
||||||
|
|
||||||
with open('./.temp/MosquitoActivity.i2m', 'w') as g:
|
async with aiofiles.open('./.temp/MosquitoActivity.i2m', 'w') as g:
|
||||||
g.write(xmlPretty[23:])
|
await g.write(xmlPretty[23:])
|
||||||
g.close()
|
await g.close()
|
||||||
|
|
||||||
|
|
||||||
# Compresss i2m to gzip
|
# Compresss i2m to gzip
|
||||||
|
@ -6,6 +6,7 @@ import os
|
|||||||
import shutil
|
import shutil
|
||||||
import xml.dom.minidom
|
import xml.dom.minidom
|
||||||
import logging, coloredlogs
|
import logging, coloredlogs
|
||||||
|
import aiohttp, aiofiles, asyncio
|
||||||
|
|
||||||
sys.path.append("./py2lib")
|
sys.path.append("./py2lib")
|
||||||
sys.path.append("./Util")
|
sys.path.append("./Util")
|
||||||
@ -31,14 +32,13 @@ l.debug(pollenIds, geocodes)
|
|||||||
|
|
||||||
apiKey = '21d8a80b3d6b444998a80b3d6b1449d3'
|
apiKey = '21d8a80b3d6b444998a80b3d6b1449d3'
|
||||||
|
|
||||||
def getData(pollenId, geocode):
|
async def getData(pollenId, geocode):
|
||||||
fetchUrl = f"https://api.weather.com/v2/indices/pollen/daypart/7day?geocode={geocode}&language=en-US&format=xml&apiKey={apiKey}"
|
fetchUrl = f"https://api.weather.com/v2/indices/pollen/daypart/7day?geocode={geocode}&language=en-US&format=xml&apiKey={apiKey}"
|
||||||
|
data = ""
|
||||||
#Fetch data
|
#Fetch data
|
||||||
|
async with aiohttp.ClientSession() as s:
|
||||||
response = requests.get(fetchUrl)
|
async with s.get(fetchUrl) as r:
|
||||||
|
data = await r.text()
|
||||||
data = response.text
|
|
||||||
|
|
||||||
newData = data[63:-26]
|
newData = data[63:-26]
|
||||||
|
|
||||||
@ -46,32 +46,33 @@ def getData(pollenId, geocode):
|
|||||||
#Write to .i2m file
|
#Write to .i2m file
|
||||||
i2Doc = '<PollenForecast id="000000000" locationKey="' + str(pollenId) + '" isWxscan="0">' + '' + newData + '<clientKey>' + str(pollenId) + '</clientKey></PollenForecast>'
|
i2Doc = '<PollenForecast id="000000000" locationKey="' + str(pollenId) + '" isWxscan="0">' + '' + newData + '<clientKey>' + str(pollenId) + '</clientKey></PollenForecast>'
|
||||||
|
|
||||||
f = open("./.temp/PollenForecast.i2m", "a")
|
async with aiofiles.open("./.temp/PollenForecast.i2m", "a") as f:
|
||||||
f.write(i2Doc)
|
await f.write(i2Doc)
|
||||||
f.close()
|
await f.close()
|
||||||
|
|
||||||
|
|
||||||
def makeDataFile():
|
async def makeDataFile():
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
l.info("Writing a PollenForecast record.")
|
l.info("Writing a PollenForecast record.")
|
||||||
header = '<Data type="PollenForecast">'
|
header = '<Data type="PollenForecast">'
|
||||||
footer = '</Data>'
|
footer = '</Data>'
|
||||||
|
|
||||||
with open("./.temp/PollenForecast.i2m", 'w') as doc:
|
async with aiofiles.open("./.temp/PollenForecast.i2m", 'w') as doc:
|
||||||
doc.write(header)
|
await doc.write(header)
|
||||||
|
|
||||||
for x, y in zip(pollenIds, geocodes):
|
for x, y in zip(pollenIds, geocodes):
|
||||||
getData(x, y)
|
await getData(x, y)
|
||||||
|
|
||||||
with open("./.temp/PollenForecast.i2m", 'a') as end:
|
async with aiofiles.open("./.temp/PollenForecast.i2m", 'a') as end:
|
||||||
end.write(footer)
|
await end.write(footer)
|
||||||
|
|
||||||
|
|
||||||
dom = xml.dom.minidom.parse("./.temp/PollenForecast.i2m")
|
dom = xml.dom.minidom.parse("./.temp/PollenForecast.i2m")
|
||||||
pretty_xml_as_string = dom.toprettyxml(indent = " ")
|
pretty_xml_as_string = dom.toprettyxml(indent = " ")
|
||||||
|
|
||||||
with open("./.temp/PollenForecast.i2m", "w") as g:
|
async with aiofiles.open("./.temp/PollenForecast.i2m", "w") as g:
|
||||||
g.write(pretty_xml_as_string[23:])
|
await g.write(pretty_xml_as_string[23:])
|
||||||
g.close()
|
await g.close()
|
||||||
|
|
||||||
files = []
|
files = []
|
||||||
commands = []
|
commands = []
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import shutil
|
import shutil
|
||||||
from xmlrpc.client import DateTime
|
|
||||||
import requests
|
|
||||||
import logging,coloredlogs
|
import logging,coloredlogs
|
||||||
import datetime
|
import datetime
|
||||||
from py2Lib import bit
|
from py2Lib import bit
|
||||||
@ -9,6 +7,7 @@ import records.LFRecord as LFR
|
|||||||
import gzip
|
import gzip
|
||||||
from os import remove
|
from os import remove
|
||||||
import xml.dom.minidom
|
import xml.dom.minidom
|
||||||
|
import aiohttp, aiofiles, asyncio
|
||||||
|
|
||||||
l = logging.getLogger(__name__)
|
l = logging.getLogger(__name__)
|
||||||
coloredlogs.install()
|
coloredlogs.install()
|
||||||
@ -22,31 +21,34 @@ for i in MPC.getTideStations():
|
|||||||
|
|
||||||
apiKey = "21d8a80b3d6b444998a80b3d6b1449d3"
|
apiKey = "21d8a80b3d6b444998a80b3d6b1449d3"
|
||||||
|
|
||||||
def getData(tideStation, geocode):
|
async def getData(tideStation, geocode):
|
||||||
today = datetime.date.today()
|
today = datetime.date.today()
|
||||||
startDate = today.strftime('%Y%m%d')
|
startDate = today.strftime('%Y%m%d')
|
||||||
endDate_unformatted = datetime.datetime.strptime(startDate, '%Y%m%d') + datetime.timedelta(days=5)
|
endDate_unformatted = datetime.datetime.strptime(startDate, '%Y%m%d') + datetime.timedelta(days=5)
|
||||||
endDate = endDate_unformatted.strftime('%Y%m%d')
|
endDate = endDate_unformatted.strftime('%Y%m%d')
|
||||||
|
data = ""
|
||||||
|
|
||||||
fetchUrl = f"https://api.weather.com/v1/geocode/{geocode}/forecast/tides.xml?language=en-US&units=e&startDate={startDate}&endDate={endDate}&apiKey={apiKey}"
|
fetchUrl = f"https://api.weather.com/v1/geocode/{geocode}/forecast/tides.xml?language=en-US&units=e&startDate={startDate}&endDate={endDate}&apiKey={apiKey}"
|
||||||
|
|
||||||
res = requests.get(fetchUrl)
|
async with aiohttp.ClientSession() as s:
|
||||||
|
async with s.get(fetchUrl) as r:
|
||||||
|
if r.status != 200:
|
||||||
|
l.error(f"Failed to write TideForecast -- status code {r.status}")
|
||||||
|
return
|
||||||
|
|
||||||
|
data = await r.text()
|
||||||
|
|
||||||
|
|
||||||
if res.status_code != 200:
|
|
||||||
l.error("DO NOT REPORT THE ERROR BELOW")
|
|
||||||
l.error(f"Failed to write TidesForecast record -- Status code {res.status_code}")
|
|
||||||
return
|
|
||||||
|
|
||||||
data = res.text
|
|
||||||
newData = data[53:-16]
|
newData = data[53:-16]
|
||||||
|
|
||||||
i2Doc = f'\n <TidesForecast id="000000000" locationKey="{tideStation}" isWxScan="0">\n {newData}\n <clientKey>{tideStation}</clientKey>\n </TidesForecast>'
|
i2Doc = f'\n <TidesForecast id="000000000" locationKey="{tideStation}" isWxScan="0">\n {newData}\n <clientKey>{tideStation}</clientKey>\n </TidesForecast>'
|
||||||
|
|
||||||
f = open('./.temp/TidesForecast.i2m', 'a')
|
async with aiofiles.open('./.temp/TidesForecast.i2m', 'a') as f:
|
||||||
f.write(i2Doc)
|
await f.write(i2Doc)
|
||||||
f.close()
|
await f.close()
|
||||||
|
|
||||||
def makeRecord():
|
async def makeRecord():
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
if len(tideStations) < 1:
|
if len(tideStations) < 1:
|
||||||
l.debug("Skipping TidesForecast -- No locations.")
|
l.debug("Skipping TidesForecast -- No locations.")
|
||||||
return
|
return
|
||||||
@ -56,21 +58,21 @@ def makeRecord():
|
|||||||
header = '<Data type="TidesForecast">'
|
header = '<Data type="TidesForecast">'
|
||||||
footer = '</Data>'
|
footer = '</Data>'
|
||||||
|
|
||||||
with open('./.temp/TidesForecast.i2m', 'a') as doc:
|
async with aiofiles.open('./.temp/TidesForecast.i2m', 'a') as doc:
|
||||||
doc.write(header)
|
await doc.write(header)
|
||||||
|
|
||||||
for (x, y) in zip(tideStations, geocodes):
|
for (x, y) in zip(tideStations, geocodes):
|
||||||
getData(x,y)
|
await getData(x,y)
|
||||||
|
|
||||||
with open('./.temp/TidesForecast.i2m', 'a') as end:
|
async with aiofiles.open('./.temp/TidesForecast.i2m', 'a') as end:
|
||||||
end.write(footer)
|
await end.write(footer)
|
||||||
|
|
||||||
dom = xml.dom.minidom.parse('./.temp/TidesForecast.i2m')
|
dom = xml.dom.minidom.parse('./.temp/TidesForecast.i2m')
|
||||||
xmlPretty = dom.toprettyxml(indent= " ")
|
xmlPretty = dom.toprettyxml(indent= " ")
|
||||||
|
|
||||||
with open('./.temp/TidesForecast.i2m', 'w') as g:
|
async with aiofiles.open('./.temp/TidesForecast.i2m', 'w') as g:
|
||||||
g.write(xmlPretty[23:])
|
await g.write(xmlPretty[23:])
|
||||||
g.close()
|
await g.close()
|
||||||
|
|
||||||
|
|
||||||
# Compresss i2m to gzip
|
# Compresss i2m to gzip
|
||||||
|
@ -7,6 +7,7 @@ import records.LFRecord as LFR
|
|||||||
import gzip
|
import gzip
|
||||||
from os import remove
|
from os import remove
|
||||||
import xml.dom.minidom
|
import xml.dom.minidom
|
||||||
|
import aiohttp, aiofiles, asyncio
|
||||||
|
|
||||||
l = logging.getLogger(__name__)
|
l = logging.getLogger(__name__)
|
||||||
coloredlogs.install()
|
coloredlogs.install()
|
||||||
@ -20,46 +21,48 @@ for i in MPC.getPrimaryLocations():
|
|||||||
|
|
||||||
apiKey = "21d8a80b3d6b444998a80b3d6b1449d3"
|
apiKey = "21d8a80b3d6b444998a80b3d6b1449d3"
|
||||||
|
|
||||||
def getData(coopId, geocode):
|
async def getData(coopId, geocode):
|
||||||
fetchUrl = f"https://api.weather.com/v2/indices/wateringNeeds/daypart/7day?geocode={geocode}&language=en-US&format=xml&apiKey={apiKey}"
|
fetchUrl = f"https://api.weather.com/v2/indices/wateringNeeds/daypart/7day?geocode={geocode}&language=en-US&format=xml&apiKey={apiKey}"
|
||||||
|
data = ""
|
||||||
res = requests.get(fetchUrl)
|
|
||||||
|
async with aiohttp.ClientSession() as s:
|
||||||
if res.status_code != 200:
|
async with s.get(fetchUrl) as r:
|
||||||
l.error("DO NOT REPORT THE ERROR BELOW")
|
if r.status != 200:
|
||||||
l.error(f"Failed to write WateringNeeds record -- Status code {res.status_code}")
|
l.error(f"Failed to WateringNeeds -- status code {r.status}")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
data = await r.text()
|
||||||
|
|
||||||
data = res.text
|
|
||||||
newData = data[63:-26]
|
newData = data[63:-26]
|
||||||
|
|
||||||
i2Doc = f'\n <WateringNeeds id="000000000" locationKey="{coopId}" isWxScan="0">\n {newData}\n <clientKey>{coopId}</clientKey>\n </WateringNeeds>'
|
i2Doc = f'\n <WateringNeeds id="000000000" locationKey="{coopId}" isWxScan="0">\n {newData}\n <clientKey>{coopId}</clientKey>\n </WateringNeeds>'
|
||||||
|
|
||||||
f = open('./.temp/WateringNeeds.i2m', 'a')
|
async with aiofiles.open('./.temp/WateringNeeds.i2m', 'a') as f:
|
||||||
f.write(i2Doc)
|
await f.write(i2Doc)
|
||||||
f.close()
|
await f.close()
|
||||||
|
|
||||||
def makeRecord():
|
async def makeRecord():
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
l.info("Writing WateringNeeds record.")
|
l.info("Writing WateringNeeds record.")
|
||||||
|
|
||||||
header = '<Data type="WateringNeeds">'
|
header = '<Data type="WateringNeeds">'
|
||||||
footer = '</Data>'
|
footer = '</Data>'
|
||||||
|
|
||||||
with open('./.temp/WateringNeeds.i2m', 'a') as doc:
|
async with aiofiles.open('./.temp/WateringNeeds.i2m', 'a') as doc:
|
||||||
doc.write(header)
|
await doc.write(header)
|
||||||
|
|
||||||
for (x, y) in zip(coopIds, geocodes):
|
for (x, y) in zip(coopIds, geocodes):
|
||||||
getData(x,y)
|
await getData(x,y)
|
||||||
|
|
||||||
with open('./.temp/WateringNeeds.i2m', 'a') as end:
|
async with aiofiles.open('./.temp/WateringNeeds.i2m', 'a') as end:
|
||||||
end.write(footer)
|
await end.write(footer)
|
||||||
|
|
||||||
dom = xml.dom.minidom.parse('./.temp/WateringNeeds.i2m')
|
dom = xml.dom.minidom.parse('./.temp/WateringNeeds.i2m')
|
||||||
xmlPretty = dom.toprettyxml(indent= " ")
|
xmlPretty = dom.toprettyxml(indent= " ")
|
||||||
|
|
||||||
with open('./.temp/WateringNeeds.i2m', 'w') as g:
|
async with aiofiles.open('./.temp/WateringNeeds.i2m', 'w') as g:
|
||||||
g.write(xmlPretty[23:])
|
await g.write(xmlPretty[23:])
|
||||||
g.close()
|
await g.close()
|
||||||
|
|
||||||
|
|
||||||
# Compresss i2m to gzip
|
# Compresss i2m to gzip
|
||||||
|
0
recordGenerators/__init__.py
Normal file
0
recordGenerators/__init__.py
Normal file
@ -37,8 +37,4 @@ def getLatLong(locId: str):
|
|||||||
return fetched[0] + "/" + fetched[1]
|
return fetched[0] + "/" + fetched[1]
|
||||||
|
|
||||||
def getLocationInfo(locId: str):
|
def getLocationInfo(locId: str):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
print(getCoopId('USAZ0278'))
|
|
||||||
print(getZip('USAZ0278'))
|
|
||||||
print(getLatLong('USAZ0278'))
|
|
Loading…
x
Reference in New Issue
Block a user