reorganization + multicast works on Linux!

This commit is contained in:
2025-10-20 22:35:35 -05:00
parent 28e56feef1
commit 0db078dbe4
28 changed files with 65 additions and 82 deletions

View File

@@ -1,35 +1,3 @@
<h1 align="center"><strong>IntelliStar 2 Message Encoder / Data Collector</strong></h1>
# py2Lib
# Requirements
* 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.
A python implementation of i2Lib from the original i2MessageEncoder.

12
main.py
View File

@@ -1,8 +1,7 @@
import asyncio, aiofiles
from asyncio.log import logger
from asyncore import loop
import logging,coloredlogs
from radar import TWCRadarCollector
import logging
import os
from datetime import datetime
import recordTasks
@@ -13,7 +12,6 @@ with open("config.json", "r") as file:
cfg = json.load(file)
l = logging.getLogger(__name__)
coloredlogs.install(logger=l)
useRadarServer = cfg["useRadarServer"]
@@ -33,9 +31,9 @@ async def createTemp():
os.mkdir('./.temp/output/satrad')
# Create msgId file for bit.py
#async with aiofiles.open('./.temp/msgId.txt', 'w') as msgId:
#await msgId.write('694203')
#await msgId.close()
async with aiofiles.open('./.temp/msgId.txt', 'w') as msgId:
await msgId.write('694203')
await msgId.close()
else:
l.debug(".temp file exists")
return
@@ -44,8 +42,10 @@ async def createTemp():
async def main():
await createTemp()
if useRadarServer:
mosaicTask = asyncio.create_task(recordTasks.updateMosaicTask())
satradTask = asyncio.create_task(recordTasks.updateSatradTask())
alertsTask = asyncio.create_task(recordTasks.alertsTask())
coTask = asyncio.create_task(recordTasks.coTask())
hfTask = asyncio.create_task(recordTasks.hfTask())

View File

@@ -0,0 +1 @@
# This file makes it to where the sys.path.append tomfoolery doesn't have to exist

View File

@@ -1,11 +1,11 @@
import asyncio
import aiohttp
import aiofiles
import logging, coloredlogs
from py2Lib import bit
import logging
from datetime import datetime
from os import path, listdir, remove
import util.bit
# Open the config file and make it accessible via "cfg"
import json
@@ -13,7 +13,6 @@ with open("config.json", "r") as file:
cfg = json.load(file)
l = logging.getLogger(__name__)
coloredlogs.install(level="DEBUG")
async def getValidTimestamps(radarType:str) -> list:
times = []
@@ -48,7 +47,6 @@ async def getValidTimestamps(radarType:str) -> list:
return times
async def downloadRadarFrames(radarType:str, timestamps: list) -> list:
url_root = None
imagesToSend = []
if (radarType == "satrad"):

View File

@@ -7,7 +7,7 @@ import aiohttp
import json
import time as epochTime
import requests
import logging,coloredlogs
import logging
from os import path, mkdir, listdir, remove, cpu_count
from shutil import rmtree
@@ -19,7 +19,6 @@ from wand.color import Color
radarType = "Radar-US"
l = logging.getLogger(__name__)
coloredlogs.install()
upperLeftX,upperLeftY,lowerRightX,lowerRightY = 0,0,0,0
xStart,xEnd,yStart,yEnd = 0,0,0,0

View File

@@ -0,0 +1 @@
# This file makes it to where the sys.path.append tomfoolery doesn't have to exist

View File

@@ -1,14 +1,16 @@
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
import util.bit
import util.machineProductCfg as MPC
import util.lfRecord as LFR
l = logging.getLogger(__name__)
coloredlogs.install()

View File

@@ -9,9 +9,9 @@ import aiohttp, aiofiles, asyncio
l = logging.getLogger(__name__)
coloredlogs.install()
import py2Lib.bit
import util.bit
import util.machineProductCfg as MPC
import records.lfRecord as LFR
import util.lfRecord as LFR
locationIds = []
zipCodes = []

View File

@@ -6,9 +6,9 @@ import xml.dom.minidom
import logging,coloredlogs
import aiohttp, aiofiles, asyncio
import py2Lib.bit
import util.bit
import util.machineProductCfg as MPC
import records.lfRecord as LFR
import util.lfRecord as LFR
l = logging.getLogger(__name__)
coloredlogs.install()

View File

@@ -2,7 +2,6 @@ import requests
import json
import os
from datetime import datetime,timedelta
from util.machineProductCfg import getAlertZones
import time
import pytz
import xml.dom.minidom
@@ -10,7 +9,11 @@ import shutil
import gzip
import logging,coloredlogs
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__)
coloredlogs.install()

