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/icons.js Device icons: path data of Material Design Icons (top level)
src/styles.css Styles – becomes the constant TP_CSS; semantic colours come from COLORS as CSS variables (--c-good, --c-medium, --c-weak, --c-warn, --c-hint)
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/prefs.js Settings remembered by the browser: one table of keys, types and defaults; prefs.get / set / remove (first of the parts)
src/helpers.js COLORS (all colours in one place), signal quality, icon images, 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/battery.js Battery forecast
src/wifi.js Matter devices on Wi-Fi / Ethernet
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, the language files in i18n/ and icons.js are top-level code.
  • core.js opens the function createThreadPulse(). The files from prefs.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. GitHub offers forms that ask for the details needed:

Form Label For
Bug report bug Something does not work – asks for Thread Pulse and Home Assistant version, installation, border router, number of devices, browser, console errors
Feature request New Feature New functionality
Translation correction translation Wrong or unnatural texts in a language

Further labels: enhancement (restructuring, maintenance, improvements of existing parts) and documentation.

Pull requests get a template with a short checklist: build, translation check, demo mode, real Home Assistant, changelog entry, documentation.

Clone this wiki locally