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/<lang>.js Texts, one file per language (TEXT_XX, and NAMES_XX for translations of common English entity names); build.py collects all files and builds TEXT and LOCAL_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/sound.js Optional sound
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 the language files in i18n/ 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/
  • Translations complete: node tests/check-i18n.js – every language has the same keys as English
  • 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.

Adding a language

  1. Copy src/i18n/en.js to src/i18n/<code>.js (two-letter code, e.g. pt.js) and rename TEXT_EN to TEXT_PT.
  2. Translate all values; optionally add NAMES_PT with translations of common English entity names (see de.js).
  3. Run node tests/check-i18n.js and python3 build.py.
  4. Add the language to the list in src/card.js (visual editor).

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