Monitor and control an openHop Repeater from Home Assistant.
This custom integration connects Home Assistant directly to the Repeater's local HTTP API. During setup it signs in once with the Repeater admin password, creates a dedicated API token, stores that token in the Home Assistant config entry, and discards the admin password.
The integration uses coordinated local polling instead of making a separate API request for every entity. The polling interval is configurable in the integration options and defaults to 15 seconds.
Normal polling reads the Repeater's cached update status without discovering GitHub branches. A separate scheduled check runs at one minute past each hour (HH:01:00) in Home Assistant's configured timezone, respecting the Repeater's cache and rate-limit hold. It does not check immediately on startup or install anything, and skips a check already in progress or an installation. The Check for updates button and explicit action still request a manual check. The channel selector uses main, dev, and the current channel without querying GitHub.
Note
The integration domain and folder remain pymc_repeater so existing installations and entity registry entries continue to work. The user-facing name is openHop Repeater.
- UI-based setup and options flows
- Configurable integration-wide polling interval
- Repeater, single/multi-radio stack, packet, routing, and signal-quality telemetry
- MQTT broker, handler, and neighbor-publication status
- Hardware, process, network, database, and metrics diagnostics
- GPS position, fix, satellite, time-sync, and location-update data
- External sensor-manager entities, including supported modem and UPS readings
- Application-plugin health counts (installed, enabled, running, and failed)
- Neighbor-link counts, neighbor-scope queries, and on-demand neighbor history
- Default-region, duty-cycle, advert-rate, advert-schedule, and Repeater-mode controls
- Update status, update-channel selection, and update actions
- CAD calibration controls and manual CAD checks
- Native Home Assistant diagnostics and an extensive example dashboard
- Home Assistant 2024.1 or newer
- A running openHop Repeater
- The Repeater HTTP API reachable from Home Assistant
- The Repeater admin password for initial setup or reauthentication
- A trusted local network, VPN, or another secure path between Home Assistant and the Repeater
This integration is currently installed as a HACS custom repository:
-
Open HACS → Integrations.
-
Open the top-right menu and select Custom repositories.
-
Add:
https://github.com/openhop-dev/openHop-HA-Integration -
Select Integration as the category.
-
Install openHop Repeater.
-
Restart Home Assistant.
-
Download the latest release.
-
Copy
custom_components/pymc_repeaterinto your Home Assistant configuration directory:/config/custom_components/pymc_repeater -
Restart Home Assistant.
After installation and restart:
- Open Settings → Devices & services.
- Select Add integration.
- Search for openHop Repeater.
- Enter the Repeater hostname or IP address, HTTP API port, and admin password.
- Submit the form.
Home Assistant will create and retain a dedicated API token. The admin password is not stored after setup completes.
Open Settings → Devices & services → openHop Repeater → Configure to change:
- Integration polling interval, defaulting to 15 seconds
- Data-size display unit
- Uptime display unit
Changing an option reloads the integration automatically.
A comprehensive native Lovelace view is included at:
dashboards/openhop_repeater_dashboard.yaml
The template covers radio health and stack diagnostics, packet flow, LBT diagnostics, routing, neighbor links, plugin health, controls, advert tuning, MQTT, companions, GPS, external modem power readings, updates, and database metrics.
To use it:
- Find one Repeater entity in Home Assistant, such as
sensor.my_repeater_repeater_version. - Copy the entity prefix—in this example,
my_repeater. - Replace every
REPEATER_SLUGin the template with that prefix. - Create or edit a dashboard view and paste the template into the view's YAML editor.
- Optionally change the view
titleandpath. - Replace the marked example MQTT broker and companion rows with entities from your installation.
- The modem percentage card automatically finds active battery and solar-rate entities even when Home Assistant adds an area prefix or numeric suffix.
- For other dynamic rows, replace the complete example entity ID with the active entity ID shown in your instance. If the external sensor is not named
modem, also update_sensor_modem_in the percentage card's two match strings.
- Uses built-in Home Assistant cards; no custom card installation is required
- Groups the view into Live overview, Recent trends, Operations, Diagnostics, and Reference notes
- Uses three responsive desktop columns and natural-height detail cards, with dense placement disabled to keep the overview first
- Keeps key metrics and optional battery/temperature in the overview; detailed controls, GPS, and secondary readings stay below
- Shows named badges, compact metric tiles, and explicit API, statistics, and radio problem banners; disabled GPS does not trigger an alarm
The template uses the current Sections frontend, which requires a newer Home Assistant frontend than the integration's minimum supported version. Configuration was saved and read back on HA 2026.9; that is not a rendered-layout verification. Numeric precision remains controlled by Home Assistant, without global entity-registry changes.
- Use exact entity IDs from the same Repeater config entry, including its radio child devices
- Radio child prefixes are independent of
REPEATER_SLUG; replacing the parent prefix alone does not resolve every row - Repeat rows for multiple radios, plugins, or sensor sources, and remove unsupported rows or cards
- Keep the existing view's title, path, icon, and other metadata when replacing it, and back up the complete dashboard first
The diagnostics include endpoint problems, last successful poll, source age and
staleness, radio settings, and individual plugin status. Battery trend means
charging, discharging, or neutral, based on fresh signed charge-rate
readings in %/h; it does not infer a full battery. The native update tile opens
more-info and does not install updates automatically.
For a smaller starting point, use the compact operations view.
Blueprints are reusable automation templates. Import a template, select the entity to monitor, and choose the actions to run. Installing the integration does not create these automations or select a notification destination for you.
- Open Settings → Automations & scenes → Blueprints in Home Assistant
- Select Import Blueprint
- Copy the link address of one of the templates below and paste it into the import URL field
- Preview and import the blueprint, then select Create automation
- Choose the entity, sustained duration, and threshold where applicable
- Under Actions to run, add your own notification or other action
- Give the automation a descriptive name and save it
The links below use the stable main branch. To test development blueprints,
replace /blob/main/ with /blob/dev/ in the import URL.
| Blueprint | Entity to select |
|---|---|
| Low battery | Battery-percentage sensor; thresholds use the selected sensor unit |
| High temperature | Temperature sensor; match the threshold to its unit |
| Repeater unavailable | A sensor that becomes unavailable when the Repeater disconnects |
| MQTT disconnected | An individual broker connectivity entity you intend to keep connected, not the aggregate any-broker entity |
| Stale sensor | The source stale problem sensor |
| Plugin failure | The individual plugin problem sensor |
| Update available | The update-available binary sensor |
Create an automation from Low battery and set:
- Entity to monitor: your Repeater's battery-percentage sensor
- Sustained duration: 5 minutes
- Threshold: 20
- Actions to run: your phone's notification action, with a message such as “Repeater battery has been below 20% for five minutes”
Reuse the same blueprint to create separate automations for other Repeaters. Threshold alerts fire when the value crosses the limit and stays there; they do not repeatedly fire while the value remains beyond it. Waiting timers reset after Home Assistant restarts or automations reload.
For manual YAML installation and further entity-selection guidance, see alerts and compact view.
The integration exposes Home Assistant actions for supported Repeater operations, including:
- Sending flood or direct adverts and restarting the Repeater service
- Checking for and installing updates
- Reading broker presets, neighbor-link history, and stored neighbor scopes
- Querying one zero-hop neighbor's scopes or scheduling an MQTT neighbors publication cycle
- Running manual CAD checks and CAD calibration
- Saving CAD settings
- Reading advert, companion, and contact diagnostics
Open Developer tools → Actions and search for openHop Repeater or pymc_repeater to see the actions and their current fields.
- aligned advanced action http budgets with backend waits plus a finite margin for ping and manual cad checks and companion text sends and login and commands
- bounded ping reply waits to 1–60 seconds with 6 additional http seconds and companion status and telemetry waits to 1–120 seconds with 10 additional http seconds
- added optional
response_variablesupport topymc_repeater.companion_request_statusandpymc_repeater.companion_request_telemetrywith unwrapped backend dictionaries and non-dictionary results wrapped underresultwhile preserving calls without responses and avoiding polling or entity attributes for these results - surfaced explicit companion
sent: falseresults as action errors without treating omittedsentfields on older backends as failures
The raw radio-config action accepts the Repeater dev radio_id field for multi-radio targeting and direct_advert_interval_hours for the additional advert schedule. The raw MQTT-config action accepts custom base_topic values and neighbor-publisher settings supported by current Repeater dev builds.
Application-plugin counts use the installed plugin manager's lightweight /api/plugins/ list on the shared polling schedule. These are separate from external sensor-manager readings. Counts and an allowlist of plugin ID, name, version, enabled, state, and has_runtime enter coordinator data. Paths, settings, logs, PID, descriptions and repository URLs are not retained. An empty inventory reports zero; unsupported/unavailable manager endpoints or malformed inventory leave the counts unknown rather than falsely reporting a healthy empty installation. Authentication and connection failures still fail the regular refresh.
Enabled plugins is not the same as Running plugins: UI-only plugins can be enabled without a running process. Failed plugins counts only the manager's explicit FAILED state, not stopped/disabled plugins.
The existing pymc_repeater.get_neighbor_link_history response-returning action accepts optional bucket_seconds (integer, minimum 60). Omit it to preserve the raw rows response. Supply it to receive buckets, bucket_seconds, and a bucket count; limit caps returned buckets rather than raw observations. This requires a Repeater build supporting bucketed history and is never polled automatically. For example:
action: pymc_repeater.get_neighbor_link_history
data:
config_entry_id: YOUR_CONFIG_ENTRY_ID
peer_hash: AB
path_hash_size: 1
hours: 24
limit: 1000
bucket_seconds: 300
response_variable: neighbor_historyReplace the example entry ID and peer hash with your target. Omit bucket_seconds for older Repeater builds; there is no silent fallback from buckets to raw rows. See installed API alignment notes for the audited source contract and intentionally deferred capabilities.
The Home Assistant integration stores an API token, while the Repeater stores the matching token hash in its SQLite database. Both the Repeater JWT secret and SQLite database must persist across Repeater restarts.
For the openHop Home Assistant add-on, use the persistent openHop storage path:
storage:
storage_dir: /var/lib/openhop_repeaterUsing the legacy, unmapped /var/lib/pymc_repeater path in the renamed add-on can cause the API-token database to disappear when the add-on restarts. The integration will then report Authentication failed for /api/stats and request reauthentication.
Do not publish your admin password, JWT secret, Home Assistant token, or Repeater API token in an issue or diagnostic upload.
- The Repeater API is currently accessed over plain
http://. - Keep Home Assistant and the Repeater on a trusted network, behind a VPN, or within another secure transport boundary.
- Revoke unused Home Assistant API tokens from the Repeater.
- If a token is revoked or no longer validates, Home Assistant starts its standard reauthentication flow.
- Join the openHop Discord
- openHop Repeater
- openHop Repeater Home Assistant add-on
- Release notes
- Issue tracker
- added parent repeater
radio_statusandradio_problementities from aggregate runtime health rather than api connectivity or configured child radios withradio_errorexposed only as a boolean or unknown attribute and never raw exception text - recognized
single_fabricfor single-radio lifecycle handling and guarded global settings fallback to the sole named default while preferringradio_typeover legacytypefor configured inventory - preferred each reading envelope's
poll_interval_secondsfor freshness and retained the legacy global-summary fallback only when that field was absent - documented that effective per-reading cadence required a companion backend scheduler metadata change not yet released or deployed and that updating this integration alone could not establish legacy plugin cadence
Aggregate flood/direct received, transmitted, and duplicate packet counters are exposed on the parent Repeater device using existing stats polling. These are process-lifetime totals, not per-radio counters or hourly rates; missing values remain unknown.
See operational monitoring for radio child devices, source freshness and component diagnostics, native update installation safety, plugin health, battery units, alert blueprints, and the separate compact operations view.
The repository includes HACS validation, Hassfest, Python compilation, and contract tests. To run the local checks:
python3 -m unittest discover -s tests -v
python3 -m compileall -q custom_components/pymc_repeaterRelease versions are defined in custom_components/pymc_repeater/manifest.json and documented in CHANGELOG.md.
Contributions and focused bug reports are welcome. Please include the Home Assistant version, integration version, Repeater version, and relevant redacted logs when reporting a problem.