Skip to content

Refactor GUI into a webpage using a HTTP-API#40

Open
13Bytes wants to merge 56 commits into
pulp-bio:mainfrom
13Bytes:main
Open

Refactor GUI into a webpage using a HTTP-API#40
13Bytes wants to merge 56 commits into
pulp-bio:mainfrom
13Bytes:main

Conversation

@13Bytes

@13Bytes 13Bytes commented Sep 10, 2025

Copy link
Copy Markdown

To increase the usability of the UI and also make it easier to extend the code, I created a big refactor of the python-part of wulpus.
It has feature-parity with some quality-of-life improvements.
Screenshot 2025-09-10 091711

The code-structure is as following:
Ther's now a main Wulpus-class, which only represents a wulpus-board and its states, without any user-interface.
The user-facing API is served via HTTP using FastAPI in main.py, which gets used by the react frontend.
The frontend can therefore take advantage of all the benefits of a browsers rendering engine.
This also increased the overall reliability of the program (at least on my system) a bunch.

It uses the same config-structure, but allows quick editing of all parameters in parallel without any reload.
It also includes an integrated log-browser with replay-functionality.
I added support for integrated bluetooth-adapters and extended the log-format so it also stores e.g. the capture-time and the used config, which allows for easier reconstruction and synchronization between different measurements.

Ther's now also an automatic build of the application (into an .exe) of every commit, which allows users who don't need the dev-environment to just run it. (Can be found as an artifact on the summary-page of every workflow run)

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
@Sergio5714

Copy link
Copy Markdown
Collaborator

@13Bytes , thank you for the contribution to the WULPUS project. It is great to see your alternative GUI.

Our team is currently in a conference trip, we will review your pull request proposal in early October.

@Sergio5714 Sergio5714 self-requested a review November 15, 2025 07:07
@Sergio5714 Sergio5714 self-assigned this Nov 15, 2025
@Sergio5714 Sergio5714 added the enhancement New feature or request label Nov 15, 2025
@Sergio5714

Sergio5714 commented Dec 26, 2025

Copy link
Copy Markdown
Collaborator

@13Bytes , sorry for the delayed reply on this pull request. Unfortunately, I could not review it on time, and since late November I am no longer a member of the PULP-BIO organization nor a maintainer of the WULPUS repository.

I hope others can take it over and merge your contributions. Thank you again for your hard work.

Best,
Sergei

@Sergio5714 Sergio5714 removed their request for review December 26, 2025 07:24
@Sergio5714 Sergio5714 removed their assignment Dec 26, 2025
@Sebi1128 Sebi1128 self-assigned this May 15, 2026
@Sebi1128 Sebi1128 self-requested a review May 15, 2026 13:20
Copilot AI review requested due to automatic review settings June 23, 2026 00:55

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

Refactors the legacy Python/Jupyter GUI into a browser-based UI backed by a FastAPI HTTP/WebSocket API, adds logging/replay functionality, and introduces a Windows build pipeline via PyInstaller + GitHub Actions.

Changes:

  • Added a FastAPI backend + WebSocket streaming layer with a new core Wulpus device/state class and typed config/models.
  • Introduced a new React/Vite frontend (config editing, live plots, logs/replay, series mode).
  • Added packaging/build automation (PyInstaller spec + GitHub Actions artifact/release flow) and updated docs/changelogs.

Reviewed changes

