WEATHER WIRE 1.0.8
ATDT BBS Native PHP Door
========================

Weather Wire presents official NOAA / National Weather Service data in an
80x25-style BBS interface.

FEATURES
--------
- Current observations from the nearest NWS observation station
- Seven-day NWS point forecast
- Next 12 hourly forecast periods
- Active NWS watches, warnings, and advisories for the selected point
- Full alert text and instructions with paging
- Latest Area Forecast Discussion (AFD) from the responsible NWS office
- NHC/CPHC Atlantic, Eastern Pacific, and Central Pacific Tropical Weather Outlooks
- Active tropical cyclone public advisories with paged storm details
- Per-caller saved location
- ZIP, city/state, or latitude/longitude location entry
- Filesystem response cache to reduce NWS API traffic and keep transient weather data out of ATDT SQLite
- ATDT SysOp admin panel with default location and HTTPS connectivity test
- Context-sensitive ANSI weather art (sun/moon/cloud/rain/wind/storm/snow/fog)
- Red alert banner on the main screen when NWS alerts are active
- ENTER cycles through Current, Forecast, Hourly, Alerts, Discussion, then Main
- M returns to the main Weather Wire screen from every secondary screen
- Q quits the door only from the main Weather Wire screen
- No Composer packages and no separate database setup

OFFICIAL SOURCES
----------------
Weather and alert data:
  https://api.weather.gov

Tropical outlooks and storm advisories:
  https://www.nhc.noaa.gov

ZIP/city location lookup:
  https://forecast.weather.gov

The National Weather Service API does not require an API key. It does require
an identifying User-Agent. Configure a SysOp contact email or web site in the
Weather Wire admin panel after installation.

INSTALLATION
------------
1. Copy the complete "weatherwire" folder into the ATDT native doors folder,
   beside your other native door folders.

   The resulting layout should be:

     doors/
       weatherwire/
         door.json
         door.php
         admin.php
         README.txt
         cache/
           .htaccess
           index.html
         lib/
           NwsClient.php
           WeatherService.php
           TropicalService.php

2. In the ATDT SysOp console, open Doors and run Scan so ATDT discovers the
   door.json manifest.

3. Open Weather Wire's admin panel.

4. Enter a contact email address or web site for the NWS User-Agent.

5. Optionally enter a board-wide default location, for example:

     10001
     New York, NY
     40.7128,-74.0060

   Callers can override the default and save their own location from inside
   Weather Wire.

6. Click "Test weather connections". A successful test confirms that the PHP host
   can reach the NWS and NHC over outbound HTTPS/TCP 443.

7. Add Weather Wire to an ATDT menu as a normal Native Door.

HOSTING REQUIREMENTS
--------------------
- PHP 8.0 or newer
- JSON support (standard PHP extension)
- Either:
    * cURL extension, preferred; or
    * allow_url_fopen enabled for HTTPS streams
- Outbound HTTPS/TCP port 443 access to:
    api.weather.gov
    forecast.weather.gov
    www.nhc.noaa.gov
- Write access to the weatherwire/cache/ directory (the door creates it if missing)

No background daemon, cron job, or API key are required.

CALLER COMMANDS
---------------
C  Current conditions
F  Seven-day forecast
H  Next 12 hours
A  Active alerts
T  NHC/CPHC Tropical Center
D  Area Forecast Discussion
L  Set/save caller location
R  Refresh cached data
?  Help
M  Return to Weather Wire main screen (secondary screens)
Q  Quit (main screen only)
ENTER  Cycle Current -> Forecast -> Hourly -> Alerts -> Discussion -> Main

CACHING
-------
Weather Wire stores transient NWS API responses as JSON files under:

  weatherwire/cache/

It does NOT store NWS response bodies in ATDT SQLite. ATDT's door KV storage is
reserved for persistent Weather Wire settings and caller locations. Approximate
cache lifetimes are:

- NWS point/grid metadata: 24 hours
- Observation station list: 24 hours
- Latest observation: 3 minutes
- Forecast/hourly forecast: 10 minutes
- Active alerts: 60 seconds
- Area Forecast Discussion: 5 minutes
- NHC/CPHC tropical outlook and basin feeds: 5 minutes

