A Cumulus station already knows how to turn observations into text: web tags in a processed extra file, or a compact realtime.txt line with unit tokens. A PHP GD banner is the next step in that chain—paint a few of those values onto a 468×60-class bitmap so a forum, sidebar, or mesomap can show the station at a glance. The historical TNET URL /projects/phpggbanner on cumulus.tnetweather.com was that renderer. This article is about the mapping: which Cumulus fields belong on a strip that thin, how type and units stay honest, and why a regenerated PNG is still not a live feed.
This is not a download of the old generator, and it is not the banner gallery. It is also not the generic hotlink essay on the main-host banner page. Here the source is Cumulus: tags, realtime fields, and the station’s own upload interval.
Historical context
Cumulus processes templates, replaces <#temp> and its neighbors, and uploads the result. Operators who wanted a status image asked PHP’s GD extension to rasterize a few of those values. Typical inputs were a processed extra file or the optional realtime.txt packet: one line of space-separated fields with unit tokens for wind, temperature, pressure, and rain (last checked 13 August 2026).
The TNET project sat on the web host. Cumulus wrote the file; PHP allocated a truecolor image, drew type, and emitted PNG or JPEG. TNET does not rehost that script. The problem remains: bind a Cumulus packet to a fixed pixel budget without implying more freshness or precision than the packet contains.
Two Cumulus inputs, one bitmap
GD does not speak web tags. Something has to resolve tags before the drawing calls.
Processed extra file. Cumulus extra-web-file processing copies template text and substitutes tags (Cumulus Wiki: Webtags, last checked 13 August 2026). A template can be a PHP snippet that assigns $temp = '<#temp rc=y>'; so the banner script requires a local file of already-substituted values. That is the clean Cumulus-native path: the station software does the binding; PHP only paints.
realtime.txt. Off by default. When enabled, it is rebuilt on the realtime interval as one line. Classic Cumulus 1.9.4 / early MX layout maps field 3 to <#temp>, field 6 to <#wspeed>, field 11 to <#press>, fields 14–17 to unit tokens, and field 2 to hh:mm:ss. Later MX releases appended feels-like and weekly rain; a fixed-column parser that ignores the build will mis-assign units.
Use one source. Mixing a processed tag file with a leftover realtime line from a different interval produces a banner whose temperature and wind did not occur together.
What belongs on a 468×60-class image
A 468×60 banner is a 1990s advertising geometry that forums already reserved. At typical screen density you get one line of 11–14 px type plus a second line of 9–11 px type. That is a caption, not a dashboard.
Fields that earn their pixels on a Cumulus banner:
- Outside temperature (
<#temp>/ realtime field 3) plus the temperature unit token. A bare23is unusable in a mixed °C/°F community. Cumulus already ships<#tempunitnodeg>; paint it. - Wind as a labeled pair. Average speed (
<#wspeed>) without a compass point is incomplete; a gust (<#wgust>) without saying “gust” is misleading. If only one wind number fits, name it. Include<#windunit>. - Station identity as a short name, not a slogan. Readers of a mesomap need to know which logger they are looking at.
- A clock or an age. Field 2 /
<#timehhmmss>is the observation time on the packet. If you refuse to paint it, the HTTPLast-Modifiedof the source file has to carry the honesty instead.
Fields that usually do not fit, and should not be squeezed in by shrinking type below about 9 px:
- Today’s rain (
<#rfall>) without the rollover rule. - Pressure tendency (
<#presstrendval>), a three-hour average rate that needs the word “trend” and a unit. - Indoor temperature, UV, solar, extra sensors, and
<#forecastnumber>(a Zambretti-style scenario, not an NWS product). - Latitude, longitude, and version/build—station metadata, not pixels.
The tiny avatar drops still more. The analog thermometer spends its canvas on one scalar. A banner is the middle product: a few independent scalars with units.
Font, units, and legibility
PHP GD can draw with built-in bitmap fonts (imagestring) or TrueType (imagettftext). Bitmap fonts are predictable in size and weak at unit glyphs. TrueType can render °C, m/s, and hPa only if the font contains those characters. A box substituted for ° turns a unit into noise.
- Size the primary temperature so it survives display at half width.
- Keep unit tokens near the number they qualify, in a related size. Orphan 7 px units are decoration.
- Do not encode the unit only in color. Paint the string Cumulus already provides.
- Antialiased type on a photographic background fails. A solid panel behind the numbers is a measurement choice.
- Cumulus realtime files use a script-friendly decimal point even when the PC locale uses commas. Processed tags may follow locale unless you pass MX modifiers such as
rc=y. A painted21,4 Cnext to a parser that expected21.4is a locale bug.
Contrast is part of the observation. A cream-on-pale night banner can collapse after JPEG recompression. PNG is the more honest status format; JPEG is for photographs.
Caching versus “live”
Cumulus realtime generation is optional and interval-based. The wiki’s Fine Offset / EasyWeather note is the instrument constraint that matters: those loggers update on the order of 48 seconds for many sensors, so a one-second banner refresh is cosmetic. Davis-class stations can be faster; the banner still should not claim to be faster than the file it read.
A PHP script that rebuilds a PNG on every HTTP hit trains the public URL to look like a live API. It is not. The pixels are a derived rendering of the last successfully read packet.
- Generate from a local processed file or realtime upload. Do not pull Cumulus over HTTP inside the image request.
- Key the cached PNG to the source file’s modification time (or a hash of the painted fields). If the packet did not change, the image must not.
- Send
Cache-Controlwith a max-age on the order of the Cumulus interval (RFC 9111). - If the source file is older than two upload intervals, drop any LIVE badge. Show the packet time or a stale marker. A fresh-looking banner of a three-hour-old temperature is a false observation.
“Live” is a claim about the whole chain: logger → Cumulus → upload → renderer → cache. The weakest link sets freshness. Painting LIVE does not shorten it.
A working field list for a first banner
If you are designing a Cumulus banner rather than restoring a ZIP, start with this set:
| Role on the strip | Cumulus tag | realtime.txt field (classic layout) |
|---|---|---|
| Air temperature | <#temp> | 3 |
| Temperature unit | <#tempunitnodeg> | 15 |
| Wind (named: avg or gust) | <#wspeed> or <#wgust> | 6 or 41 |
| Wind unit | <#windunit> | 14 |
| Direction | <#currentwdir> or <#wdir> | 12 or 52 |
| Packet time | <#timehhmmss> | 2 |
| Optional: pressure + unit | <#press> + <#pressunit> | 11 + 16 |
That table is a layout contract, not a climate archive. Missing values must not become zero. A calm wind can be 0; a missing wind cannot. Cumulus MX documents that unknown web tags become error strings rather than silent blanks—surface those errors as a blank field or a visible fault, not as 0.0.
What still applies
The Cumulus contract is still clean: tags for processed pages, optional realtime file for frequent consumers, logs for climate. MX JSON and HTTP interfaces obtain the same scalars another way. A GD banner remains a human-facing summary, not a substitute for dayfile.txt.
Choosing which atmospheric fields survive a 60-pixel height is the grouping problem any short status display faces. TNET’s public account of those groups is evidence families. Freshness and units of source files are data sources and methodology.
The Cumulus hub indexes related projects. The web-tag vocabulary is the language this renderer consumes; the TNET web-tags project is the extra-file pattern behind many templates.
Sources
- PHP image processing and GD (last checked 13 August 2026)
- PHP imagettftext
- Cumulus Wiki: Webtags (last checked 13 August 2026)
- Cumulus Wiki: realtime.txt (last checked 13 August 2026)
- RFC 9111: HTTP Caching
- TNET, The evidence families behind a connection outlook
- TNET, Data sources, quality controls and methodology