Sal W6SAL - Updated on: 2026-02-15
So a days weeks ago I wrote a little love letter to the self-appointed sheriffs of MeshCore — the ones who migrated over from Meshtastic like digital refugees, bringing nothing with them except bad attitudes and an inflated sense of authority. If you missed it, go read it. I’ll wait.
Good. Now that you’re caught up, let me tell you what I’ve been doing while those clowns were busy telling everyone else what NOT to do. I’ve been building things. Actual, useful things. Things that turn a MeshCore node from a glorified walkie-talkie into an automated information beacon that serves real data to real operators who actually give a damn about emergency communications and community information.
I call it MeshBeacon, and it’s a suite of seven Python scripts that fetch live data from public APIs and broadcast formatted messages to your LoRa mesh channels. No internet required on the receiving end. You set it up, schedule it with cron, and your mesh network starts doing actual work — like a responsible piece of technology instead of a digital paperweight.
Let me walk you through what this thing does, because unlike the armchair critics, I believe in showing my work.
Every building needs a foundation, and every broadcast system needs a reliable way to talk to the radio. That’s meshcore_send.py. This is the core messaging infrastructure — it handles BLE and serial connections to your MeshCore device, resolves channels by their cryptographic secrets (not just slot numbers, because slot numbers change and I’m not an animal), and validates that your messages fit within the 135-byte UTF-8 limit that LoRa demands.
Here’s the thing that separates this from amateur hour: channel resolution matches by channel_secret hash. That means even if somebody rearranges their channel slots — because apparently that’s a thing people do at three in the morning — your broadcast scripts don’t break. They find the right channel by its cryptographic fingerprint every single time.
python meshcore_send.py --channel myhams "Hello from MeshBeacon!"
python meshcore_send.py --list-channels
Simple. Clean. Works. Three words the packet police have never experienced simultaneously.
You know what’s useful when you’re sitting on a mountaintop doing a SOTA activation, or when you’re coordinating an emergency response, or when you’re just trying to figure out if you should bother putting up the antenna today? The weather. Actual, real-time, local weather data.
weather_broadcast.py pulls data from Weather Underground — both Personal Weather Station observations and 5-day forecasts. It supports multiple stations and cities, so you can give your mesh network hyper-local conditions from actual PWS hardware sitting in somebody’s backyard, not some generic forecast for a region the size of Rhode Island.
Every message follows the same clean format:
WX My Backyard
Temp 58F Feels 56F
Hi 63F Lo 44F
Hum 65% Rain 20%
Wind 5mph NW G10
Partly Cloudy
Six lines. Everything you need. Nothing you don’t. All under 135 bytes. You set it to run twice a day via cron and your mesh network becomes a weather station. An actual useful service for the people monitoring the channel.
The API key is free. The setup takes five minutes. The value it adds to your network is immeasurable — unless you’re one of those guys who thinks the only legitimate use of radio technology is keying up to say “good morning” and then complaining about band conditions for forty-five minutes. In which case, this probably isn’t for you.
We live in California. The ground moves. This is not breaking news to anyone who’s been here longer than fifteen minutes.
earthquake_broadcast.py monitors the USGS Earthquake Hazards Program API — free, no API key required, real-time data — and broadcasts seismic events within 100 miles of San Jose. Magnitude 2.5 and up by default, because anything smaller and you’re just reporting truck traffic on 101.
EARTHQUAKE
🟡 M3.3 - 5 km SW of Ridgemark
46.5mi from SJC | Depth: 5.0mi
Feb 11 03:34 PST
Color-coded by severity: green for minor, yellow for light, orange for moderate, red for major. You run this every 30 minutes with a 2-hour lookback window and you’ve got yourself an earthquake early-awareness system on your mesh network. No smartphone required. No cell towers required. No internet on the receiving end. Just a LoRa radio and the knowledge that when the Hayward Fault finally decides to ruin everyone’s Tuesday, your mesh network will be the first to know.
For emergency communications — which is supposedly what amateur radio is all about, though you wouldn’t know it from listening to some of these guys — this is exactly the kind of tool that justifies the existence of these networks.
Speaking of emergency communications, let’s talk about the thing that actually kills people: weather.
Not earthquakes — those are dramatic, sure, but in California you might feel a decent shaker once or twice a year. Weather, on the other hand? Tornadoes, flash floods, severe thunderstorms, ice storms — these are the events that the National Weather Service issues watches and warnings for, and these are the events that Skywarn spotters have been tracking since 1972. And now your mesh network can track them too.
skywarn_broadcast.py pulls active watches, warnings, and advisories directly from the NWS API — free, no API key, near real-time data — and broadcasts them to your MeshCore channels. You give it a zip code and a radius, and it finds every active alert within that circle, sorts them by severity, and puts them on the mesh.
⚠️ SKYWARN
🟠 Svr T-Storm Wrn
Santa Clara County, CA
Until 3:45 PM PST
23mi
Color-coded by NWS severity levels: red for extreme, orange for severe, yellow for moderate, green for minor. It even abbreviates common event names to save bytes — because when you only have 135 bytes and the NWS calls it a “Severe Thunderstorm Warning,” you learn to call it “Svr T-Storm Wrn” real fast.
The location handling is slick. Give it a zip code and it geocodes it automatically. Give it raw coordinates. Give it a state abbreviation and it pulls everything for the entire state. It combines both point-based and area-based NWS queries, deduplicates by alert ID, and filters by computing the distance from your center point to each alert polygon’s centroid. The --skywarn-only flag limits output to classic Skywarn events — tornadoes, severe thunderstorms, flash floods, and flood warnings — filtering out the noise of frost advisories and wind chill warnings that nobody on a mesh network needs to hear about at three in the morning.
And here’s the cherry on top: the --send-clear flag. When there are no active alerts, it broadcasts an all-clear message. Because in emergency communications, knowing that nothing bad is happening is just as important as knowing when something bad is happening.
⚠️ SKYWARN
✅ No active alerts
San Jose, CA
Radius: 50mi
Run it every 15 minutes during severe weather season. Run it every 30 minutes for routine monitoring. Your mesh network just became a Skywarn repeater that never sleeps, never gets tired, and never forgets to check in.
No API keys. No subscriptions. No accounts. Just the National Weather Service doing what it does, and your mesh radio putting that information where it belongs — in the hands of people who need it.
Now we’re getting into the good stuff. The stuff that separates operators who actually understand radio from the ones who think “propagation” is a fancy word for plant reproduction.
solar_broadcast.py pulls data from HamQSL (the N0NBH solar feed) and Open-Meteo atmospheric data, and it gives you everything you need to know about what the ionosphere is doing right now and what that means for your ability to make contacts.
The standard mode sends two messages — solar indices and HF band conditions:
☀️ SOLAR:
SFI=185
SN=85
A=5
K=2
Xray=A1.2
Wind=425km/s
Bt=-3nT
[10 Feb 1800z] ✅
📡 BANDS D/N:
80 = ✅
40 = ✅
30 = ✅
20 = 🟡
17 = 🟡
15 = ❌
12 = ❌
10 = ❌
Add the --vhf flag and you get two more messages: VHF status (E-skip, aurora, nearest meteor shower) and a tropospheric ducting index computed from actual atmospheric pressure-level data for San Jose. That’s right — I wrote a Hepburn-style tropo index calculator that uses 925hPa and 850hPa temperature inversions, surface pressure, and relative humidity to tell you whether there’s ducting potential. Because the Bay Area marine layer makes this one of the best tropo locations in the continental US, and operators should know when conditions are ripe.
The system even fires automatic NOAA-scale alerts when conditions warrant — G-scale geomagnetic storms, R-scale radio blackouts from solar flares, S-scale solar radiation storms. You don’t have to check anything. The script does the analysis and broadcasts when something significant is happening.
Every three hours for HF bands. Once a day for the full VHF/tropo report. Set it and forget it. Your mesh network becomes a propagation dashboard.
Here’s one that’s all about community coordination. calendar_broadcast.py connects to a Google Sheet published as CSV and sends notification messages to your mesh channels at two intervals: 24 hours before an event and 2 hours before.
EVENT TOMORROW:
WVARA Net
Sat Feb 14 @ 7:00 PM
Weekly 2m net on 146.76 MHz
It routes notifications to the appropriate channels based on a column in the spreadsheet, tracks what’s been sent in a state file to prevent duplicates, and cleans up old notification records automatically. You run it every 15-30 minutes via cron and your mesh network becomes a community bulletin board.
Club nets, ARES exercises, field days, VE sessions, swap meets — anything you put on the calendar gets broadcast to the mesh. No one has to remember to check a website. No one has to subscribe to an email list. The information comes to them, right on their radio.
This is the newest addition and honestly one of the coolest. sotapota_broadcast.py fetches real-time activator spots from the Summits on the Air and Parks on the Air APIs and broadcasts nearby activations to your mesh network.
POTA
US-4701
Call: KC1GGP
SSB 14.307
09:31 PST
45mi SE of SJC
It does smart distance-based filtering with separate radius rings for HF and VHF/UHF, because a VHF activation 50 miles away is very different from an HF activation 50 miles away. HF gets a default 1000-mile radius. VHF gets 100 miles. You can set minimum radii too — donut queries — so you can filter out the HF activations in your own backyard that you could work on a rubber duck.
The system deduplicates by callsign (keeping the most recent spot), pre-filters SOTA spots to North American associations to minimize API calls, and automatically excludes QRT spots. Every 15 minutes during daytime hours, your mesh network tells nearby operators who’s out there on a summit or in a park, ready to be worked.
No API keys required. Both APIs are free and public. Set it up in five minutes.
Every broadcast script follows the same pattern: fetch data from external APIs, format messages to fit the 135-byte limit, connect to the MeshCore device, resolve the channel by secret, transmit with error handling, and disconnect cleanly. All credentials live in .keys files excluded from version control. All scripts support --dry-run for previewing without transmitting. All of them are designed for unattended operation via cron.
The whole system runs on a Raspberry Pi, a Mac, a Linux box — whatever you’ve got. BLE or USB serial. Set up your cron schedule, point it at your MeshCore device, and walk away. Your node becomes an automated beacon serving real, useful data to every operator on your mesh — weather, earthquakes, severe weather alerts, solar propagation, activator spots, and community events, all without a single human having to remember to do anything.
This is what MeshCore can be. This is what mesh networking should be. Not just a toy for sending “hello” messages, but an actual information infrastructure that serves a community.
And by “elephants” I mean the herd of self-righteous gatekeepers who’ve recently stampeded into MeshCore from the land of Meshtastic, bringing with them all the charm and social grace of a HOA board meeting run by people who peaked in middle school hall monitor training.
Here’s what’s been happening, and I need to say this clearly because apparently subtlety is lost on some people: A contingent of individuals — and I use that word loosely, because their behavior suggests they operate as a single hive mind powered by entitlement and caffeinated by Mountain Dew — have decided that they are the arbiters of what belongs on MeshCore. They’ve taken it upon themselves to police the channels, criticize the bots, and lecture actual builders about what should and shouldn’t exist on the network.
And here’s the part that really makes my fillings itch: these people don’t even understand what MeshCore is. Let me spell it out for the folks in the cheap seats.
MeshCore is not a ham radio exclusive platform. It is not restricted to licensed amateur radio operators. It operates on ISM band frequencies — the same unlicensed spectrum that Meshtastic uses, that your garage door opener uses, that the baby monitor next door uses. ANYBODY can use it. You don’t need a license. You don’t need a callsign. You don’t need to pass a test. You don’t need permission from some guy in his underwear who’s decided he’s the FCC.
The only regulations that apply — the ONLY ones, and I cannot stress this enough — are the Part 15 / Part 18 rules that the FCC has laid out for these ISM bands: keep your output power and radiated energy under the specified limits, and stay within the designated frequency band. That’s it. That is the entire regulatory framework. There is no rule that says “thou shalt not run a weather bot.” There is no regulation that says “automated messages are forbidden.” There is no section of Part 97 that applies here BECAUSE THIS ISN’T PART 97. This isn’t the amateur radio service. This is ISM band. The rules are: don’t exceed the power limit, stay in the band, and don’t cause harmful interference. Full stop. End of list. Nothing else. Go home.
So when these Meshtastic refugees — who, let’s be honest, come from the EXACT SAME regulatory environment — start playing cop on MeshCore, telling people what they should and shouldn’t do, acting like there’s some sacred rulebook being violated… they’re not enforcing anything. They’re making it up. They are cosplaying as regulators on a platform that has essentially no regulations to enforce beyond basic power limits.
And that’s what makes it so infuriating. It’s not just that they’re wrong — it’s that they’re confidently wrong. They strut around these channels with the swagger of someone who thinks they know something about radio, and they know NOTHING. They couldn’t explain the difference between ISM and amateur allocations if you spotted them the first two letters. They don’t understand power budgets, link margins, duty cycles, or spectral efficiency. They don’t know what they’re talking about, and they don’t know that they don’t know what they’re talking about, which is the most dangerous kind of ignorance — the kind that comes with a megaphone and an attitude.
MeshCore is not a replacement for your phone. It is not WhatsApp on a LoRa radio. It is not a consumer product designed to protect you from seeing things you didn’t ask for. It is an experimental communications platform on unlicensed spectrum, and experimentation means — stay with me here, because this is apparently a difficult concept — that people will try new things. They will build bots. They will write software. They will push the boundaries of what the technology can do. That’s not a bug. That’s the entire point.
Here’s what these packet police don’t understand — and this is the part that really twists my antenna — they’re not protecting anything. They’re not preserving some sacred tradition. They’re just being loud. They contribute nothing to the technology, nothing to the community, nothing to the advancement of what mesh networking can become. They don’t write code. They don’t build tools. They don’t set up infrastructure. They just complain. And then they complain about the complaining. It’s complaints all the way down, like a fractal of uselessness.
Meanwhile, the rest of us — the actual builders, the people who got into this because we wanted to learn, experiment, and create — we’re out here writing earthquake monitors and propagation forecasters and weather beacons and event notification systems. We’re turning mesh networks into something genuinely useful for emergency communications and community information. We’re building the future of off-grid communications while these clowns are busy building bureaucracies on a network that doesn’t need one and never asked for one.
MeshBeacon is open source. The whole thing. Every script, every config example, every line of code. It’s sitting right here:
Fork it. Clone it. Adapt it for your area. Change the coordinates from San Jose to wherever you are. Add your own local weather stations. Point the earthquake monitor at your own fault lines. Write a new broadcast module that does something I haven’t thought of yet. I want this code running on mesh networks everywhere — in every city, on every mountaintop, in every emergency communications trailer in every county in this country.
And I’ll be honest with you: if MeshBeacon’s widespread adoption happens to irritate the self-appointed sheriffs of MeshCore — the ones who think a mesh network should be a quiet, orderly, sterile place where nothing interesting ever happens — then that’s not a side effect. That’s a feature. Nothing would make me happier than knowing that somewhere out there, some guy who’s never written a line of code in his life, who’s never contributed a single useful thing to this platform, is sitting in front of his radio watching earthquake alerts and weather reports and SOTA spots scroll by, absolutely fuming that someone had the audacity to make the network actually useful.
Build something. Share it. Make the mesh better. And if someone tells you you’re doing it wrong on a platform where there are essentially no rules? Point them to the block button and suggest they use it. Vigorously.
The code is open source. The APIs are free. The spectrum belongs to all of us.
Now get out there and build something.
73 W6SAL