- Update all submodule URLs from gitea.centraal.wbd-rd.nl to gitea.wbd-rd.nl - Add settler as proper submodule in .gitmodules - Add agent skills, function anchors, decisions, and improvements - Add Docker configuration and scripts - Add manuals and third_party docs - Update .gitignore with secrets and build artifacts - Remove stale .tgz build artifact Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
227 lines
25 KiB
Markdown
227 lines
25 KiB
Markdown
# Rotating Machine Function Anchor
|
|
|
|
## 0) Connection Map (At a Glance)
|
|
- **Node type**: `rotatingMachine` (`nodes/rotatingMachine/rotatingMachine.js:1`, `nodes/rotatingMachine/rotatingMachine.html:16`)
|
|
- **Consumes parent/control topics**: `setMode`, `execSequence`, `execMovement`, `flowMovement`, `emergencystop`, `simulateMeasurement`, `registerChild`, `showWorkingCurves`, `CoG` (`nodes/rotatingMachine/src/nodeClass.js:267`)
|
|
- **Publishes periodic outputs**:
|
|
- Output `0`: process payload (`nodes/rotatingMachine/src/nodeClass.js:249`)
|
|
- Output `1`: influx payload (`nodes/rotatingMachine/src/nodeClass.js:251`)
|
|
- Output `2`: registration/control plumbing (`registerChild`) (`nodes/rotatingMachine/src/nodeClass.js:222`)
|
|
- **Cross-node integrations (direct observed)**:
|
|
- Registered/managed by `machineGroupControl` as `machine`, which then commands each machine via `handleInput('parent', ...)` (`nodes/machineGroupControl/src/specificClass.js:50`, `nodes/machineGroupControl/src/specificClass.js:711`, `nodes/machineGroupControl/src/specificClass.js:1028`)
|
|
- Can be orchestrated by `pumpingStation` via `execSequence` and movement commands (`nodes/pumpingStation/src/specificClass.js:296`, `nodes/pumpingStation/src/specificClass.js:297`)
|
|
- Dashboard/test flows inject `simulateMeasurement` and consume process output topics (`nodes/rotatingMachine/examples/basic.flow.json:380`, `nodes/rotatingMachine/examples/basic.flow.json:412`)
|
|
- **Admin/UI endpoints**:
|
|
- `GET /rotatingMachine/menu.js`
|
|
- `GET /rotatingMachine/configData.js` (`nodes/rotatingMachine/rotatingMachine.js:17`, `nodes/rotatingMachine/rotatingMachine.js:27`)
|
|
|
|
## 1) Unit Table (Anchor Starts Here)
|
|
| Signal/Field | Represents | Asset Type | Default Unit | Accepted Units | Source of Truth | Produced By | Consumed By | Fallback/Degraded Behavior |
|
|
|---|---|---|---|---|---|---|---|---|
|
|
| `pressure.measured.*` | pressure input (upstream/downstream) | measurement child (`pressure`) | `mbar` | any convertible via `MeasurementContainer` | `nodes/rotatingMachine/src/specificClass.js:48`, `nodes/rotatingMachine/src/specificClass.js:708` | real child sensors and virtual dashboard child | pressure dimension for curve selection (`predict*.fDimension`) | if missing, pressure dimension forced to minimum (`0`) (`nodes/rotatingMachine/src/specificClass.js:552`) |
|
|
| `flow.predicted.downstream` | predicted flow at discharge | rotating machine | `general.unit` from config | convertible (`m3/h`, `l/s`, etc.) | `nodes/rotatingMachine/src/specificClass.js:53`, `nodes/rotatingMachine/src/specificClass.js:423` | `calcFlow()` | output formatting, status text, parent/group logic | forced `0` if non-operational or no curve (`nodes/rotatingMachine/src/specificClass.js:415`, `nodes/rotatingMachine/src/specificClass.js:429`) |
|
|
| `flow.predicted.atEquipment` | same flow at equipment point | rotating machine | `general.unit` | convertible | `nodes/rotatingMachine/src/specificClass.js:53`, `nodes/rotatingMachine/src/specificClass.js:424` | `calcFlow()` | efficiency calculations | forced `0` if non-operational/no curve |
|
|
| `power.predicted.atEquipment` | predicted power draw | rotating machine | `kW` | convertible (`W`, `kW`) | `nodes/rotatingMachine/src/specificClass.js:54`, `nodes/rotatingMachine/src/specificClass.js:448` | `calcPower()` | efficiency calculations, status text | forced `0` if non-operational/no curve |
|
|
| `ctrl.predicted.atEquipment` | predicted control position for requested flow | rotating machine | unitless (%) semantic | numeric | `nodes/rotatingMachine/src/specificClass.js:482` | `calcCtrl()` | `flowmovement` command path | returns `0` if no curve |
|
|
| `temperature.measured.atEquipment` | process temp for density lookup | machine fluid context | `C` default, converted to `K` when used | convertible | init at `15 C` (`nodes/rotatingMachine/src/specificClass.js:149`) | init + measurement updates | CoolProp density input | if missing conversion, efficiency can degrade silently |
|
|
| `atmPressure.measured.atEquipment` | atmospheric pressure for density lookup | machine fluid context | `Pa` | convertible | init at `101325 Pa` (`nodes/rotatingMachine/src/specificClass.js:151`) | init | CoolProp density input | fallback density `1000 kg/m3` on CoolProp error (`nodes/rotatingMachine/src/specificClass.js:867`) |
|
|
| `efficiency.*` | specific flow (`flow/power`) | derived metric | implicit unitless ratio | numeric | `nodes/rotatingMachine/src/specificClass.js:878`, `nodes/rotatingMachine/src/specificClass.js:881` | `calcEfficiency()` | output and BEP distance metrics | unchanged if power/flow are zero |
|
|
| `specificEnergyConsumption.*` | power per flow | derived metric | implicit | numeric | `nodes/rotatingMachine/src/specificClass.js:879`, `nodes/rotatingMachine/src/specificClass.js:882` | `calcEfficiency()` | output consumers | unchanged if power/flow zero |
|
|
| `nHydraulicEfficiency.*` | hydraulic-efficiency-like metric | derived metric | unitless | numeric | `nodes/rotatingMachine/src/specificClass.js:884` | `calcEfficiency()` | diagnostic output | skipped if pressure/flow/power conversions unavailable |
|
|
| `cog`, `NCog`, `NCogPercent` | efficiency-curve peak indicators | derived curve metrics | unitless | numeric | `nodes/rotatingMachine/src/specificClass.js:796`, `nodes/rotatingMachine/src/specificClass.js:948` | `calcCog()`, `getOutput()` | group optimization, dashboards | retains last computed values |
|
|
| `effDistFromPeak`, `effRelDistFromPeak` | distance from best-efficiency point | derived | unitless | numeric | `nodes/rotatingMachine/src/specificClass.js:924`, `nodes/rotatingMachine/src/specificClass.js:962` | `calcDistanceBEP()` | output consumers | remains last computed value |
|
|
| `runtime`, `maintenanceTime`, `moveTimeleft`, `state` | movement/state telemetry | state machine | `h`/`s`/enum | numeric/string | `nodes/rotatingMachine/src/specificClass.js:943` | `state` module | output/status/parent control | depends on `state` module behavior |
|
|
|
|
## 2) Class Identity
|
|
- **Runtime registration + endpoints**: `nodes/rotatingMachine/rotatingMachine.js`
|
|
- **Node-RED wrapper/routing**: `nodes/rotatingMachine/src/nodeClass.js`
|
|
- **Domain/mechanical logic**: `nodes/rotatingMachine/src/specificClass.js`
|
|
- **Editor UI/defaults**: `nodes/rotatingMachine/rotatingMachine.html`
|
|
- **Default config schema/validation rules**: `nodes/generalFunctions/src/configs/rotatingMachine.json`
|
|
|
|
## 3) Configuration Contract
|
|
| UI Field | Runtime Path | Default | Validation/Coercion | Behavior Impact | Source |
|
|
|---|---|---|---|---|---|
|
|
| `speed` | `stateConfig.movement.speed` | `1` | `Number(uiConfig.speed)` | movement progression speed | `nodes/rotatingMachine/rotatingMachine.html:22`, `nodes/rotatingMachine/src/nodeClass.js:91` |
|
|
| `startup/warmup/shutdown/cooldown` | `stateConfig.time.*` | `0` | `Number(...)` | sequence transition durations | `nodes/rotatingMachine/rotatingMachine.html:23`, `nodes/rotatingMachine/src/nodeClass.js:95` |
|
|
| `movementMode` | `stateConfig.movement.mode` | `staticspeed` | raw string | state movement model selection | `nodes/rotatingMachine/rotatingMachine.html:27`, `nodes/rotatingMachine/src/nodeClass.js:92` |
|
|
| `unit` | `config.general.unit` + `config.asset.unit` | UI empty, config default `l/s` | direct assign then config init | base flow unit for measurements and outputs | `nodes/rotatingMachine/src/nodeClass.js:50`, `nodes/generalFunctions/src/configs/rotatingMachine.json:18` |
|
|
| `model` | `config.asset.model` | UI empty, config default `Unknown` | direct assign | curve loading via `loadCurve(model)` | `nodes/rotatingMachine/src/nodeClass.js:62`, `nodes/rotatingMachine/src/specificClass.js:18` |
|
|
| logging fields | `config.general.logging.*` | `enableLog=false`, `logLevel=error` in UI; config default enabled/info | direct assign | runtime verbosity | `nodes/rotatingMachine/rotatingMachine.html:39`, `nodes/rotatingMachine/src/nodeClass.js:51` |
|
|
| `positionVsParent` | `config.functionality.positionVsParent` | UI empty, config default `atEquipment` | direct assign + default in schema | registration topology to parent | `nodes/rotatingMachine/src/nodeClass.js:66`, `nodes/generalFunctions/src/configs/rotatingMachine.json:74` |
|
|
| Mode/action/source rules | `config.mode.*` | schema defaults | configUtils validation into `Set` semantics | command gating | `nodes/generalFunctions/src/configs/rotatingMachine.json:231`, `nodes/rotatingMachine/src/specificClass.js:269` |
|
|
| Sequences | `config.sequences.*` | schema defaults | configUtils validation | machine state transitions | `nodes/generalFunctions/src/configs/rotatingMachine.json:360`, `nodes/rotatingMachine/src/specificClass.js:363` |
|
|
|
|
## 4) Input/Output Contract
|
|
### 4.1 Input topics (`nodeClass`)
|
|
| Topic | Payload schema | Handler | Side effects |
|
|
|---|---|---|---|
|
|
| `registerChild` | `payload=<nodeId>`, optional `positionVsParent` | registers child source via `childRegistrationUtils` | starts measurement event wiring (`nodes/rotatingMachine/src/nodeClass.js:268`) |
|
|
| `setMode` | `payload=<mode>` | `setMode()` | updates command policy mode |
|
|
| `execSequence` | `{source, action, parameter}` | `handleInput()` | executes state sequence |
|
|
| `execMovement` | `{source, action, setpoint}` | `handleInput()` | moves position |
|
|
| `flowMovement` | `{source, action, setpoint}` | `handleInput()` | converts flow->ctrl then moves |
|
|
| `emergencystop` | `{source, action}` | `handleInput()` | emergency sequence attempt |
|
|
| `simulateMeasurement` | `{type, position, value, unit, timestamp?}` | measurement update handlers | updates virtual pressure or measured values |
|
|
| `showWorkingCurves` | any | immediate response on output 0 | emits curve/cog debug payload |
|
|
| `CoG` | any | immediate response on output 0 | calls `m.showCoG()` (method currently not defined in `specificClass`) |
|
|
|
|
### 4.2 Output ports
|
|
| Port | Message type | Source |
|
|
|---|---|---|
|
|
| `0` | formatted process message from flattened measurements + state fields | `nodes/rotatingMachine/src/nodeClass.js:250` |
|
|
| `1` | formatted influxdb message | `nodes/rotatingMachine/src/nodeClass.js:251` |
|
|
| `2` | registration to parent: `{topic:'registerChild', payload:id, positionVsParent}` | `nodes/rotatingMachine/src/nodeClass.js:222` |
|
|
|
|
### 4.3 Admin endpoints
|
|
| Endpoint | Purpose | Source |
|
|
|---|---|---|
|
|
| `/rotatingMachine/menu.js` | dynamic editor menu script (`asset`, `logger`, `position`) | `nodes/rotatingMachine/rotatingMachine.js:17` |
|
|
| `/rotatingMachine/configData.js` | dynamic default/config script | `nodes/rotatingMachine/rotatingMachine.js:27` |
|
|
|
|
## 5) Mode, State, and Control Model
|
|
- **Modes**: `auto`, `virtualControl`, `fysicalControl` (`nodes/generalFunctions/src/configs/rotatingMachine.json:233`)
|
|
- **Mode gate enforcement**:
|
|
- `isValidActionForMode(action, mode)` (`nodes/rotatingMachine/src/specificClass.js:279`)
|
|
- `isValidSourceForMode(source, mode)` (`nodes/rotatingMachine/src/specificClass.js:269`)
|
|
- **Actions supported by handler**: `execsequence`, `execmovement`, `flowmovement`, `entermaintenance`, `exitmaintenance`, `emergencystop`, `statuscheck` (`nodes/rotatingMachine/src/specificClass.js:303`)
|
|
- **Operational states for active prediction**: `operational`, `warmingup`, `accelerating`, `decelerating` (`nodes/rotatingMachine/src/specificClass.js:739`)
|
|
- **Sequence defaults**: startup/shutdown/emergencystop/maintenance flows defined in config schema (`nodes/generalFunctions/src/configs/rotatingMachine.json:365`)
|
|
|
|
## 6) End-to-End Execution Flow
|
|
1. Node registration instantiates `nodeClass`, then `Specific` (`Machine`).
|
|
2. `Machine` constructor loads model curve, initializes predictors/state/measurements, creates virtual pressure children, and subscribes to state events.
|
|
3. `nodeClass` starts delayed child registration (`output 2`) and 1-second tick/status loops.
|
|
4. Incoming topics route through `switch(msg.topic)` to mode changes, movement/sequence commands, child registration, and simulated measurements.
|
|
5. Child measurement events update parent measurement container and dispatch typed handlers.
|
|
6. Pressure updates set predictor dimension, recompute flow/power/efficiency/CoG/BEP metrics.
|
|
7. Each tick emits formatted process + influx messages.
|
|
|
|
## 7) Full Function Inventory
|
|
### 7.1 `nodes/rotatingMachine/rotatingMachine.js`
|
|
| Function | Purpose | Source |
|
|
|---|---|---|
|
|
| module export init | register Node-RED node type and admin endpoints | `nodes/rotatingMachine/rotatingMachine.js:5` |
|
|
|
|
### 7.2 `nodes/rotatingMachine/src/nodeClass.js`
|
|
| Function | Purpose | Key effects | Source |
|
|
|---|---|---|---|
|
|
| `constructor` | boot wrapper lifecycle | load config, create source, start loops/handlers | `nodes/rotatingMachine/src/nodeClass.js:16` |
|
|
| `_loadConfig` | map UI config to runtime config | builds `general/asset/functionality`; builds `outputUtils` | `nodes/rotatingMachine/src/nodeClass.js:44` |
|
|
| `_setupSpecificClass` | build `Machine` with movement/time state config | instantiates `Specific`; stores on `node.source` | `nodes/rotatingMachine/src/nodeClass.js:77` |
|
|
| `_bindEvents` | placeholder | no-op currently | `nodes/rotatingMachine/src/nodeClass.js:112` |
|
|
| `_updateNodeStatus` | compose Node-RED status icon/text | warns once for missing pressure init; includes flow/power/state | `nodes/rotatingMachine/src/nodeClass.js:116` |
|
|
| `_registerChild` | announce self to parent | sends `registerChild` on output 2 after 100ms | `nodes/rotatingMachine/src/nodeClass.js:217` |
|
|
| `_startTickLoop` | periodic work | 1s `_tick`; 1s status refresh | `nodes/rotatingMachine/src/nodeClass.js:230` |
|
|
| `_tick` | periodic output generation | `formatMsg(process)` + `formatMsg(influxdb)` send to outputs 0/1 | `nodes/rotatingMachine/src/nodeClass.js:246` |
|
|
| `_attachInputHandler` | route inbound topics | dispatches all command/simulation/register/show topics | `nodes/rotatingMachine/src/nodeClass.js:260` |
|
|
| `_attachCloseHandler` | shutdown cleanup | clears intervals | `nodes/rotatingMachine/src/nodeClass.js:357` |
|
|
|
|
### 7.3 `nodes/rotatingMachine/src/specificClass.js`
|
|
| Function | Purpose | Key effects | Source |
|
|
|---|---|---|---|
|
|
| `constructor` | initialize machine domain object | config/curve/predictors/state/measurement/events/virtual children | `nodes/rotatingMachine/src/specificClass.js:7` |
|
|
| `_initVirtualPressureChildren` | create simulated upstream/downstream pressure children | registers virtual measurement children | `nodes/rotatingMachine/src/specificClass.js:104` |
|
|
| `_init` | seed base measurements and min/max flow | sets temperature, atmPressure, curve min/max | `nodes/rotatingMachine/src/specificClass.js:147` |
|
|
| `_updateState` | enforce non-operational flow = 0 | overwrites predicted flow when inactive | `nodes/rotatingMachine/src/specificClass.js:163` |
|
|
| `registerChild` | subscribe to child measurement events | stores real pressure child IDs, updates measurements, calls handlers | `nodes/rotatingMachine/src/specificClass.js:173` |
|
|
| `_callMeasurementHandler` | typed measurement dispatch | pressure/flow/temp handlers + fallback | `nodes/rotatingMachine/src/specificClass.js:212` |
|
|
| `assessDrift` | compare measured vs predicted windows | delegates to `nrmse.assessDrift` | `nodes/rotatingMachine/src/specificClass.js:237` |
|
|
| `reverseCurve` | flip x/y arrays | used for flow->ctrl predictor | `nodes/rotatingMachine/src/specificClass.js:252` |
|
|
| `updateConfig` | apply validated config patch | merges via `configUtils` | `nodes/rotatingMachine/src/specificClass.js:264` |
|
|
| `isValidSourceForMode` | mode source gate | checks configured allowed set | `nodes/rotatingMachine/src/specificClass.js:269` |
|
|
| `isValidActionForMode` | mode action gate | checks configured allowed set | `nodes/rotatingMachine/src/specificClass.js:279` |
|
|
| `handleInput` | main command dispatcher | executes sequence/movement/status commands | `nodes/rotatingMachine/src/specificClass.js:289` |
|
|
| `abortMovement` | cancel current movement | delegates to state abort if available | `nodes/rotatingMachine/src/specificClass.js:345` |
|
|
| `setMode` | update current mode | validates against schema enum values | `nodes/rotatingMachine/src/specificClass.js:351` |
|
|
| `executeSequence` | run state sequence | transitions through configured states; updatePosition at end | `nodes/rotatingMachine/src/specificClass.js:363` |
|
|
| `setpoint` | move to numeric target | validates non-negative number then `state.moveTo` | `nodes/rotatingMachine/src/specificClass.js:394` |
|
|
| `calcFlow` | predict flow from current curve and ctrl position | writes predicted flow measurements | `nodes/rotatingMachine/src/specificClass.js:413` |
|
|
| `calcPower` | predict power from current curve and ctrl position | writes predicted power measurement | `nodes/rotatingMachine/src/specificClass.js:438` |
|
|
| `inputFlowCalcPower` | estimate power from requested flow | flow->ctrl->power chained prediction | `nodes/rotatingMachine/src/specificClass.js:460` |
|
|
| `calcCtrl` | estimate ctrl for desired flow | writes predicted ctrl | `nodes/rotatingMachine/src/specificClass.js:478` |
|
|
| `getMeasuredPressure` | choose pressure basis for prediction | differential preferred; then downstream; then upstream; else 0 | `nodes/rotatingMachine/src/specificClass.js:496` |
|
|
| `_getPreferredPressureValue` | pressure source priority resolver | real child > virtual child > aggregated position value | `nodes/rotatingMachine/src/specificClass.js:570` |
|
|
| `getPressureInitializationStatus` | pressure readiness status model | upstream/downstream/differential flags | `nodes/rotatingMachine/src/specificClass.js:600` |
|
|
| `updateSimulatedMeasurement` | write dashboard-sim values | pressure route via virtual child; others dispatch typed handler | `nodes/rotatingMachine/src/specificClass.js:617` |
|
|
| `handleMeasuredFlow` | reconcile measured flow availability/consistency | returns matched/single measurement or null | `nodes/rotatingMachine/src/specificClass.js:644` |
|
|
| `handleMeasuredPower` | read measured power | returns value or null with error | `nodes/rotatingMachine/src/specificClass.js:685` |
|
|
| `updateMeasuredTemperature` | temp update hook | currently log-only | `nodes/rotatingMachine/src/specificClass.js:698` |
|
|
| `updateMeasuredPressure` | pressure update hook | stores pressure, recomputes pressure basis and position metrics | `nodes/rotatingMachine/src/specificClass.js:703` |
|
|
| `updateMeasuredFlow` | flow update hook | stores measured flow if operational; mirrors predicted flow value | `nodes/rotatingMachine/src/specificClass.js:718` |
|
|
| `_isOperationalState` | operational predicate | active states used by prediction guards | `nodes/rotatingMachine/src/specificClass.js:737` |
|
|
| `updatePosition` | core recompute pipeline on movement/state changes | calc flow/power -> efficiency -> cog -> BEP distance | `nodes/rotatingMachine/src/specificClass.js:745` |
|
|
| `calcDistanceFromPeak` | abs distance metric | absolute efficiency delta | `nodes/rotatingMachine/src/specificClass.js:767` |
|
|
| `calcRelativeDistanceFromPeak` | normalized distance metric | interpolation to [0,1] | `nodes/rotatingMachine/src/specificClass.js:771` |
|
|
| `showWorkingCurves` | debugging snapshot of current curve context | returns current curves + metrics | `nodes/rotatingMachine/src/specificClass.js:779` |
|
|
| `calcCog` | compute peak efficiency point on current curve | updates `cog`, `NCog`, indexes, minEfficiency | `nodes/rotatingMachine/src/specificClass.js:796` |
|
|
| `calcEfficiencyCurve` | derive efficiency curve and peak/min | from aligned power/flow arrays | `nodes/rotatingMachine/src/specificClass.js:817` |
|
|
| `calcFlowPower` | convenience combined prediction | calls `calcFlow` and `calcPower` | `nodes/rotatingMachine/src/specificClass.js:845` |
|
|
| `calcEfficiency` | compute efficiency family metrics | CoolProp density path + fallback + writes derived metrics | `nodes/rotatingMachine/src/specificClass.js:854` |
|
|
| `updateCurve` | replace machine curve at runtime | validates config and updates predictors | `nodes/rotatingMachine/src/specificClass.js:897` |
|
|
| `getCompleteCurve` | return full loaded curves | power+flow input curves | `nodes/rotatingMachine/src/specificClass.js:910` |
|
|
| `getCurrentCurves` | return currently selected pressure curve slices | current flow/power curves | `nodes/rotatingMachine/src/specificClass.js:916` |
|
|
| `calcDistanceBEP` | write BEP distance metrics | updates `absDistFromPeak`, `relDistFromPeak` | `nodes/rotatingMachine/src/specificClass.js:924` |
|
|
| `getOutput` | flatten and enrich output object | adds state/runtime/ctrl/mode/cog/drift/eff-distance | `nodes/rotatingMachine/src/specificClass.js:936` |
|
|
|
|
## 8) Calculations and Capability Matrix
|
|
- **Curve-backed capabilities**:
|
|
- flow prediction (`nq`) via `predictFlow`
|
|
- power prediction (`np`) via `predictPower`
|
|
- control inversion (flow->ctrl) via reversed `nq`
|
|
- **Pressure basis selection order**:
|
|
1. real differential (`downstream - upstream`)
|
|
2. real/virtual downstream only
|
|
3. real/virtual upstream only
|
|
4. fallback `0` (minimum pressure behavior)
|
|
- **Availability-first behavior**:
|
|
- missing pressure does not stop operation; it degrades predictions and warns.
|
|
- CoolProp failure does not stop operation; density fallback is used.
|
|
- non-operational states force predicted flow/power to zero.
|
|
- **BEP indicators**:
|
|
- computes peak efficiency index and normalized CoG (`NCog`) for optimization usage by parent/group controllers.
|
|
|
|
## 9) Error Handling and Safeguards
|
|
- Invalid actions/sources are rejected by mode gates, with warnings (`nodes/rotatingMachine/src/specificClass.js:297`).
|
|
- Invalid setpoint (`<0` or non-number) is rejected in `setpoint()` (`nodes/rotatingMachine/src/specificClass.js:398`).
|
|
- Missing curve model disables predictor objects but keeps class alive (`nodes/rotatingMachine/src/specificClass.js:27`).
|
|
- Missing pressure initialization surfaces Node-RED warning ring status (`nodes/rotatingMachine/src/nodeClass.js:126`).
|
|
- `simulateMeasurement` rejects non-finite values and unsupported types (`nodes/rotatingMachine/src/nodeClass.js:312`).
|
|
|
|
## 10) Test Evidence Matrix
|
|
| Test file | Covered behavior |
|
|
|---|---|
|
|
| `nodes/rotatingMachine/test/basic/constructor.basic.test.js` | constructor curve/no-curve behavior and output shape |
|
|
| `nodes/rotatingMachine/test/basic/mode-and-input.basic.test.js` | `setMode`, `handleInput` validation, operational-state predicate |
|
|
| `nodes/rotatingMachine/test/edge/error-paths.edge.test.js` | negative setpoint resilience, status failure path |
|
|
| `nodes/rotatingMachine/test/edge/nodeClass-routing.edge.test.js` | input-topic routing, pressure initialization status warning, curve/CoG reply routing |
|
|
| `nodes/rotatingMachine/test/integration/sequences.integration.test.js` | startup sequence and movement execution |
|
|
| `nodes/rotatingMachine/test/integration/registration.integration.test.js` | child registration and pressure event propagation |
|
|
| `nodes/rotatingMachine/test/integration/pressure-initialization.integration.test.js` | explicit pressure init combinations and real-vs-virtual pressure priority |
|
|
| `nodes/rotatingMachine/test/integration/coolprop.integration.test.js` | efficiency path with CoolProp and medium-pressure initialization behavior |
|
|
| `nodes/rotatingMachine/test/integration/basic-flow-dashboard.integration.test.js` | example-flow parser/wiring contracts for dashboard topics |
|
|
|
|
## 11) Invariants (Anchor Truth)
|
|
- `specificClass` is the mechanical/logic source of truth; `nodeClass` is routing/lifecycle only.
|
|
- Prediction calculations must be curve-backed when curve exists, and availability-first fallback when it does not.
|
|
- Pressure selection priority is **real sensor > virtual dashboard > aggregated fallback**.
|
|
- Command execution must remain mode-gated by both action and source.
|
|
- Output shape must keep process/influx separation and parent registration on output port 2.
|
|
- Operational-state gating must continue to prevent active prediction outputs in inactive states.
|
|
|
|
## 12) Known Gaps / Risks (Current Implementation)
|
|
- `nodeClass` routes topic `CoG` to `m.showCoG()`, but `showCoG` is not present in `specificClass` (runtime risk on that topic): `nodes/rotatingMachine/src/nodeClass.js:340`.
|
|
- `handleInput('emergencystop')` calls sequence `"emergencyStop"`, but config default key is `"emergencystop"` (case/name mismatch risk): `nodes/rotatingMachine/src/specificClass.js:327`, `nodes/generalFunctions/src/configs/rotatingMachine.json:381`.
|
|
- `_setupSpecificClass` uses `machineConfig.eneableLog` (typo) for state logging config; likely not intended: `nodes/rotatingMachine/src/nodeClass.js:86`.
|
|
- Label expression can evaluate unexpectedly because `+` and `||` precedence are mixed: `nodes/rotatingMachine/rotatingMachine.html:58`.
|
|
|
|
## 13) Change Checklist
|
|
When changing rotatingMachine logic, update all of:
|
|
1. Runtime logic in `nodes/rotatingMachine/src/specificClass.js`.
|
|
2. Node-RED routing/lifecycle in `nodes/rotatingMachine/src/nodeClass.js`.
|
|
3. UI defaults/fields in `nodes/rotatingMachine/rotatingMachine.html`.
|
|
4. Config schema and mode/action/source/sequence defaults in `nodes/generalFunctions/src/configs/rotatingMachine.json`.
|
|
5. Example flow contracts in `nodes/rotatingMachine/examples/*.flow.json`.
|
|
6. Tests under `nodes/rotatingMachine/test/` (basic, edge, integration).
|
|
|