Commit Graph

51 Commits

Author SHA1 Message Date
znetsixe
b0e8bbb95d docs(wiki): regenerate topic-contract AUTOGEN block via wiki-gen
Replaces the agent-written placeholder inside Reference-Contracts.md with
the authoritative table generated from src/commands/index.js. Both the
BEGIN and END markers are normalized to the canonical form used by
`@evolv/wiki-gen`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 10:11:48 +02:00
znetsixe
1a16f9c4f1 docs(wiki): full 5-page wiki matching the rotatingMachine reference format
Replaces the prior stub/partial wiki with a Home + Reference-{Architecture,
Contracts,Examples,Limitations} + _Sidebar structure. Topic-contract and
data-model sections wrapped in AUTOGEN markers for the future wiki-gen tool.
Source-vs-spec contradictions surfaced and flagged inline (not silently
fixed). Pending-review notes mark sections that need a full node review.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 09:42:10 +02:00
znetsixe
b884c0f085 docs: add Folder & File Layout section per EVOLV convention
Each repo can now be read standalone for the file-naming convention. Full rule:
.claude/rules/node-architecture.md in the EVOLV superproject.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 21:30:23 +02:00
znetsixe
ffc03584ed wiki: rewrite Home.md per visual-first 14-section template
- Run npm run wiki:all (wiki:contract + wiki:datamodel both wrote cleanly)
- Remove section 10 (State chart) — measurement is stateless, no FSM
- Renumber sections 11→10, 12→11, 13→12, 14→13 for correct 13-section layout
- Update banner git hash from afc304b to 125f964

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 21:03:23 +02:00
znetsixe
125f964d31 P11.6 wiki regen + Phase 10 private-test rewrites where applicable
For all 11 nodes with auto-gen markers: wiki/Home.md sections 5 (topic
contract) and 9 (data model) regenerated via npm run wiki:all. New
Unit column shows '<measure> (default <unit>)' for declared topics,
'—' otherwise. Effect column now uses descriptor.description (P11.2
field) overriding the generic per-prefix fallback.

For rotatingMachine + reactor: Phase 10 test rewrites — 3 + 8 files
moved off private nodeClass internals (_attachInputHandler, _commands,
_pendingExtras, _registerChild, _tick, etc.) to the public
BaseNodeAdapter surface (node.handlers.input, node.source.*).
+6 / +7 net new tests.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 19:44:04 +02:00
znetsixe
15b7414d41 P11.5 + B2.1/B2.2: per-command units + description (where applicable)
Adds  to scalar setters whose payloads are
plain numbers OR {value, unit}. Skipped where payload is compound or
mode-dependent (control-%, {F, C: [...]}, etc.) — documented inline.
Every command gains a description field for wikiGen consumption.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 17:41:19 +02:00
znetsixe
497f05d92c B1.3: isStable real threshold (config-driven, replaces tautology)
The legacy stdDev < stdDev*2 was always true. New behaviour: stdDev <=
config.calibration.stabilityThreshold OR stdDev === 0. Default
threshold 0.01 in scaling-units. Schema field + editor UI added. 4
BUG-PRESERVED tests rewritten + 4 new edge tests. 101/101 pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 17:29:15 +02:00
znetsixe
e6e212a504 B2.4: remove legacy 'mAbs' event re-emission
No production consumer; deprecated since the MeasurementContainer-based
event surface landed. Drops the on-emit subscription that bridged the
analog channel's <type>.measured.<position> event to source.emitter
as 'mAbs'. 96/96 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 17:13:17 +02:00
znetsixe
2aa80212e4 P9.3: wiki/Home.md following 14-section visual-first template + wiki:* scripts
Auto-generated topic-contract + data-model sections via shared wikiGen
script. Hand-written Mermaid diagrams for position-in-platform, code
map, child registration, lifecycle, configuration, state chart (where
applicable).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 15:17:33 +02:00
znetsixe
42a0333b7c P3 wave 2: convert measurement to BaseDomain + Channel-based analog
specificClass.js: 716 → 244 lines.
  Measurement extends BaseDomain. Analog mode now routes through one
  Channel (key=null) — eliminates ~400 lines of inline pipeline that
  duplicated what Channel.update() already did.

  Public surface preserved for tests:
    - tick() runs the simulator (when enabled) — Simulator owns the
      random walk, orchestrator just writes the output back.
    - inputValue setter routes through analogChannel.update.
    - calibrate() / evaluateRepeatability() delegate to Calibrator.
    - toggleSimulation / toggleOutlierDetection unchanged.
    - 'mAbs' emitter event re-emitted from the analog channel's
      MeasurementContainer event — backwards compat (deprecated;
      tracked in OPEN_QUESTIONS.md for removal in Phase 7/8.5).

