reorganization + multicast works on Linux!
This commit is contained in:
36
README.md
36
README.md
@@ -1,35 +1,3 @@
|
|||||||
<h1 align="center"><strong>IntelliStar 2 Message Encoder / Data Collector</strong></h1>
|
# py2Lib
|
||||||
|
|
||||||
# Requirements
|
A python implementation of i2Lib from the original i2MessageEncoder.
|
||||||
* Properly set up interface for UDP.
|
|
||||||
* TWC API Key
|
|
||||||
|
|
||||||
## Completed Records
|
|
||||||
- [X] Aches and Pains
|
|
||||||
- [X] Air Quality
|
|
||||||
- [X] Airport Delays + National Airport delays
|
|
||||||
- [X] Alerts *(BERecord)*
|
|
||||||
- [X] Breathing
|
|
||||||
- [X] Current Conditions
|
|
||||||
- [X] Daily Forecasts
|
|
||||||
- [X] Hourly Forecasts
|
|
||||||
- [X] Heating and Cooling
|
|
||||||
- [X] Mosquito Activity
|
|
||||||
- [X] Pollen Forecasts
|
|
||||||
- [X] Tide Station Forecasts
|
|
||||||
- [X] Watering Needs
|
|
||||||
- [ ] Marine Forecasts
|
|
||||||
- [ ] Traffic Forecasts **(API access missing)**
|
|
||||||
|
|
||||||
# Usage instructions
|
|
||||||
1) Ensure that [Python is installed](https://www.python.org), or from your package repository (apt/winget).
|
|
||||||
2) [Download the code or git clone this URL] and unzip to the wanted directory.
|
|
||||||
3) Use command prompt to enter the directory of the scripts, then install package requirements:<br/>
|
|
||||||
```pip install -r requirements.txt``` <br/>
|
|
||||||
4) Copy **config.example.json** to **config.json** and edit to your specific config.
|
|
||||||
4) Drop your unit's **MachineProductCfg.xml** file into the root of the script
|
|
||||||
5) Run ``py main.py``
|
|
||||||
|
|
||||||
### Attributions & Disclaimers
|
|
||||||
Air Quality reports are powered by Copernicus Atmosphere Monitoring Service Information 2022.
|
|
||||||
Neither the European Commission nor ECMWF is responsible for any use that may be made of the Copernicus Information or Data it contains.
|
|
||||||
16
main.py
16
main.py
@@ -1,8 +1,7 @@
|
|||||||
import asyncio, aiofiles
|
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
|
||||||
from radar import TWCRadarCollector
|
|
||||||
import os
|
import os
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import recordTasks
|
import recordTasks
|
||||||
@@ -13,7 +12,6 @@ with open("config.json", "r") as file:
|
|||||||
cfg = json.load(file)
|
cfg = json.load(file)
|
||||||
|
|
||||||
l = logging.getLogger(__name__)
|
l = logging.getLogger(__name__)
|
||||||
coloredlogs.install(logger=l)
|
|
||||||
|
|
||||||
useRadarServer = cfg["useRadarServer"]
|
useRadarServer = cfg["useRadarServer"]
|
||||||
|
|
||||||
@@ -33,9 +31,9 @@ async def createTemp():
|
|||||||
os.mkdir('./.temp/output/satrad')
|
os.mkdir('./.temp/output/satrad')
|
||||||
|
|
||||||
# Create msgId file for bit.py
|
# Create msgId file for bit.py
|
||||||
#async with aiofiles.open('./.temp/msgId.txt', 'w') as msgId:
|
async with aiofiles.open('./.temp/msgId.txt', 'w') as msgId:
|
||||||
#await msgId.write('694203')
|
await msgId.write('694203')
|
||||||
#await msgId.close()
|
await msgId.close()
|
||||||
else:
|
else:
|
||||||
l.debug(".temp file exists")
|
l.debug(".temp file exists")
|
||||||
return
|
return
|
||||||
@@ -44,8 +42,10 @@ async def createTemp():
|
|||||||
async def main():
|
async def main():
|
||||||
await createTemp()
|
await createTemp()
|
||||||
|
|
||||||
mosaicTask = asyncio.create_task(recordTasks.updateMosaicTask())
|
if useRadarServer:
|
||||||
satradTask = asyncio.create_task(recordTasks.updateSatradTask())
|
mosaicTask = asyncio.create_task(recordTasks.updateMosaicTask())
|
||||||
|
satradTask = asyncio.create_task(recordTasks.updateSatradTask())
|
||||||
|
|
||||||
alertsTask = asyncio.create_task(recordTasks.alertsTask())
|
alertsTask = asyncio.create_task(recordTasks.alertsTask())
|
||||||
coTask = asyncio.create_task(recordTasks.coTask())
|
coTask = asyncio.create_task(recordTasks.coTask())
|
||||||
hfTask = asyncio.create_task(recordTasks.hfTask())
|
hfTask = asyncio.create_task(recordTasks.hfTask())
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
# This file makes it to where the sys.path.append tomfoolery doesn't have to exist
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import aiofiles
|
import aiofiles
|
||||||
import logging, coloredlogs
|
import logging
|
||||||
from py2Lib import bit
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from os import path, listdir, remove
|
from os import path, listdir, remove
|
||||||
|
|
||||||
|
import util.bit
|
||||||
|
|
||||||
# Open the config file and make it accessible via "cfg"
|
# Open the config file and make it accessible via "cfg"
|
||||||
import json
|
import json
|
||||||
@@ -13,7 +13,6 @@ with open("config.json", "r") as file:
|
|||||||
cfg = json.load(file)
|
cfg = json.load(file)
|
||||||
|
|
||||||
l = logging.getLogger(__name__)
|
l = logging.getLogger(__name__)
|
||||||
coloredlogs.install(level="DEBUG")
|
|
||||||
|
|
||||||
async def getValidTimestamps(radarType:str) -> list:
|
async def getValidTimestamps(radarType:str) -> list:
|
||||||
times = []
|
times = []
|
||||||
@@ -48,7 +47,6 @@ async def getValidTimestamps(radarType:str) -> list:
|
|||||||
return times
|
return times
|
||||||
|
|
||||||
async def downloadRadarFrames(radarType:str, timestamps: list) -> list:
|
async def downloadRadarFrames(radarType:str, timestamps: list) -> list:
|
||||||
url_root = None
|
|
||||||
imagesToSend = []
|
imagesToSend = []
|
||||||
|
|
||||||
if (radarType == "satrad"):
|
if (radarType == "satrad"):
|
||||||
@@ -7,7 +7,7 @@ import aiohttp
|
|||||||
import json
|
import json
|
||||||
import time as epochTime
|
import time as epochTime
|
||||||
import requests
|
import requests
|
||||||
import logging,coloredlogs
|
import logging
|
||||||
|
|
||||||
from os import path, mkdir, listdir, remove, cpu_count
|
from os import path, mkdir, listdir, remove, cpu_count
|
||||||
from shutil import rmtree
|
from shutil import rmtree
|
||||||
@@ -19,7 +19,6 @@ from wand.color import Color
|
|||||||
radarType = "Radar-US"
|
radarType = "Radar-US"
|
||||||
|
|
||||||
l = logging.getLogger(__name__)
|
l = logging.getLogger(__name__)
|
||||||
coloredlogs.install()
|
|
||||||
|
|
||||||
upperLeftX,upperLeftY,lowerRightX,lowerRightY = 0,0,0,0
|
upperLeftX,upperLeftY,lowerRightX,lowerRightY = 0,0,0,0
|
||||||
xStart,xEnd,yStart,yEnd = 0,0,0,0
|
xStart,xEnd,yStart,yEnd = 0,0,0,0
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
# This file makes it to where the sys.path.append tomfoolery doesn't have to exist
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
import shutil
|
import shutil
|
||||||
import requests
|
import requests
|
||||||
import logging,coloredlogs
|
import logging,coloredlogs
|
||||||
import py2Lib.bit
|
|
||||||
import util.machineProductCfg as MPC
|
|
||||||
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
|
import aiohttp, aiofiles, asyncio
|
||||||
|
|
||||||
|
import util.bit
|
||||||
|
import util.machineProductCfg as MPC
|
||||||
|
import util.lfRecord as LFR
|
||||||
|
|
||||||
|
|
||||||
l = logging.getLogger(__name__)
|
l = logging.getLogger(__name__)
|
||||||
coloredlogs.install()
|
coloredlogs.install()
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ import aiohttp, aiofiles, asyncio
|
|||||||
l = logging.getLogger(__name__)
|
l = logging.getLogger(__name__)
|
||||||
coloredlogs.install()
|
coloredlogs.install()
|
||||||
|
|
||||||
import py2Lib.bit
|
import util.bit
|
||||||
import util.machineProductCfg as MPC
|
import util.machineProductCfg as MPC
|
||||||
import records.lfRecord as LFR
|
import util.lfRecord as LFR
|
||||||
|
|
||||||
locationIds = []
|
locationIds = []
|
||||||
zipCodes = []
|
zipCodes = []
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import xml.dom.minidom
|
|||||||
import logging,coloredlogs
|
import logging,coloredlogs
|
||||||
import aiohttp, aiofiles, asyncio
|
import aiohttp, aiofiles, asyncio
|
||||||
|
|
||||||
import py2Lib.bit
|
import util.bit
|
||||||
import util.machineProductCfg as MPC
|
import util.machineProductCfg as MPC
|
||||||
import records.lfRecord as LFR
|
import util.lfRecord as LFR
|
||||||
|
|
||||||
l = logging.getLogger(__name__)
|
l = logging.getLogger(__name__)
|
||||||
coloredlogs.install()
|
coloredlogs.install()
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import requests
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
from datetime import datetime,timedelta
|
from datetime import datetime,timedelta
|
||||||
from util.machineProductCfg import getAlertZones
|
|
||||||
import time
|
import time
|
||||||
import pytz
|
import pytz
|
||||||
import xml.dom.minidom
|
import xml.dom.minidom
|
||||||
@@ -10,7 +9,11 @@ import shutil
|
|||||||
import gzip
|
import gzip
|
||||||
import logging,coloredlogs
|
import logging,coloredlogs
|
||||||
import aiohttp, aiofiles, asyncio
|
import aiohttp, aiofiles, asyncio
|
||||||
import py2Lib.bit
|
|
||||||
|
import util.bit
|
||||||
|
import util.machineProductCfg as MPC
|
||||||
|
import util.lfRecord as LFR
|
||||||
|
from util.machineProductCfg import getAlertZones
|
||||||
|
|
||||||
l = logging.getLogger(__name__)
|
l = logging.getLogger(__name__)
|
||||||
coloredlogs.install()
|
coloredlogs.install()
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ import xml.dom.minidom
|
|||||||
import logging,coloredlogs
|
import logging,coloredlogs
|
||||||
import aiohttp, aiofiles, asyncio
|
import aiohttp, aiofiles, asyncio
|
||||||
|
|
||||||
import py2Lib.bit
|
import util.bit
|
||||||
import util.machineProductCfg as MPC
|
import util.machineProductCfg as MPC
|
||||||
import records.lfRecord as LFR
|
import util.lfRecord as LFR
|
||||||
|
|
||||||
l = logging.getLogger(__name__)
|
l = logging.getLogger(__name__)
|
||||||
coloredlogs.install()
|
coloredlogs.install()
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import requests
|
import requests
|
||||||
import py2Lib.bit as bit
|
|
||||||
import gzip
|
import gzip
|
||||||
import uuid
|
import uuid
|
||||||
import os
|
import os
|
||||||
@@ -8,9 +7,9 @@ import xml.dom.minidom
|
|||||||
import logging,coloredlogs
|
import logging,coloredlogs
|
||||||
import aiohttp, aiofiles, asyncio
|
import aiohttp, aiofiles, asyncio
|
||||||
|
|
||||||
import py2Lib.bit
|
import util.bit
|
||||||
import util.machineProductCfg as MPC
|
import util.machineProductCfg as MPC
|
||||||
import records.lfRecord as LFR
|
import util.lfRecord as LFR
|
||||||
|
|
||||||
l = logging.getLogger(__name__)
|
l = logging.getLogger(__name__)
|
||||||
coloredlogs.install()
|
coloredlogs.install()
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ import xml.dom.minidom
|
|||||||
import logging,coloredlogs
|
import logging,coloredlogs
|
||||||
import aiohttp, aiofiles, asyncio
|
import aiohttp, aiofiles, asyncio
|
||||||
|
|
||||||
import py2Lib.bit
|
import util.bit
|
||||||
import util.machineProductCfg as MPC
|
import util.machineProductCfg as MPC
|
||||||
import records.lfRecord as LFR
|
import util.lfRecord as LFR
|
||||||
|
|
||||||
l = logging.getLogger(__name__)
|
l = logging.getLogger(__name__)
|
||||||
coloredlogs.install()
|
coloredlogs.install()
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import shutil
|
import shutil
|
||||||
import requests
|
import requests
|
||||||
import logging,coloredlogs
|
import logging,coloredlogs
|
||||||
import py2Lib.bit
|
|
||||||
|
import util.bit
|
||||||
import util.machineProductCfg as MPC
|
import util.machineProductCfg as MPC
|
||||||
import records.lfRecord as LFR
|
import util.lfRecord as LFR
|
||||||
|
|
||||||
import gzip
|
import gzip
|
||||||
from os import remove
|
from os import remove
|
||||||
import xml.dom.minidom
|
import xml.dom.minidom
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ import xml.dom.minidom
|
|||||||
import logging,coloredlogs
|
import logging,coloredlogs
|
||||||
import aiohttp, aiofiles, asyncio, asyncio
|
import aiohttp, aiofiles, asyncio, asyncio
|
||||||
|
|
||||||
import py2Lib.bit
|
import util.bit
|
||||||
import util.machineProductCfg as MPC
|
import util.machineProductCfg as MPC
|
||||||
import records.lfRecord as LFR
|
import util.lfRecord as LFR
|
||||||
|
|
||||||
l = logging.getLogger(__name__)
|
l = logging.getLogger(__name__)
|
||||||
coloredlogs.install()
|
coloredlogs.install()
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import shutil
|
import shutil
|
||||||
import requests
|
import requests
|
||||||
import logging,coloredlogs
|
import logging,coloredlogs
|
||||||
import py2Lib.bit
|
|
||||||
|
import util.bit
|
||||||
import util.machineProductCfg as MPC
|
import util.machineProductCfg as MPC
|
||||||
import records.lfRecord as LFR
|
import util.lfRecord as LFR
|
||||||
|
|
||||||
import gzip
|
import gzip
|
||||||
from os import remove
|
from os import remove
|
||||||
import xml.dom.minidom
|
import xml.dom.minidom
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ import xml.dom.minidom
|
|||||||
import logging, coloredlogs
|
import logging, coloredlogs
|
||||||
import aiohttp, aiofiles, asyncio
|
import aiohttp, aiofiles, asyncio
|
||||||
|
|
||||||
import py2Lib.bit
|
import util.bit
|
||||||
import util.machineProductCfg as MPC
|
import util.machineProductCfg as MPC
|
||||||
import records.lfRecord as LFR
|
import util.lfRecord as LFR
|
||||||
|
|
||||||
|
|
||||||
l = logging.getLogger(__name__)
|
l = logging.getLogger(__name__)
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import shutil
|
import shutil
|
||||||
import logging,coloredlogs
|
import logging,coloredlogs
|
||||||
import datetime
|
import datetime
|
||||||
import py2Lib.bit
|
|
||||||
|
import util.bit
|
||||||
import util.machineProductCfg as MPC
|
import util.machineProductCfg as MPC
|
||||||
import records.lfRecord as LFR
|
import util.lfRecord as LFR
|
||||||
|
|
||||||
import gzip
|
import gzip
|
||||||
from os import remove
|
from os import remove
|
||||||
import xml.dom.minidom
|
import xml.dom.minidom
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import shutil
|
import shutil
|
||||||
import requests
|
import requests
|
||||||
import logging,coloredlogs
|
import logging,coloredlogs
|
||||||
import py2Lib.bit
|
|
||||||
|
import util.bit
|
||||||
import util.machineProductCfg as MPC
|
import util.machineProductCfg as MPC
|
||||||
import records.lfRecord as LFR
|
import util.lfRecord as LFR
|
||||||
|
|
||||||
import gzip
|
import gzip
|
||||||
from os import remove
|
from os import remove
|
||||||
import xml.dom.minidom
|
import xml.dom.minidom
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
from recordGenerators import alerts,currentObservations,hourlyForecast,dailyForecast, airQuality, airportDelays, achesAndPains, breathing, heatingAndCooling, mosquitoActivity, pollenForecast, tideForecast, wateringNeeds
|
from recordGenerators import alerts,currentObservations,hourlyForecast,dailyForecast, airQuality, airportDelays, achesAndPains, breathing, heatingAndCooling, mosquitoActivity, pollenForecast, tideForecast, wateringNeeds
|
||||||
from radar import TWCRadarCollector
|
from radar import radarCollector
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ async def updateMosaicTask():
|
|||||||
while True:
|
while True:
|
||||||
# Mosaic intervals are 5+1 minutes, so instead of waiting 40 seconds and running "Datetime.now()" twice, We run it once and wait for 60.
|
# Mosaic intervals are 5+1 minutes, so instead of waiting 40 seconds and running "Datetime.now()" twice, We run it once and wait for 60.
|
||||||
if datetime.now().minute in mosaicUpdateIntervals:
|
if datetime.now().minute in mosaicUpdateIntervals:
|
||||||
await TWCRadarCollector.collect("radarmosaic")
|
await radarCollector.collect("radarmosaic")
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
async def updateSatradTask():
|
async def updateSatradTask():
|
||||||
@@ -19,7 +19,7 @@ async def updateSatradTask():
|
|||||||
while True:
|
while True:
|
||||||
#Satrad intervals are 10+1 minutes, so instead of waiting 40 seconds and running "Datetime.now()" twice, We run it once and wait for 60.
|
#Satrad intervals are 10+1 minutes, so instead of waiting 40 seconds and running "Datetime.now()" twice, We run it once and wait for 60.
|
||||||
if datetime.now().minute in satradUpdateIntervals:
|
if datetime.now().minute in satradUpdateIntervals:
|
||||||
await TWCRadarCollector.collect("satrad")
|
await radarCollector.collect("satrad")
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
# This file makes it to where the sys.path.append tomfoolery doesn't have to exist
|
||||||
@@ -22,8 +22,10 @@ BUF_SIZE = 1396
|
|||||||
|
|
||||||
MULTICAST_TTL = 2
|
MULTICAST_TTL = 2
|
||||||
|
|
||||||
conn = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
|
conn = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
conn.setsockopt(socket.IPPROTO_IP,socket.IP_ADD_MEMBERSHIP,socket.inet_aton(MCAST_GRP)+socket.inet_aton(MCAST_IF))
|
conn.bind((MCAST_IF, 63216))
|
||||||
|
# The below multicast socket options to bind to an interface/add a membership doesn't work on Linux systems.
|
||||||
|
# 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"
|
test = b"This is a test"
|
||||||
|
|
||||||
@@ -147,6 +149,7 @@ def sendCommand(command, Pri, msgNum = None):
|
|||||||
with open(msg_id_file, "r") as f:
|
with open(msg_id_file, "r") as f:
|
||||||
oMsgId = f.read()
|
oMsgId = f.read()
|
||||||
msgNum = int(oMsgId)
|
msgNum = int(oMsgId)
|
||||||
|
l.debug(f"Got message ID {msgNum}")
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
nMsgNum = msgNum + 1
|
nMsgNum = msgNum + 1
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import sqlite3
|
import sqlite3
|
||||||
|
|
||||||
# Make a connection to the LFRecord database
|
# Make a connection to the LFRecord database
|
||||||
con = sqlite3.connect("records/LFRecord.db")
|
con = sqlite3.connect("util/LFRecord.db")
|
||||||
cur = con.cursor()
|
cur = con.cursor()
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user