diff --git a/.github/workflows/site-checks.yml b/.github/workflows/site-checks.yml
index 9bb68db..fbac1c7 100644
--- a/.github/workflows/site-checks.yml
+++ b/.github/workflows/site-checks.yml
@@ -12,8 +12,8 @@ jobs:
verify:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-python@v5
+ - uses: actions/checkout@v6
+ - uses: actions/setup-python@v6
with:
python-version: "3.11"
- name: Check landing page structure and links
diff --git a/README.md b/README.md
index b40d457..fed0888 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,8 @@
# NILMTK ecosystem site
-This repository publishes the canonical NILMTK ecosystem router at
- . It explains which repository to use, the supported
-installation paths, the container policy, citation guidance, and the route from
-a model contribution to a leaderboard result.
+This repository publishes the NILMTK start page at .
+It answers four questions: which repository to use, how to install it, which
+paper to cite, and how a model reaches the benchmark leaderboard.
The site is deliberately dependency-free: semantic HTML, one stylesheet, and a
small progressive-enhancement script. Existing generated core API documentation
@@ -24,8 +23,9 @@ python3 scripts/check_site.py
```
The check rejects duplicate IDs, broken local assets and fragment links,
-insecure public URLs, missing canonical repository or citation links, and
-accidental reintroduction of the retired Bootstrap/jQuery stack.
+missing tab panels, insecure public URLs, missing canonical repository or
+citation links, promotional copy that was intentionally removed, and accidental
+reintroduction of the retired Bootstrap/jQuery stack.
## Editing policy
diff --git a/css/landing-page.css b/css/landing-page.css
index f085a15..0deea6e 100644
--- a/css/landing-page.css
+++ b/css/landing-page.css
@@ -264,13 +264,6 @@ h3 {
content: "";
}
-.hero-grid {
- display: grid;
- align-items: end;
- gap: 58px;
- grid-template-columns: minmax(0, 1.35fr) minmax(350px, 0.65fr);
-}
-
.hero-copy {
min-width: 0;
}
@@ -290,199 +283,121 @@ h3 {
margin-bottom: 65px;
}
-.button {
- display: inline-flex;
- min-height: 51px;
- align-items: center;
- justify-content: center;
- gap: 18px;
- padding: 12px 20px;
- border: 1px solid var(--forest);
- border-radius: 4px;
- font-size: 0.8rem;
- font-weight: 700;
- letter-spacing: 0.01em;
- text-decoration: none;
- transition: transform 160ms ease, background-color 160ms ease, color 160ms ease;
-}
-
-.button:hover {
- transform: translateY(-2px);
-}
-
-.button-primary {
- color: white;
- background: var(--forest);
-}
-
-.button-primary:hover {
- background: var(--green);
-}
-
-.button-secondary {
- color: var(--forest);
- background: transparent;
+.hero-copy-plain {
+ max-width: 900px;
}
-.button-secondary:hover {
- color: white;
- background: var(--forest);
-}
-
-.button-light {
- border-color: var(--surface);
- color: var(--forest-deep);
- background: var(--surface);
+.hero-copy-plain .hero-lede {
+ max-width: 760px;
+ margin-bottom: 0;
}
-.hero-facts {
+.quick-routes {
display: grid;
- max-width: 720px;
- margin: 0;
- padding: 0;
- border-top: 1px solid var(--line);
- list-style: none;
- grid-template-columns: repeat(3, 1fr);
+ margin-top: 52px;
+ border-top: 1px solid var(--ink);
+ border-bottom: 1px solid var(--line);
+ grid-template-columns: repeat(4, 1fr);
}
-.hero-facts li {
- padding: 18px 22px 0 0;
+.quick-route {
+ position: relative;
+ display: flex;
+ min-height: 230px;
+ flex-direction: column;
+ padding: 27px 24px 24px;
+ color: var(--ink);
+ background: rgba(251, 250, 246, 0.48);
+ text-decoration: none;
+ transition: background-color 160ms ease, transform 160ms ease;
}
-.hero-facts li + li {
- padding-left: 22px;
+.quick-route + .quick-route {
border-left: 1px solid var(--line);
}
-.hero-facts strong,
-.hero-facts span {
- display: block;
-}
-
-.hero-facts strong {
- margin-bottom: 3px;
- color: var(--forest);
- font-size: 0.82rem;
-}
-
-.hero-facts span {
- color: var(--ink-soft);
- font-size: 0.68rem;
-}
-
-.signal-panel {
- position: relative;
- margin-bottom: 2px;
- padding: 24px 25px 20px;
- border: 1px solid rgba(20, 35, 31, 0.22);
- border-radius: 3px;
- background: rgba(251, 250, 246, 0.58);
- box-shadow: var(--shadow);
-}
-
-.signal-panel::before {
+.quick-route::before {
position: absolute;
- z-index: -1;
- right: -16px;
- bottom: -16px;
- width: 68%;
- height: 54%;
- border: 1px solid rgba(13, 106, 84, 0.26);
- border-top: 0;
- border-left: 0;
+ top: -1px;
+ right: 24px;
+ left: 24px;
+ height: 3px;
+ background: var(--row-accent, var(--green));
content: "";
}
-.signal-heading,
-.signal-legend,
-.signal-note {
- display: flex;
+.quick-route:hover {
+ background: var(--surface);
+ transform: translateY(-3px);
+}
+
+.quick-route > span {
+ margin-bottom: 17px;
color: var(--ink-soft);
font-family: var(--mono);
- font-size: 0.61rem;
+ font-size: 0.64rem;
+ font-weight: 600;
letter-spacing: 0.06em;
text-transform: uppercase;
}
-.signal-heading {
- justify-content: space-between;
- padding-bottom: 13px;
- border-bottom: 1px solid var(--line);
-}
-
-.signal {
- display: block;
- width: 100%;
- height: auto;
- margin: 12px 0 2px;
- overflow: visible;
-}
-
-.grid-lines {
- fill: none;
- stroke: rgba(20, 35, 31, 0.07);
- stroke-width: 1;
-}
-
-.aggregate-line,
-.appliance-line {
- fill: none;
- stroke-linecap: square;
- stroke-linejoin: miter;
- vector-effect: non-scaling-stroke;
+.quick-route strong {
+ margin-bottom: 9px;
+ color: var(--forest);
+ font-size: 1.15rem;
}
-.aggregate-line {
- stroke: var(--forest-deep);
- stroke-width: 3;
+.quick-route small {
+ color: var(--ink-soft);
+ font-size: 0.76rem;
+ line-height: 1.65;
}
-.appliance-line {
- stroke-width: 2.3;
+.quick-route b {
+ margin-top: auto;
+ padding-top: 24px;
+ color: var(--green);
+ font-size: 0.72rem;
}
-.line-one { stroke: var(--green); }
-.line-two { stroke: var(--blue); }
-.line-three { stroke: var(--amber); }
-
-.signal-legend {
- flex-wrap: wrap;
- gap: 13px;
- margin-bottom: 22px;
- text-transform: none;
+.hero-actions-plain {
+ margin: 24px 0 0;
}
-.signal-legend span {
- display: flex;
+.button {
+ display: inline-flex;
+ min-height: 51px;
align-items: center;
- gap: 6px;
+ justify-content: center;
+ gap: 18px;
+ padding: 12px 20px;
+ border: 1px solid var(--forest);
+ border-radius: 4px;
+ font-size: 0.8rem;
+ font-weight: 700;
+ letter-spacing: 0.01em;
+ text-decoration: none;
+ transition: transform 160ms ease, background-color 160ms ease, color 160ms ease;
}
-.dot {
- width: 6px;
- height: 6px;
- border-radius: 50%;
- background: currentColor;
+.button:hover {
+ transform: translateY(-2px);
}
-.aggregate-dot { color: var(--forest-deep); }
-.one-dot { color: var(--green); }
-.two-dot { color: var(--blue); }
-.three-dot { color: var(--amber); }
+.button-secondary {
+ color: var(--forest);
+ background: transparent;
+}
-.signal-note {
- align-items: center;
- justify-content: space-between;
- padding: 14px 0 0;
- border-top: 1px solid var(--line);
- color: var(--green);
+.button-secondary:hover {
+ color: white;
+ background: var(--forest);
}
-.signal-note svg {
- width: 70px;
- fill: none;
- stroke: var(--green);
- stroke-width: 1;
+.button-light {
+ border-color: var(--surface);
+ color: var(--forest-deep);
+ background: var(--surface);
}
.router {
@@ -1173,11 +1088,6 @@ h3 {
}
@media (max-width: 1050px) {
- .hero-grid {
- align-items: center;
- grid-template-columns: minmax(0, 1.2fr) minmax(320px, 0.8fr);
- }
-
.repo-row {
grid-template-columns: 45px 165px minmax(0, 1fr) 135px;
}
@@ -1287,7 +1197,6 @@ h3 {
padding: 70px 0 66px;
}
- .hero-grid,
.split-intro,
.architecture-grid,
.citation-grid,
@@ -1296,18 +1205,10 @@ h3 {
grid-template-columns: 1fr;
}
- .hero-grid {
- gap: 62px;
- }
-
.hero-actions {
margin-bottom: 45px;
}
- .signal-panel {
- width: min(100%, 560px);
- }
-
.split-intro {
gap: 28px;
}
@@ -1470,28 +1371,6 @@ h3 {
justify-content: space-between;
}
- .hero-facts {
- grid-template-columns: 1fr;
- }
-
- .hero-facts li,
- .hero-facts li + li {
- padding: 13px 0;
- border-left: 0;
- }
-
- .hero-facts li + li {
- border-top: 1px solid var(--line);
- }
-
- .signal-panel {
- padding: 18px 16px;
- }
-
- .signal-note svg {
- width: 42px;
- }
-
.repo-row {
padding: 25px 0;
}
@@ -1611,6 +1490,37 @@ h3 {
}
}
+@media (max-width: 1050px) {
+ .quick-routes {
+ grid-template-columns: repeat(2, 1fr);
+ }
+
+ .quick-route:nth-child(odd) {
+ border-left: 0;
+ }
+
+ .quick-route:nth-child(n + 3) {
+ border-top: 1px solid var(--line);
+ }
+}
+
+@media (max-width: 560px) {
+ .quick-routes {
+ grid-template-columns: 1fr;
+ }
+
+ .quick-route,
+ .quick-route + .quick-route {
+ min-height: 190px;
+ border-top: 1px solid var(--line);
+ border-left: 0;
+ }
+
+ .quick-route:first-child {
+ border-top: 0;
+ }
+}
+
@media (prefers-reduced-motion: reduce) {
html {
scroll-behavior: auto;
diff --git a/index.html b/index.html
index 42928df..35e18a0 100644
--- a/index.html
+++ b/index.html
@@ -3,10 +3,10 @@
-
+
-
-
+
+
@@ -16,7 +16,7 @@
- NILMTK · Open infrastructure for energy disaggregation
+ NILMTK · Start here
Skip to content
@@ -34,10 +34,10 @@
- Choose a package
- Start
- Cite
- Contribute
+ Repositories
+ Install
+ Citations
+ Add a model
GitHub ↗
@@ -45,50 +45,43 @@
-
-
-
Open infrastructure for energy disaggregation
-
From household power to reproducible insight.
-
NILMTK is a research ecosystem for loading real energy datasets, resolving their meaning, implementing disaggregation models, and comparing them under frozen protocols.
-
-
- Python 3.11 supported research path
- Real data REDD · UK-DALE · REFIT
- Open source Apache-2.0 ecosystem
-
+
+
+
Start here
+
Choose what you need.
+
NILMTK is split across four repositories. Pick the job below; the site will take you to the right package and commands.
-
@@ -97,22 +90,22 @@
From household power to reproducible insight.
-
Choose by job
-
Four repositories. Four distinct responsibilities.
+
Repositories
+
Which repository should I use?
-
Start with the question you are trying to answer. The packages work together, but each has one canonical job. This separation keeps data semantics, model code, and scientific claims reviewable.
+
Use core for data, metadata for shared meaning, contrib for models, and NILMbench for fixed protocols and published results.
01
-
Data layer
+
Data and metrics
NILMTK
-
Load, convert, inspect, and score energy data.
-
Use core for dataset converters, buildings and meters, preprocessing, metrics, and classical baselines.
+
Use this for dataset and meter work.
+
Converters, buildings, meters, preprocessing, metrics, and classical baselines.
Repository ↗
@@ -122,12 +115,12 @@
NILMTK
02
-
Semantic layer
+
Names and schema
NILM Metadata
-
Make datasets mean the same thing.
-
Use metadata for the canonical schema, appliance taxonomy, synonyms, meter relationships, and dataset consistency.
+
Use this for shared dataset semantics.
+
Appliance taxonomy, synonyms, meter relationships, and dataset schema.
Repository ↗
@@ -137,12 +130,12 @@
NILM Metadata
03
-
Model layer
+
Model implementations
nilmtk-contrib
-
Use or contribute a disaggregation model.
-
Use contrib for maintained classical, TensorFlow, and PyTorch implementations behind shared NILMTK contracts.
+
Use this to run or add a model.
+
Maintained classical, TensorFlow, and PyTorch implementations with shared interfaces.
Repository ↗
@@ -152,12 +145,12 @@
nilmtk-contrib
04
-
Evidence layer
+
Benchmarks and results
NILMbench
-
Reproduce protocols and compare real runs.
-
Use the benchmark for T1/T2/T3 tasks, provenance, CPU smoke tests, CUDA runs, immutable results, and the living leaderboard.
+
Use this for comparable experiments.
+
T1/T2/T3 protocols, CPU smoke tests, CUDA runs, result provenance, and the leaderboard.
Repository ↗
@@ -171,10 +164,10 @@
NILMbench
-
The system
-
One path from files to claims.
-
NILM Metadata supplies shared meaning across the entire path. Core turns physical files into consistent meters and windows. Contrib supplies models. NILMbench freezes the comparison and publishes only provenance-complete results.
-
Explore the organization ↗
+
How they connect
+
Data → model → benchmark.
+
NILM Metadata defines shared names and schema. NILMTK loads the data. nilmtk-contrib runs models. NILMbench fixes the protocol and publishes results.
+
Open the GitHub organization ↗
NILM Metadata
@@ -193,25 +186,25 @@
One path from files to claims.
-
Start clean
-
A supported route, not another dated tutorial.
+
Install
+
Python 3.11 + uv.
-
Use Python 3.11 and uv . Pick the smallest installation that matches your job. The model install brings core and metadata with it.
+
Choose a tab and copy the commands. The model install includes core and metadata. Dataset files are downloaded separately.
- Recommended Try a model
+ Most users Models
- Data work Core only
+ Data work Core
- No setup Docker
+ Container Docker
- Research Benchmark
+ Results Benchmark
@@ -256,15 +249,15 @@
A supported route, not another dated tutorial.
A
- Bring licensed data Datasets are not baked into packages or images. Download them from their official custodians, follow their licenses, and mount local NILMTK HDF5 conversions read-only.
+ Datasets are not included Download data from its official custodian, follow its license, and convert or mount it locally.
B
- Keep one general image The contrib Dockerfile defines the common starting environment. Model contributions do not create a new container tag or image family.
+ One development Dockerfile nilmtk-contrib provides the common environment. Do not create an image for every model.
C
- Separate benchmark runtimes NILMbench owns pinned CPU-smoke and CUDA-benchmark runtimes. Those images certify results; they are not per-algorithm development images.
+ Benchmark images are separate NILMbench pins CPU-smoke and CUDA runtimes used to certify results.
@@ -273,10 +266,10 @@
A supported route, not another dated tutorial.
-
Cite precisely
-
Credit the layer your work relies on.
-
There is no single citation that describes every part of the current ecosystem. Cite the infrastructure paper for each layer you use, plus the original model and dataset papers.
-
Copy BibTeX from the repositories ↗
+
Citations
+
What should I cite?
+
Cite each NILMTK layer you use. Also cite the original model and dataset papers.
+
Open the core BibTeX ↗
@@ -313,15 +306,15 @@ Credit the layer your work relies on.
-
Extend the ecosystem
-
One model contribution. One auditable route to rank.
+
Add a model
+
Add a model, then benchmark it.
-
Algorithm code and benchmark evidence move at different cadences. A model can merge once its implementation contract is sound. It enters the leaderboard only after the pinned benchmark matrix passes on real data.
+
Model code goes to nilmtk-contrib. Leaderboard evidence goes to NILMbench after the fixed real-data protocol passes.
01 Implement Add the model to nilmtk-contrib using shared validation, windowing, checkpoint, and logging utilities.
Model repository ↗
- 02 Break it on purpose Test malformed inputs, short chunks, lazy imports, determinism, serialization, CPU smoke, and the targeted CUDA path.
Model tests ↗
+ 02 Test Cover malformed inputs, short chunks, lazy imports, determinism, serialization, CPU smoke, and the targeted CUDA path.
Model tests ↗
03 Register Add only the adapter and search space to NILMbench. Dataset and task logic stays in the benchmark, never in a model notebook.
Benchmark repository ↗
04 Run real data Freeze source revisions, image digest, data identity, hardware, seeds, and protocol. Candidate results remain separate.
Run protocol ↗
05 Publish evidence Review immutable result bundles; CI regenerates the leaderboard and rejects hand-edited or incomparable ranks.
Living leaderboard ↗
@@ -329,9 +322,9 @@ One model contribution. One auditable route to rank.
-
New here?
-
Start with a reproducible failure.
-
Open an issue with the repository, exact command, operating system, Python version, dataset identity, and the smallest trace that reproduces the problem.
+
Help
+
Need help?
+
Open an issue with the exact command, operating system, Python version, dataset, and a small reproducer.
Choose a repository ↗
@@ -346,14 +339,14 @@ Start with a reproducible failure.
NILMTK
- Open, inspectable infrastructure for non-intrusive load monitoring research.
+ Data tools, metadata, models, and benchmarks for non-intrusive load monitoring.
-
+