summaryrefslogtreecommitdiff
path: root/core/profile.py
AgeCommit message (Collapse)Author
2026-09-20Make Channel the single source of truth for a reading's nameChristian Kolset
Device tab stays hardware-only (pins, wiring, may vary per workstation); the Channels window owns the profile-facing identity. Concretely: - Fix a real regression: SerialDevice generic-format Apply & Reconnect nulled out custom channel_names/units every time (no fallback, unlike every other optional field in reconfigure()), silently reverting to sig0/sig1/... ids. - Plot legend now live-tracks the current Signal/Channel name instead of freezing tr.label at add-time, so a rename shows up without re-adding the trace. - Add an inline quick-reconnect (combo + button, pre-selects the actual current source) directly on each Channel block in the Channels window, for the common single-source case — rewiring hardware no longer means touching every Plot/pipeline that referenced it. - Collapse the Channel ID field behind an "ID ▸" advanced toggle; channel_id is already auto-derived from the name (_slug_id) and rarely needs to be seen. - Devices tab's Signal "Name" column relabeled "Label" with a tooltip — de-emphasized now that Channel name is the real identity. - Move "create a Channel from this Signal" from a column on the Devices tab's signal table to a ⊕ button on each Signal row in the Channels tab's Namespace panel — the action now lives where the identity is created, not on the hardware tab. Only that instance opts in (on_create_channel); the read-only Namespace dock on the main window is unaffected. - Floor the Namespace panel's width at its columns' natural size so dragging the Channels-tab splitter narrower can't push the ⊕ column behind the horizontal scrollbar. - Breadcrumb log when a profile-saved Signal override can't be applied because the signal_id no longer exists. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-19Redesign Signal/Channel naming and fix pin-remap breaking referencesChristian Kolset
Arduino analog Signal ids used to be the pin name itself, so fixing a wrong pin silently changed the id and orphaned any plot trace, control, or filter pipeline pointing at it. Analog Signal ids are now positional (ai0, ai1, ...) and decoupled from the underlying pin, matching how digital I/O already worked. More broadly, formalizes a Device -> Signal -> Channel -> Plot naming model (SignalConfig for physical device channels, Channel for derived/ computed ones) and adds core/reference_registry.py to propagate any Signal or Channel id rename through plot traces, controls, and filter pipelines instead of leaving them dangling. Signal ids are now editable in the Signals tab with the same propagation. .labui profile schema bumped to v2.0 with a transparent migration for old files, including remapping old pin-name Signal ids to the new positional ones. Removed six confirmed-dead files (two legacy device classes, four superseded top-level ui/ duplicates).
2026-08-13Re-detect serial device ports by identity when a profile loads on another ↵Christian Kolset
machine COM/tty numbers aren't stable across machines or replugs. Devices now save their USB serial number and OS description alongside the port; on profile load, if the saved port isn't present, ArduinoLayer.find_port_by_identity() looks for a match and remaps it. Falls back to the saved port (device shows ERROR) if nothing matches. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-13Fixed loading profiles data retention and display.Christian Kolset
2026-08-01Rename LabDAQ → LabUI and overhaul plugin systemChristian Kolset
Branding: - Rename app, window title, file extension (.labdaq → .labui), user data dirs (~/.labui/), spec file (labdaq.spec → labui.spec), and APP_NAME throughout all source, docs, and config files Plugin system: - Plugins no longer bundled in the PyInstaller build — installed at runtime by users via Settings → Plugins → Install Plugin (zip) - PluginManager now takes user_dir + extra_scan_dirs; user plugins live in ~/.labui/plugins/, dev scan additionally covers project plugins/ - install_from_zip / uninstall / is_user_installed added to PluginManager - vendor/ dir inside plugin zips: prepended to sys.path at load time so plugins can ship their own deps without requiring pip on end-user machine - source_url field in manifest.json: shown as Download button in the missing-plugins dialog when a profile requires an absent plugin - Frozen-app pip install now targets ~/.labui/plugin_packages/ using a real system Python (sys.executable is the exe in frozen builds) Profile loading: - Profile now stores plugins_manifest snapshot (id, name, version, source_url) alongside plugins_enabled - On load, missing or dep-broken plugins trigger MissingPluginsDialog before the rest of the profile is applied; user can install from zip or download via source_url in-dialog, or cancel the load - Plugin reconciliation only enables installed plugins — missing ones are not written to enabled.json UI: - Version label added to status bar (bottom-right, muted colour) - Settings → Plugins tab: Install Plugin… button, per-plugin Remove button for user-installed plugins, live list refresh after install/remove Docs: - New docs/building.md covers the full release pipeline - docs/plugin-development.md updated for new install flow, vendoring, source_url, profile behaviour, and distribution instructions Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-29Add editable device display name, persist it across profile save/loadChristian Kolset
DeviceInfo.name existed but was hardcoded per device type and never operator-editable. Adds a Display Name field to Add Device and makes the Info-tab Name field in the device config dialog editable, and threads the name through get_save_config()/ProfileManager.apply() so a custom name survives a .labdaq save/reload instead of reverting to the type default. Name is applied post-construction rather than as a constructor kwarg, since no device factory declares a "name" param. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-06-09Derived channels: signal display names as vars, auto-update template code, ↵Christian Kolset
None op - Variable names derived from signal display name (e.g. "Acceleration X" → acceleration_x) instead of raw channel ID; all auto-names lowercase with underscores - Template code auto-updates x[0]/x[1] refs to named vars as sources are added/changed; stops updating once user edits the code manually - Derivative wrt-channel mode uses separate template with x[1] substituted to channel var - Added "None" passthrough operation (result = x[0]) - source_names persisted in .labdaq profiles Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09Scripting: named signal vars, shared vars dict, control scripts, code templatesChristian Kolset
- Named variables in expressions: source channel IDs injected as Python identifiers alongside x[] (e.g. write `A0 * 2` instead of `x[0] * 2`) - Shared `vars` dict on SignalProcessor accessible from all expressions, functions, and control scripts; persisted in .labdaq profiles - Per-derived-channel `state` dict for persistent computation state in custom scripts - Control widgets gain optional on_action_script (Python snippet with value, vars, channels, math in scope); syntax-checked in editor dialog - Built-in derived kinds (derivative, rms, power, etc.) now show their Python implementation as read-only code previews; "Edit as Custom Script" converts to custom_script kind with template pre-filled Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09Motion capture: profile support, FPS config, persistent tracking, window stateChristian Kolset
Profile integration: - CameraDevice.get_save_config() serialises camera_index, simulate, resolution, fps — cameras now persist in .labdaq profiles - ProfileManager.register/unregister_device_factory() lets plugins register their device classes for profile restoration without core → plugin dependency - MotionCapturePlugin registers CameraDevice factory on load/unload Camera configuration: - Add Frame Rate combo to CameraPanel (Default/15/24/30/60/120 fps) defaults to 30 fps; flows through to CAP_PROP_FPS on connect - tracker.start() accepts fps param alongside existing resolution Tracking persistence: - CameraTracker.is_running() — checks thread alive state - MotionCaptureWindow initialises _connected from tracker.is_running() so reopening the window resumes the live feed without restarting the camera or losing the active tracking state Window state: - Plugin saves px_per_mm + camera_idx when window closes - Reopened window restores saved values and syncs mode/shape UI from tracker state via restore_ui_state() (signals blocked to avoid resetting tracker) - Window type changed to Qt.WindowType.Window for independent close button on all Linux WMs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03Added plugin/add-on systemChristian Kolset
Plugins live in plugins/<name>/ with a manifest.json and a LabPlugin subclass. Enabled/disabled in Settings > Plugins tab; state persists in plugins/enabled.json and in .labdaq profiles (loading a profile enables/disables plugins to match). Plugins can contribute toolbar buttons, BaseDevice instances (auto-wired into acquisition pipeline), custom signal filter classes, a settings widget, and profile state via get_save_state/apply_save_state. Load errors now report the exact failing stage (file not found, class missing, on_load crash). Includes example plugin skeleton and docs/plugin-development.md. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27Improved arduino interface. Now allowing the user to configure pins on the fly.Christian Kolset
2026-04-22Added derived signal to be sources of other derived signals.Christian Kolset
Fixed derived signal saving profile. Renamed Signals>Pipeline to Signas>Channels and adding/removing channels feature.
2026-04-22Fixed saving profile to include devices and their configurationChristian Kolset
2026-04-21V13Christian Kolset
This version contains the profile feature. Allowins users to save the channels, signals and plots for specific labs.