Skip to content

Wulpus web gui - #47

Merged
Sebi1128 merged 60 commits into
devfrom
wulpus-web-gui
Sep 1, 2026
Merged

Wulpus web gui #47
Sebi1128 merged 60 commits into
devfrom
wulpus-web-gui

Conversation

@Sebi1128

@Sebi1128 Sebi1128 commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

13Bytes and others added 30 commits August 15, 2025 09:10
= switch to compressed log
+ Add stop-button
+ Add fullscreen-mode for graph
…oints for logs and configs and a new ConfigFilesPanel
- Add documentation for new GUI / wulpus controller
Add gitlab runner build of a all-in-one exe using pyinstaller
13Bytes and others added 26 commits September 9, 2025 16:49
… only sending ws-message on change)

+ adding warning about offline-server to ui
(+ fix build by removing unnecessary import)
+ Add Matlab import script
+ make logfiles more tracable to wulpus by appending connection details
Add support for multiple WULPUS in parallel
Merge dev into main for v1.2.3 release
update fork with upstream
move from pip to uv and clean up READMEs
Copilot AI lite review requested due to automatic review settings September 1, 2026 12:57
@Sebi1128
Sebi1128 merged commit 290731c into dev Sep 1, 2026
2 checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a web-based WULPUS GUI (React/Vite) and a FastAPI backend with WebSocket streaming, configuration endpoints, logging/replay, plus build/release packaging updates and refreshed documentation.

Changes:

  • Introduce a FastAPI backend (sw/wulpus/) with typed config/models, dongle interfaces (USB/BLE/mock), data processing, and WebSocket broadcasting.
  • Add a React/Vite frontend (sw/wulpus-frontend/) for connection management, live plotting (A-mode/B-mode), configuration editing, series execution, and log replay/download.
  • Update packaging and docs (PyInstaller spec, GitHub Actions release workflow, changelogs, READMEs, ignores).

Reviewed changes