nodeClass.js: 230 → 42 lines.
  Extends BaseNodeAdapter. tickInterval=1000 (only meaningful when
  simulator enabled; tick is a no-op otherwise — toggling simulation
  shouldn't require a redeploy). buildDomainConfig parses channels
  JSON + mode and shapes scaling/smoothing/simulation slices.

96 / 96 tests pass (basic 77 + integration 17 + edge 2).
Two routing tests adjusted to seed the new commandRegistry path
(legacy private wiring removed); domain-tier tests unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 20:39:54 +02:00
znetsixe
b990f67df1 P3 wave 1: extract measurement simulator/calibration/commands + CONTRACT
src/simulation/simulator.js  random-walk generator (was simulateInput inline)
  src/calibration/calibrator.js  calibrate + isStable + evaluateRepeatability,
                                using generalFunctions/stats. NB: isStable
                                tautology preserved verbatim — see
                                OPEN_QUESTIONS.md 2026-05-10 for the bug.
  src/commands/                  registry + handlers (canonical names from start)
  CONTRACT.md                    inputs/outputs/events surface

77 basic tests pass (62 pre-refactor + 15 new across the three new files).
specificClass.js / nodeClass.js untouched — integration is P3 wave 2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 20:32:26 +02:00
znetsixe
998b2002e9 docs: add CLAUDE.md with S88 classification and superproject rule reference
References the flow-layout rule set in the EVOLV superproject
(.claude/rules/node-red-flow-layout.md) so Claude Code sessions working
in this repo know the S88 level, colour, and placement lane for this node.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 07:47:22 +02:00
znetsixe
fb8d5c03e6 fix(editor): asset/logger/position menus broken by TDZ ReferenceError in oneditprepare
The previous oneditprepare ran applyMode(initialMode) early in the
function, which called validateChannelsJson(), which referenced const
declarations (channelsArea, channelsHint) that were declared later in
the same function. JavaScript hoists const into the Temporal Dead Zone,
so accessing them before the declaration line throws a ReferenceError.
That uncaught throw aborted the rest of oneditprepare — including the
waitForMenuData() call that initialises the asset / logger / position
menu placeholders. Symptom for the user: opening a measurement node in
the editor showed Mode + analog fields but the asset menu was empty.

Fixes:

1. Move waitForMenuData() to the very top of oneditprepare so the
   shared menu init is independent of any later mode-block work. Even
   if the mode logic ever throws again, the asset / logger / position
   menus still render.

2. Resolve every DOM reference (modeSelect, analogBlock, digitalBlock,
   modeHint, channelsArea, channelsHint) at the top of the function
   before any helper that touches them is invoked. validateChannelsJson
   and applyMode now read closed-over names that are guaranteed to be
   initialised.

3. Guard applyMode(initialMode) with try/catch as defense in depth and
   add null-checks on every DOM reference. A future template change
   that drops one of the IDs will only no-op rather than break the
   editor.

No runtime change. 71/71 tests still green.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 14:15:06 +02:00
znetsixe
d6f8af4395 fix(editor): make Input Mode the top-level switch, hide wrong-mode fields
Prior behaviour: the Mode dropdown existed but nothing consumed it in the
editor — analog fields (Scaling, Source Min/Max, Smoothing, …) were
always visible, and the Channels JSON editor was always visible too.
For a legacy node with no saved mode the dropdown defaulted blank so
users reported "I cant even select digital or analog".

Changes:
- Initialize the Mode <select> from node.mode with an 'analog' fallback
  for legacy nodes (safe default — matches pre-digital behaviour).
- Wrap analog-only fields and digital-only fields in labelled containers
  and toggle their display based on the selected mode. Mode change is
  live — no redeploy needed to see the right form.
- Inline hint under the Mode dropdown tells the user what payload shape
  is expected for the current mode.
- Channels JSON gets live validation — shows channel count + names on
  valid JSON, warns on missing key/type, errors on invalid JSON.
- Label function appends ' [digital]' so the node visibly differs in a
  flow from an analog sibling.
- oneditsave is mode-aware: only warns about incomplete scaling ranges
  in analog mode; in digital mode warns if the channels array is empty
  or unparseable.

Runtime friendliness:
- nodeClass node-status now shows 'digital · N channel(s)' on startup in
  digital mode, and 'digital · N/M ch updated' after each incoming msg
  so the editor has a live heartbeat even when there is no single scalar.
- When analog mode receives an object payload (or digital receives a
  number), the node logs an actionable warn suggesting the mode switch
  instead of silently dropping the message.

Explicit, not auto-detected: mode remains a deployment-time choice
because the two modes take different editor config (scaling/smoothing vs
channels map). Auto-detecting at runtime would leave the node
unconfigured in whichever mode the user hadn't anticipated.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 14:00:34 +02:00
znetsixe
495b4cf400 feat: digital (MQTT) mode + fix silent dispatcher bug for camelCase methods
Runtime:
- Fix silent no-op when user selected any camelCase smoothing or outlier
  method from the editor. validateEnum in generalFunctions lowercases enum
  values (zScore -> zscore, lowPass -> lowpass, ...) but the dispatcher
  compared against camelCase keys. Effect: 5 of 11 smoothing methods
  (lowPass, highPass, weightedMovingAverage, bandPass, savitzkyGolay) and
  2 of 3 outlier methods (zScore, modifiedZScore) silently fell through.
  Users got the raw last value or no outlier filtering with no error log.
  Review any pre-2026-04-13 flows that relied on these methods.
  Fix: normalize method names to lowercase on both sides of the lookup.

- New Channel class (src/channel.js) — self-contained per-channel pipeline:
  outlier -> offset -> scaling -> smoothing -> min/max -> constrain -> emit.
  Pure domain logic, no Node-RED deps, reusable by future nodes that need
  the same signal-conditioning chain.

Digital mode:
- config.mode.current = 'digital' opts in. config.channels declares one
  entry per expected JSON key; each channel has its own type, position,
  unit, distance, and optional scaling/smoothing/outlierDetection blocks
  that override the top-level analog-mode fields. One MQTT-shaped payload
  ({t:22.5, h:45, p:1013}) dispatches N independent pipelines and emits N
  MeasurementContainer slots from a single input message.
- Backward compatible: absent mode config = analog = pre-digital behaviour.
  Every existing measurement flow keeps working unchanged.

UI:
- HTML editor: new Mode dropdown and Channels JSON textarea. The Node-RED
  help panel is rewritten end-to-end with topic reference, port contracts,
  per-mode configuration, smoothing/outlier method tables, and a note
  about the pre-fix behaviour.
- README.md rewritten (was a one-line stub).

Tests (12 -> 71, all green):
- test/basic/smoothing-methods.basic.test.js (+16): every smoothing method
  including the formerly-broken camelCase ones.
- test/basic/outlier-detection.basic.test.js (+10): every outlier method,
  fall-through, toggle.
- test/basic/scaling-and-interpolation.basic.test.js (+10): offset,
  interpolateLinear, constrain, handleScaling edge cases, min/max
  tracking, updateOutputPercent fallback, updateOutputAbs emit dedup.
- test/basic/calibration-and-stability.basic.test.js (+11): calibrate
  (stable and unstable), isStable, evaluateRepeatability refusals,
  toggleSimulation, tick simulation on/off.
- test/integration/digital-mode.integration.test.js (+12): channel build
  (including malformed entries), payload dispatch, multi-channel emit,
  unknown keys, per-channel scaling/smoothing/outlier, empty channels,
  non-numeric value rejection, getDigitalOutput shape, analog-default
  back-compat.

E2E verified on Dockerized Node-RED: analog regression unchanged; digital
mode deploys with three channels, dispatches MQTT-style payload, emits
per-channel events, accumulates per-channel smoothing, ignores unknown
keys.

Depends on generalFunctions commit e50be2e (permissive unit check +
mode/channels schema).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 13:43:03 +02:00
znetsixe
0918be7705 Merge commit 'f7c3dc2' into HEAD
# Conflicts:
#	src/nodeClass.js
2026-03-31 18:11:37 +02:00
Rene De Ren
f7c3dc2482 Expose output format selectors in editor 2026-03-12 16:39:25 +01:00
Rene De Ren
ed5f02605a test: add unit tests for specificClass
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 16:31:53 +01:00
Rene De Ren
1b7285f29e refactor: adopt POSITIONS constants and fix ESLint warnings
Replace hardcoded position strings with POSITIONS.* constants.
Prefix unused variables with _ to resolve no-unused-vars warnings.
Fix no-prototype-builtins where applicable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 15:35:28 +01:00
Rene De Ren
294cf49521 Migrate _loadConfig to use ConfigManager.buildConfig()
Replaces manual base config construction with shared buildConfig() method.
Node now only specifies domain-specific config sections.

Part of #1: Extract base config schema

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 14:59:41 +01:00
znetsixe
43b5269f0b updates 2026-03-11 11:13:38 +01:00
znetsixe
c587ed9c7b working 2026-02-23 13:17:03 +01:00
znetsixe
9e0e3e3859 before functional changes by codex 2026-02-19 17:37:21 +01:00
znetsixe
f979b1ae2b updates 2026-01-29 10:22:20 +01:00
znetsixe
671eb5f5fb updates 2026-01-29 09:16:33 +01:00
znetsixe
339ae6bdde Updated naming convention for displaying 2025-11-13 19:38:25 +01:00
756cc4bd20 Merge pull request 'changed colours and icon based on s88 and cleanup of file' (#6) from dev-Rene into main
Reviewed-on: https://gitea.centraal.wbd-rd.nl/RnD/measurement/pulls/6
2025-10-16 13:22:23 +00:00
znetsixe
a12c083b3f changed colours and icon based on s88 2025-10-14 13:52:34 +02:00
496c5688bc Merge pull request 'dev-Rene' (#5) from dev-Rene into main
Reviewed-on: https://gitea.centraal.wbd-rd.nl/RnD/measurement/pulls/5
2025-10-06 14:09:06 +00:00
znetsixe
5a0c46cb67 fixed distance compoment for measurement class 2025-10-05 09:34:35 +02:00
znetsixe
b1ba23212d ok 2025-10-05 07:56:58 +02:00
znetsixe
f6da9a6fc5 init dev branch 2025-10-02 17:16:04 +02:00
znetsixe
94da1a36e4 Constrain value before checking for updates to avoid out of bound scaling event triggers / updates when nothing changes. 2025-10-02 17:10:23 +02:00
p.vanderwilt
9a7b5a93ed Add distance functionality to node configuration and update measurement logging 2025-09-26 13:34:39 +02:00
znetsixe
be7c929600 physicalPosition 1D update 2025-09-05 16:20:12 +02:00
znetsixe
de76803f7e added childId and childname for debug 2025-09-04 17:05:39 +02:00
znetsixe
bef39bc533 license update and enhancements to measurement functionality + child parent relationship 2025-08-07 13:51:28 +02:00
znetsixe
6aa6a226ea updates 2025-07-24 13:15:56 +02:00
znetsixe
4e2cdb389e bug fixes 2025-07-02 10:54:44 +02:00
znetsixe
625e0dd7e8 small changes 2025-07-01 17:02:17 +02:00
znetsixe
edf9b09af1 Generic updates completed for now 2025-07-01 15:24:18 +02:00
znetsixe
b4803e5e9b small adjusts 2025-06-25 17:25:13 +02:00
znetsixe
b3f1fad74e final mods for first generic standardisation 2025-06-25 14:52:20 +02:00
znetsixe
57f6ec9cde fix for childregistration 2025-06-25 11:45:32 +02:00
znetsixe
0feff2e0fe updates for standaardisation 2025-06-25 10:43:15 +02:00
znetsixe
0f855a8d2f standaardisation of EVOLV eco 2025-06-24 10:48:40 +02:00
znetsixe
d05d521408 standaardisation of EVOLV eco 2025-06-23 13:23:51 +02:00
znetsixe
6f63415698 menu fixes with min lines of code and standard menus - WORKING- 2025-06-20 17:14:22 +02:00
znetsixe
c4f16fb36d updated new method 2025-06-12 17:05:28 +02:00
znetsixe
a97326af08 first commit 2025-05-14 10:31:50 +02:00