Copilot reviewed 77 out of 94 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
sw/wulpus/wulpus.py New core device/state class (connect/start/measure/save).
sw/wulpus/wulpus_model.py Adds typed status/measurement + HTTP response model.
sw/wulpus/wulpus_mock.py Adds mock/replay implementation for backend.
sw/wulpus/wulpus_config_models.py Adds Pydantic config models for US + TX/RX configs.
sw/wulpus/wulpus_api.py Generates HW config/restart byte packages.
sw/wulpus/wulpus_api_helper.py Helpers for package building and TX/RX bitmask building.
sw/wulpus/websocket_manager.py Manages WS clients + status/data broadcast.
sw/wulpus/series.py Implements measurement series scheduling loop + models.
sw/wulpus/plot_helpers.py Adds plotting utilities for saved log format.
sw/wulpus/helper.py Adds zip/parquet log helpers, config persistence helpers, misc utilities.
sw/wulpus/data_processing.py Adds DSP/peak detection processor + analysis config model.
sw/wulpus/interface.py Introduces async dongle interface contract + connection types.
sw/wulpus/interface_usb.py Implements serial dongle backend under new interface.
sw/wulpus/interface_direct.py Implements direct BLE backend using Bleak + frame assembly.
sw/wulpus/interface_mock.py Implements mock dongle backend for simulation.
sw/wulpus/main.spec PyInstaller spec for building backend + bundled frontend assets.
sw/wulpus/.gitignore Ignores backend build artifacts.
sw/wulpus/configs/.gitignore Keeps configs dir tracked but empty by default.
sw/wulpus/config-analysis/.gitignore Keeps analysis-config dir tracked but empty by default.
sw/wulpus/measurements/.gitignore Keeps measurements dir tracked but empty by default.
sw/wulpus/production-frontend/.gitignore Keeps production frontend dir tracked but empty by default.
sw/wulpus-frontend/package.json Defines frontend dependencies/scripts (Vite/React/Tailwind/Plotly/etc.).
sw/wulpus-frontend/vite.config.ts Adds dev proxy for API/log/config/ws endpoints.
sw/wulpus-frontend/tsconfig.json TS project references setup.
sw/wulpus-frontend/tsconfig.app.json App TS config (strict, bundler mode).
sw/wulpus-frontend/tsconfig.node.json Node/Vite TS config.
sw/wulpus-frontend/eslint.config.js ESLint configuration for TS/React hooks/refresh.
sw/wulpus-frontend/index.html Frontend HTML entrypoint.
sw/wulpus-frontend/README.md Frontend dev/build instructions.
sw/wulpus-frontend/.gitignore Ignores node/dist/editor artifacts.
sw/wulpus-frontend/build.py Builds frontend and copies into backend production dir.
sw/wulpus-frontend/public/vite.svg Adds Vite logo asset.
sw/wulpus-frontend/src/main.tsx React app bootstrap + router + query client.
sw/wulpus-frontend/src/App.tsx Main dashboard wiring (WS, config state, panels, graph).
sw/wulpus-frontend/src/api.ts Frontend API client for backend endpoints.
sw/wulpus-frontend/src/websocket-types.ts Frontend types mirroring backend models.
sw/wulpus-frontend/src/ConnectionPanel.tsx Connection management UI + mock toggle + start/stop controls.
sw/wulpus-frontend/src/StatusView.tsx Per-device status + connect/disconnect controls.
sw/wulpus-frontend/src/UsConfig.tsx US config panel UI (basic/advanced fields).
sw/wulpus-frontend/src/TxRxConfig.tsx TX/RX config editor UI.
sw/wulpus-frontend/src/SeriesPanel.tsx Series mode UI (interval/number/progress).
sw/wulpus-frontend/src/AnalysisConfigPanel.tsx Analysis/peak detection config UI.
sw/wulpus-frontend/src/ConfigFilesPanel.tsx Save/load/delete config files via backend endpoints.
sw/wulpus-frontend/src/LogsPage.tsx Log browser UI (list/download/replay).
sw/wulpus-frontend/src/Graph.tsx Live plotting (Plotly) including B-mode and filters/fullscreen.
sw/wulpus-frontend/src/helper.ts Frontend helper utilities (default config, DSP helpers, fullscreen).
sw/wulpus-frontend/src/Fields.tsx Small form-field components.
sw/wulpus-frontend/src/MultiNumField.tsx Multi-number input with channel toggles.
sw/wulpus-frontend/src/index.css Tailwind + Material Symbols + slider styling.
sw/wulpus-frontend/src/vite-env.d.ts Vite types reference.
sw/wulpus-frontend/src/assets/react.svg Adds React logo asset.
sw/pyproject.toml Defines Python project deps (FastAPI, pandas/pyarrow, bleak, etc.).
sw/README.md Updates software run/build instructions for web UI + artifacts.
sw/CHANGELOG.md Documents web UI refactor release notes.
sw/LICENSE Updates license header content (Apache 2.0 text retained).
sw/MATLAB_load_wulpus_log.m Adds MATLAB helper to load the new zip/parquet log format.
sw/convert_measurements.ipynb Adds notebook to convert legacy measurements into new format.
sw/how_to_install_dependencies.md Removes legacy conda-based dependency instructions.
sw/jupyter notebook (legacy)/.gitignore Ignores user outputs/configs except examples.
sw/jupyter notebook (legacy)/LICENSE Adds legacy notebook license file.
sw/jupyter notebook (legacy)/wulpus_gui.ipynb Updates imports to new legacy package path.
sw/jupyter notebook (legacy)/wulpus_jptnbk/init.py Adds package init for legacy notebook code.
sw/jupyter notebook (legacy)/wulpus_jptnbk/config_package.py Moves legacy config package code under legacy namespace.
sw/jupyter notebook (legacy)/wulpus_jptnbk/dongle.py Moves legacy dongle implementation under legacy namespace.
sw/jupyter notebook (legacy)/wulpus_jptnbk/rx_tx_conf.py Adds helper to build TX/RX configs from WulpusConfig in legacy code.
sw/jupyter notebook (legacy)/wulpus_jptnbk/rx_tx_conf_gui.py Updates legacy GUI code imports/formatting under legacy namespace.
sw/jupyter notebook (legacy)/wulpus_jptnbk/test_rx_tx_conf.py Adds/updates tests for legacy TX/RX config generation.
sw/jupyter notebook (legacy)/wulpus_jptnbk/uss_conf.py Updates legacy US config imports/formatting under legacy namespace.
sw/jupyter notebook (legacy)/wulpus_jptnbk/uss_conf_gui.py Updates legacy US config GUI imports/formatting under legacy namespace.
sw/jupyter notebook (legacy)/examples/uss_config.json Adds example legacy US config JSON.
sw/jupyter notebook (legacy)/examples/tx_rx_configs.json Adds example legacy TX/RX configs JSON.
README.md Updates top-level README to reference new software flow.
docs/CHANGELOG.md Documents documentation-side release notes for new GUI/API.
AGENTS.md Adds developer commands/architecture/style guidelines.
.gitignore Expands ignore rules (uv/venv/build artifacts, etc.).
.github/workflows/release-gui.yml Adds CI workflow to build frontend, package exe, and publish artifacts/releases.
fw/nrf52/README.md Fixes paths/wording in firmware docs.
fw/nrf52/how_to_setup_nRF52_toolchain.md Fixes wording in setup doc.
fw/nrf52/how_to_flash_nrf52840_dongle.md Fixes title/paths/wording for dongle flashing doc.
fw/msp430/wulpus_msp430_firmware/wulpus/wulpus_sys.h Adds “new config” condition helper prototype.
fw/msp430/wulpus_msp430_firmware/wulpus/wulpus_sys.c Refactors restart/config checks; minor cleanup.
fw/msp430/wulpus_msp430_firmware/main.c Refactors acquisition loop flow; adds preparation function.
fw/msp430/README.md Fixes paths/wording in MSP430 firmware docs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +95 to +99
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}")
Comment on lines +163 to +169
if not self._bleak_client or not self._bleak_client.is_connected:
print("Error: BLE client is not connected.")
return None, None, None

if self._data_queue is None:
print("Error: Data queue not initialized.")
return None, None, None
f"Warning: Oversized frame discarded ({len(frame_buffer)} bytes)")
frame_buffer = bytearray()

return None, None, None
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 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.py
while data_cnt < number_of_acq and self._acquisition_running:
# need to be a object so it gets passes by ref
data = await current_intf.receive_data(self, self._config.us_config.num_samples)
timestamp = int(time.time_ns()/1e3)
Comment on lines +26 to +30
class AnalysisConfig(BaseModel):
spacers: List[Dict[str, Union[float, str]]] = [
{"thickness": 0.6, "note": "PDMS", "speedOfSound": 1030},
{"thickness": 8, "note": "PEEK spacer", "speedOfSound": 2500}
]
Comment on lines +56 to +67
export type DataFrame = {
measurement: {
data: number[]
time: number[]
tx: number[]
rx: number[]
}
peaks: number[]
wavelet: number[]
spacer_region: [number, number]
wulpus_id?: number;
} No newline at end of file
update fork with upstream
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants