summaryrefslogtreecommitdiff
path: root/core/signal_processor.py
diff options
context:
space:
mode:
Diffstat (limited to 'core/signal_processor.py')
-rw-r--r--core/signal_processor.py31
1 files changed, 20 insertions, 11 deletions
diff --git a/core/signal_processor.py b/core/signal_processor.py
index e2752cd..bfb7ba3 100644
--- a/core/signal_processor.py
+++ b/core/signal_processor.py
@@ -200,24 +200,28 @@ def unregister_filter_class(name: str) -> None:
# Helpers
# ══════════════════════════════════════════════════════════════════════════════
-def _make_src_names(sources: List[Tuple[str, str]]) -> List[str]:
+def _make_src_names(sources: List[Tuple[str, str]],
+ source_names: Optional[List[str]] = None) -> List[str]:
"""
- Build a list of Python-safe variable names from (device_id, channel_id) pairs.
- Uses channel_id alone when unambiguous; prefixes device_id when two sources
- share the same channel_id from different devices.
+ Build Python-safe variable names for each source.
+ Priority: user-defined name > channel_id (with device prefix if ambiguous).
+ User names are lowercased and spaces replaced with underscores.
"""
- seen: Dict[str, str] = {} # ch_id -> dev_id of first occurrence
+ seen: Dict[str, str] = {}
names = []
- for dev_id, ch_id in sources:
- if ch_id in seen and seen[ch_id] != dev_id:
+ for i, (dev_id, ch_id) in enumerate(sources):
+ user = source_names[i].strip() if (source_names and i < len(source_names)) else ""
+ if user:
+ raw = user.lower().replace(" ", "_")
+ elif ch_id in seen and seen[ch_id] != dev_id:
raw = f"{dev_id}_{ch_id}"
else:
- seen[ch_id] = dev_id
raw = ch_id
- safe = re.sub(r"\W", "_", raw)
+ seen[ch_id] = dev_id
+ safe = re.sub(r"\W", "_", raw.lower())
if safe and safe[0].isdigit():
safe = "_" + safe
- names.append(safe or "_ch")
+ names.append(safe or f"_ch{i}")
return names
@@ -252,6 +256,8 @@ class DerivedChannel:
expression: str = "" # single-line: "x[0] * 2"
script: str = "" # multi-line function body
enabled: bool = True
+ # User-defined names for each source (e.g. ["force", "moment"])
+ source_names: List[str] = field(default_factory=list)
# Runtime: compiled callable and per-channel script state (not serialised)
_fn: Optional[Callable] = field(default=None, repr=False, compare=False)
_exec_state: dict = field(default_factory=dict, repr=False, compare=False)
@@ -270,7 +276,7 @@ class DerivedChannel:
state — per-channel persistent dict (survives between evaluations)
"""
try:
- src_names = _make_src_names(self.sources)
+ src_names = _make_src_names(self.sources, self.source_names)
if self.kind == "expression":
code = compile(f"__result__ = {self.expression}", "<expr>", "exec")
@@ -585,4 +591,7 @@ class SignalProcessor(QObject):
elif dc.kind == "sum":
return sum(inputs)
+ elif dc.kind == "none":
+ return inputs[0] if inputs else None
+
return None