The caller can press R on the main screen or supported detail screens to request a
fresh response. A manual refresh still respects the short failure-suppression window
when an upstream source has just failed, preventing a multi-node board from repeatedly
hammering the same unavailable endpoint.

CACHE HOUSEKEEPING
------------------
Weather Wire automatically removes stale cache files. A response first keeps its
normal TTL above; after that TTL expires, the JSON file is retained for a six-hour
grace period and then deleted. During that grace period, Weather Wire can use the
stale response when a live NOAA/NWS/NHC/CPHC request fails, and the screen is clearly
marked as cached/stale. Cleanup runs opportunistically during normal door use, at most
once per hour. Atomic temp-file writes and short non-blocking per-endpoint locks protect
concurrent callers from partial cache files without making another node wait.

The cache remains entirely inside:

  doors/weatherwire/cache/

It is not moved to or stored in an ATDT shared data directory. Short-lived negative
cache markers suppress repeated failed network requests for roughly 45 seconds.


RELIABILITY AND SAFETY
----------------------
Weather Wire is designed for shared/multi-node BBS use:

- Main-screen current observations and alerts fail independently. If one product is
  unavailable, the other can still display.
- Individual HTTPS requests use short connect/request timeouts, and each Weather Wire
  service object enforces an approximately 10-second total network budget.
- Failed endpoints are negatively cached for about 45 seconds to prevent a burst of
  identical failing requests from multiple nodes.
- Expired-but-recent cache entries can be used as stale-if-error fallback for up to
  six hours beyond their normal TTL. Screens identify when stale data is being shown.
- Remote responses are limited to 2 MiB and malformed JSON/RSS/XML is rejected.
- NHC/CPHC feeds are validated before "no active storms" is accepted as a real result;
  HTML error pages or malformed feeds display an unavailable message instead.
- Remote text is sanitized before rendering. ANSI/VT control sequences and unsafe
  control characters are stripped, and ATDT pipe/color sequences are escaped by the
  door renderer.
- Text wrapping/truncation is UTF-8/multibyte safe and constrained to the 80-column
  BBS layout.
- Weather timestamps use the selected location's timezone when appropriate; products
  whose source timezone is retained always display an explicit timezone abbreviation.
- The configured WeatherWire User-Agent/contact is used consistently for NWS,
  forecast.weather.gov, NHC, and CPHC requests.

LOCATION NOTES
--------------
ZIP and city/state lookups use the official forecast.weather.gov location
search. Weather Wire then converts the resulting coordinates through the NWS
/points API, which identifies the responsible forecast office, grid, forecast
URLs, observation stations, and local place name.

A caller who enters latitude/longitude can select a more precise point than a
ZIP or city lookup. The selected coordinates and resolved display name are
stored in the Weather Wire door KV store for that caller.

TROUBLESHOOTING
---------------
If the door displays "Weather service unavailable":

1. Run the Network Test in the Weather Wire admin panel.
2. Confirm outbound HTTPS/TCP 443 is allowed by the hosting provider.
3. Confirm api.weather.gov, forecast.weather.gov, and www.nhc.noaa.gov are not blocked.
4. Confirm either PHP cURL or allow_url_fopen is available.
5. Configure a valid contact value for the NWS User-Agent.


Weather Wire is not affiliated with or endorsed by NOAA or the National
Weather Service. It redisplays public U.S. Government weather information.

TROPICAL CENTER
---------------
Press T from the main Weather Wire screen to open the Tropical Center. It
provides separate basin views for:

- Atlantic / Caribbean / Gulf of America
- Eastern North Pacific (east of 140W)
- Central North Pacific (140W to 180)

Each basin view shows the latest official Tropical Weather Outlook plus the
latest active tropical cyclone Public Advisories. Press O for the full outlook
or select a numbered storm for the full advisory text and forecast narrative.
The tropical products are location-independent and are available even if the
caller has not configured a local weather location.

DAY / NIGHT WEATHER ART
-----------------------
Weather Wire uses the NWS /points timeZone value for the selected location and
PHP sunrise/sunset calculations for that latitude/longitude. Clear weather
therefore displays a sun during local daylight and a moon after local sunset.
Existing saved locations from earlier Weather Wire versions are automatically
resolved through the cached NWS point metadata, so they do not need to be re-set.
