# Copyright 2026 Kemal Yaylali
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The dashboard: four tabs, one viewport, no scrolling.
Layout contract. The page is a fixed three-row grid pinned to the
viewport height: header, tab bar, then a content region that takes the
remaining space and never overflows the fold. Each tab lays its panels
out on an internal grid sized in fractions of that region, so nothing
depends on content height. Where a panel genuinely holds more than fits
(the daily records table, the methods prose) that individual panel
scrolls internally while the page frame stays put. Below 1024 px the
constraint is released, because pinning five panels into a phone
viewport produces unreadable eight-pixel type, and a phone user expects
to scroll anyway.
Visual language carries over unchanged from the previous station page:
slate-950 ground, glass panels, Jakarta for prose and JetBrains Mono for
anything numeric. The one new structural device is the tab bar, and it
earns its place. Five distinct questions (what is it doing, what will it
do, what did it do, is the model any good, how does it work) were
previously one long scroll where the important things sat below the
fold.
The signature element is the estimator internals panel on the Live tab.
Most weather dashboards show numbers. This one shows the state estimator
working: self-heating coefficient, Kalman innovation, novelty distance
and drift pressure, all ticking at 2 Hz. It is the part of the system
that is normally invisible, and watching a filter converge is the most
honest possible demonstration that there is real machinery underneath.
"""
DASHBOARD_HTML = r"""
Ashvale Station
Ashvale Station
- · 0 d logged · k=-
health--:--:--
TemperatureKALMAN
--°C
rate--
raw / cpu--
HumidityHTS221
--%
dew point--
depression--
BarometerMSL
--hPa
tendency--
character--
Sky
--clr
cloud index--
sun / cct--
Observed and forecast
90% band
Conditions ahead
Zambretti prior + online logistic
--
Z=- · -
rain probability--
prior -learner -trust -
Was it wet in the last hour?
0 confirmed observations
pressure, last 24 h--
The only signal here that sees past your walls. Its slope, not its level, is what drives the forecast above.
climatology plus decaying anomaly, not a synoptic forecast
warming up
Verification scorecard
skill above zero means it beats persistence
target
lead
MAE
persist
skill
cover
n
p/c/l
No matured forecasts yet. Rows appear as each horizon reaches its validity time: 15 minutes first, 24 hours tomorrow. The p/c/l column is the ensemble weight on persistence, climatology and the learned model.
Calibration and state
self-heating k--
cpu offset--
Removes the SoC bias. Set it from the reading below.
Trusted thermometer reading
Recursive least squares on the self-heating coefficient. One good reading is enough.
Storage tiers
Precipitation coefficients
novelty d²--
drift pressure--
Novelty is a multivariate departure from the recent norm. Drift reaching 100% queues a retrain.