Copilot reviewed 80 out of 97 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
sw/wulpus/wulpus.py Core device controller: connect/start/measure/save log frames.
sw/wulpus/wulpus_model.py Shared status + measurement response models.
sw/wulpus/wulpus_mock.py Mock/replay-capable Wulpus implementation.
sw/wulpus/wulpus_config_models.py Pydantic configuration models + validation.
sw/wulpus/wulpus_api.py Byte-package generation for HW config/restart.
sw/wulpus/wulpus_api_helper.py Helper constants + TX/RX bitmask builder.
sw/wulpus/websocket_manager.py WebSocket connection management + broadcasts.
sw/wulpus/series.py Series scheduling models + loop.
sw/wulpus/production-frontend/.gitignore Keep production frontend dir but ignore built assets.
sw/wulpus/plot_helpers.py Plotting helpers for loading/formatting measurement logs.
sw/wulpus/measurements/.gitignore Ignore recorded measurement outputs.
sw/wulpus/main.spec PyInstaller packaging (includes frontend assets).
sw/wulpus/interface.py Async dongle interface contract + connection types.
sw/wulpus/interface_usb.py Serial (USB dongle) implementation.
sw/wulpus/interface_mock.py Mock dongle implementation for simulation.
sw/wulpus/interface_direct.py Direct BLE implementation (Nordic UART Service).
sw/wulpus/helper.py IO/helpers: zip log load, config load, misc utilities.
sw/wulpus/data_processing.py Peak detection + wavelet/envelope processing pipeline.
sw/wulpus/configs/.gitignore Ignore saved config files output.
sw/wulpus/config-analysis/.gitignore Ignore analysis config output.
sw/wulpus/.gitignore Ignore backend build/dist artifacts.
sw/wulpus-frontend/vite.config.ts Dev proxy for API/logs/configs/ws.
sw/wulpus-frontend/tsconfig.node.json TS config for Vite/node tooling.
sw/wulpus-frontend/tsconfig.json TS project references.
sw/wulpus-frontend/tsconfig.app.json TS config for the app bundle.
sw/wulpus-frontend/src/websocket-types.ts Frontend types mirroring backend payloads.
sw/wulpus-frontend/src/vite-env.d.ts Vite type declarations.
sw/wulpus-frontend/src/UsConfig.tsx UI panel for ultrasound config (basic/advanced).
sw/wulpus-frontend/src/TxRxConfig.tsx UI for editing TX/RX channel configs.
sw/wulpus-frontend/src/StatusView.tsx Connection/status dropdown + connect/disconnect actions.
sw/wulpus-frontend/src/SeriesPanel.tsx UI to start/stop repeated measurement series.
sw/wulpus-frontend/src/MultiNumField.tsx Input widget for comma-separated channel lists + toggles.
sw/wulpus-frontend/src/main.tsx App bootstrap + routing.
sw/wulpus-frontend/src/LogsPage.tsx Recorded logs listing + replay/download UI.
sw/wulpus-frontend/src/index.css Tailwind base + icon font + slider styling.
sw/wulpus-frontend/src/helper.ts Config defaults + DSP helpers + fullscreen helper.
sw/wulpus-frontend/src/Graph.tsx Plotly rendering for signal + B-mode heatmap + filter controls.
sw/wulpus-frontend/src/Fields.tsx Small form field components.
sw/wulpus-frontend/src/ConnectionPanel.tsx Connection orchestration (scan/mock/start/stop).
sw/wulpus-frontend/src/ConfigFilesPanel.tsx Save/load/delete configs via API + local upload.
sw/wulpus-frontend/src/assets/react.svg Frontend asset.
sw/wulpus-frontend/src/App.tsx Main dashboard layout + WS integration + state handling.
sw/wulpus-frontend/src/api.ts Frontend API client functions + shared types.
sw/wulpus-frontend/src/AnalysisConfigPanel.tsx UI for peak/spacer analysis configuration.
sw/wulpus-frontend/README.md Frontend dev/build instructions.
sw/wulpus-frontend/public/vite.svg Frontend asset.
sw/wulpus-frontend/package.json Frontend dependencies + scripts.
sw/wulpus-frontend/index.html Frontend HTML entry.
sw/wulpus-frontend/eslint.config.js ESLint config for TS/React setup.
sw/wulpus-frontend/build.py Build+copy script into backend-served production directory.
sw/wulpus-frontend/.gitignore Ignore node/build/editor artifacts.
sw/uss_config.json Example ultrasound config JSON.
sw/uss_config_hand_tests.json Example config for hand tests.
sw/tx_rx_configs.json Example TX/RX config JSON.
sw/README.md Updated software usage instructions (web UI + source build).
sw/pyproject.toml Python project deps (FastAPI, BLE, parquet, etc.).
sw/MATLAB_load_wulpus_log.m MATLAB loader updated for new zip/parquet log format.
sw/LICENSE License header adjustment.
sw/jupyter notebook (legacy)/wulpus_jptnbk/uss_conf.py Legacy notebook import path + formatting updates.
sw/jupyter notebook (legacy)/wulpus_jptnbk/uss_conf_gui.py Legacy notebook import path + formatting updates.
sw/jupyter notebook (legacy)/wulpus_jptnbk/test_rx_tx_conf.py Added tests for legacy rx/tx logic.
sw/jupyter notebook (legacy)/wulpus_jptnbk/rx_tx_conf.py Added helper to build tx/rx configs from a config object.
sw/jupyter notebook (legacy)/wulpus_jptnbk/dongle.py Legacy dongle module moved under legacy package.
sw/jupyter notebook (legacy)/wulpus_jptnbk/config_package.py Legacy config package moved under legacy package.
sw/jupyter notebook (legacy)/wulpus_jptnbk/init.py Legacy package marker.
sw/jupyter notebook (legacy)/wulpus_gui.ipynb Updated imports to legacy package namespace.
sw/jupyter notebook (legacy)/LICENSE Added legacy license file.
sw/jupyter notebook (legacy)/examples/uss_config.json Legacy example config.
sw/jupyter notebook (legacy)/examples/tx_rx_configs.json Legacy example TX/RX configs.
sw/jupyter notebook (legacy)/.gitignore Ignore user outputs except examples.
sw/how_to_install_dependencies.md Removed obsolete conda-based instructions.
sw/convert_measurements.ipynb Notebook to convert old measurements into new log format.
sw/CHANGELOG.md Changelog entries for web UI/backend release.
README.md Root README updates (typos + software instructions + attribution).
fw/nrf52/README.md Path fixes + wording for firmware docs.
fw/nrf52/how_to_setup_nRF52_toolchain.md Minor wording fix.
fw/nrf52/how_to_flash_nrf52840_dongle.md Corrected dongle flashing doc + paths.
fw/msp430/wulpus_msp430_firmware/wulpus/wulpus_sys.h Add new-config condition helper + comments.
fw/msp430/wulpus_msp430_firmware/wulpus/wulpus_sys.c Use new-config condition helper + cleanup.
fw/msp430/wulpus_msp430_firmware/main.c Refactor acquisition prep/power sequencing for new config flow.
fw/msp430/README.md Path fix in firmware README.
docs/CHANGELOG.md Docs changelog updated for new GUI/API.
AGENTS.md Repo agent guidance (commands/architecture/style).
.gitignore Ignore uv/venv/build artifacts and local dev dirs.
.github/workflows/release-gui.yml Windows build workflow: build UI, PyInstaller, artifact + release.
Suppressed comments (3)

