diff --git a/README.md b/README.md index 9fae8532..fe525ea8 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ curl -X POST http://your-pi-ip:5000/api/v3/plugins/install \ | [Simple Clock](./plugins/clock-simple/) | Time and date display | clock-simple on an LED panel | | [7-Segment Clock](./plugins/7-segment-clock/) | Retro-style 7-segment clock with customizable colors | 7-segment-clock on an LED panel | | [Google Calendar](./plugins/calendar/) | Upcoming events from Google Calendar | | -| [Geochron World Clock](./plugins/geochron/) | World map with the real-time day/night terminator | | +| [Geochron World Clock](./plugins/geochron/) | World map with the real-time day/night terminator | geochron on an LED panel | ### Weather (2) diff --git a/docs/assets/geochron/clock.png b/docs/assets/geochron/clock.png new file mode 100644 index 00000000..f075bcdf Binary files /dev/null and b/docs/assets/geochron/clock.png differ diff --git a/docs/assets/geochron/graticule.png b/docs/assets/geochron/graticule.png new file mode 100644 index 00000000..8f5c58ed Binary files /dev/null and b/docs/assets/geochron/graticule.png differ diff --git a/docs/assets/geochron/hero.png b/docs/assets/geochron/hero.png new file mode 100644 index 00000000..5e5a04fe Binary files /dev/null and b/docs/assets/geochron/hero.png differ diff --git a/docs/assets/geochron/map-centre.png b/docs/assets/geochron/map-centre.png new file mode 100644 index 00000000..714b9c1d Binary files /dev/null and b/docs/assets/geochron/map-centre.png differ diff --git a/docs/assets/geochron/markers.png b/docs/assets/geochron/markers.png new file mode 100644 index 00000000..9f482bdb Binary files /dev/null and b/docs/assets/geochron/markers.png differ diff --git a/docs/assets/geochron/night-brightness.png b/docs/assets/geochron/night-brightness.png new file mode 100644 index 00000000..91be5d7c Binary files /dev/null and b/docs/assets/geochron/night-brightness.png differ diff --git a/docs/assets/geochron/panel-sizes.png b/docs/assets/geochron/panel-sizes.png new file mode 100644 index 00000000..891d88fe Binary files /dev/null and b/docs/assets/geochron/panel-sizes.png differ diff --git a/docs/assets/geochron/seasons.png b/docs/assets/geochron/seasons.png new file mode 100644 index 00000000..1d2b6d88 Binary files /dev/null and b/docs/assets/geochron/seasons.png differ diff --git a/docs/assets/geochron/shots.json b/docs/assets/geochron/shots.json new file mode 100644 index 00000000..919a8730 --- /dev/null +++ b/docs/assets/geochron/shots.json @@ -0,0 +1,524 @@ +{ + "plugin": "geochron", + "defaults": { + "width": 128, + "height": 32, + "scale": 6, + "freeze_time": "2026-09-02T12:00:00+00:00", + "config": { + "enabled": true, + "timezone": "America/New_York" + } + }, + "shots": [ + { + "name": "hero", + "width": 256, + "height": 128, + "scale": 4 + }, + { + "name": "term-bands", + "config": { + "show_terminator_bands": true + }, + "standalone": false, + "width": 256, + "height": 128, + "scale": 3 + }, + { + "name": "term-hard", + "config": { + "show_terminator_bands": false + }, + "standalone": false, + "width": 256, + "height": 128, + "scale": 3 + }, + { + "name": "night-02", + "config": { + "night_brightness": 0.2 + }, + "standalone": false, + "width": 256, + "height": 128, + "scale": 3 + }, + { + "name": "night-05", + "config": { + "night_brightness": 0.5 + }, + "standalone": false, + "width": 256, + "height": 128, + "scale": 3 + }, + { + "name": "night-10", + "config": { + "night_brightness": 1.0 + }, + "standalone": false, + "width": 256, + "height": 128, + "scale": 3 + }, + { + "name": "night-00", + "config": { + "night_brightness": 0.0 + }, + "standalone": false, + "width": 256, + "height": 128, + "scale": 3 + }, + { + "name": "grid-15", + "config": { + "show_grid": true, + "graticule_step_deg": 15 + }, + "standalone": false, + "width": 256, + "height": 128, + "scale": 3 + }, + { + "name": "grid-30", + "config": { + "show_grid": true, + "graticule_step_deg": 30 + }, + "standalone": false, + "width": 256, + "height": 128, + "scale": 3 + }, + { + "name": "grid-45", + "config": { + "show_grid": true, + "graticule_step_deg": 45 + }, + "standalone": false, + "width": 256, + "height": 128, + "scale": 3 + }, + { + "name": "grid-90", + "config": { + "show_grid": true, + "graticule_step_deg": 90 + }, + "standalone": false, + "width": 256, + "height": 128, + "scale": 3 + }, + { + "name": "grid-off", + "config": { + "show_grid": false + }, + "standalone": false, + "width": 256, + "height": 128, + "scale": 3 + }, + { + "name": "markers-all", + "config": { + "show_sun_marker": true, + "show_cities": true + }, + "standalone": false, + "width": 256, + "height": 128, + "scale": 3 + }, + { + "name": "markers-sun", + "config": { + "show_sun_marker": true, + "show_cities": false + }, + "standalone": false, + "width": 256, + "height": 128, + "scale": 3 + }, + { + "name": "markers-city", + "config": { + "show_sun_marker": false, + "show_cities": true + }, + "standalone": false, + "width": 256, + "height": 128, + "scale": 3 + }, + { + "name": "markers-none", + "config": { + "show_sun_marker": false, + "show_cities": false + }, + "standalone": false, + "width": 256, + "height": 128, + "scale": 3 + }, + { + "name": "clock-24", + "config": { + "clock_format": "24h", + "show_seconds": true + }, + "standalone": false, + "width": 256, + "height": 128, + "scale": 3 + }, + { + "name": "clock-12", + "config": { + "clock_format": "12h", + "show_seconds": true + }, + "standalone": false, + "width": 256, + "height": 128, + "scale": 3 + }, + { + "name": "clock-nosec", + "config": { + "clock_format": "24h", + "show_seconds": false + }, + "standalone": false, + "width": 256, + "height": 128, + "scale": 3 + }, + { + "name": "clock-off", + "config": { + "show_digital_clock": false + }, + "standalone": false, + "width": 256, + "height": 128, + "scale": 3 + }, + { + "name": "season-mar", + "freeze_time": "2026-03-20T12:00:00+00:00", + "standalone": false, + "width": 256, + "height": 128, + "scale": 3 + }, + { + "name": "season-jun", + "freeze_time": "2026-06-21T12:00:00+00:00", + "standalone": false, + "width": 256, + "height": 128, + "scale": 3 + }, + { + "name": "season-sep", + "freeze_time": "2026-09-22T12:00:00+00:00", + "standalone": false, + "width": 256, + "height": 128, + "scale": 3 + }, + { + "name": "season-dec", + "freeze_time": "2026-12-21T12:00:00+00:00", + "standalone": false, + "width": 256, + "height": 128, + "scale": 3 + }, + { + "name": "p-64x32", + "width": 64, + "height": 32, + "scale": 8, + "standalone": false + }, + { + "name": "p-128x32", + "width": 128, + "height": 32, + "scale": 8, + "standalone": false + }, + { + "name": "p-128x64", + "width": 128, + "height": 64, + "scale": 6, + "standalone": false + }, + { + "name": "p-256x128", + "width": 256, + "height": 128, + "scale": 3, + "standalone": false + }, + { + "name": "centre-auto", + "width": 64, + "height": 64, + "scale": 8, + "standalone": false + }, + { + "name": "centre-0", + "config": { + "map_center_longitude": 0 + }, + "width": 64, + "height": 64, + "scale": 8, + "standalone": false + }, + { + "name": "centre-neg", + "config": { + "map_center_longitude": -100 + }, + "width": 64, + "height": 64, + "scale": 8, + "standalone": false + }, + { + "name": "centre-pos", + "config": { + "map_center_longitude": 140 + }, + "width": 64, + "height": 64, + "scale": 8, + "standalone": false + } + ], + "composites": [ + { + "name": "terminator", + "columns": 1, + "cells": [ + { + "shot": "term-bands", + "label": "show_terminator_bands: true", + "sublabel": "the default; civil, nautical and astronomical twilight blend into night" + }, + { + "shot": "term-hard", + "label": "show_terminator_bands: false", + "sublabel": "a hard day/night line" + } + ] + }, + { + "name": "night-brightness", + "columns": 2, + "cells": [ + { + "shot": "night-00", + "label": "night_brightness: 0.0", + "sublabel": "the night side goes black" + }, + { + "shot": "night-02", + "label": "night_brightness: 0.2", + "sublabel": "the default" + }, + { + "shot": "night-05", + "label": "night_brightness: 0.5", + "sublabel": "land still readable at night" + }, + { + "shot": "night-10", + "label": "night_brightness: 1.0", + "sublabel": "no darkening at all; only the tint remains" + } + ] + }, + { + "name": "graticule", + "columns": 2, + "cells": [ + { + "shot": "grid-15", + "label": "graticule_step_deg: 15", + "sublabel": "one line per hour of longitude" + }, + { + "shot": "grid-30", + "label": "graticule_step_deg: 30", + "sublabel": "the default" + }, + { + "shot": "grid-45", + "label": "graticule_step_deg: 45", + "sublabel": "" + }, + { + "shot": "grid-90", + "label": "graticule_step_deg: 90", + "sublabel": "equator and prime meridian only" + }, + { + "shot": "grid-off", + "label": "show_grid: false", + "sublabel": "no graticule" + } + ] + }, + { + "name": "markers", + "columns": 2, + "cells": [ + { + "shot": "markers-all", + "label": "Both (the default)", + "sublabel": "subsolar point in yellow, cities in red" + }, + { + "shot": "markers-sun", + "label": "show_cities: false", + "sublabel": "just the subsolar point" + }, + { + "shot": "markers-city", + "label": "show_sun_marker: false", + "sublabel": "just the cities" + }, + { + "shot": "markers-none", + "label": "Neither", + "sublabel": "the bare map" + } + ] + }, + { + "name": "clock", + "columns": 2, + "cells": [ + { + "shot": "clock-24", + "label": "24h with seconds", + "sublabel": "the default" + }, + { + "shot": "clock-12", + "label": "clock_format: 12h", + "sublabel": "" + }, + { + "shot": "clock-nosec", + "label": "show_seconds: false", + "sublabel": "a shorter readout" + }, + { + "shot": "clock-off", + "label": "show_digital_clock: false", + "sublabel": "map only" + } + ] + }, + { + "name": "seasons", + "columns": 2, + "cells": [ + { + "shot": "season-mar", + "label": "20 March", + "sublabel": "equinox: the terminator runs pole to pole" + }, + { + "shot": "season-jun", + "label": "21 June", + "sublabel": "northern solstice: the Arctic is in full daylight" + }, + { + "shot": "season-sep", + "label": "22 September", + "sublabel": "equinox again, tilted the other way through the year" + }, + { + "shot": "season-dec", + "label": "21 December", + "sublabel": "southern solstice: the Antarctic never sets" + } + ] + }, + { + "name": "panel-sizes", + "columns": 1, + "cells": [ + { + "shot": "p-64x32", + "label": "64 x 32", + "sublabel": "a slice of the map, centred on your timezone" + }, + { + "shot": "p-128x32", + "label": "128 x 32", + "sublabel": "the common two-panel chain" + }, + { + "shot": "p-128x64", + "label": "128 x 64", + "sublabel": "most of the globe" + }, + { + "shot": "p-256x128", + "label": "256 x 128", + "sublabel": "the full 360 degrees, which is what this plugin wants" + } + ] + }, + { + "name": "map-centre", + "columns": 2, + "cells": [ + { + "shot": "centre-auto", + "label": "auto (null)", + "sublabel": "derived from your timezone" + }, + { + "shot": "centre-0", + "label": "map_center_longitude: 0", + "sublabel": "Greenwich" + }, + { + "shot": "centre-neg", + "label": "-100", + "sublabel": "North America" + }, + { + "shot": "centre-pos", + "label": "140", + "sublabel": "East Asia and Australia" + } + ] + } + ] +} diff --git a/docs/assets/geochron/terminator.png b/docs/assets/geochron/terminator.png new file mode 100644 index 00000000..c290a692 Binary files /dev/null and b/docs/assets/geochron/terminator.png differ diff --git a/plugins.json b/plugins.json index f900d57c..9eecd2a9 100644 --- a/plugins.json +++ b/plugins.json @@ -263,10 +263,10 @@ "plugin_path": "plugins/geochron", "stars": 0, "downloads": 0, - "last_updated": "2026-07-17", + "last_updated": "2026-09-02", "verified": true, "screenshot": "", - "latest_version": "1.0.3", + "latest_version": "1.0.4", "icon": "fa-globe" }, { diff --git a/plugins/geochron/README.md b/plugins/geochron/README.md index b22e7dee..3e4157a2 100644 --- a/plugins/geochron/README.md +++ b/plugins/geochron/README.md @@ -1,89 +1,335 @@ # Geochron World Clock -image +A real-time Geochron-style world map: an equirectangular map of the Earth with +a live day/night terminator, smooth twilight bands, the subsolar point, +configurable city markers, and a digital clock — scaled to fit any panel size +or shape. -A real-time "Geochron"-style world map: a high-fidelity equirectangular map -of the Earth with a live day/night terminator, smooth twilight bands, the -subsolar point, configurable city markers, and a digital clock - scaled to -fit any LED matrix panel size or shape. +![The world map on a 256x128 panel at 12:00 UTC, with the terminator over the +Pacific and the Atlantic, city markers, and a UTC clock in the +corner](../../docs/assets/geochron/hero.png) + +*Every image in this README is real plugin output, rendered at the true panel +size against a frozen clock and then scaled up so the pixels stay pixels. The +terminator positions are what the plugin actually computes for the dates +shown.* **Data source:** [Natural Earth](https://www.naturalearthdata.com/) 110m -Admin-0 Countries (public domain), vendored locally - no network access -required. +Admin-0 Countries (public domain), vendored locally — **no network access +required**. --- -## How it works +## Table of Contents -- The sun's subsolar point (the location on Earth where the sun is directly - overhead) is computed from a NOAA simplified solar position algorithm, - accurate to a fraction of a degree. -- A 720x360 equirectangular base map is rasterized once at startup from the - vendored country outlines, then cropped/resized per panel size for crisp, - high-resolution output regardless of matrix dimensions. -- Every `update_interval` seconds, the night side of the map is darkened and - tinted, with smooth civil/nautical/astronomical twilight bands across the - terminator (or a hard day/night line if bands are disabled). -- The digital clock ticks every frame for smooth seconds, independent of the - map update cadence. +1. [How It Works](#how-it-works) +2. [Installation](#installation) +3. [Layout Modes](#layout-modes) +4. [Configuration Reference](#configuration-reference) + - [The terminator](#the-terminator) + - [The graticule](#the-graticule) + - [Markers](#markers) + - [The clock](#the-clock) + - [Cities](#cities) + - [Map centring](#map-centring) + - [Colours](#colours) +5. [Through the Year](#through-the-year) +6. [Troubleshooting](#troubleshooting) +7. [Development](#development) +8. [Support](#support) --- -## Layout modes +## How It Works + +- The **subsolar point** — where the sun is directly overhead — is computed + from a NOAA simplified solar position algorithm, accurate to a fraction of a + degree. +- A **720×360 equirectangular base map** is rasterised once at startup from the + vendored country outlines, then cropped and resized per panel size, so output + stays crisp whatever the matrix dimensions. +- Every `update_interval` seconds the night side is darkened and tinted, with + smooth civil, nautical and astronomical twilight bands across the terminator + — or a hard line if bands are off. +- The **digital clock ticks every frame** for smooth seconds, independent of + the map's update cadence. That is why `update_interval` can be generous + without the clock stuttering. + +All computation is `numpy` over a fixed lat/lon grid, cheap enough to run on +Pi-class hardware. + +--- -The map and overlays adapt automatically based on panel aspect ratio: +## Installation + +**From the Plugin Store (recommended).** Open the LEDMatrix web interface at +`http://:5000`, go to **Plugin Manager**, find **Geochron World +Clock** in the **Plugin Store** section, and click **Install**. + +**Manually.** Copy this directory into your LEDMatrix `plugin-repos/` and +restart the display service. + +`enabled` defaults to **`false`**. There is nothing else to configure — the map +data ships with the plugin and no API key or account is involved. + +--- + +## Layout Modes + +The map and overlays adapt to the panel's **aspect ratio**, not its absolute +size: | Aspect ratio | Mode | Layout | -|---|---|---| -| >= 3.0 (e.g. 128x32, 256x32) | Wide sidebar | Map + a sidebar with UTC time/date, local time, and subsolar coordinates | -| 1.5 - 3.0 (e.g. 64x32, 128x64) | Near bleed | Full-bleed map with a small corner time readout | -| < 1.5 (e.g. 64x64, 128x96) | Square/tall | Full-bleed map cropped to a configurable longitude band, with a corner readout | +|--------------|------|--------| +| ≥ 3.0 (128×32, 256×32) | Wide sidebar | Map plus a sidebar with UTC time and date, local time, and subsolar coordinates | +| 1.5 – 3.0 (64×32, 128×64) | Near bleed | Full-bleed map with a small corner readout | +| < 1.5 (64×64, 128×96) | Square / tall | Full-bleed map cropped to a longitude band, with a corner readout | + +![The same map on 64x32, 128x32, 128x64 and 256x128 +panels](../../docs/assets/geochron/panel-sizes.png) + +This plugin rewards width more than most: a 256×128 panel shows the full 360° +at a glance, while a 64-wide panel can only show a slice — which is why +[map centring](#map-centring) exists. --- -## Configuration - -| Option | Default | Description | -|--------|---------|-------------| -| `display_duration` | `20` | Seconds to show before rotating to the next plugin | -| `update_interval` | `45` | How often (seconds) to recompute the sun position and re-render the map | -| `timezone` | `null` | IANA timezone for the local time readout and default map centering. `null` inherits the global LEDMatrix timezone | -| `map_center_longitude` | `null` | Longitude to center on for square/tall panels. `null` auto-derives from the local timezone's UTC offset | -| `show_terminator_bands` | `true` | Smooth civil/nautical/astronomical twilight gradient vs. a hard day/night line | -| `night_brightness` | `0.20` | Brightness multiplier for the night side of the map | -| `show_grid` | `true` | Draw a lat/lon graticule | -| `graticule_step_deg` | `30` | Graticule line spacing in degrees (15/30/45/90) | -| `show_sun_marker` | `true` | Draw a marker at the subsolar point | -| `show_cities` | `true` | Draw configured city markers | -| `cities` | 8 classic cities | Up to 8 `{name, lat, lon, timezone}` entries | -| `show_digital_clock` | `true` | Show the digital time readout | -| `clock_format` | `24h` | `12h` or `24h` | -| `show_seconds` | `true` | Show seconds in the clock readout | -| `colors` | see `config_schema.json` | Ocean, land, coastline, night tint, sun marker, city marker, grid, and text colors | +## Configuration Reference + +| Option | Type | Default | What it does | +|--------|------|---------|--------------| +| `enabled` | boolean | `false` | Whether the plugin runs at all | +| `display_duration` | number | `20` | Seconds on screen before the rotation moves on | +| `update_interval` | integer | `45` | Seconds between recomputing the sun and re-rendering the map | +| `timezone` | string / null | `null` | IANA zone for the local readout and default centring; `null` inherits the global setting | +| `map_center_longitude` | number / null | `null` | Longitude to centre on for square/tall panels | +| `show_terminator_bands` | boolean | `true` | Twilight gradient, or a hard day/night line | +| `night_brightness` | number | `0.2` | Brightness multiplier for the night side | +| `show_grid` | boolean | `true` | Draw the lat/lon graticule | +| `graticule_step_deg` | integer | `30` | Graticule spacing: `15`, `30`, `45` or `90` | +| `show_sun_marker` | boolean | `true` | Marker at the subsolar point | +| `show_cities` | boolean | `true` | Markers for the configured cities | +| `cities` | array | 8 cities | Up to 8 `{name, lat, lon, timezone}` entries | +| `show_digital_clock` | boolean | `true` | The digital time readout | +| `clock_format` | string | `24h` | `12h` or `24h` | +| `show_seconds` | boolean | `true` | Seconds in the readout | +| `colors.*` | array | see below | Nine RGB colours for map and text elements | + +The terminator drifts about a quarter of a degree a minute, so +`update_interval: 45` is already finer than the panel can show. Raising it to +several minutes costs nothing visible and saves CPU; the clock is unaffected +either way. + +### The terminator + +![The map with twilight bands and with a hard day/night +line](../../docs/assets/geochron/terminator.png) + +With `show_terminator_bands` on — the default — the night side fades in through +civil, nautical and astronomical twilight, which is what makes the boundary +look like dusk rather than a cut. Turning it off draws a hard line, which is +sharper on a small panel where a gradient has only a few pixels to work in. + +`night_brightness` controls how dark the night side goes: + +![The map at night_brightness 0.0, 0.2, 0.5 and +1.0](../../docs/assets/geochron/night-brightness.png) + +At `0.0` the night side goes black and only the terminator reads. The default +`0.2` keeps continents faintly visible. At `1.0` there is no darkening at all +and only the tint remains, which makes the day/night boundary nearly invisible +— useful only if you want the map for its own sake. + +### The graticule + +![The graticule at 15, 30, 45 and 90 degree spacing, and turned +off](../../docs/assets/geochron/graticule.png) + +`graticule_step_deg: 15` gives one line per hour of longitude, which is +handsome on a large panel and noise on a small one. `90` leaves just the +equator and the prime meridian. All four values render distinctly. + +### Markers + +![The map with both markers, sun only, cities only, and +neither](../../docs/assets/geochron/markers.png) + +The **subsolar point** is the yellow marker — the single place on Earth where +the sun is directly overhead at that instant. It tracks west at roughly 15° an +hour and north/south with the seasons, which is what the +[seasonal comparison](#through-the-year) below shows. + +**City markers** are red dots at each configured city. Labels and local times +appear when the panel has room for them. + +### The clock + +![The clock in 24-hour, 12-hour, without seconds, and turned +off](../../docs/assets/geochron/clock.png) + +The readout shows UTC time and date, and on a wide panel the local time and the +subsolar coordinates as well. It redraws every frame regardless of +`update_interval`, so seconds tick smoothly. + +### Cities + +`cities` takes up to eight entries: + +```json +{ + "cities": [ + { "name": "New York", "lat": 40.71, "lon": -74.01, "timezone": "America/New_York" }, + { "name": "Tokyo", "lat": 35.68, "lon": 139.65, "timezone": "Asia/Tokyo" } + ] +} +``` + +| Key | What it does | +|-----|--------------| +| `name` | Label, shown when there is room | +| `lat` / `lon` | Decimal degrees; negative is south and west | +| `timezone` | IANA zone, used for that city's local time | + +The defaults are eight well-spread cities, chosen to span the map rather than +for any other reason. Replace them with your own — these are here so you can +copy the exact timezone strings: + +| City | Latitude | Longitude | Timezone | +|------|----------|-----------|----------| +| New York | `40.71` | `-74.01` | `America/New_York` | +| Los Angeles | `34.05` | `-118.24` | `America/Los_Angeles` | +| Rio de Janeiro | `-22.91` | `-43.17` | `America/Sao_Paulo` | +| London | `51.51` | `-0.13` | `Europe/London` | +| Cairo | `30.04` | `31.24` | `Africa/Cairo` | +| Moscow | `55.75` | `37.62` | `Europe/Moscow` | +| Tokyo | `35.68` | `139.65` | `Asia/Tokyo` | +| Sydney | `-33.87` | `151.21` | `Australia/Sydney` | + +### Map centring + +On a square or tall panel the map cannot show all 360°, so it is cropped to a +band. `map_center_longitude` picks the centre of that band: + +![A 64x64 panel centred automatically, on 0, on -100 and on +140](../../docs/assets/geochron/map-centre.png) + +Left at `null` it is derived from your timezone's UTC offset, which puts your +part of the world in the middle — usually what you want. Set it explicitly to +watch somewhere else. It has no effect on wide panels, which show everything +anyway. + +### Colours + +Nine settings under `colors`, each an `[R, G, B]` array: + +| Key | Default | Colours | +|-----|---------|---------| +| `ocean_color` | `[10, 35, 90]` | Water | +| `land_color` | `[40, 110, 50]` | Land masses | +| `coastline_color` | `[90, 160, 100]` | Coastlines and country borders | +| `night_tint_color` | `[10, 10, 40]` | What the night side is tinted toward | +| `sun_marker_color` | `[255, 220, 0]` | The subsolar point | +| `city_marker_color` | `[255, 60, 60]` | City dots | +| `grid_color` | `[70, 70, 70]` | The graticule | +| `text_primary_color` | `[255, 255, 255]` | Clock and headings | +| `text_secondary_color` | `[180, 180, 180]` | Dates and labels | + +Keep `coastline_color` lighter than `land_color` — the coastline is what gives +the continents their shape at small sizes, and losing the contrast turns the +map into green blobs. --- -## Default cities +## Through the Year + +The terminator's shape is the plugin's most visible output, and it is not +decorative — it is computed, and it changes with the season: -| City | Timezone | -|------|----------| -| New York | America/New_York | -| Los Angeles | America/Los_Angeles | -| Rio de Janeiro | America/Sao_Paulo | -| London | Europe/London | -| Cairo | Africa/Cairo | -| Moscow | Europe/Moscow | -| Tokyo | Asia/Tokyo | -| Sydney | Australia/Sydney | +![The map at the March equinox, June solstice, September equinox and December +solstice, all at 12:00 UTC](../../docs/assets/geochron/seasons.png) -Edit, remove, or add to this list (up to 8 entries) in the plugin -configuration. +At the **equinoxes** the terminator runs nearly pole to pole and day and night +are equal everywhere. At the **June solstice** the subsolar point sits over the +Tropic of Cancer and the Arctic never gets dark; at the **December solstice** +it is the Antarctic's turn. All four are rendered from the same code that runs +on your panel, at 12:00 UTC on the real dates. --- -## Notes +## Troubleshooting + +**Nothing appears.** +`enabled` defaults to `false`. + +**The local time is wrong.** +`timezone` is `null` by default and inherits the global LEDMatrix setting. +Check that first, then set it here if you want this plugin to differ. + +**The map is centred on the wrong part of the world.** +On a square or tall panel that is `map_center_longitude` — see +[Map centring](#map-centring). On a wide panel the whole map is shown and there +is nothing to centre. + +**The day/night boundary is hard to see.** +`night_brightness` may be too high. The default is `0.2`; at `1.0` there is +effectively no darkening. + +**City labels do not appear.** +They are drawn only when the panel has room. The dots are always drawn — on a +small panel that is all you get. + +**The map looks like green blobs.** +Coastlines are probably too close in colour to the land. Keep +`coastline_color` clearly lighter than `land_color`. + +**The seconds stutter.** +They should not — the clock redraws every frame independently of +`update_interval`. If they do, the panel's overall frame rate is the +constraint, not this setting. + +--- + +## Development + +### Project structure + +```text +geochron/ +├── manifest.json # Plugin metadata and version history +├── manager.py # GeochronPlugin — config, layout modes, overlays +├── geochron_renderer.py # The drawing, shared with render_preview.py +├── solar.py # Subsolar point and twilight bands +├── worldmap.py # Rasterises the vendored country outlines +├── data/ # Natural Earth 110m countries (public domain) +├── render_preview.py # Standalone preview generator +├── config_schema.json # Settings schema; source of truth for defaults +└── test/ +``` + +`render_preview.py` imports `geochron_renderer` — the same module `manager.py` +draws with — so its previews cannot disagree with the plugin. That is worth +copying if you add a preview generator elsewhere: share the renderer rather +than keeping a second copy of the drawing code. + +### Regenerating the images in this README + +```bash +python scripts/render_docs_assets.py --plugin geochron +``` + +`--check` verifies the committed images still match. The clock is frozen in the +shot list, which is what pins the terminator — without that every image would +change by the minute. + +--- + +## Support + +- YouTube: +- Instagram: +- Discord: +- Sponsor: [GitHub Sponsors](https://github.com/sponsors/ChuckBuilds) · + [Buy Me a Coffee](https://buymeacoffee.com/chuckbuilds) · + [Ko-fi](https://ko-fi.com/chuckbuilds/) -- Map data is vendored at `data/world-countries.geojson` (simplified Natural - Earth 110m countries, public domain) - the plugin makes no network calls. -- All computation is done with `numpy` over a fixed lat/lon grid, so it's - cheap enough to run on Pi-class hardware every `update_interval` seconds. +Released under the GNU General Public License v3.0 — see [LICENSE](LICENSE). diff --git a/plugins/geochron/manifest.json b/plugins/geochron/manifest.json index 55e22752..a7ba75df 100644 --- a/plugins/geochron/manifest.json +++ b/plugins/geochron/manifest.json @@ -1,7 +1,7 @@ { "id": "geochron", "name": "Geochron World Clock", - "version": "1.0.3", + "version": "1.0.4", "author": "ChuckBuilds", "description": "High-fidelity world map clock showing the real-time day/night terminator with civil/nautical/astronomical twilight bands, the subsolar point, configurable city markers, and a digital UTC/local clock - a classic Geochron, reimagined for LED matrix panels of any size.", "entry_point": "manager.py", @@ -24,6 +24,12 @@ ">=2.0.0" ], "versions": [ + { + "version": "1.0.4", + "released": "2026-09-02", + "ledmatrix_min_version": "2.0.0", + "notes": "Documentation only, no behaviour change. Adds real rendered screenshots for every setting that has a visible effect and documents all 24 of them. The hero image was an uploaded GitHub attachment on an external URL; it is now a committed render that regenerates from the plugin and is verified by --check. Adds a seasonal comparison showing the terminator at both equinoxes and both solstices, rendered from the real solar code at 12:00 UTC on those dates, and a map-centring comparison for square and tall panels. Both enum settings were hash-checked: all four graticule_step_deg values and both clock_format values render distinctly. The existing content -- how it works, the aspect-ratio layout table, the default cities and the vendored-data notes -- is kept, with the cities table regaining the latitude and longitude alongside the timezone strings." + }, { "version": "1.0.3", "released": "2026-08-14", @@ -54,7 +60,7 @@ "license": "GPL-3.0", "homepage": "https://github.com/ChuckBuilds/ledmatrix-plugins/tree/main/plugins/geochron", "config_schema": "config_schema.json", - "last_updated": "2026-07-17", + "last_updated": "2026-09-02", "stars": 0, "downloads": 0, "verified": true,