Commit Graph
785 Commits
Author SHA1 Message Date
Rightup 2eaf380d3d fix: add nosec comments for subprocess.run calls in service_utils.py 2026-09-07 16:51:27 +01:00
Rightup 0b98d2b680 add qr code to FE 2026-09-07 13:39:29 +01:00
Rightup 63ce5b4294 fix: include public key in API response for configured room servers 2026-09-07 13:36:04 +01:00
Rightup ab2e79d771 add further ins to update process. 2026-09-07 12:55:53 +01:00
Rightup cc7a1c426d fix: add notes on how to fix the issue. 2026-09-07 12:12:50 +01:00
Rightup b1c9b6f6a5 fix: enhance plugin manager service bootstrap to support sudo execution 2026-09-07 12:06:38 +01:00
Rightup 3afec59c1a feat: implement plugin manager service bootstrap and add tests 2026-09-07 10:31:05 +01:00
Rightup b65e54196b Merge branch 'pr-436' into dev 2026-09-06 20:35:09 +01:00
Rightup c9fddbfd4b fix: update file handling to use UTF-8 encoding for YAML operations 2026-09-06 20:32:43 +01:00
Rightup 6a2315d5ce feat: add plugin update checking and display in Plugins view 2026-09-05 23:37:22 +01:00
Rightup 8182242f9f update home page plugin buttons 2026-09-05 22:07:12 +01:00
Rightup 3836cb8cf3 feat(catalogue): add homepage field to CataloguePlugin and validate URL format - tighten the fixes to be portable across macOS/Linux 2026-09-05 21:56:19 +01:00
yellowcooln 766c2c2605 docs(web): direct frontend edits to matching RepeaterUI branch 2026-09-05 15:39:17 -04:00
yellowcooln 4aa67a354f fix(plugins): recover interrupted Python environment rebuilds 2026-09-05 13:15:26 -04:00
yellowcooln 1cafdd0383 fix(auth): serialize setup and configuration import transactions 2026-09-05 13:15:26 -04:00
yellowcooln c294de2b12 fix(web): confine frontend assets by resolved path components 2026-09-05 13:11:11 -04:00
yellowcooln 06c41bccba fix(plugins): harden provisioning, runtime, IPC and native upgrades 2026-09-05 13:04:34 -04:00
Rightup c32fb83626 update ui for larger imgs 2026-09-05 00:13:04 +01:00
Rightup 6a393c5c61 feat(plugins): add runtime endpoint and functionality to retrieve plugin runtime data 2026-09-04 22:16:52 +01:00
Rightup 6f9ef1c394 fix(stats): handle missing plugin argument in StatsApp routing 2026-09-04 21:38:10 +01:00
Rightup 9ce23a77d5 feat(plugins): add plugin manager service installation and restart logic 2026-09-04 21:30:29 +01:00
yellowcooln c6098f88e3 Download approved plugins from GitHub Releases 2026-09-04 13:08:09 -04:00
yellowcooln eb8f934124 Install approved plugin wheels directly from R2 2026-09-04 12:13:08 -04:00
yellowcooln 3e008cac26 fix(plugins): use hosted catalogue endpoint 2026-09-04 11:00:03 -04:00
yellowcooln 9150264f49 ci: satisfy plugin branch quality gates 2026-09-04 10:42:33 -04:00
yellowcooln c0aeb89399 fix(docker): supervise plugin manager lifecycle 2026-09-04 10:39:42 -04:00
Rightup 8054333e3f feat:add ui switcher for plugins 2026-09-04 11:12:15 +01:00
Rightup ae8569bbec feat: add web frontends API endpoint and corresponding tests 2026-09-04 11:09:48 +01:00
Rightup 472025da16 feat:add images to catalogue 2026-09-04 08:58:18 +01:00
Rightup 03efbf1a21 feat:plugin-ui 2026-09-03 22:21:07 +01:00
Rightup 26560fd50a Add comprehensive tests for plugin management and IPC functionality
- Introduced tests for the plugin catalogue installation and update flows in `test_plugin_catalogue_install.py`.
- Added unit tests for the GitHub Releases plugin client in `test_plugin_github_releases.py`.
- Implemented IPC tests for the plugin manager Unix socket protocol in `test_plugin_ipc.py`.
- Created lifecycle and installation tests for the plugin manager in `test_plugin_manager_lifecycle.py`.
- Added tests for plugin manifest parsing in `test_plugin_manifest.py`.
- Developed tests for plugin filesystem layout and state management in `test_plugin_storage.py`.
2026-09-03 22:16:38 +01:00
Perry MosbacherandClaude Opus 5 72da7eed7b fix(companion): make bulk contact import match stored advert types
"Import repeater contacts" wrote nothing whenever a contact-type filter was
supplied, and reported success having imported zero rows.

`adverts.contact_type` holds the *display* name written through
`handler_helpers.discovery.NODE_TYPE_NAMES` — "Chat Node", "Repeater",
"Room Server", "Sensor". The import API accepts MeshCore's names — "companion",
"repeater", "room_server", "sensor", validated in
`companion_endpoints.import_repeater_contacts`. `companion_import_repeater_contacts`
compared them directly:

    query += f" AND contact_type IN ({placeholders})"

so "repeater" never matched "Repeater", "room_server" never matched
"Room Server", and "companion" never matched "Chat Node" at all. On a live
repeater with 285 adverts, every one of the four permitted values selected 0
rows, as did all four together; only an unfiltered import worked.

A second defect had the same cause. The adv_type lookup normalised the stored
name (`lower()`, spaces to underscores) but mapped it with the API-name table,
where "chat_node" is absent — so chat contacts imported as adv_type 0 rather
than 1, even on an unfiltered import. That is silently wrong rather than empty,
and needs a manual `UPDATE companion_contacts SET adv_type=1 WHERE adv_type=0`
to repair.

Both sites derived the mapping independently, which is how they drifted. They
now share one `_ADVERT_TYPE_BY_STORED` table keyed on the normalised stored
form: the filter reverse-maps the requested API names onto the stored keys and
compares `LOWER(REPLACE(TRIM(contact_type), ' ', '_'))`, and the adv_type comes
from the same table. Filtering and limiting stay in SQL. An unrecognised type
still selects nothing rather than silently widening the query.

Tested against the real stored forms: 6 of the 8 new tests fail on current dev
(each of the four type filters, all four combined, and the adv_type mapping)
and all 8 pass with this change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-03 11:06:44 -04:00
Perry MosbacherandClaude Opus 5 bd0c340856 fix(sqlite): stop creating the upstream index before its columns exist
`SQLiteHandler.__init__` runs `_init_database()` and then `_run_migrations()`.
`_init_database` created `idx_packets_upstream_time`, which spans
`upstream_hash` and `upstream_hash_size` -- columns that, on a database
predating migration 13, only appear once `add_upstream_hash_to_packets` has
added them in the *later* migration step.

Fresh installs were fine, because the `CREATE TABLE` carries both columns. Any
existing database raised `no such column: upstream_hash` part-way through
`_init_database`, which caught and logged it. Every statement after the failing
index was therefore skipped -- including the `room_messages` and
`room_client_sync` tables -- and the daemon started with a partially-created
schema while reporting itself healthy: service active, radio initialised,
companions serving, HTTP up, and no packets recorded.

The `add_upstream_hash_to_packets` migration already creates this index, right
after adding the columns it depends on, so the copy in `_init_database` was
redundant as well as too early. Remove it and leave the index to the migration
that owns those columns. All three paths still end up with it: a fresh database
gets the columns from `CREATE TABLE` and the index when the migration runs, an
un-migrated database gets both from the migration, and an already-migrated one
kept the index from its earlier run.

