Compare commits

..

2 Commits

Author SHA1 Message Date
znetsixe
c96ad94c40 feat(commands): adopt unified command envelope — msg.origin provenance
Resolve command origin via msg.origin (registry-stamped, default parent) with a
legacy fallback to the previous payload.source/msg.source field. Feeds the
existing mode/allowedSources arbitration unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 18:41:16 +02:00
znetsixe
bd67b22197 style: palette swatch → (domain-hue redesign 2026-05-21)
Sidebar swatch now follows function family rather than S88 level, so the
palette is visually identifiable instead of monochromatically blue. Editor-group
rectangles in flow.json still follow S88 — only the registerType color changed.
Full table + rationale: superproject .claude/rules/node-red-flow-layout.md §10.0
and .claude/refactor/OPEN_QUESTIONS.md (2026-05-21 entry).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 15:05:55 +02:00
2 changed files with 17 additions and 13 deletions

View File

@@ -9,6 +9,16 @@ function _logger(source, ctx) {
return ctx?.logger || source?.logger || null;
}
// Resolve the command origin (control authority: parent | GUI | fysical).
// The shared commandRegistry stamps msg.origin (default 'parent'); legacy flows
// carried it as payload.source. Prefer the legacy field when present so existing
// flows keep working, otherwise use the registry-stamped msg.origin.
function _origin(msg) {
const p = msg && msg.payload;
if (p && typeof p === 'object' && typeof p.source === 'string' && p.source) return p.source;
return (typeof msg?.origin === 'string' && msg.origin) ? msg.origin : 'parent';
}
exports.setMode = (source, msg) => {
source.setMode(msg.payload);
};
@@ -31,25 +41,18 @@ exports.registerChild = (source, msg, ctx) => {
};
exports.execSequence = async (source, msg) => {
const { source: seqSource, action: seqAction, parameter } = msg.payload || {};
await source.handleInput(seqSource, seqAction, parameter);
const { action: seqAction, parameter } = msg.payload || {};
await source.handleInput(_origin(msg), seqAction, parameter);
};
exports.totalFlowChange = async (source, msg) => {
const payload = msg.payload || {};
if (payload && typeof payload === 'object' && Object.prototype.hasOwnProperty.call(payload, 'source')) {
const src = payload.source || 'parent';
const action = payload.action || 'totalFlowChange';
await source.handleInput(src, action, payload);
return;
}
await source.handleInput('parent', 'totalFlowChange', payload);
const action = payload.action || 'totalFlowChange';
await source.handleInput(_origin(msg), action, payload);
};
exports.emergencyStop = async (source, msg) => {
const payload = msg.payload || {};
const src = payload.source || 'parent';
await source.handleInput(src, 'emergencystop');
await source.handleInput(_origin(msg), 'emergencystop');
};
exports.setReconcileInterval = (source, msg) => {

View File

@@ -14,7 +14,7 @@
<script>
RED.nodes.registerType('valveGroupControl',{
category: "EVOLV",
color: "#50a8d9",
color: "#2A8A82",
defaults: {
// Define default properties
name: { value: "" },
@@ -91,6 +91,7 @@
<label for="node-input-dbaseOutputFormat"><i class="fa fa-database"></i> Database Output</label>
<select id="node-input-dbaseOutputFormat" style="width:60%;">
<option value="influxdb">influxdb</option>
<option value="frost">frost</option>
<option value="json">json</option>
<option value="csv">csv</option>
</select>