sw/wulpus/interface_direct.py:169

  • Same issue as above: returning (None, None, None) makes the caller think a frame was received.
    sw/wulpus/interface_direct.py:224
  • The function also returns (None, None, None) when acquisition ends, which should be None so callers can reliably use if data is None:.
    sw/wulpus-frontend/src/App.tsx:138
  • React Query's onError callback signature is (error, variables, contextFromOnMutate); the current implementation uses a non-existent context.client and won't restore the previous cached value.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +95 to +100
def validate_channel_ids(cls, channels):
for ch in channels:
if not (0 <= ch <= MAX_CH_ID):
raise ValueError(
f"Channel ID {ch} must be between 0 and {MAX_CH_ID}")
return channels
Comment thread sw/wulpus/wulpus.py
Comment on lines +98 to +99
def set_config(self, config: WulpusConfig) -> bytes:
self._config = config
Comment thread sw/wulpus/wulpus_mock.py
from wulpus.interface_mock import WulpusDongleMock
from wulpus.helper import zip_to_dataframe

from wulpus.wulpus import Status, Wulpus
Comment thread sw/wulpus/helper.py
Comment on lines +90 to +94
zip_files = glob.glob(os.path.join(measurement_dir, '*.zip'))
if not zip_files:
raise FileNotFoundError(f"No zip files found in {measurement_dir}")
zip_files.sort()
return zip_files[:n]
Comment on lines +163 to +165
if not self._bleak_client or not self._bleak_client.is_connected:
print("Error: BLE client is not connected.")
return None, None, None
export type DataFrame = {
measurement: {
data: number[]
time: number[]
Comment on lines +129 to +135
onMutate: async (newData, context) => {
// Cancel any outgoing refetches (so they don't overwrite our optimistic update)
await context.client.cancelQueries({ queryKey: ['fetchAnalyzeConfig'] })
const previousVal = context.client.getQueryData(['fetchAnalyzeConfig'])
context.client.setQueryData(['fetchAnalyzeConfig'], () => newData)
return { previousVal }
},
Comment on lines +111 to +125
try {
const reader = new FileReader();
reader.onload = async (e) => {
const content = e.target?.result;
if (typeof content === 'string') {
const config = JSON.parse(content);
handleApplyConfig(config);
}
};
reader.readAsText(file);
} catch (e) {
setError(String(e));
} finally {
setUploading(false);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants