node-red-contrib-questdb 0.6.8 → 0.6.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -8,8 +8,7 @@
|
|
|
8
8
|
category: 'questdb',
|
|
9
9
|
color: '#a54a7b',
|
|
10
10
|
defaults: {
|
|
11
|
-
name: {value:""}
|
|
12
|
-
contextName: {value: "questdbTypeMap"}
|
|
11
|
+
name: {value:""}
|
|
13
12
|
},
|
|
14
13
|
inputs:1,
|
|
15
14
|
outputs:5,
|
|
@@ -26,14 +25,10 @@
|
|
|
26
25
|
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
27
26
|
<input type="text" id="node-input-name" placeholder="Name">
|
|
28
27
|
</div>
|
|
29
|
-
<div class="form-row">
|
|
30
|
-
<label for="node-input-contextName"><i class="fa fa-database"></i> Type Map</label>
|
|
31
|
-
<input type="text" id="node-input-contextName" placeholder="questdbTypeMap">
|
|
32
|
-
</div>
|
|
33
28
|
</script>
|
|
34
29
|
|
|
35
30
|
<script type="text/html" data-help-name="questdb-type-router">
|
|
36
|
-
<p>Routes messages to different outputs based on payload data type
|
|
31
|
+
<p>Routes messages to different outputs based on payload data type.</p>
|
|
37
32
|
|
|
38
33
|
<h3>Outputs</h3>
|
|
39
34
|
<ol class="node-ports">
|
|
@@ -41,7 +36,7 @@
|
|
|
41
36
|
<li><b>Double:</b> Floating-point values (float and double both map here)</li>
|
|
42
37
|
<li><b>Bool:</b> Boolean values (including "true"/"false" strings)</li>
|
|
43
38
|
<li><b>String:</b> String values that are not numbers or booleans</li>
|
|
44
|
-
<li><b>Unresolvable:</b> Values whose type cannot be determined,
|
|
39
|
+
<li><b>Unresolvable:</b> Values whose type cannot be determined (objects, arrays, null, NaN, Infinity)</li>
|
|
45
40
|
</ol>
|
|
46
41
|
|
|
47
42
|
<h3>Type Detection</h3>
|
|
@@ -53,11 +48,6 @@
|
|
|
53
48
|
<li><b>Unresolvable:</b> Objects, arrays, <code>null</code>, <code>NaN</code>, <code>Infinity</code></li>
|
|
54
49
|
</ul>
|
|
55
50
|
|
|
56
|
-
<h3>Type Latching</h3>
|
|
57
|
-
<p>When a message includes <code>msg.topic</code>, the detected type is stored in the global context under the configured <b>Type Map</b> name (default: <code>questdbTypeMap</code>). The context holds a dictionary of <code>topic → type</code>.</p>
|
|
58
|
-
<p>Subsequent messages with the same topic are cast to the latched type. If the value cannot be cast (e.g. a string arrives for a topic latched as <code>long</code>), the message is routed to the <b>Unresolvable</b> output.</p>
|
|
59
|
-
<p>Messages without a topic are still routed by type but do not update the type map.</p>
|
|
60
|
-
|
|
61
51
|
<h3>Conversion</h3>
|
|
62
|
-
<p>String representations of numbers and booleans are automatically converted to their native types
|
|
52
|
+
<p>String representations of numbers and booleans are automatically converted to their native types.</p>
|
|
63
53
|
</script>
|
|
@@ -2,7 +2,6 @@ module.exports = function (RED) {
|
|
|
2
2
|
function TypeRouterNode(config) {
|
|
3
3
|
RED.nodes.createNode(this, config);
|
|
4
4
|
var node = this;
|
|
5
|
-
node.contextName = config.contextName || 'questdbTypeMap';
|
|
6
5
|
|
|
7
6
|
// Detect the canonical type from a value.
|
|
8
7
|
// Returns 'long' | 'double' | 'bool' | 'string' | null (unresolvable)
|
|
@@ -60,46 +59,18 @@ module.exports = function (RED) {
|
|
|
60
59
|
var TYPE_COLOR = { long: 'blue', double: 'green', bool: 'purple', string: 'yellow' };
|
|
61
60
|
|
|
62
61
|
node.on('input', function (msg) {
|
|
63
|
-
var topic = msg.topic;
|
|
64
62
|
var value = msg.payload;
|
|
65
|
-
var globalCtx = node.context().global;
|
|
66
|
-
var typeMap = globalCtx.get(node.contextName) || {};
|
|
67
63
|
|
|
68
|
-
var type
|
|
64
|
+
var type = detectType(value);
|
|
65
|
+
if (type === null) {
|
|
66
|
+
node.status({ fill: 'red', shape: 'ring', text: 'unresolvable' });
|
|
67
|
+
return node.send([null, null, null, null, msg]);
|
|
68
|
+
}
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
node.status({ fill: 'red', shape: 'ring', text: 'unresolvable [' + topic + ']' });
|
|
75
|
-
return node.send([null, null, null, null, msg]);
|
|
76
|
-
}
|
|
77
|
-
castedValue = castToType(value, type);
|
|
78
|
-
if (castedValue === null) {
|
|
79
|
-
node.status({ fill: 'red', shape: 'ring', text: "can't cast [" + topic + ']' });
|
|
80
|
-
return node.send([null, null, null, null, msg]);
|
|
81
|
-
}
|
|
82
|
-
} else {
|
|
83
|
-
// First time: auto-detect and latch
|
|
84
|
-
type = detectType(value);
|
|
85
|
-
if (type === null) {
|
|
86
|
-
if (topic) {
|
|
87
|
-
typeMap[topic] = 'unresolvable';
|
|
88
|
-
globalCtx.set(node.contextName, typeMap);
|
|
89
|
-
}
|
|
90
|
-
node.status({ fill: 'red', shape: 'ring', text: 'unresolvable' });
|
|
91
|
-
return node.send([null, null, null, null, msg]);
|
|
92
|
-
}
|
|
93
|
-
if (topic) {
|
|
94
|
-
typeMap[topic] = type;
|
|
95
|
-
globalCtx.set(node.contextName, typeMap);
|
|
96
|
-
}
|
|
97
|
-
castedValue = castToType(value, type);
|
|
98
|
-
if (castedValue === null) {
|
|
99
|
-
// Guard: detectType and castToType should always be consistent
|
|
100
|
-
node.status({ fill: 'red', shape: 'ring', text: 'cast error' });
|
|
101
|
-
return node.send([null, null, null, null, msg]);
|
|
102
|
-
}
|
|
70
|
+
var castedValue = castToType(value, type);
|
|
71
|
+
if (castedValue === null) {
|
|
72
|
+
node.status({ fill: 'red', shape: 'ring', text: 'cast error' });
|
|
73
|
+
return node.send([null, null, null, null, msg]);
|
|
103
74
|
}
|
|
104
75
|
|
|
105
76
|
msg.payload = castedValue;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-red-contrib-questdb",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.9",
|
|
4
4
|
"description": "Node-RED nodes for writing high-performance time-series data to QuestDB using Influx Line Protocol (ILP). Supports IoT, industrial monitoring, smart buildings, fleet telematics, healthcare, agriculture, and more.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Holger Amort"
|