From three projects to a single window

At the end of October three systems were running in my home and barely talking to each other: HNCC scanned the network, Eon answered questions, and Little Hub, the old laptop that became my home lab, hosted them. Each one had its own interface, and none of them showed the whole picture.

HOMEVERSE was born for that. It’s an Infrastructure Digital Twin of my home: an inventory of rooms, devices and services, with the network that connects them, the status of each one and its metrics, all drawn in an isometric 3D view of the house. I made the first commit on October 30, 2026.

I set the main rule before writing any code: HOMEVERSE observes, it doesn’t control. It isn’t home automation, it doesn’t turn on lights and it never acts on devices. Its job is to show how the home infrastructure is built and how it’s doing, nothing more.

As with HNCC, I built it with Claude Code: I decided the goals, rules and priorities, Claude designed the architecture and wrote most of the code, and every decision is recorded in a dedicated file.

At a glance

BackendPython 3.12+, FastAPI, Pydantic v2, httpx, SQLite with numbered SQL migrations, no ORM
FrontendAstro 7 with static pages and TypeScript modules, no UI framework, self-hosted fonts
3D enginetwin-engine, a standalone TypeScript package built on Three.js
MetricsPrometheus 3.5, plus node_exporter where needed
DeploymentDocker Compose on Little Hub: backend, nginx and Prometheus
Qualitypytest, strict mypy and ruff; astro check and the 3D engine tests
Tests44 for the backend and 5 for the 3D engine

Architecture