Observed on a Raspberry Pi 4 upgrading a ~13 MB production database from 1.1.1;
the repeater was off-air for four minutes before the cause was found. It
self-heals on a second start, because the migration still runs after the failed
init, which makes it easy to misread as harmless.

`tests/test_sqlite_upgrade_existing_db.py` builds a database with the
pre-migration-13 schema and asserts `_init_database` runs to completion, keyed
on tables created after the old failure point. Asserting only on the upstream
columns is not sufficient -- the migration adds those either way.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-03 09:05:50 +01:00
yellowcooln f665237825 ci: format room server for pre-commit 2026-09-02 15:57:30 -04:00
yellowcooln 991cf8c47e fix(companion): resolve storage paths consistently 2026-09-02 12:05:57 -04:00
yellowcooln e2ea8b01ad fix(companion): reject non-finite battery values 2026-09-02 10:12:26 -04:00
skjegg a3f8ec18e7 fix(companion): report battery and storage to companion clients
The previous commit fixed battery_mv in the STATS_TYPE_CORE frame, but that is
not the path companion apps use to display battery. CMD_GET_BATT_AND_STORAGE
goes through `CompanionFrameServer._get_batt_and_storage()`, an openhop_core
extension hook documented as "Default: all zeros" that the repeater never
overrode — so apps showed 0% regardless of what any sensor reported.

Override it in the repeater's frame server: battery from the same sensor lookup
added for core stats, storage from the filesystem holding the configured
storage_dir. Both are wired in from main.py alongside stats_getter.

Found by deploying the previous fix and observing that Home Assistant showed the
modem battery correctly while the phone app still showed 0% — two different
paths, only one of which had been fixed.
2026-08-30 12:18:52 -04:00
skjegg 0a2eeea8ee fix(companion): report real battery voltage in core stats
`_get_companion_stats` hardcoded `battery_mv: 0`, so every MeshCore companion
client connected to a Python repeater showed no battery, even when a sensor
plug-in was reporting one. The protocol side is already complete: the frame
server packs `battery_mv` into the STATS_TYPE_CORE frame and clients request it
via CMD_GET_BATT_AND_STORAGE.

Surface the first sensor reading that publishes a usable battery voltage,
accepting either `battery_voltage_mv` or `battery_voltage_v`. This covers an
attached UPS HAT as well as the battery of an openHop modem the repeater is
driving, which is the case that prompted this: a solar-powered modem whose
battery was invisible to the companion app right up until it went flat.

Returns 0 when no sensor reports a battery, which is what clients already
expect from a mains-powered node, and the lookup never raises — stats must
not be able to take down the companion connection.
2026-08-30 08:54:36 -04:00
yellowcooln 50921e1400 refactor(sensors): remove legacy Station G3 fallback 2026-09-01 10:48:36 -04:00
yellowcooln 40a4e4f245 fix(sensors): normalize modem power telemetry 2026-08-30 20:55:48 -04:00
CB 035ba2f672 bus current power sensor payload 2026-08-30 11:42:56 -04:00
Rightup e28be27a77 Merge branch 'pr-402' into dev 2026-08-27 20:53:21 +01:00
Rightup 8bc2cd68e9 fix: update map UI 2026-08-27 20:52:12 +01:00
Rightup 539f9d4454 fix:update ui-yellow 2026-08-24 14:27:37 +01:00
Rightup 24a45ba641 Merge branch 'pr-397' into dev 2026-08-24 14:21:50 +01:00
yellowcooln f280bbdc5c fix: secure modem migration and backup paths 2026-08-24 09:00:50 -04:00
Rightup 303e606bd4 fix:remove-ui-blocker 2026-08-24 13:55:57 +01:00
yellowcooln ada8ba98fb Merge current dev and preserve modem tokens 2026-08-24 08:50:44 -04:00
Rightup 047a68706d Merge branch 'pr-408' into dev 2026-08-24 13:48:47 +01:00
Rightup 7bd0c77c49 Merge branch 'pr-403' into dev 2026-08-24 13:28:04 +01:00