View File

@@ -7,9 +7,9 @@ import xml.dom.minidom
import logging,coloredlogs
import aiohttp, aiofiles, asyncio
import py2Lib.bit
import util.bit
import util.machineProductCfg as MPC
import records.lfRecord as LFR
import util.lfRecord as LFR
l = logging.getLogger(__name__)
coloredlogs.install()

View File

@@ -1,5 +1,4 @@
import requests
import py2Lib.bit as bit
import gzip
import uuid
import os
@@ -8,9 +7,9 @@ import xml.dom.minidom
import logging,coloredlogs
import aiohttp, aiofiles, asyncio
import py2Lib.bit
import util.bit
import util.machineProductCfg as MPC
import records.lfRecord as LFR
import util.lfRecord as LFR
l = logging.getLogger(__name__)
coloredlogs.install()

View File

@@ -7,9 +7,9 @@ import xml.dom.minidom
import logging,coloredlogs
import aiohttp, aiofiles, asyncio
import py2Lib.bit
import util.bit
import util.machineProductCfg as MPC
import records.lfRecord as LFR
import util.lfRecord as LFR
l = logging.getLogger(__name__)
coloredlogs.install()

View File

@@ -1,9 +1,11 @@
import shutil
import requests
import logging,coloredlogs
import py2Lib.bit
import util.bit
import util.machineProductCfg as MPC
import records.lfRecord as LFR
import util.lfRecord as LFR
import gzip
from os import remove
import xml.dom.minidom

View File

@@ -7,9 +7,9 @@ import xml.dom.minidom
import logging,coloredlogs
import aiohttp, aiofiles, asyncio, asyncio
import py2Lib.bit
import util.bit
import util.machineProductCfg as MPC
import records.lfRecord as LFR
import util.lfRecord as LFR
l = logging.getLogger(__name__)
coloredlogs.install()

View File

@@ -1,9 +1,11 @@
import shutil
import requests
import logging,coloredlogs
import py2Lib.bit
import util.bit
import util.machineProductCfg as MPC
import records.lfRecord as LFR
import util.lfRecord as LFR
import gzip
from os import remove
import xml.dom.minidom

View File

@@ -7,9 +7,9 @@ import xml.dom.minidom
import logging, coloredlogs
import aiohttp, aiofiles, asyncio
import py2Lib.bit
import util.bit
import util.machineProductCfg as MPC
import records.lfRecord as LFR
import util.lfRecord as LFR
l = logging.getLogger(__name__)

View File

@@ -1,9 +1,11 @@
import shutil
import logging,coloredlogs
import datetime
import py2Lib.bit
import util.bit
import util.machineProductCfg as MPC
import records.lfRecord as LFR
import util.lfRecord as LFR
import gzip
from os import remove
import xml.dom.minidom

View File

@@ -1,9 +1,11 @@
import shutil
import requests
import logging,coloredlogs
import py2Lib.bit
import util.bit
import util.machineProductCfg as MPC
import records.lfRecord as LFR
import util.lfRecord as LFR
import gzip
from os import remove
import xml.dom.minidom

View File

@@ -1,6 +1,6 @@
import asyncio
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
@@ -10,7 +10,7 @@ async def updateMosaicTask():
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.
if datetime.now().minute in mosaicUpdateIntervals:
await TWCRadarCollector.collect("radarmosaic")
await radarCollector.collect("radarmosaic")
await asyncio.sleep(1)
async def updateSatradTask():
@@ -19,7 +19,7 @@ async def updateSatradTask():
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.
if datetime.now().minute in satradUpdateIntervals:
await TWCRadarCollector.collect("satrad")
await radarCollector.collect("satrad")
await asyncio.sleep(1)

View File

@@ -0,0 +1 @@
# This file makes it to where the sys.path.append tomfoolery doesn't have to exist

View File

@@ -22,8 +22,10 @@ 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))
conn = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
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"
@@ -147,6 +149,7 @@ def sendCommand(command, Pri, msgNum = None):
with open(msg_id_file, "r") as f:
oMsgId = f.read()
msgNum = int(oMsgId)
l.debug(f"Got message ID {msgNum}")
f.close()
nMsgNum = msgNum + 1

View File

@@ -1,7 +1,7 @@
import sqlite3
# Make a connection to the LFRecord database
con = sqlite3.connect("records/LFRecord.db")
con = sqlite3.connect("util/LFRecord.db")
cur = con.cursor()