The Cumulus RSS Project: Generating a Feed from Station Files

How a Cumulus RSS project builds a syndication document from realtime.txt, web tags, and XML—distinct from the HTTP endpoint that later serves that feed.

Back to Cumulus weather software guides

An RSS document on a Cumulus site does not appear by magic. Something has to read the files Cumulus already wrote and emit XML that a reader can poll. The historical path /projects.rssfeed named that project: a generator that turned Cumulus data files into a feed. This article is about that production pipeline.

It is not the public endpoint. What a consumer should require when they GET the live URL is rss.php. It is not a Google Gadget sidebar contract; that is gadgetfeed.php. It is not the tnetweather.com essays on station RSS as a generic observation contract or on /index.rss as bytes on the wire. Those pages are about PWS feeds in general. This page is about Cumulus inputs.

Historical context

Cumulus publishes by processing templates and optionally uploading realtime.txt, extra XML, and HTML (Cumulus Wiki: Webtags; realtime.txt). It does not, by itself, define a universal RSS schema for personal weather stations. Community projects filled the gap: PHP on the web host, or an extra template processed on the PC, produced an RSS 2.0 file so aggregators and other station sites could subscribe.

The historical TNET Cumulus project index treated “RSS feed” as a named package in the same family as banners, realtime logs, and WAP pages. The original ZIP and PHP are not rehosted. The URL remains because the engineering problem is still real: map a Cumulus file contract onto a syndication document without inventing a second climate record.

Inputs: three Cumulus files, three jobs

A generator has to choose a source. Mixing sources without labels is how a feed lies.

realtime.txt as the current packet

realtime.txt is the file designed for near-current values: one line, space-separated fields, unit tokens in-band, rebuilt on the realtime timer if the operator enables it. The wiki is explicit that it is optional, that field counts grew by version, that decimal points are forced for scripts, and that it is not a substitute for dayfile or monthly logs.

For an RSS status feed (one item that represents “now”), realtime.txt is the honest input. Field 1–2 are date and time; fields 14–17 are wind, temperature, pressure, and rain units; later fields include version and build. A generator that ignores the unit fields and prints “mph” because the operator is in the United States has already broken the observation.

A generator that polls faster than the hardware updates (EasyWeather-class loggers on the order of tens of seconds) is not creating a higher-frequency climate series. It is re-serializing the last packet.

Web tags as a processed snapshot

An extra template can contain RSS markup with Cumulus tags in the value positions: <#temp>, <#hum>, <#press>, <#wspeed>, date/time tags, unit tags. Cumulus replaces the tags at process time and uploads the file. That is the same mechanism as the XML webtag dump, except the output dialect is RSS rather than a custom weatherdata tree.

This path is attractive because no PHP parser is required on the host. It is fragile because RSS is XML: an unescaped station name with an ampersand, a forecast phrase with <, or a degree character in the wrong encoding will make the document not well-formed. Web-tag processing does not automatically XML-escape operator-supplied strings. The project must either use tags that emit safe text or wrap values in a way that remains valid XML.

XML export as a named-element source

A generator can parse the community webtag XML and wrap selected items as RSS. That is two schemas in series. It is only justified if you already maintain the XML dump for other tools. Otherwise you have doubled the upload and inherited every parse problem for the sake of a feed that realtime.txt could have filled.

Do not generate RSS by scraping the Cumulus HTML site. Layout is not a schema.

What the project must write

RSS 2.0 still requires a channel title, link, and description (RSS Advisory Board). For a Cumulus station those should identify the station and software, not a news brand. The scientifically load-bearing content is the item.

A Cumulus-aware item should be built so a machine can recover:

  1. The values taken from the chosen Cumulus file (temperature, humidity, pressure, rain, wind).
  2. The unit tokens from that same file, not from a README.
  3. The observation time from the file’s date/time fields, with a timezone or numeric offset. Cumulus date tags follow the PC locale; RSS pubDate is an RFC 822-style date. The project is a clock translation, not a copy-paste of 19/08/09 16:03:45.
  4. Station coordinates if you have them. Cumulus configuration knows lat/lon; realtime.txt does not include them in the classic field list. If the feed omits coordinates, the generator should say so rather than hoping a consumer will scrape the HTML map.
  5. A guid that stays stable when the same “current conditions” item is overwritten.

Channel lastBuildDate is when the RSS bytes were written. Item pubDate is when the Cumulus packet was valid. If the generator runs against a stale realtime.txt, those times diverge. Collapsing them hides a stopped FTP job.

Derived fields in the packet—wind chill, heat index, Zambretti-style forecastnumber—are software-derived. If they appear in the description, label them. They are not NWS products.

Project design choices that are not optional

One current item versus a history. Cumulus realtime.txt overwrites. A generator that appends a new RSS item every poll will create a fake time series with whatever poll interval the cron used, not the logger interval. If you want a history, archive the packet in a separate log and say that log is derived. The RSS project’s default should be overwrite-in-place with a stable guid.

Cadence. Extra-file and realtime timers are quality-control knobs. Generating RSS on the realtime interval is rarely justified: readers will not poll every 10 seconds, and the file is larger than realtime.txt. Generate on the ordinary web-update interval unless you have a documented consumer that needs faster.

Encoding. Emit UTF-8, declare it in the XML header, and escape text. The community XML dump’s ISO-8859-1 example is a warning, not a model for a new feed.

No second schema pretending to be Cumulus. Do not map ClientRaw indexes onto realtime.txt. Do not invent METAR-like tokens in the description unless you are explicitly documenting a hobby encoding, which is a different project (projects.metar).

Practical build checklist

  1. Name the input file and the Cumulus version/build you tested (fields 39–40 in the classic realtime.txt layout; later MX fields exist).
  2. Write a fixture: one captured packet, one expected RSS document, including units and pubDate.
  3. Fail the build if web tags remain unprocessed or if a required field is missing.
  4. Refuse to publish a “current” item when the source file is older than the station’s maximum upload gap.
  5. Document the field list next to the feed URL. The project is incomplete without that note.

The Cumulus hub places this project among the other historical file-contract tools. Provenance and freshness for any public weather record, including a homemade feed, are the subject of data sources, quality controls, and methodology. How TNET later uses public weather evidence in connection research is conceptual on how the service works.

Modern relevance

MX can publish JSON extra files and HTTP interfaces. An operator who still wants RSS can generate it from those interfaces with the same rules: named units, valid time, stable identity, overwrite versus append. The historical /projects.rssfeed path is the name of that generator problem, not a download of 2008 PHP.

If you are consuming rather than generating, skip this page and read the Cumulus-host RSS endpoint.

Sources