chore: initial coresync scaffold
EVOLV CoreSync node — FROST/SensorThings handoff path. First version forwards FROST-ready HTTP request messages on the dbase output; a downstream Node-RED http-request node performs the actual POST and feeds responses back on msg.topic = "frost.response". Lazy stream resolver, latest-wins queue for unresolved/FROST-down streams (keep first + latest, drop middle), knot-emit on slope change, provenance preserved in Observation parameters. Interview state + open Q20 (slope angle vs. relative delta) recorded in superproject CORESYNC_FROST_INTERVIEW_HANDOFF.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
51
coresync.js
Normal file
51
coresync.js
Normal file
@@ -0,0 +1,51 @@
|
||||
'use strict';
|
||||
|
||||
const { CoreSyncDomain } = require('./src/coreSyncDomain');
|
||||
|
||||
module.exports = function(RED) {
|
||||
RED.nodes.registerType('coresync', function(config) {
|
||||
RED.nodes.createNode(this, config);
|
||||
const node = this;
|
||||
const hub = new CoreSyncDomain({
|
||||
frostBaseUrl: config.frostBaseUrl,
|
||||
serviceVersion: config.serviceVersion,
|
||||
dbaseFormat: config.dbaseFormat,
|
||||
assetTagOverride: config.assetTagOverride,
|
||||
sensorTagOverride: config.sensorTagOverride,
|
||||
maxQueuedObservationsPerStream: config.maxQueuedObservationsPerStream,
|
||||
reducer: {
|
||||
angleToleranceDeg: Number(config.angleToleranceDeg),
|
||||
timeScaleMs: Number(config.timeScaleMs),
|
||||
maxGapMs: Number(config.maxGapMs),
|
||||
minDeltaTimeMs: Number(config.minDeltaTimeMs),
|
||||
minDeltaValue: Number(config.minDeltaValue),
|
||||
comparisonMode: config.comparisonMode || 'angle',
|
||||
},
|
||||
});
|
||||
|
||||
node.on('input', (msg, send, done) => {
|
||||
try {
|
||||
const output = hub.handleMessage(msg);
|
||||
const dbaseCount = Array.isArray(output[1]) ? output[1].length : (output[1] ? 1 : 0);
|
||||
if (dbaseCount > 0) node.status({ fill: 'blue', shape: 'dot', text: `${dbaseCount} FROST request(s)` });
|
||||
send(output);
|
||||
} catch (error) {
|
||||
node.status({ fill: 'red', shape: 'ring', text: error.message });
|
||||
node.error(error, msg);
|
||||
} finally {
|
||||
if (typeof done === 'function') done();
|
||||
}
|
||||
});
|
||||
|
||||
node.on('close', (removed, done) => {
|
||||
const closeDone = typeof removed === 'function' ? removed : done;
|
||||
try {
|
||||
const output = hub.flushAll('close');
|
||||
if (output[1]) node.send(output);
|
||||
node.status({});
|
||||
} finally {
|
||||
if (typeof closeDone === 'function') closeDone();
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user