diff options
| author | Christian Kolset <christian.kolset@gmail.com> | 2026-04-22 14:50:13 -0600 |
|---|---|---|
| committer | Christian Kolset <christian.kolset@gmail.com> | 2026-04-22 14:50:13 -0600 |
| commit | 99445c6fd2fd4f15df828c79600b96b80fa1cfa6 (patch) | |
| tree | 22c9933fc6bb942172a1f456bef7a35ec4be1726 /core | |
| parent | 445403fdc61f4e65736dc65a959f119fc096f4c0 (diff) | |
Added derived signal to be sources of other derived signals.
Fixed derived signal saving profile. Renamed Signals>Pipeline to Signas>Channels
and adding/removing channels feature.
Diffstat (limited to 'core')
| -rw-r--r-- | core/__pycache__/profile.cpython-312.pyc | bin | 14026 -> 14149 bytes | |||
| -rw-r--r-- | core/__pycache__/signal_processor.cpython-312.pyc | bin | 23674 -> 23682 bytes | |||
| -rw-r--r-- | core/profile.py | 21 | ||||
| -rw-r--r-- | core/signal_processor.py | 13 |
4 files changed, 16 insertions, 18 deletions
diff --git a/core/__pycache__/profile.cpython-312.pyc b/core/__pycache__/profile.cpython-312.pyc Binary files differindex 0fee9d9..208b48b 100644 --- a/core/__pycache__/profile.cpython-312.pyc +++ b/core/__pycache__/profile.cpython-312.pyc diff --git a/core/__pycache__/signal_processor.cpython-312.pyc b/core/__pycache__/signal_processor.cpython-312.pyc Binary files differindex adcf10d..e914490 100644 --- a/core/__pycache__/signal_processor.cpython-312.pyc +++ b/core/__pycache__/signal_processor.cpython-312.pyc diff --git a/core/profile.py b/core/profile.py index 2a70370..ef8c55b 100644 --- a/core/profile.py +++ b/core/profile.py @@ -231,6 +231,16 @@ class ProfileManager: except Exception: pass + # Clear all existing devices — profile defines the complete device set + for dev in list(registry.all_instances()): + try: + dev.disconnect() + except Exception: + pass + registry.remove_instance(dev.info.device_id) + if engine is not None: + engine.remove_device(dev.info.device_id) + for dev_cfg in profile.devices: dev_type = dev_cfg.get("device_type") dev_id = dev_cfg.get("device_id") @@ -241,17 +251,6 @@ class ProfileManager: print(f"[Profile] Unknown device type: {dev_type}") continue try: - # Replace existing device so saved config takes effect - existing = registry.get_instance(dev_id) - if existing is not None: - try: - existing.disconnect() - except Exception: - pass - registry.remove_instance(dev_id) - if engine is not None: - engine.remove_device(dev_id) - kwargs = {k: v for k, v in dev_cfg.items() if k != "device_type"} dev = factory(**kwargs) registry.add_instance(dev) diff --git a/core/signal_processor.py b/core/signal_processor.py index 4161d4d..0d4ed39 100644 --- a/core/signal_processor.py +++ b/core/signal_processor.py @@ -10,7 +10,7 @@ Provides two capabilities: 2. DERIVED CHANNELS — virtual channels computed from one or more physical channels. Each derived channel runs a user-defined function every time - new data arrives. Built-ins: velocity/acceleration from displacement, + new data arrives. Built-ins: derivative/second_derivative from displacement, power from voltage+current, RMS, etc. Custom: arbitrary Python snippet. Architecture @@ -195,8 +195,8 @@ class DerivedChannel: A virtual channel computed from one or more physical channels. kind options: - "velocity" — derivative of a displacement source - "acceleration" — second derivative of a displacement source + "derivative" — derivative of a source (dy/dt) + "second_derivative" — second derivative of a source (d²y/dt²) "power" — voltage_source * current_source "rms" — rolling RMS of a source (window samples) "expression" — arbitrary Python expression string @@ -418,7 +418,7 @@ class SignalProcessor(QObject): return None return dc._fn(inputs, t) - elif dc.kind == "velocity": + elif dc.kind == "derivative": # derivative of source[0] src = dc.sources[0] if dc.sources else None if src is None: return None @@ -428,12 +428,11 @@ class SignalProcessor(QObject): if prev_t is None or t == prev_t: return 0.0 return (inputs[0] - prev_v) / (t - prev_t) - elif dc.kind == "acceleration": - # second derivative — derivative of velocity + elif dc.kind == "second_derivative": + # second derivative — derivative of derivative src = dc.sources[0] if dc.sources else None if src is None: return None state = dc.params.setdefault("_state", {}) - # First get velocity prev_t = state.get("t"); prev_v = state.get("v") cur_vel = 0.0 if prev_t is not None and t != prev_t: |
