2026-05-21 15:07:12 +02:00
< script type = "text/javascript" >
RED.nodes.registerType('coresync', {
category: 'EVOLV',
color: '#54647B',
defaults: {
name: { value: '' },
frostBaseUrl: { value: 'http://localhost:8080/FROST-Server', required: true },
serviceVersion: { value: 'v1.1', required: true },
dbaseFormat: { value: 'frost' },
assetTagOverride: { value: '' },
sensorTagOverride: { value: '' },
comparisonMode: { value: 'angle' },
angleToleranceDeg: { value: 5, required: true, validate: RED.validators.number() },
timeScaleMs: { value: 60000, required: true, validate: RED.validators.number() },
maxGapMs: { value: 300000, required: true, validate: RED.validators.number() },
minDeltaTimeMs: { value: 0, required: true, validate: RED.validators.number() },
minDeltaValue: { value: 0, required: true, validate: RED.validators.number() },
2026-05-22 20:27:28 +02:00
burstWindowMs: { value: 0, required: true, validate: RED.validators.number() },
2026-05-21 15:07:12 +02:00
maxQueuedObservationsPerStream: { value: 2, required: true, validate: RED.validators.number() },
diagnosticsEnabled: { value: false },
},
inputs: 1,
outputs: 3,
inputLabels: ['EVOLV dbase / FROST response'],
outputLabels: ['process', 'dbase', 'parent'],
icon: 'font-awesome/fa-cloud-upload',
label: function() {
return this.name || 'CoreSync';
},
});
< / script >
< script type = "text/html" data-template-name = "coresync" >
< div class = "form-row" >
< label for = "node-input-name" > < i class = "fa fa-tag" > < / i > Name< / label >
< input type = "text" id = "node-input-name" >
< / div >
< div class = "form-row" >
< label for = "node-input-frostBaseUrl" > < i class = "fa fa-globe" > < / i > FROST URL< / label >
< input type = "text" id = "node-input-frostBaseUrl" >
< / div >
< div class = "form-row" >
< label for = "node-input-serviceVersion" > < i class = "fa fa-code-fork" > < / i > Version< / label >
< input type = "text" id = "node-input-serviceVersion" >
< / div >
< div class = "form-row" >
< label for = "node-input-dbaseFormat" > < i class = "fa fa-database" > < / i > Output< / label >
< select id = "node-input-dbaseFormat" style = "width:70%;" >
< option value = "frost" > frost< / option >
< / select >
< / div >
< div class = "form-row" >
< label for = "node-input-assetTagOverride" > < i class = "fa fa-cube" > < / i > Thing Tag< / label >
< input type = "text" id = "node-input-assetTagOverride" placeholder = "optional override" >
< / div >
< div class = "form-row" >
< label for = "node-input-sensorTagOverride" > < i class = "fa fa-bullseye" > < / i > Sensor Tag< / label >
< input type = "text" id = "node-input-sensorTagOverride" placeholder = "optional override" >
< / div >
< div class = "form-row" >
< label for = "node-input-comparisonMode" > < i class = "fa fa-compress" > < / i > Reducer< / label >
< select id = "node-input-comparisonMode" style = "width:70%;" >
< option value = "angle" > Angle change< / option >
< option value = "relative-slope" > Relative slope change< / option >
< / select >
< / div >
< div class = "form-row" >
< label for = "node-input-angleToleranceDeg" > < i class = "fa fa-arrows-h" > < / i > Angle Tol.< / label >
< input type = "number" id = "node-input-angleToleranceDeg" style = "width:70%;" >
< / div >
< div class = "form-row" >
< label for = "node-input-timeScaleMs" > < i class = "fa fa-clock-o" > < / i > Time Scale< / label >
< input type = "number" id = "node-input-timeScaleMs" style = "width:70%;" >
< / div >
< div class = "form-row" >
< label for = "node-input-maxGapMs" > < i class = "fa fa-hourglass-half" > < / i > Max Gap< / label >
< input type = "number" id = "node-input-maxGapMs" style = "width:70%;" >
< / div >
< div class = "form-row" >
< label for = "node-input-minDeltaTimeMs" > < i class = "fa fa-filter" > < / i > Min dt< / label >
< input type = "number" id = "node-input-minDeltaTimeMs" style = "width:70%;" >
< / div >
< div class = "form-row" >
< label for = "node-input-minDeltaValue" > < i class = "fa fa-filter" > < / i > Min dv< / label >
< input type = "number" id = "node-input-minDeltaValue" style = "width:70%;" >
< / div >
2026-05-22 20:27:28 +02:00
< div class = "form-row" >
< label for = "node-input-burstWindowMs" title = "Collapse sub-tick sample bursts: when two samples arrive within this many milliseconds, treat them as the same observation. 0 disables. Set to ~10 ms when an upstream node emits multiple telemetry rows per logical tick (e.g. rotatingMachine reacting to two simultaneous simulateMeasurement msgs)." > < i class = "fa fa-compress" > < / i > Burst dt< / label >
< input type = "number" id = "node-input-burstWindowMs" style = "width:70%;" >
< / div >
2026-05-21 15:07:12 +02:00
< div class = "form-row" >
< label for = "node-input-maxQueuedObservationsPerStream" > < i class = "fa fa-list" > < / i > Queue< / label >
< input type = "number" id = "node-input-maxQueuedObservationsPerStream" style = "width:70%;" >
< / div >
< / script >
< script type = "text/html" data-help-name = "coresync" >
< p > Collects EVOLV dbase telemetry, reduces numeric streams, and emits FROST-ready HTTP request messages on the dbase output.< / p >
< p > Feed HTTP responses back into this node with < code > msg.topic = "frost.response"< / code > so metadata lookup/create state can advance.< / p >
< / script >