Skip to content

Development

riticulus edited this page Oct 11, 2026 · 18 revisions

Development

Code layout

All source code is in src/, one file per topic. build.py assembles the files in a fixed order – there is no bundler and no dependency besides Python.

File Content
src/version.js Version number (VERSION)
src/i18n.js Texts in English and German, German names for common entity names
src/styles.css Styles – becomes the constant TP_CSS
src/markup.html HTML skeleton – becomes the constant TP_HTML
src/core.js Start of createThreadPulse(root, opts, host) and the state shared by all parts
src/helpers.js Colours, signal quality, icons, theme, connection to Home Assistant, language
src/data.js Loading the data from Home Assistant (registries, cached Matter diagnostics, border router)
src/graph.js Building and drawing the map, the list below it
src/live.js Routing tables, path calculation, animated messages, ticker, subscription to Home Assistant events
src/heat.js Traffic heat
src/rooms.js Room view
src/panel.js Badges and detail panel
src/hints.js Weak-spot hints
src/search.js Search
src/changes.js Change log
src/response.js Response time
src/demo.js Demo mode
src/ui.js List and legend, errors, loading, keyboard and click handling
src/ambient.js Ambient mode
src/start.js Start-up and the public API (destroy, theme)
src/standalone.html Shell of the standalone page (iframe): reads URL parameters
src/card.js Shell of the dashboard card custom:thread-pulse-card: options, visual editor, loading the graph library

How the parts fit together

  • version.js and i18n.js are top-level code.
  • core.js opens the function createThreadPulse(). The files from helpers.js to ambient.js and finally start.js are placed inside this function, in the order listed in build.py; build.py adds the closing brace. That is why the feature files are not valid JavaScript on their own – they use the shared state (network, nodeById, T …) declared in core.js and the other parts.
  • Function declarations can be anywhere in these files. Code that runs immediately during start-up (not inside a function) must only use variables declared in an earlier file.
  • Lines starting with //# at the top of a file are notes for developers and are not copied into the output.
  • The shells (standalone.html, card.js) call createThreadPulse() with a host object that tells the core how to reach Home Assistant, where the theme colours come from and how to open a page in Home Assistant.

Generated files

File Content
thread-pulse.html Standalone page
dist/ha-thread-pulse.js Dashboard card (HACS file)
dist/thread-pulse-vis-network.js, thread-pulse-vis-network.js Graph library (vis-network 9.1.9, unmodified, readable build)

Never edit the generated files by hand.

Building

python3 build.py

Edit only the files in src/; never edit the generated files by hand.

Trying changes

  • Open thread-pulse.html?demo in a browser (served from a local web server, e.g. python3 -m http.server) – no Home Assistant needed.
  • In Home Assistant: copy thread-pulse.html to /config/www/ under another name and open it in an iframe card, or replace the card file of a manual installation.

Checks

A GitHub action runs on every pull request:

  • HACS validation of the repository
  • Build check: build.py is run and the generated files must match src/
  • Syntax check of the card and the page

Workflow

  • One branch and one pull request per issue (feature/<number>-<name>, fix/<number>-<name>); pull requests are squash-merged.
  • New entries go to CHANGELOG.md under Unreleased.
  • Between releases the version is <last release>+dev.
  • A release sets VERSION in src/version.js, moves the changelog section, gets a tag vX.Y.Z and a GitHub release without attachments – HACS would otherwise download the attachment instead of the card.

Contributing

Issues and pull requests are welcome. Please describe your setup (Home Assistant version, border router, number and type of devices) when reporting a problem.

Clone this wiki locally