diff --git a/py2Lib/bit.old b/py2Lib/bit.old deleted file mode 100644 index 158be51..0000000 --- a/py2Lib/bit.old +++ /dev/null @@ -1,216 +0,0 @@ -import socket -import sys -import os -import struct -import binascii -import math -import time -import logging,coloredlogs - -# Open the config file and make it accessible via "cfg" -import json -with open("conf.json", "r") as file: - cfg = json.load(file) - -l = logging.getLogger(__name__) -coloredlogs.install() - -MCAST_GRP = cfg["multicastGroup"] -MCAST_IF = cfg["multicastIf"] -BUF_SIZE = 1396 - -MULTICAST_TTL = 2 - -conn = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) -conn.setsockopt(socket.IPPROTO_IP,socket.IP_ADD_MEMBERSHIP,socket.inet_aton(MCAST_GRP)+socket.inet_aton(MCAST_IF)) - -test = b"This is a test" - -def sendFile(files, commands, numSgmts, Pri): - if Pri == 0: - MCAST_PORT = 7787 - elif Pri == 1: - MCAST_PORT = 7788 - else: - l.critical("Invalid Priority Flag. 0 = Routine Message 1 = High Priority Message\n\nScript will now terminate...") - exit() - #Get the next message ID - with open('./.temp/msgId.txt', "r") as f: - oMsgId = f.read() - msgNum = int(oMsgId) - f.close() - - nMsgNum = msgNum + 1 - h = open('./.temp/msgId.txt', "w") - h.write(str(nMsgNum)) - h.close() - segnmNum = 0 - if Pri == 0: - l.info("Sending Routine Msg-" + str(msgNum) + " on UDP " + MCAST_GRP + " " + str(MCAST_PORT) + "....") - elif Pri == 1: - l.info("Sending High Priority Msg-" + str(msgNum) + " on UDP " + MCAST_GRP + " " + str(MCAST_PORT) + "....") - startFlag = False - - for x, y in zip(files, commands): - size = os.path.getsize(x) - check = size - BUF_SIZE - pToBeSent = size / 1405 - packRounded = math.ceil(pToBeSent) + 1 - numSegments = numSgmts + 3 - total_sent = 0 - payloadLength = 0 - packet_count = 1 - j = 0 - pc = packet_count.to_bytes(1, byteorder='big') - i = 0 - encode1 = bytes(y + 'I2MSG', 'UTF-8') - commandLength = len(y) - encode2 = commandLength.to_bytes(4, byteorder='little') - theCommand = b"".join([encode1, encode2]) - char = '' - new_file = open(x, "ab") - new_file.write(theCommand) # Append command to end of the file - new_file.close() - new_size = os.path.getsize(x) - - if startFlag == False: - #Our 34 byte beginning packet - p1 = struct.pack(">BHHHIIBBBBBBBIBIBBB", 18, 1, 0 , 16, msgNum, 0, segnmNum, 0, 0, 8, numSegments, 3, 0, 0, 8, packRounded, 0, 0, 0) - conn.sendto(p1, (MCAST_GRP, MCAST_PORT)) - startFlag = True - with open(x,"rb") as message: - message.seek(0) - data = message.read(BUF_SIZE) - while data: - packetHeader = struct.pack(">BHHHIIBBB", 18, 1, 0, 1405, msgNum, packet_count, 0, 0, 0) - fec = struct.pack("BHHHIIBBBBBBBI", 18, 1, 1, 8, msgNum, 0, segnmNum, 0, 0, 8, 0, 0, 0, 67108864) - p4 = struct.pack(">BHHHIIBBB", 18, 1, 1, 14, msgNum, 1, segnmNum, 0, 0) + test - conn.sendto(p3, (MCAST_GRP, MCAST_PORT)) - conn.sendto(p4, (MCAST_GRP, MCAST_PORT)) - segnmNum += 1 - w -= 1 - #------------------------------------------------------------------------------------------------------- -def sendCommand(command, Pri, msgNum = None): - if Pri == 0: - MCAST_PORT = 7787 - elif Pri == 1: - MCAST_PORT = 7788 - else: - l.critical("Invalid Priority Flag. 0 = Routine Message 1 = High Priority Message\n\nScript will now terminate...") - exit() - #Get the next message ID - with open('./.temp/msgId.txt', "r") as f: - oMsgId = f.read() - msgNum = int(oMsgId) - f.close() - - nMsgNum = msgNum + 1 - h = open('./.temp/msgId.txt', "w") - h.write(str(nMsgNum)) - h.close() - segnmNum = 0 - if Pri == 0: - l.info("Sending Routine Msg-" + str(msgNum) + " on UDP " + MCAST_GRP + " " + str(MCAST_PORT) + "....") - elif Pri == 1: - l.info("Sending High Priority Msg-" + str(msgNum) + " on UDP " + MCAST_GRP + " " + str(MCAST_PORT) + "....") - startFlag = False - - for x in command: - bx = bytes(x, 'utf-8') - with open('./.temp/command', 'wb') as c: - c.write(bx) - c.close() - size = os.path.getsize('./.temp/command') - encode1 = bytes('I2MSG', 'UTF-8') - commandLength = size - encode2 = commandLength.to_bytes(4, byteorder='little') - theCommand = b"".join([encode1, encode2]) - with open('./.temp/command', 'ab') as d: - d.write(theCommand) - d.close() - check = size - BUF_SIZE - pToBeSent = size / 1405 - packRounded = math.ceil(pToBeSent) + 1 - numSegments = 4 - total_sent = 0 - payloadLength = 0 - packet_count = 1 - j = 0 - pc = packet_count.to_bytes(4, byteorder='little') - i = 0 - char = '' - new_size = os.path.getsize('./.temp/command') - - if startFlag == False: - #Our 34 byte beginning packet - p1 = struct.pack(">BHHHIIBBBBBBBIBIBBB", 18, 1, 0 , 16, msgNum, 0, segnmNum, 0, 0, 8, numSegments, 3, 0, 0, 8, packRounded, 0, 0, 0) - conn.sendto(p1, (MCAST_GRP, MCAST_PORT)) - startFlag = True - with open('./.temp/Command',"rb") as message: - message.seek(0) - data = message.read(BUF_SIZE) - while data: - packetHeader = struct.pack(">BHHHIIBBB", 18, 1, 0, 1405, msgNum, packet_count, 0, 0, 0) - fec = struct.pack("BHHHIIBBBBBBBI", 18, 1, 1, 8, msgNum, 0, segnmNum, 0, 0, 8, 0, 0, 0, 67108864) - p4 = struct.pack(">BHHHIIBBB", 18, 1, 1, 14, msgNum, 1, segnmNum, 0, 0) + test - conn.sendto(p3, (MCAST_GRP, MCAST_PORT)) - conn.sendto(p4, (MCAST_GRP, MCAST_PORT)) - segnmNum += 1 - w -= 1 - #------------------------------------------------------------------------------------------------------- diff --git a/radar/TWCRadarProcessor.py b/radar/TWCRadarProcessor.py index b8ec4c2..6ba685b 100644 --- a/radar/TWCRadarProcessor.py +++ b/radar/TWCRadarProcessor.py @@ -26,11 +26,8 @@ xStart,xEnd,yStart,yEnd = 0,0,0,0 imgW = 0 imgH = 0 -import sys -sys.path.append("./py2lib") -sys.path.append("./radar") +import py2Lib.bit from RadarProcessor import * -import bit async def getValidTimestamps(boundaries:ImageBoundaries) -> list: """Gets all valid UNIX timestamps for the TWCRadarMosaic product """ diff --git a/recordGenerators/AchesAndPains.py b/recordGenerators/AchesAndPains.py deleted file mode 100644 index 323c34b..0000000 --- a/recordGenerators/AchesAndPains.py +++ /dev/null @@ -1,85 +0,0 @@ -import shutil -import requests -import logging,coloredlogs -import py2Lib.bit -import util.machineProductCfg as MPC -import records.lfRecord as LFR -import gzip -from os import remove -import xml.dom.minidom -import aiohttp, aiofiles, asyncio - -l = logging.getLogger(__name__) -coloredlogs.install() - -geocodes = [] -coopIds = [] - -for i in MPC.getPrimaryLocations(): - coopIds.append(LFR.getCoopId(i)) - geocodes.append(LFR.getLatLong(i).replace('/', ',')) - -# Open the config file and make it accessible via "cfg" -import json -with open("config.json", "r") as file: - cfg = json.load(file) - -apiKey = cfg["twcApiKey"] - -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}" - 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() - - - newData = data[63:-26] - - i2Doc = f'\n \n {newData}\n {coopId}\n ' - - async with aiofiles.open('./.temp/AchesAndPains.i2m', 'a') as f: - await f.write(i2Doc) - await f.close() - -async def makeRecord(): - loop = asyncio.get_running_loop() - l.info("Writing AchesAndPains record.") - - header = '' - footer = '' - - async with aiofiles.open('./.temp/AchesAndPains.i2m', 'a') as doc: - await doc.write(header) - - for (x, y) in zip(coopIds, geocodes): - await getData(x,y) - - async with aiofiles.open('./.temp/AchesAndPains.i2m', 'a') as end: - await end.write(footer) - - dom = xml.dom.minidom.parse('./.temp/AchesAndPains.i2m') - xmlPretty = dom.toprettyxml(indent= " ") - - async with aiofiles.open('./.temp/AchesAndPains.i2m', 'w') as g: - await g.write(xmlPretty[23:]) - await g.close() - - - # Compresss i2m to gzip - with open ('./.temp/AchesAndPains.i2m', 'rb') as f_in: - with gzip.open('./.temp/AchesAndPains.gz', 'wb') as f_out: - shutil.copyfileobj(f_in, f_out) - - file = "./.temp/AchesAndPains.gz" - command = '' - - bit.sendFile([file], [command], 1, 0) - - remove('./.temp/AchesAndPains.i2m') - remove('./.temp/AchesAndPains.gz') diff --git a/recordGenerators/AirQuality.py b/recordGenerators/AirQuality.py deleted file mode 100644 index 86520c9..0000000 --- a/recordGenerators/AirQuality.py +++ /dev/null @@ -1,110 +0,0 @@ -import requests -import gzip -import os -import shutil -import xml.dom.minidom -import logging,coloredlogs -import aiohttp, aiofiles, asyncio - -l = logging.getLogger(__name__) -coloredlogs.install() - -import py2Lib.bit -import util.machineProductCfg as MPC -import records.lfRecord as LFR - -locationIds = [] -zipCodes = [] -epaIds = [] - -for i in MPC.getPrimaryLocations(): - locationIds.append(LFR.getCoopId(i)) - zipCodes.append(LFR.getZip(i)) - epaIds.append(LFR.getEpaId(i)) - -# Open the config file and make it accessible via "cfg" -import json -with open("config.json", "r") as file: - cfg = json.load(file) - -apiKey = cfg["twcApiKey"] - -async def getData(epaId, zipcode): - url = f"https://api.weather.com/v1/location/{zipcode}:4:US/airquality.xml?language=en-US&apiKey={apiKey}" - data = "" - - async with aiohttp.ClientSession() as s: - async with s.get(url) as r: - data = await r.text() - - newData = data[57:-11] - - # Write to i2doc file - i2Doc = f'' + '' + newData + f'{epaId}' - - async with aiofiles.open("./.temp/AirQuality.i2m", 'a') as f: - await f.write(i2Doc) - await f.close() - -async def writeData(): - loop = asyncio.get_running_loop() - useData = False - workingEpaIds = [] - - for i in epaIds: - if i == None: - l.debug(f"No EPA ID found for location -- Skipping.") - else: - l.debug(f"EPA ID found for location! Writing data for Air Quality.") - workingEpaIds.append(i) - useData = True - - - # Check to see if we even have EPA ids, as some areas don't have air quality reports - if (useData): - try: - l.info("Writing an AirQuality record.") - header = '' - footer = "" - - async with aiofiles.open("./.temp/AirQuality.i2m", 'w') as doc: - await doc.write(header) - - for (x, y) in zip(workingEpaIds, zipCodes): - await getData(x, y) - - async with aiofiles.open("./.temp/AirQuality.i2m", 'a') as end: - await end.write(footer) - - dom = xml.dom.minidom.parse("./.temp/AirQuality.i2m") - xmlPretty = dom.toprettyxml(indent = " ") - - async with aiofiles.open("./.temp/AirQuality.i2m", 'w') as g: - await g.write(xmlPretty[23:]) - await g.close() - - files = [] - commands = [] - with open("./.temp/AirQuality.i2m", 'rb') as f_in: - with gzip.open("./.temp/AirQuality.gz", 'wb') as f_out: - shutil.copyfileobj(f_in, f_out) - - gZipFile = "./.temp/AirQuality.gz" - - files.append(gZipFile) - comand = commands.append('') - numFiles = len(files) - - bit.sendFile(files, commands, numFiles, 0) - - os.remove("./.temp/AirQuality.i2m") - os.remove("./.temp/AirQuality.gz") - except Exception as e: - l.error("DO NOT REPORT THE ERROR BELOW") - l.error("Failed to write an AirQuality record.") - os.remove('./.temp/AirQuality.i2m') - else: - l.info("Not writing an AirQuality record due to a lack of working EPA ids.") - - - diff --git a/recordGenerators/AirportDelays.py b/recordGenerators/AirportDelays.py deleted file mode 100644 index 2440ef9..0000000 --- a/recordGenerators/AirportDelays.py +++ /dev/null @@ -1,103 +0,0 @@ -import requests -import gzip -import os -import shutil -import xml.dom.minidom -import logging,coloredlogs -import aiohttp, aiofiles, asyncio - -import py2Lib.bit -import util.machineProductCfg as MPC -import records.lfRecord as LFR - -l = logging.getLogger(__name__) -coloredlogs.install() - -locationIds = [] -zipCodes = [] -airports = [] - -for i in MPC.getPrimaryLocations(): - locationIds.append(LFR.getCoopId(i)) - zipCodes.append(LFR.getZip(i)) - -airports = MPC.getAirportCodes() -l.debug(airports) - -# Open the config file and make it accessible via "cfg" -import json -with open("config.json", "r") as file: - cfg = json.load(file) - -apiKey = cfg["twcApiKey"] - -async def getData(airport): - url = f"https://api.weather.com/v1/airportcode/{airport}/airport/delays.xml?language=en-US&apiKey={apiKey}" - data = "" - - async with aiohttp.ClientSession() as s: - async with s.get(url) as r: - data = await r.text() - - newData = data[48:-11].replace('¿', '-') - - # Write to i2doc file - i2Doc = f'' + '' + newData + f'{airport}' - - async with aiofiles.open("./.temp/AirportDelays.i2m", 'a') as f: - await f.write(i2Doc) - await f.close() - -async def writeData(): - loop = asyncio.get_running_loop() - useData = False - airportsWithDelays = [] - - for x in airports: - async with aiohttp.ClientSession() as s: - 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: - l.debug(f"No delay for {x} found, skipping..") - else: - airportsWithDelays.append(x) - useData = True - - if (useData): - l.info("Writing an AirportDelays record.") - header = '' - footer = "" - - async with aiofiles.open("./.temp/AirportDelays.i2m", 'w') as doc: - await doc.write(header) - - for x in airportsWithDelays: - await getData(x) - - async with aiofiles.open("./.temp/AirportDelays.i2m", 'a') as end: - await end.write(footer) - - dom = xml.dom.minidom.parse("./.temp/AirportDelays.i2m") - prettyXml = dom.toprettyxml(indent=" ") - - async with aiofiles.open("./.temp/AirportDelays.i2m", 'w') as g: - await g.write(prettyXml) - await g.close() - - files = [] - commands = [] - with open("./.temp/AirportDelays.i2m", 'rb') as f_in: - with gzip.open("./.temp/AirportDelays.gz", 'wb') as f_out: - shutil.copyfileobj(f_in, f_out) - - gZipFile = "./.temp/AirportDelays.gz" - - files.append(gZipFile) - comand = commands.append('') - numFiles = len(files) - - bit.sendFile(files, commands, numFiles, 0) - - os.remove("./.temp/AirportDelays.i2m") - os.remove("./.temp/AirportDelays.gz") - else: - l.info("No airport delays found.") diff --git a/recordGenerators/Alerts.py b/recordGenerators/Alerts.py deleted file mode 100644 index 3665af4..0000000 --- a/recordGenerators/Alerts.py +++ /dev/null @@ -1,365 +0,0 @@ -import requests -import json -import os -from datetime import datetime,timedelta -from util.machineProductCfg import getAlertZones -import time -import pytz -import xml.dom.minidom -import shutil -import gzip -import logging,coloredlogs -import aiohttp, aiofiles, asyncio -import py2Lib.bit - -l = logging.getLogger(__name__) -coloredlogs.install() - -#Zones/Counties to fetch alerts for -alertLocations = getAlertZones() -# Open the config file and make it accessible via "cfg" -import json -with open("config.json", "r") as file: - cfg = json.load(file) - -headlineApiKey = cfg["twcApiKey"] -detailsApiKey = cfg["twcApiKey"] - -k = 0 -async def getAlerts(location): - global k - fetchUrl = 'https://api.weather.com/v3/alerts/headlines?areaId=' + location + ':US&format=json&language=en-US&apiKey=' + headlineApiKey - # response = requests.get(fetchUrl) - - # theCode = response.status_code - - theCode = 0 - - async with aiohttp.ClientSession() as s: - async with s.get(fetchUrl) as r: - theCode = r.status - - #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 - - # Map headline variables - l.debug('Found Alert for ' + location + '\n') - dataH = await r.json() - 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']) - - #Is this for a NWS Zone or County? - last4 = location[2:] - locationType = None - if 'C' in last4: - locationType = 'C' - 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 - - if vocalCheck == 'HU_W': - vocalCode = 'HE001' - elif vocalCheck == 'TY_W': - vocalCode = 'HE002' - elif vocalCheck == 'HI_W': - vocalCode = 'HE003' - elif vocalCheck == 'TO_A': - vocalCode = 'HE004' - elif vocalCheck == 'SV_A': - vocalCode = 'HE005' - elif vocalCheck == 'HU_A': - vocalCode = 'HE006' - elif vocalCheck == 'TY_A': - vocalCode = 'HE007' - elif vocalCheck == 'TR_W': - vocalCode = 'HE008' - elif vocalCheck == 'TR_A': - vocalCode = 'HE009' - elif vocalCheck == 'TI_W': - vocalCode = 'HE010' - elif vocalCheck == 'HI_A': - vocalCode = 'HE011' - elif vocalCheck == 'TI_A': - vocalCode = 'HE012' - elif vocalCheck == 'BZ_W': - vocalCode = 'HE013' - elif vocalCheck == 'IS_W': - vocalCode = 'HE014' - elif vocalCheck == 'WS_W': - vocalCode = 'HE015' - elif vocalCheck == 'HW_W': - vocalCode = 'HE016' - elif vocalCheck == 'LE_W': - vocalCode = 'HE017' - elif vocalCheck == 'ZR_Y': - vocalCode = 'HE018' - elif vocalCheck == 'CF_W': - vocalCode = 'HE019' - elif vocalCheck == 'LS_W': - vocalCode = 'HE020' - elif vocalCheck == 'WW_Y': - vocalCode = 'HE021' - elif vocalCheck == 'LB_Y': - vocalCode = 'HE022' - elif vocalCheck == 'LE_Y': - vocalCode = 'HE023' - elif vocalCheck == 'BZ_A': - vocalCode = 'HE024' - elif vocalCheck == 'WS_A': - vocalCode = 'HE025' - elif vocalCheck == 'FF_A': - vocalCode = 'HE026' - elif vocalCheck == 'FA_A': - vocalCode = 'HE027' - elif vocalCheck == 'FA_Y': - vocalCode = 'HE028' - elif vocalCheck == 'HW_A': - vocalCode = 'HE029' - elif vocalCheck == 'LE_A': - vocalCode = 'HE030' - elif vocalCheck == 'SU_W': - vocalCode = 'HE031' - elif vocalCheck == 'LS_Y': - vocalCode = 'HE032' - elif vocalCheck == 'CF_A': - vocalCode = 'HE033' - elif vocalCheck == 'ZF_Y': - vocalCode = 'HE034' - elif vocalCheck == 'FG_Y': - vocalCode = 'HE035' - elif vocalCheck == 'SM_Y': - vocalCode = 'HE036' - elif vocalCheck == 'EC_W': - vocalCode = 'HE037' - elif vocalCheck == 'EH_W': - vocalCode = 'HE038' - elif vocalCheck == 'HZ_W': - vocalCode = 'HE039' - elif vocalCheck == 'FZ_W': - vocalCode = 'HE040' - elif vocalCheck == 'HT_Y': - vocalCode = 'HE041' - elif vocalCheck == 'WC_Y': - vocalCode = 'HE042' - elif vocalCheck == 'FR_Y': - vocalCode = 'HE043' - elif vocalCheck == 'EC_A': - vocalCode = 'HE044' - elif vocalCheck == 'EH_A': - vocalCode = 'HE045' - elif vocalCheck == 'HZ_A': - vocalCode = 'HE046' - elif vocalCheck == 'DS_W': - vocalCode = 'HE047' - elif vocalCheck == 'WI_Y': - vocalCode = 'HE048' - elif vocalCheck == 'SU_Y': - vocalCode = 'HE049' - elif vocalCheck == 'AS_Y': - vocalCode = 'HE050' - elif vocalCheck == 'WC_W': - vocalCode = 'HE051' - elif vocalCheck == 'FZ_A': - vocalCode = 'HE052' - elif vocalCheck == 'WC_A': - vocalCode = 'HE053' - elif vocalCheck == 'AF_W': - vocalCode = 'HE054' - elif vocalCheck == 'AF_Y': - vocalCode = 'HE055' - elif vocalCheck == 'DU_Y': - vocalCode = 'HE056' - elif vocalCheck == 'LW_Y': - vocalCode = 'HE057' - elif vocalCheck == 'LS_A': - vocalCode = 'HE058' - elif vocalCheck == 'HF_W': - vocalCode = 'HE059' - elif vocalCheck == 'SR_W': - vocalCode = 'HE060' - elif vocalCheck == 'GL_W': - vocalCode = 'HE061' - elif vocalCheck == 'HF_A': - vocalCode = 'HE062' - elif vocalCheck == 'UP_W': - vocalCode = 'HE063' - elif vocalCheck == 'SE_W': - vocalCode = 'HE064' - elif vocalCheck == 'SR_A': - vocalCode = 'HE065' - elif vocalCheck == 'GL_A': - vocalCode = 'HE066' - elif vocalCheck == 'MF_Y': - vocalCode = 'HE067' - elif vocalCheck == 'MS_Y': - vocalCode = 'HE068' - elif vocalCheck == 'SC_Y': - vocalCode = 'HE069' - elif vocalCheck == 'UP_Y': - vocalCode = 'HE073' - elif vocalCheck == 'LO_Y': - vocalCode = 'HE074' - elif vocalCheck == 'AF_V': - vocalCode = 'HE075' - elif vocalCheck == 'UP_A': - vocalCode = 'HE076' - elif vocalCheck == 'TAV_W': - vocalCode = 'HE077' - elif vocalCheck == 'TAV_A': - vocalCode = 'HE078' - elif vocalCheck == 'TO_W': - vocalCode = 'HE110' - else: - vocalCode = '' - - #Do some date/time conversions - EndTimeUTCEpoch = x['expireTimeUTC'] - EndTimeUTC = datetime.utcfromtimestamp(EndTimeUTCEpoch).strftime('%Y%m%d%H%M') - #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' - - #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 = 'NOT_USED' + x['productIdentifier'] + 'NOT_USED' + Action + '' + x['officeCode'] + '' + x['phenomena'] + '' + x['significance'] + '' + x['eventTrackingNumber'] + '' + x['eventDescription'] + 'NOT_USED' + EndTimeUTC + '' + str(x['severityCode']) + 'NOT_USED' + expireTimeUTC + '' + location + '' + x['adminDistrictCode'] + 'NOT_USEDNOT_USEDNOT_USED' + x['identifier'] + '' + processTime + '' + issueTimeUtc + '' + x['headlineText'] + '' + vocalCode + 'NOT_USED' + description + 'NOT_USED' + location + '_' + x['phenomena'] + '_' + x['significance'] + '_' + x['eventTrackingNumber'] + '_' + x['officeCode'] + '' - - #Append BERecord - async with aiofiles.open('./.temp/BERecord.xml', "a") as b: - await b.write(alertMsg) - await 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. - async with aiofiles.open('./.temp/alertmanifest.txt', "a") as c: - await c.write('\n' + location + '_' + x['phenomena'] + '_' + x['significance'] + '_' + str(x['processTimeUTC'])) - await c.close() - - - -async def makeRecord(): - loop = asyncio.get_running_loop() - global k - - async with aiofiles.open("./.temp/BERecord.xml", 'w') as BERecord: - await BERecord.write('') - await BERecord.close() - - for z in alertLocations: - await getAlerts(z) - - async with aiofiles.open('./.temp/BERecord.xml', 'a') as BERecord: - await BERecord.write("") - 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() - - # The BERecord XML doesn't need to be written if there's no alerts. - if k > 0: - l.info("Sending alert(s) to the IntelliStar 2!") - with open("./.temp/BERecord.i2m", 'rb') as f_in: - with gzip.open("./.temp/BERecord.gz", 'wb') as f_out: - shutil.copyfileobj(f_in, f_out) - - files = [] - commands = [] - gZipFile = "./.temp/BERecord.gz" - files.append(gZipFile) - command = commands.append('') - bit.sendFile(files, commands, 1, 0) - os.remove(gZipFile) - k = 0 - - os.remove("./.temp/BERecord.xml") - os.remove("./.temp/BERecord.i2m") - diff --git a/recordGenerators/Breathing.py b/recordGenerators/Breathing.py deleted file mode 100644 index 9dab8c1..0000000 --- a/recordGenerators/Breathing.py +++ /dev/null @@ -1,93 +0,0 @@ -import requests -import gzip -import uuid -import os -import shutil -import xml.dom.minidom -import logging,coloredlogs -import aiohttp, aiofiles, asyncio - -import py2Lib.bit -import util.machineProductCfg as MPC -import records.lfRecord as LFR - -l = logging.getLogger(__name__) -coloredlogs.install() - -coopIds = [] -geocodes = [] - - -# Auto-grab the tecci and zip codes -for i in MPC.getPrimaryLocations(): - coopIds.append(LFR.getCoopId(i)) - geocodes.append(LFR.getLatLong(i).replace('/', ',')) - -l.debug(coopIds, geocodes) - -# Open the config file and make it accessible via "cfg" -import json -with open("config.json", "r") as file: - cfg = json.load(file) - -apiKey = cfg["twcApiKey"] - -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}" - data = "" - - #Fetch data - async with aiohttp.ClientSession() as s: - async with s.get(fetchUrl) as r: - data = await r.text() - - newData = data[63:-26] - - l.debug('Gathering data for location id ' + coopId) - #Write to .i2m file - i2Doc = '' + '' + newData + '' + str(coopId) + '' - - async with aiofiles.open("./.temp/Breathing.i2m", "a") as f: - await f.write(i2Doc) - await f.close() - - -async def makeDataFile(): - loop = asyncio.get_running_loop() - l.info("Writing a Breathing forecast record.") - header = '' - footer = '' - - async with aiofiles.open("./.temp/Breathing.i2m", 'w') as doc: - await doc.write(header) - - for x, y in zip(coopIds, geocodes): - await getData(x, y) - - async with aiofiles.open("./.temp/Breathing.i2m", 'a') as end: - await end.write(footer) - - - dom = xml.dom.minidom.parse("./.temp/Breathing.i2m") - pretty_xml_as_string = dom.toprettyxml(indent = " ") - - async with aiofiles.open("./.temp/Breathing.i2m", "w") as g: - await g.write(pretty_xml_as_string[23:]) - await g.close() - - files = [] - commands = [] - with open("./.temp/Breathing.i2m", 'rb') as f_in: - with gzip.open("./.temp/Breathing.gz", 'wb') as f_out: - shutil.copyfileobj(f_in, f_out) - - gZipFile = "./.temp/Breathing.gz" - - files.append(gZipFile) - command = commands.append('') - numFiles = len(files) - - bit.sendFile(files, commands, numFiles, 0) - - os.remove("./.temp/Breathing.i2m") - os.remove("./.temp/Breathing.gz") diff --git a/recordGenerators/CurrentObservations.py b/recordGenerators/CurrentObservations.py deleted file mode 100644 index d3d693e..0000000 --- a/recordGenerators/CurrentObservations.py +++ /dev/null @@ -1,99 +0,0 @@ -import requests -import py2Lib.bit as bit -import gzip -import uuid -import os -import shutil -import xml.dom.minidom -import logging,coloredlogs -import aiohttp, aiofiles, asyncio - -import py2Lib.bit -import util.machineProductCfg as MPC -import records.lfRecord as LFR - -l = logging.getLogger(__name__) -coloredlogs.install() - -tecciId = [] -zipCodes = [] - -# Auto-grab the tecci and zip codes -for i in MPC.getPrimaryLocations(): - tecciId.append("T" + LFR.getCoopId(i)) - zipCodes.append(LFR.getZip(i)) - -# Obtain metro map city TECCI and zips: -for i in MPC.getMetroCities(): - tecciId.append("T" + LFR.getCoopId(i)) - zipCodes.append(LFR.getZip(i)) - - -# Open the config file and make it accessible via "cfg" -import json -with open("config.json", "r") as file: - cfg = json.load(file) - -apiKey = cfg["twcApiKey"] - -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 - data = "" - - async with aiohttp.ClientSession() as s: - async with s.get(fetchUrl) as r: - data = await r.text() - - newData = data[67:-30] - - #Write to .i2m file - i2Doc = '' + '' + newData + '' + str(tecci) + '' - async with aiofiles.open("./.temp/CurrentObservations.i2m", 'a') as f: - await f.write(i2Doc) - await f.close() - - -async def makeDataFile(): - loop = asyncio.get_running_loop() - l.info("Writing a CurrentObservations record.") - header = '' - footer = '' - - async with aiofiles.open("./.temp/CurrentObservations.i2m", 'w') as doc: - await doc.write(header) - - for x, y in zip(tecciId, zipCodes): - await getData(x, y) - - async with aiofiles.open("./.temp/CurrentObservations.i2m", 'a') as end: - await end.write(footer) - - dom = xml.dom.minidom.parse("./.temp/CurrentObservations.i2m") - pretty_xml_as_string = dom.toprettyxml(indent = " ") - - async with aiofiles.open("./.temp/CurrentObservations.i2m", "w") as g: - await g.write(pretty_xml_as_string[23:]) - await g.close() - - files = [] - 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 gzip.open("./.temp/CurrentObservations.gz", 'wb') as f_out: - shutil.copyfileobj(f_in, f_out) - - gZipFile = "./.temp/CurrentObservations.gz" - - files.append(gZipFile) - command = commands.append('') - numFiles = len(files) - - bit.sendFile(files, commands, numFiles, 0) - - os.remove("./.temp/CurrentObservations.i2m") - os.remove("./.temp/CurrentObservations.gz") diff --git a/recordGenerators/DailyForecast.py b/recordGenerators/DailyForecast.py deleted file mode 100644 index 41f1441..0000000 --- a/recordGenerators/DailyForecast.py +++ /dev/null @@ -1,94 +0,0 @@ -import requests -import gzip -import uuid -import os -import shutil -import xml.dom.minidom -import logging,coloredlogs -import aiohttp, aiofiles, asyncio - -import py2Lib.bit -import util.machineProductCfg as MPC -import records.lfRecord as LFR - -l = logging.getLogger(__name__) -coloredlogs.install() - -tecciId = [] -zipCodes = [] - -# Auto-grab the tecci and zip codes -for i in MPC.getPrimaryLocations(): - tecciId.append(LFR.getCoopId(i)) - zipCodes.append(LFR.getZip(i)) - -# Grab metro map city tecci and zip codes -for i in MPC.getMetroCities(): - tecciId.append(LFR.getCoopId(i)) - zipCodes.append(LFR.getZip(i)) - -# Open the config file and make it accessible via "cfg" -import json -with open("config.json", "r") as file: - cfg = json.load(file) - -apiKey = cfg["twcApiKey"] - -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 - data = "" - - async with aiohttp.ClientSession() as s: - async with s.get(fetchUrl) as r: - data = await r.text() - - newData = data[61:-24] - - l.debug('Gathering data for location id ' + tecci) - #Write to .i2m file - i2Doc = '' + '' + newData + '' + str(tecci) + '' - - async with aiofiles.open('./.temp/DailyForecast.i2m', 'a') as f: - await f.write(i2Doc) - await f.close() - - -async def makeDataFile(): - loop = asyncio.get_running_loop() - l.info("Writing a DailyForecast record.") - header = '' - footer = '' - - async with aiofiles.open("./.temp/DailyForecast.i2m", 'w') as doc: - await doc.write(header) - - for x, y in zip(tecciId, zipCodes): - await getData(x, y) - - async with aiofiles.open("./.temp/DailyForecast.i2m", 'a') as end: - await end.write(footer) - - - dom = xml.dom.minidom.parse("./.temp/DailyForecast.i2m") - pretty_xml_as_string = dom.toprettyxml(indent = " ") - - async with aiofiles.open("./.temp/DailyForecast.i2m", "w") as g: - await g.write(pretty_xml_as_string[23:]) - await g.close() - - files = [] - commands = [] - with open("./.temp/DailyForecast.i2m", 'rb') as f_in: - with gzip.open("./.temp/DailyForecast.gz", 'wb') as f_out: - shutil.copyfileobj(f_in, f_out) - - gZipFile = "./.temp/DailyForecast.gz" - - files.append(gZipFile) - command = commands.append('') - numFiles = len(files) - - bit.sendFile(files, commands, numFiles, 0) - - os.remove("./.temp/DailyForecast.i2m") - os.remove("./.temp/DailyForecast.gz") diff --git a/recordGenerators/HeatingAndCooling.py b/recordGenerators/HeatingAndCooling.py deleted file mode 100644 index 58f866a..0000000 --- a/recordGenerators/HeatingAndCooling.py +++ /dev/null @@ -1,85 +0,0 @@ -import shutil -import requests -import logging,coloredlogs -import py2Lib.bit -import util.machineProductCfg as MPC -import records.lfRecord as LFR -import gzip -from os import remove -import xml.dom.minidom -import aiohttp, aiofiles, asyncio - -l = logging.getLogger(__name__) -coloredlogs.install() - -geocodes = [] -coopIds = [] - -for i in MPC.getPrimaryLocations(): - coopIds.append(LFR.getCoopId(i)) - geocodes.append(LFR.getLatLong(i).replace('/', ',')) - -# Open the config file and make it accessible via "cfg" -import json -with open("config.json", "r") as file: - cfg = json.load(file) - -apiKey = cfg["twcApiKey"] - -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}" - data = "" - - 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] - - i2Doc = f'\n \n {newData}\n {coopId}\n ' - - async with aiofiles.open('./.temp/HeatingAndCooling.i2m', 'a') as f: - await f.write(i2Doc) - await f.close() - -async def makeRecord(): - loop = asyncio.get_running_loop() - l.info("Writing HeatingAndCooling record.") - - header = '' - footer = '' - - async with aiofiles.open('./.temp/HeatingAndCooling.i2m', 'a') as doc: - await doc.write(header) - - for (x, y) in zip(coopIds, geocodes): - await getData(x,y) - - async with aiofiles.open('./.temp/HeatingAndCooling.i2m', 'a') as end: - await end.write(footer) - - dom = xml.dom.minidom.parse('./.temp/HeatingAndCooling.i2m') - xmlPretty = dom.toprettyxml(indent= " ") - - async with aiofiles.open('./.temp/HeatingAndCooling.i2m', 'w') as g: - await g.write(xmlPretty[23:]) - await g.close() - - - # Compresss i2m to gzip - with open ('./.temp/HeatingAndCooling.i2m', 'rb') as f_in: - with gzip.open('./.temp/HeatingAndCooling.gz', 'wb') as f_out: - shutil.copyfileobj(f_in, f_out) - - file = "./.temp/HeatingAndCooling.gz" - command = '' - - bit.sendFile([file], [command], 1, 0) - - remove('./.temp/HeatingAndCooling.i2m') - remove('./.temp/HeatingAndCooling.gz') diff --git a/recordGenerators/HourlyForecast.py b/recordGenerators/HourlyForecast.py deleted file mode 100644 index 7cb3e48..0000000 --- a/recordGenerators/HourlyForecast.py +++ /dev/null @@ -1,96 +0,0 @@ -import requests -import gzip -import uuid -import os -import shutil -import xml.dom.minidom -import logging,coloredlogs -import aiohttp, aiofiles, asyncio, asyncio - -import py2Lib.bit -import util.machineProductCfg as MPC -import records.lfRecord as LFR - -l = logging.getLogger(__name__) -coloredlogs.install() - -tecciId = [] -zipCodes = [] - -# Auto-grab the tecci and zip codes -for i in MPC.getPrimaryLocations(): - tecciId.append(LFR.getCoopId(i)) - zipCodes.append(LFR.getZip(i)) - -for i in MPC.getMetroCities(): - tecciId.append(LFR.getCoopId(i)) - zipCodes.append(LFR.getZip(i)) - - -# Open the config file and make it accessible via "cfg" -import json -with open("config.json", "r") as file: - cfg = json.load(file) - -apiKey = cfg["twcApiKey"] - -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 - data = "" - - #Fetch data - async with aiohttp.ClientSession() as s: - async with s.get(fetchUrl) as r: - data = await r.text() - - newData = data[48:-11] - - #Write to .i2m file - i2Doc = '' + '' + newData + '' + str(tecci) + '' - - async with aiofiles.open('./.temp/HourlyForecast.i2m', 'a') as f: - await f.write(i2Doc) - await f.close() - - -async def makeDataFile(): - loop = asyncio.get_running_loop() - l.info("Writing an HourlyForecast record.") - header = '' - footer = '' - - async with aiofiles.open("./.temp/HourlyForecast.i2m", 'w') as doc: - await doc.write(header) - - - for x, y in zip(tecciId, zipCodes): - await getData(x, y) - - async with aiofiles.open("./.temp/HourlyForecast.i2m", 'a') as end: - await end.write(footer) - - - dom = xml.dom.minidom.parse("./.temp/HourlyForecast.i2m") - pretty_xml_as_string = dom.toprettyxml(indent = " ") - - async with aiofiles.open("./.temp/HourlyForecast.i2m", "w") as g: - await g.write(pretty_xml_as_string[23:]) - await g.close() - - files = [] - commands = [] - with open("./.temp/HourlyForecast.i2m", 'rb') as f_in: - with gzip.open("./.temp/HourlyForecast.gz", 'wb') as f_out: - shutil.copyfileobj(f_in, f_out) - - gZipFile = "./.temp/HourlyForecast.gz" - - files.append(gZipFile) - command = commands.append('') - numFiles = len(files) - - bit.sendFile(files, commands, numFiles, 0) - - os.remove("./.temp/HourlyForecast.i2m") - os.remove("./.temp/HourlyForecast.gz") diff --git a/recordGenerators/MosquitoActivity.py b/recordGenerators/MosquitoActivity.py deleted file mode 100644 index 94b51e7..0000000 --- a/recordGenerators/MosquitoActivity.py +++ /dev/null @@ -1,85 +0,0 @@ -import shutil -import requests -import logging,coloredlogs -import py2Lib.bit -import util.machineProductCfg as MPC -import records.lfRecord as LFR -import gzip -from os import remove -import xml.dom.minidom -import aiohttp, aiofiles, asyncio - -l = logging.getLogger(__name__) -coloredlogs.install() - -geocodes = [] -coopIds = [] - -for i in MPC.getPrimaryLocations(): - coopIds.append(LFR.getCoopId(i)) - geocodes.append(LFR.getLatLong(i).replace('/', ',')) - -# Open the config file and make it accessible via "cfg" -import json -with open("config.json", "r") as file: - cfg = json.load(file) - -apiKey = cfg["twcApiKey"] - -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}" - 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() - - - newData = data[63:-26] - - i2Doc = f'\n \n {newData}\n {coopId}\n ' - - async with aiofiles.open('./.temp/MosquitoActivity.i2m', 'a') as f: - await f.write(i2Doc) - await f.close() - -async def makeRecord(): - loop = asyncio.get_running_loop() - l.info("Writing MosquitoActivity record.") - - header = '' - footer = '' - - async with aiofiles.open('./.temp/MosquitoActivity.i2m', 'a') as doc: - await doc.write(header) - - for (x, y) in zip(coopIds, geocodes): - await getData(x,y) - - async with aiofiles.open('./.temp/MosquitoActivity.i2m', 'a') as end: - await end.write(footer) - - dom = xml.dom.minidom.parse('./.temp/MosquitoActivity.i2m') - xmlPretty = dom.toprettyxml(indent= " ") - - async with aiofiles.open('./.temp/MosquitoActivity.i2m', 'w') as g: - await g.write(xmlPretty[23:]) - await g.close() - - - # Compresss i2m to gzip - with open ('./.temp/MosquitoActivity.i2m', 'rb') as f_in: - with gzip.open('./.temp/MosquitoActivity.gz', 'wb') as f_out: - shutil.copyfileobj(f_in, f_out) - - file = "./.temp/MosquitoActivity.gz" - command = '' - - bit.sendFile([file], [command], 1, 0) - - remove('./.temp/MosquitoActivity.i2m') - remove('./.temp/MosquitoActivity.gz') diff --git a/recordGenerators/PollenForecast.py b/recordGenerators/PollenForecast.py deleted file mode 100644 index 3d28ca1..0000000 --- a/recordGenerators/PollenForecast.py +++ /dev/null @@ -1,93 +0,0 @@ -import requests -import gzip -import uuid -import os -import shutil -import xml.dom.minidom -import logging, coloredlogs -import aiohttp, aiofiles, asyncio - -import py2Lib.bit -import util.machineProductCfg as MPC -import records.lfRecord as LFR - - -l = logging.getLogger(__name__) -coloredlogs.install() - -pollenIds = [] -geocodes = [] - - -# Auto-grab the tecci and zip codes -for i in MPC.getPrimaryLocations(): - pollenIds.append(LFR.getPollenInfo(i)) - geocodes.append(LFR.getLatLong(i).replace('/', ',')) - -l.debug(pollenIds, geocodes) - -# Open the config file and make it accessible via "cfg" -import json -with open("config.json", "r") as file: - cfg = json.load(file) - -apiKey = cfg["twcApiKey"] - -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}" - data = "" - #Fetch data - async with aiohttp.ClientSession() as s: - async with s.get(fetchUrl) as r: - data = await r.text() - - newData = data[63:-26] - - l.debug('Gathering data for location id ' + pollenId) - #Write to .i2m file - i2Doc = '' + '' + newData + '' + str(pollenId) + '' - - async with aiofiles.open("./.temp/PollenForecast.i2m", "a") as f: - await f.write(i2Doc) - await f.close() - - -async def makeDataFile(): - loop = asyncio.get_running_loop() - l.info("Writing a PollenForecast record.") - header = '' - footer = '' - - async with aiofiles.open("./.temp/PollenForecast.i2m", 'w') as doc: - await doc.write(header) - - for x, y in zip(pollenIds, geocodes): - await getData(x, y) - - async with aiofiles.open("./.temp/PollenForecast.i2m", 'a') as end: - await end.write(footer) - - - dom = xml.dom.minidom.parse("./.temp/PollenForecast.i2m") - pretty_xml_as_string = dom.toprettyxml(indent = " ") - - async with aiofiles.open("./.temp/PollenForecast.i2m", "w") as g: - await g.write(pretty_xml_as_string[23:]) - await g.close() - - files = [] - commands = [] - with open("./.temp/PollenForecast.i2m", 'rb') as f_in: - with gzip.open("./.temp/PollenForecast.gz", 'wb') as f_out: - shutil.copyfileobj(f_in, f_out) - - gZipFile = "./.temp/PollenForecast.gz" - - files.append(gZipFile) - command = commands.append('') - numFiles = len(files) - - bit.sendFile(files, commands, numFiles, 0) - - os.remove("./.temp/PollenForecast.i2m") - os.remove("./.temp/PollenForecast.gz") diff --git a/recordGenerators/TideForecast.py b/recordGenerators/TideForecast.py deleted file mode 100644 index 2756297..0000000 --- a/recordGenerators/TideForecast.py +++ /dev/null @@ -1,94 +0,0 @@ -import shutil -import logging,coloredlogs -import datetime -import py2Lib.bit -import util.machineProductCfg as MPC -import records.lfRecord as LFR -import gzip -from os import remove -import xml.dom.minidom -import aiohttp, aiofiles, asyncio - -l = logging.getLogger(__name__) -coloredlogs.install() - -geocodes = [] -tideStations = [] - -for i in MPC.getTideStations(): - tideStations.append(i) - geocodes.append(LFR.getLatLong(i)) - -# Open the config file and make it accessible via "cfg" -import json -with open("config.json", "r") as file: - cfg = json.load(file) - -apiKey = cfg["twcApiKey"] - -async def getData(tideStation, geocode): - today = datetime.date.today() - startDate = today.strftime('%Y%m%d') - endDate_unformatted = datetime.datetime.strptime(startDate, '%Y%m%d') + datetime.timedelta(days=5) - 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}" - - 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() - - - newData = data[53:-16] - - i2Doc = f'\n \n {newData}\n {tideStation}\n ' - - async with aiofiles.open('./.temp/TidesForecast.i2m', 'a') as f: - await f.write(i2Doc) - await f.close() - -async def makeRecord(): - loop = asyncio.get_running_loop() - if len(tideStations) < 1: - l.debug("Skipping TidesForecast -- No locations.") - return - - l.info("Writing TidesForecast record.") - - header = '' - footer = '' - - async with aiofiles.open('./.temp/TidesForecast.i2m', 'a') as doc: - await doc.write(header) - - for (x, y) in zip(tideStations, geocodes): - await getData(x,y) - - async with aiofiles.open('./.temp/TidesForecast.i2m', 'a') as end: - await end.write(footer) - - dom = xml.dom.minidom.parse('./.temp/TidesForecast.i2m') - xmlPretty = dom.toprettyxml(indent= " ") - - async with aiofiles.open('./.temp/TidesForecast.i2m', 'w') as g: - await g.write(xmlPretty[23:]) - await g.close() - - - # Compresss i2m to gzip - with open ('./.temp/TidesForecast.i2m', 'rb') as f_in: - with gzip.open('./.temp/TidesForecast.gz', 'wb') as f_out: - shutil.copyfileobj(f_in, f_out) - - file = "./.temp/TidesForecast.gz" - command = '' - - bit.sendFile([file], [command], 1, 0) - - remove('./.temp/TidesForecast.i2m') - remove('./.temp/TidesForecast.gz') diff --git a/recordGenerators/WateringNeeds.py b/recordGenerators/WateringNeeds.py deleted file mode 100644 index cd44f4a..0000000 --- a/recordGenerators/WateringNeeds.py +++ /dev/null @@ -1,84 +0,0 @@ -import shutil -import requests -import logging,coloredlogs -import py2Lib.bit -import util.machineProductCfg as MPC -import records.lfRecord as LFR -import gzip -from os import remove -import xml.dom.minidom -import aiohttp, aiofiles, asyncio - -l = logging.getLogger(__name__) -coloredlogs.install() - -geocodes = [] -coopIds = [] - -for i in MPC.getPrimaryLocations(): - coopIds.append(LFR.getCoopId(i)) - geocodes.append(LFR.getLatLong(i).replace('/', ',')) - -# Open the config file and make it accessible via "cfg" -import json -with open("config.json", "r") as file: - cfg = json.load(file) - -apiKey = cfg["twcApiKey"] - -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}" - data = "" - - async with aiohttp.ClientSession() as s: - async with s.get(fetchUrl) as r: - if r.status != 200: - l.error(f"Failed to WateringNeeds -- status code {r.status}") - return - - data = await r.text() - - newData = data[63:-26] - - i2Doc = f'\n \n {newData}\n {coopId}\n ' - - async with aiofiles.open('./.temp/WateringNeeds.i2m', 'a') as f: - await f.write(i2Doc) - await f.close() - -async def makeRecord(): - loop = asyncio.get_running_loop() - l.info("Writing WateringNeeds record.") - - header = '' - footer = '' - - async with aiofiles.open('./.temp/WateringNeeds.i2m', 'a') as doc: - await doc.write(header) - - for (x, y) in zip(coopIds, geocodes): - await getData(x,y) - - async with aiofiles.open('./.temp/WateringNeeds.i2m', 'a') as end: - await end.write(footer) - - dom = xml.dom.minidom.parse('./.temp/WateringNeeds.i2m') - xmlPretty = dom.toprettyxml(indent= " ") - - async with aiofiles.open('./.temp/WateringNeeds.i2m', 'w') as g: - await g.write(xmlPretty[23:]) - await g.close() - - - # Compresss i2m to gzip - with open ('./.temp/WateringNeeds.i2m', 'rb') as f_in: - with gzip.open('./.temp/WateringNeeds.gz', 'wb') as f_out: - shutil.copyfileobj(f_in, f_out) - - file = "./.temp/WateringNeeds.gz" - command = '' - - bit.sendFile([file], [command], 1, 0) - - remove('./.temp/WateringNeeds.i2m') - remove('./.temp/WateringNeeds.gz') diff --git a/recordGenerators/__init__.py b/recordGenerators/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/records/LFRecord.db b/records/LFRecord.db deleted file mode 100644 index d3fe24c..0000000 Binary files a/records/LFRecord.db and /dev/null differ diff --git a/records/LFRecord.py b/records/LFRecord.py deleted file mode 100644 index cd15b95..0000000 --- a/records/LFRecord.py +++ /dev/null @@ -1,40 +0,0 @@ -import sqlite3 - -# Make a connection to the LFRecord database -con = sqlite3.connect("records/LFRecord.db") -cur = con.cursor() - - -def getZip(locId: str): - """ Returns the zip code for a given location """ - COMMAND = (f"SELECT zip2locId FROM lfrecord WHERE locId='{locId}'") - cur.execute(COMMAND) - return cur.fetchone()[0] - -def getCoopId(locId: str): - """ Returns the TWC co-op ID for a given location """ - COMMAND = (f"SELECT coopId FROM lfrecord WHERE locId='{locId}'") - cur.execute(COMMAND) - return cur.fetchone()[0] - -def getEpaId(locId: str): - """ Return the Air Quality station id for a given location. """ - COMMAND = (f"SELECT epaId FROM lfrecord WHERE locId='{locId}'") - cur.execute(COMMAND) - return cur.fetchone()[0] - -def getPollenInfo(locId: str): - """ Return the Pollen forecast id for a given location. """ - COMMAND = (f"SELECT pllnId FROM lfrecord WHERE locId='{locId}'") - cur.execute(COMMAND) - return cur.fetchone()[0] - -def getLatLong(locId: str): - """ Return the Pollen forecast id for a given location. """ - COMMAND = (f"SELECT lat,long FROM lfrecord WHERE locId='{locId}'") - cur.execute(COMMAND) - fetched = cur.fetchone() - return fetched[0] + "/" + fetched[1] - -def getLocationInfo(locId: str): - pass \ No newline at end of file