Browser (Astro + TypeScript)
   │  HTTP /api/*      WebSocket /ws
   ▼
nginx ── static frontend + reverse proxy (a single origin)
   │
   ▼
FastAPI backend
 ├─ api/routes ── repositories ── SQLite
 ├─ monitoring/    TCP probes, status, metrics
 ├─ integrations/  HNCC, Eon (adapter registry)
 └─ realtime/      WebSocket hub
      │ PromQL        │ TCP          │ HTTP
  Prometheus       Devices       HNCC · Eon

In production nginx serves the frontend and proxies /api and /ws, so the browser and the backend share one origin and no CORS rules are needed. HOMEVERSE isn’t exposed to the Internet: from outside the house you only get in through a VPN.

It’s a monorepo with npm workspaces: the frontend, the 3D engine as a separate package and the Python backend. The domain (rooms, devices, services, links, events, status, metrics and floor plan) is defined with Pydantic in the backend and mirrored by a TypeScript model in the frontend.

Real data, labeled as such

HNCC taught me that a dashboard that makes things up is worse than one that admits it doesn’t know. In HOMEVERSE every piece of data carries its origin:

  • real, if it comes from an actual measurement: a probe, Prometheus, HNCC;
  • demo, if it’s sample data, which looks different in the interface;
  • unavailable, if there’s no way to know.
HOMEVERSE overview: counters for total, online, offline and no-real-data devices, the device list with each status, the Eon and HNCC integrations both reachable, and recent events
The Overview: devices that are online only in demo data are counted separately. IP addresses and people's names are blurred

It isn’t a cosmetic detail. When Eon analyzes the state of the house, it receives only real data: a language model has no way to tell an invented value from a measured one, so the code has to filter first.

Monitoring without noise

  • Periodic TCP probes to the devices instead of ping: ICMP would need extra privileges inside the container, a TCP connection doesn’t. The device just needs one open port.
  • A device goes offline only after two consecutive failures, so a single lost packet doesn’t make the status flap.
  • Events and WebSocket messages are sent only on transitions: a device that stays online for three days doesn’t produce three days of notifications.
  • Metrics are read from Prometheus on demand and never copied into SQLite. Prometheus is already a time-series database; duplicating it would make no sense.

HNCC as the network sensor

HOMEVERSE doesn’t scan the network on its own: it uses HNCC, which already does that well. One rule I set was to integrate HNCC and Eon only after checking their real APIs in the code, without assuming any endpoint.

  • HOMEVERSE pairs with HNCC like any other client, with the viewer role: read-only.
  • Every 30 seconds it imports devices, the links declared by the router and access points, status and alerts. It matches devices by MAC and IP and avoids duplicates with an external reference.
  • When I edit a field in HOMEVERSE, such as a device’s name or room, that field goes into locked_fields and the sync never overwrites it again. The owner’s data always wins.
  • Imported devices start out untrusted: I confirm them myself.
Network page with latency, speed, obstruction, packet loss and uptime of the Starlink connection, 24-hour charts and per-device traffic
Starlink status comes from HNCC and is labeled REAL
Radial network topology: the router in the middle, an access point with its clients on the left and the other devices around it, green when online and red when offline
The topology: solid lines for cables, dashed for Wi-Fi, and only the links declared by the router and access points

Since HOMEVERSE arrived, HNCC’s web dashboard is off and I no longer use the TV app. One interface to maintain instead of three.

Eon as the analyst

On the AI Analyst page I can ask questions about the state of the house. HOMEVERSE builds a summary of the real data only and sends it to Eon in the request’s context field, which I added to Eon for exactly this: the summary reaches the model only for that question and never enters Eon’s history or memory.

Eon runs on the same Little Hub, on CPU, so answers can be slow: the timeout is 300 seconds. Requests are authenticated with Eon’s API token, and the HOMEVERSE container reaches it through Docker’s network interface, without Eon having to listen on the whole LAN.

The digital twin in 3D

The most visible part is the house in 3D, drawn by twin-engine, a TypeScript package that depends only on Three.js. It knows nothing about the backend or the API: it takes a floor plan and a list of devices, and returns selection events. That way it can be tested and reused on its own.

  • An isometric orthographic camera, with orbit, zoom and pan. I chose orthographic over perspective because in an isometric view measurements stay readable.
  • A grid in meters, lights and shadows.
  • Devices are markers colored by status, and sample devices look different. A click selects a device or a room, telling a click apart from a drag.
Isometric view of the two-floor example house, with the study on the first floor, green and red device markers in the rooms and, on the right, the list of rooms with their offline devices
The Digital Twin with both floors: every marker is a device, colored by its status

The floor plan is a versioned JSON file (homeverse.floorplan, version 1): rooms as polygons, walls with their thickness, doors and windows placed along the walls. The backend validates and stores it, and the inventory’s rooms link to the floor plan’s rooms.

The real floor plan of my home isn’t there yet. To avoid an empty digital twin, an example house is active today: 12 × 10 meters on two floors, with the study on the first floor; floors are shown one at a time. When I load the real floor plan, the positions I picked by hand for the devices will stay where they are.

Security

  • A single API token, generated on first start with 0600 permissions and compared in constant time. It’s a single-owner system: I’ll add users and roles if they’re ever needed.
  • The WebSocket authenticates with its first message, so the token never ends up in a URL or in the logs. When it reconnects, the client reloads the full state through REST instead of trusting the messages it missed.
  • The parameter that identifies a device in Prometheus is validated, so nobody can inject a PromQL query.
  • No ports exposed to the Internet and no administrative actions on devices, by design.

The pages

The interface is in English: Overview, Digital Twin, Devices, Network, Services, Monitoring, AI Analyst and Settings, where you paste the API token.

What’s missing

HOMEVERSE is the youngest project in the house, and I’ll say so plainly:

  • the real floor plan is missing: the house you see today is an example;
  • node_exporter still has to be installed on the devices I want to monitor, otherwise their metrics stay empty;
  • I still have to decide the final host for Eon and HNCC, and which VPN to use for remote access;
  • several choices are recorded as pending approval: SQLite without an ORM, readable IDs, a single token, TCP probes instead of ICMP, hand-written TypeScript models and the orthographic camera. They work, but I want to review them calmly before calling them final.

Closing

With HOMEVERSE the home projects stopped being islands. HNCC became a sensor, Eon an analyst, Little Hub the place where everything runs, and HOMEVERSE the window I look through.

It’s also the project closest to the work I want to do as a Cloud Engineer: a system made of independent services, each with a clear role, connected by APIs, observed with real metrics and secure by default. Only, for now, it all fits inside my house.