node-red-contrib-3dm-space 0.0.8 → 1.0.2
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.
- package/3dm-cloud-config.html +80 -16
- package/3dm-cloud-config.js +197 -192
- package/3dm-cloud-in.html +27 -14
- package/3dm-cloud-in.js +115 -115
- package/3dm-cloud-out.html +23 -10
- package/3dm-cloud-out.js +736 -669
- package/3dm-config-store.html +236 -0
- package/3dm-config-store.js +883 -0
- package/README.md +193 -58
- package/node-red-contrib-3dm-space-1.0.0.tgz +0 -0
- package/package.json +12 -5
package/3dm-cloud-in.js
CHANGED
|
@@ -1,115 +1,115 @@
|
|
|
1
|
-
module.exports = function (RED) {
|
|
2
|
-
"use strict";
|
|
3
|
-
|
|
4
|
-
/*
|
|
5
|
-
* Hidden cloud subscribe settings.
|
|
6
|
-
*/
|
|
7
|
-
var ATTRIBUTES_TOPIC = "v1/devices/me/attributes";
|
|
8
|
-
var MQTT_QOS = 1;
|
|
9
|
-
|
|
10
|
-
function ThreeDMCloudInNode(config) {
|
|
11
|
-
RED.nodes.createNode(this, config);
|
|
12
|
-
|
|
13
|
-
var node = this;
|
|
14
|
-
|
|
15
|
-
node.name = config.name;
|
|
16
|
-
node.server = RED.nodes.getNode(config.server);
|
|
17
|
-
node.keyFilter = config.keyFilter || "";
|
|
18
|
-
node.outputMode = config.outputMode || "value";
|
|
19
|
-
|
|
20
|
-
if (!node.server) {
|
|
21
|
-
node.status({ fill: "red", shape: "ring", text: "missing config" });
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function updateStatus(connected) {
|
|
26
|
-
if (connected) {
|
|
27
|
-
node.status({ fill: "green", shape: "dot", text: "connected" });
|
|
28
|
-
} else {
|
|
29
|
-
node.status({ fill: "red", shape: "ring", text: "disconnected" });
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function parsePayload(payload) {
|
|
34
|
-
var text = payload.toString();
|
|
35
|
-
|
|
36
|
-
try {
|
|
37
|
-
return JSON.parse(text);
|
|
38
|
-
} catch (
|
|
39
|
-
return text;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function hasOwn(obj, key) {
|
|
44
|
-
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
var stateHandler = function (connected) {
|
|
48
|
-
updateStatus(connected);
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
var messageHandler = function (topic, payload) {
|
|
52
|
-
if (topic !== ATTRIBUTES_TOPIC) {
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
var data = parsePayload(payload);
|
|
57
|
-
|
|
58
|
-
if (node.keyFilter) {
|
|
59
|
-
if (typeof data !== "object" || data === null || Array.isArray(data)) {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (!hasOwn(data, node.keyFilter)) {
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
var msg = {
|
|
68
|
-
topic: node.keyFilter,
|
|
69
|
-
key: node.keyFilter,
|
|
70
|
-
value: data[node.keyFilter],
|
|
71
|
-
values: data
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
if (node.outputMode === "object") {
|
|
75
|
-
var obj = {};
|
|
76
|
-
obj[node.keyFilter] = data[node.keyFilter];
|
|
77
|
-
msg.payload = obj;
|
|
78
|
-
} else {
|
|
79
|
-
msg.payload = data[node.keyFilter];
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
node.send(msg);
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
node.send({
|
|
87
|
-
topic: "3dm.attributes",
|
|
88
|
-
payload: data
|
|
89
|
-
});
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
node.server.on("state", stateHandler);
|
|
93
|
-
node.server.on("cloud-message", messageHandler);
|
|
94
|
-
|
|
95
|
-
node.server.subscribe(ATTRIBUTES_TOPIC, { qos: MQTT_QOS }, function (err) {
|
|
96
|
-
if (err) {
|
|
97
|
-
node.status({ fill: "red", shape: "ring", text: "subscribe failed" });
|
|
98
|
-
node.warn("3DM Cloud attribute subscribe failed: " + (err.message || err));
|
|
99
|
-
} else {
|
|
100
|
-
updateStatus(node.server.connected);
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
updateStatus(node.server.connected);
|
|
105
|
-
|
|
106
|
-
node.on("close", function () {
|
|
107
|
-
if (node.server) {
|
|
108
|
-
node.server.removeListener("state", stateHandler);
|
|
109
|
-
node.server.removeListener("cloud-message", messageHandler);
|
|
110
|
-
}
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
RED.nodes.registerType("3dm-cloud-in", ThreeDMCloudInNode);
|
|
115
|
-
};
|
|
1
|
+
module.exports = function (RED) {
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* Hidden cloud subscribe settings.
|
|
6
|
+
*/
|
|
7
|
+
var ATTRIBUTES_TOPIC = "v1/devices/me/attributes";
|
|
8
|
+
var MQTT_QOS = 1;
|
|
9
|
+
|
|
10
|
+
function ThreeDMCloudInNode(config) {
|
|
11
|
+
RED.nodes.createNode(this, config);
|
|
12
|
+
|
|
13
|
+
var node = this;
|
|
14
|
+
|
|
15
|
+
node.name = config.name;
|
|
16
|
+
node.server = RED.nodes.getNode(config.server);
|
|
17
|
+
node.keyFilter = config.keyFilter || "";
|
|
18
|
+
node.outputMode = config.outputMode || "value";
|
|
19
|
+
|
|
20
|
+
if (!node.server) {
|
|
21
|
+
node.status({ fill: "red", shape: "ring", text: "missing config" });
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function updateStatus(connected) {
|
|
26
|
+
if (connected) {
|
|
27
|
+
node.status({ fill: "green", shape: "dot", text: "connected" });
|
|
28
|
+
} else {
|
|
29
|
+
node.status({ fill: "red", shape: "ring", text: "disconnected" });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function parsePayload(payload) {
|
|
34
|
+
var text = payload.toString();
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
return JSON.parse(text);
|
|
38
|
+
} catch (err) {
|
|
39
|
+
return text;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function hasOwn(obj, key) {
|
|
44
|
+
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
var stateHandler = function (connected) {
|
|
48
|
+
updateStatus(connected);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
var messageHandler = function (topic, payload) {
|
|
52
|
+
if (topic !== ATTRIBUTES_TOPIC) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
var data = parsePayload(payload);
|
|
57
|
+
|
|
58
|
+
if (node.keyFilter) {
|
|
59
|
+
if (typeof data !== "object" || data === null || Array.isArray(data)) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (!hasOwn(data, node.keyFilter)) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
var msg = {
|
|
68
|
+
topic: node.keyFilter,
|
|
69
|
+
key: node.keyFilter,
|
|
70
|
+
value: data[node.keyFilter],
|
|
71
|
+
values: data
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
if (node.outputMode === "object") {
|
|
75
|
+
var obj = {};
|
|
76
|
+
obj[node.keyFilter] = data[node.keyFilter];
|
|
77
|
+
msg.payload = obj;
|
|
78
|
+
} else {
|
|
79
|
+
msg.payload = data[node.keyFilter];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
node.send(msg);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
node.send({
|
|
87
|
+
topic: "3dm.attributes",
|
|
88
|
+
payload: data
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
node.server.on("state", stateHandler);
|
|
93
|
+
node.server.on("cloud-message", messageHandler);
|
|
94
|
+
|
|
95
|
+
node.server.subscribe(ATTRIBUTES_TOPIC, { qos: MQTT_QOS }, function (err) {
|
|
96
|
+
if (err) {
|
|
97
|
+
node.status({ fill: "red", shape: "ring", text: "subscribe failed" });
|
|
98
|
+
node.warn("3DM Cloud attribute subscribe failed: " + (err.message || err));
|
|
99
|
+
} else {
|
|
100
|
+
updateStatus(node.server.connected);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
updateStatus(node.server.connected);
|
|
105
|
+
|
|
106
|
+
node.on("close", function () {
|
|
107
|
+
if (node.server) {
|
|
108
|
+
node.server.removeListener("state", stateHandler);
|
|
109
|
+
node.server.removeListener("cloud-message", messageHandler);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
RED.nodes.registerType("3dm-cloud-in", ThreeDMCloudInNode);
|
|
115
|
+
};
|
package/3dm-cloud-out.html
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<script type="text/javascript">
|
|
2
2
|
RED.nodes.registerType("3dm-cloud-out", {
|
|
3
3
|
category: "3DM.space",
|
|
4
|
-
color: "#
|
|
4
|
+
color: "#6D6D6D",
|
|
5
5
|
defaults: {
|
|
6
6
|
name: { value: "" },
|
|
7
7
|
server: { value: "", type: "3dm-cloud-config", required: true }
|
|
8
8
|
},
|
|
9
9
|
inputs: 1,
|
|
10
10
|
outputs: 1,
|
|
11
|
-
icon: "
|
|
11
|
+
icon: "font-awesome/fa-cloud-upload",
|
|
12
12
|
label: function () {
|
|
13
13
|
return this.name || "3DM telemetry out";
|
|
14
14
|
},
|
|
@@ -18,23 +18,36 @@
|
|
|
18
18
|
|
|
19
19
|
<script type="text/html" data-template-name="3dm-cloud-out">
|
|
20
20
|
<div class="form-row">
|
|
21
|
-
<label for="node-input-name"
|
|
22
|
-
|
|
21
|
+
<label for="node-input-name">
|
|
22
|
+
<i class="fa fa-tag"></i> Node Name
|
|
23
|
+
</label>
|
|
24
|
+
<input type="text" id="node-input-name" placeholder="Optional, e.g. Pump Telemetry Out">
|
|
23
25
|
</div>
|
|
24
26
|
|
|
25
27
|
<div class="form-row">
|
|
26
|
-
<label for="node-input-server"
|
|
28
|
+
<label for="node-input-server">
|
|
29
|
+
<i class="fa fa-cloud"></i> 3DM Cloud Login
|
|
30
|
+
</label>
|
|
27
31
|
<input type="text" id="node-input-server">
|
|
28
32
|
</div>
|
|
29
33
|
</script>
|
|
30
34
|
|
|
31
35
|
<script type="text/html" data-help-name="3dm-cloud-out">
|
|
32
|
-
<p>Sends
|
|
36
|
+
<p>Sends telemetry to 3DM.space SCADA Cloud.</p>
|
|
33
37
|
|
|
34
|
-
<p>Input
|
|
35
|
-
<pre>{"tank_level":74,"pump_run":true,"battery":12.8}</pre>
|
|
38
|
+
<p>Input must be a JSON object.</p>
|
|
36
39
|
|
|
37
|
-
<p>
|
|
40
|
+
<p>Example:</p>
|
|
38
41
|
|
|
39
|
-
<
|
|
42
|
+
<pre>{
|
|
43
|
+
"tank_level": 74,
|
|
44
|
+
"pump_run": true,
|
|
45
|
+
"battery": 12.8
|
|
46
|
+
}</pre>
|
|
47
|
+
|
|
48
|
+
<p>The node automatically adds the timestamp before sending to 3DM.space.</p>
|
|
49
|
+
|
|
50
|
+
<p>Store and forward is built in. If the cloud is offline, messages are stored locally and sent later when the cloud reconnects.</p>
|
|
51
|
+
|
|
52
|
+
<p>Live online messages are limited to 1 update per minute. Stored messages backhaul faster when the connection returns.</p>
|
|
40
53
|
</script>
|