(I ran this on my Slackware box and it worksa great.)
#!/usr/bin/env python3
import urllib.request
import xml.etree.ElementTree as ET
import sys
# Change this path to your BBS bulletin directory (e.g., /home/bbs/text/prop.txt)
OUTPUT_FILE = "/home/bbs/files/hfprop.txt"
URL = "
https://www.hamqsl.com/solarxml.php"
try:
# Fetch the raw N0NBH solar XML data stream
req = urllib.request.Request(URL, headers={'User-Agent': 'Mozilla/5.0'})
with urllib.request.urlopen(req) as response:
xml_data = response.read()
root = ET.fromstring(xml_data)
solardata = root.find('solardata')
# Extract core solar metrics
updated = solardata.find('updated').text.strip()
sfi = solardata.find('solarflux').text.strip()
ssn = solardata.find('sunspots').text.strip()
aindex = solardata.find('aindex').text.strip()
kindex = solardata.find('kindex').text.strip()
# Process calculated HF band conditions (Day/Night maps)
bands = {}
for calc in solardata.findall('calculatedconditions/band'):
name = calc.get('name')
time = calc.get('time')
status = calc.text.strip()
if name not in bands:
bands[name] = {}
bands[name][time] = status
# Construct clean, standard ASCII display text block
lines = [
"+-----------------------------------------------+",
"| CURRENT HF BAND PROPAGATION |",
f"| Updated: {updated:<36} |",
"+-----------------------+--------------+--------+",
"| Band / Frequency | Daytime | Night |",
"+-----------------------+--------------+--------+"
]
# Output rows mimicking solar.w5mmw.net layout
for b in ["80m-40m", "30m-20m", "17m-15m", "12m-10m"]:
day = bands.get(b, {}).get('day', '---')
night = bands.get(b, {}).get('night', '---')
lines.append(f"| {b:<21} | {day:<12} | {night:<6} |")
lines.extend([
"+-----------------------+--------------+--------+",
f"| Solar Flux Index: {sfi:<4} Sunspot Number: {ssn:<4} |",
f"| Geomag A-Index: {aindex:<4} Geomag K-Index: {kindex:<4} |",
"+-----------------------------------------------+"
])
# Flush output block seamlessly into your local BBS bulletin text file
with open(OUTPUT_FILE, "w", encoding="ascii", errors="ignore") as f:
f.write("\n".join(lines) + "\n")
except Exception as e:
print(f"Execution Error: {e}", file=sys.stderr)
sys.exit(1)
-- Sean KS4TD
... "Bother," said Pooh as Caesar gasped "Et tu, Poohte?"
--- MultiMail/Win
* Origin: Outpost BBS * Johnson City, TN (1:18/200)