You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
3.6 KiB

import argparse
import yaml
import time
import logging
from .models import AlertSeverity
from .location import LocationService
from .provider.factory import get_provider_instance
from .provider.astro import AstroProvider
from .narrator import Narrator
from .audio import AudioHandler
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("asl3_wx")
def load_config(path):
with open(path, 'r') as f:
return yaml.safe_load(f)
def do_full_report(config):
loc_svc = LocationService(config)
lat, lon = loc_svc.get_coordinates()
# Provider
prov_code = config.get('location', {}).get('provider')
provider = get_provider_instance(CountryCode=prov_code, Lat=lat, Lon=lon, Config=config)
# Fetch Data
loc_info = provider.get_location_info(lat, lon)
logger.info(f"Resolved Location: {loc_info.city}, {loc_info.region} ({loc_info.country_code})")
conditions = provider.get_conditions(lat, lon)
forecast = provider.get_forecast(lat, lon)
alerts = provider.get_alerts(lat, lon)
# Astro
astro = AstroProvider()
sun_info = astro.get_astro_info(loc_info)
# Narrate
narrator = Narrator(config)
text = narrator.build_full_report(loc_info, conditions, forecast, alerts, sun_info)
logger.info(f"Report Text: {text}")
# Audio
handler = AudioHandler(config)
wav_file = handler.generate_audio(text, "report.ul")
# Play
nodes = config.get('audio', {}).get('nodes', [])
handler.play_on_nodes(wav_file, nodes)
def monitor_loop(config):
interval = config.get('alerts', {}).get('check_interval_minutes', 10) * 60
known_alerts = set()
loc_svc = LocationService(config)
narrator = Narrator(config)
handler = AudioHandler(config)
nodes = config.get('audio', {}).get('nodes', [])
prov_code = config.get('location', {}).get('provider')
logger.info("Starting Alert Monitor...")
while True:
try:
# Update location each interval for mobile nodes
lat, lon = loc_svc.get_coordinates()
# Re-init provider with new coords
provider = get_provider_instance(CountryCode=prov_code, Lat=lat, Lon=lon, Config=config)
alerts = provider.get_alerts(lat, lon)
current_ids = {a.id for a in alerts}
new_alerts = []
for a in alerts:
if a.id not in known_alerts:
new_alerts.append(a)
known_alerts.add(a.id)
# Announce new items
if new_alerts:
logger.info(f"New Alerts detected: {len(new_alerts)}")
text = narrator.announce_alerts(new_alerts)
wav = handler.generate_audio(text, "alert.ul")
handler.play_on_nodes(wav, nodes)
# Cleanup expired from known
known_alerts = known_alerts.intersection(current_ids)
except Exception as e:
logger.error(f"Monitor error: {e}")
time.sleep(interval)
def main():
parser = argparse.ArgumentParser(description="ASL3 Weather Announcer")
parser.add_argument("--config", default="config.yaml", help="Path to config file")
parser.add_argument("--report", action="store_true", help="Play full weather report now")
parser.add_argument("--monitor", action="store_true", help="Run in continuous monitor mode")
args = parser.parse_args()
config = load_config(args.config)
if args.report:
do_full_report(config)
elif args.monitor:
monitor_loop(config)
else:
parser.print_help()
if __name__ == "__main__":
main()

Powered by TurnKey Linux.