/index.rss is a well-known path: many sites put a feed at the site root so aggregators can guess the URL. On a weather station host, that file is not a homepage and not a news dump. It is an XML document that happens to travel over HTTP. The historical TNET Weather capture of this address had already been replaced by a domain-expiry notice; this article restores the URL as documentation of the document, not as a simulated RSS payload.
How to design the observation fields themselves is the subject of station RSS as a contract. This page is about bytes on the wire: media type, caching, and how a consumer should interpret timestamps and holes.
A feed is a data file at a stable URL
HTML pages are for browsers. They tolerate missing closing tags, mixed encodings, and a <title> that does not match the body. RSS is a dialect of XML 1.0 (W3C XML; RSS 2.0). The first non-well-formed character can make the entire document unusable to a strict parser. That is a feature. A weather feed that “mostly parses” is a corrupted data file.
Place the document at a path you are willing to keep. /index.rss and /RSS/rss-feed.php look similar to humans and are different objects to caches. A .rss suffix suggests a static or infrequently generated file. A .php suffix suggests per-request generation. Consumers and CDNs take the hint. If you generate XML from PHP, you can still serve it at /index.rss via an internal rewrite, but then you must set headers as if it were a data file, not an HTML template.
Do not wrap the XML in a site chrome, cookie banner, or expired-domain HTML. The Wayback residue on this URL is exactly that class of mistake: a client asked for a feed and received a human notice. A parser cannot recover observations from that.
Content-type and encoding
Browsers will display RSS as a tree or a pretty page if the server sends text/html or text/xml with a stylesheet. That convenience trains publishers to “check the feed” by opening it in Chrome. Check it with a validator and a raw header dump instead.
The RSS Advisory Board supported application/rss+xml as the media type for RSS documents. Many hosts still send application/xml or text/xml. text/html is wrong. text/plain is wrong. Charset belongs in the Content-Type header and in the XML declaration, and they must agree. UTF-8 is the only encoding you should offer unless you have a documented legacy constraint.
A small, honest header set for a station feed:
Content-Type: application/rss+xml; charset=utf-8Last-Modifiedfrom the observation file or the generated XML mtimeCache-Controlwith a max-age aligned to the upload intervalETagfrom a hash of the XML bytes if you can compute one cheaply
If PHP prints a warning before the XML declaration, the document is not XML. Display errors belong in a log, not in the feed body.
Caching is how freshness is published
HTTP freshness is defined in RFC 9111. RSS 2.0 also has an optional ttl element in minutes. Those two layers should not contradict each other. If ttl is 10 and Cache-Control says max-age=86400, aggregators that honor HTTP will serve a day-old “current” temperature.
Choose one station-true interval—the same interval Weather Display or Cumulus uses to FTP the source file—and publish it in both places. A consumer should then treat the feed as observed as of pubDate / item time, not as of the moment they requested /index.rss.
Conditional GET (If-Modified-Since, If-None-Match) is how a mesomap should poll. Returning 304 with no body is cheaper than regenerating XML and is more honest than returning 200 with identical bytes.
Interpreting a weather feed versus HTML
HTML can show “72°F” in a <div> and a forecast in a <p> and a webcam in an <img>. A feed consumer does not get layout cues. Everything that matters must be in elements or in documented conventions inside description.
Practical interpretation rules:
- Channel vs item. Channel
titleis the station or site name. Item content is the observation (or a snapshot in a series). Do not read the channel description as a temperature. - HTML inside description. RSS allows entity-encoded HTML. If you receive markup, strip it before parsing numbers. If you receive CDATA with
<b>Temp:</b> 72, the number is still not typed; you are scraping a string that happens to travel in XML. - One current item vs a history. A weblog-style feed appends items. A status-style weather feed often overwrites a single item. Consumers must use
guid(andisPermaLink) to avoid treating an overwrite as a new event or a new event as an overwrite. - Language. Channel
language(en-us, and so on) tells you how to parse month names and decimal commas if those appear in prose. Prefer numeric fields.
The scripts index historically pointed at PHP that produced HTML tables from WD files. Those tables are a different media type with the same underlying lesson: the publication format is not the logger.
Timestamps
RSS item pubDate uses RFC 822 date language, with a four-digit year preferred. That is not ISO 8601. A consumer should parse the offset. If the offset is missing, the value is not comparable to NOAA products or to another station.
Three clocks appear on every request:
- The HTTP
Dateheader (the server’s idea of “now”). lastBuildDate(when the XML was written).- The observation time (item
pubDateor a field inside the payload).
If (3) is older than the station’s maximum upload gap, the feed is a historical snapshot even though the URL still looks like “current conditions.” If (2) is recent and (3) is old, the generator is running against a stale station file. If (1) disagrees with (2) by hours, the host clock is wrong and every timestamp is suspect.
Never substitute the HTTP date for the observation time. Never assume local civil time equals UTC. Never assume a pubDate in the future is a forecast; it is more often a timezone bug. Forecasts, if present, must be labeled as such in the payload.
Missing fields
XML that omits an element is not the same as XML that includes <wind>0</wind>. Consumers should:
- treat absent optional elements as unknown, not zero;
- treat empty strings as unknown;
- accept an explicit missing token if the publisher documents one;
- refuse to interpolate neighboring hours to fill a hole in a status feed (that would be a derived value you invented).
If the document fails to parse, the correct result is an error, not the previous successful parse presented as live. Keeping a last-good cache is reasonable for display, but it must be labeled as last-good and dated.
What this URL is not
This article does not reprint a fake RSS document. Invented XML would be worse than the expired-domain HTML it replaces: it would look machine-readable and be fiction. The historical TNET Weather site offered feeds from the projects cluster and PHP utilities under legacy scripts. Those paths remain the human index.
TNET’s current research still depends on knowing whether a record is an observation, a model field, or a derived summary, and on knowing when it was valid. That source-level discipline is documented in data sources, quality controls, and methodology. A well-known /index.rss path is only useful when it meets the same bar: declared media type, honest cache lifetime, timestamps with zones, and missing values that stay missing.