未验证 提交 4a63f359 编写于 作者: K KP45 提交者: GitHub

Add Node-Red TDEngine integration node (#9433)

上级 a2d3c27a
node_modules
\ No newline at end of file
This repositry create a custom Node-Red node for configing TDEngine server connection and execute SQL from preview node msg.payload
## Design
Use Taos data restful API to commit SQL, API call like
```
curl -H 'Authorization: Basic <TOKEN>' -d '<SQL>' <ip>:<PORT>/rest/sql/[db_name]
```
Input options:
* DB Server: Setup server connection or select a exist server
* DB Name: Database to execute SQL
Use [axios](https://axios-http.com/) to call http request
## Usage
1. Start Node-Red
2. Install TDEngine node
3. Add "taos query" node to workspace from palette
4. Setup a TDEngine server and database name
5. Add function or other node to create SQL, put SQL into msg.payload
6. Link to "taos query" node
### Demo
1. Start Node-Red by docker
```
docker run -it -p 1880:1880 -v node_red_data:/data --name mynodered nodered/node-red
```
2. Import sample flow "demo/flow.json"
![import-flow](demo/ImportFlow.png)
3. Install TDEngine node by name "node-red-contrib-tdengine", current version is 0.0.2
![alt](demo/InstallTDEngineNode.png)
4. Modify your TDEngine server config
![alt](demo/ModifyServerConfig.png)
5. Edit test SQL
![alt](demo/EditTestSQL.png)
6. Start flow by click Inject node
[
{
"id": "01ad89bea2c249f6",
"type": "tab",
"label": "流程 1",
"disabled": false,
"info": "",
"env": [
{
"name": "test",
"value": "abc",
"type": "str"
},
{
"name": "path",
"value": "{\"codes\":\"/usr/local/processing/codes\",\"parameters\":\"/usr/local/processing/parameters\"}",
"type": "json"
}
]
},
{
"id": "0ab8aa0c7f1b7522",
"type": "taos-query",
"z": "01ad89bea2c249f6",
"server": "e385222cd91994dc",
"database": "demo",
"x": 780,
"y": 400,
"wires": [
[
"f9c4f70dc2d79548"
]
]
},
{
"id": "ba09b80a40b65780",
"type": "inject",
"z": "01ad89bea2c249f6",
"name": "",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "INSERT INTO t VALUES (NOW, 23)",
"payloadType": "str",
"x": 490,
"y": 400,
"wires": [
[
"0ab8aa0c7f1b7522"
]
]
},
{
"id": "f9c4f70dc2d79548",
"type": "debug",
"z": "01ad89bea2c249f6",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 1050,
"y": 400,
"wires": []
},
{
"id": "e385222cd91994dc",
"type": "taos-config",
"host": "localhost",
"port": "6030",
"username": "root",
"password": "taosdata"
}
]
\ No newline at end of file
{
"name": "node-red-contrib-tdengine",
"version": "0.0.2",
"description": "",
"main": "tdengine.js",
"repository": {
"type": "git",
"url": "git+https://github.com/kevinpan45/node-red-contrib-tdengine.git"
},
"author": "kevinpan45@163.com",
"license": "ISC",
"dependencies": {
"axios": "^0.24.0",
"mocha": "^9.1.3"
},
"node-red": {
"nodes": {
"tdengine": "tdengine.js"
}
},
"keywords": [
"node-red",
"tdengine"
],
"devDependencies": {
"node-red": "^2.1.4",
"node-red-node-test-helper": "^0.2.7"
}
}
<script type="text/javascript">
"use strict";
/*global RED*/
RED.nodes.registerType('taos-config', {
category: 'config',
defaults: {
host: {
value: "localhost",
required: true
},
port: {
value: "6030",
required: true
},
username: {
value: "",
required: false
},
password: {
value: "",
required: false
}
},
label: function () {
return this.host || "TDEngine host";
}
});
</script>
<script type="text/x-red" data-template-name="taos-config">
<div class="form-row">
<label for="node-config-input-host"><i class="fa fa-server"></i> Host</label>
<input type="text" id="node-config-input-host">
</div>
<div class="form-row">
<label for="node-config-input-port"><i class="fa fa-server"></i> Port</label>
<input type="text" id="node-config-input-port">
</div>
<div class="form-row">
<label for="node-config-input-username"><i class="fa fa-server"></i> User Name</label>
<input type="text" id="node-config-input-username">
</div>
<div class="form-row">
<label for="node-config-input-password"><i class="fa fa-server"></i> Password</label>
<input type="text" id="node-config-input-password">
</div>
</script>
<script type="text/javascript">
/*global RED*/
RED.nodes.registerType('taos-query', {
category: 'TDEngine',
inputs: 1,
outputs: 1,
color: "#ffffff",
paletteLabel: "taos query",
defaults: {
server: {
value: "",
type: "taos-config"
},
database: {
value: ""
},
sql: {
value: ""
}
},
label: function () {
return this.name || "taos " + this.database;
}
});
</script>
<script type="text/x-red" data-template-name="taos-query">
<div class="form-row">
<label for="node-input-server"><i class="fa fa-globe"></i> Server</label>
<input type="text" id="node-input-server" placeholder="Server">
</div>
<div class="form-row">
<label for="node-input-database"><i class="fa fa-tag"></i> Database</label>
<input type="text" id="node-input-database" placeholder="Database">
</div>
</script>
<script type="text/x-red" data-help-name="taos-query">
<p>TDEngine Query</p>
<p>Execute SQL on remote TDEngine server by restful API</p>
</script>
\ No newline at end of file
module.exports = function (RED) {
"use strict";
const axios = require('axios');
function TaosConfig(n) {
RED.nodes.createNode(this, n);
this.host = n.host;
this.port = n.port;
this.username = n.username;
this.password = n.password;
}
RED.nodes.registerType("taos-config", TaosConfig);
function TaosQuery(n) {
RED.nodes.createNode(this, n);
this.server = RED.nodes.getNode(n.server);
this.database = n.database;
var node = this;
node.on("close", function (done) {
node.status({});
client = null;
done();
});
node.on("input", async function (msg, send, done) {
send = send || function () { node.send.apply(node, arguments) }
done = done || function (err) { if (err) node.error(err, msg); }
let sql = msg.payload;
if (!msg.payload || msg.payload == "") {
throw new Error("Execute SQL must be set.");
}
try {
msg.payload = await query(this.server, sql);
send(msg);
done();
} catch (error) {
done(error);
}
});
}
RED.nodes.registerType("taos-query", TaosQuery);
function query(server, sql) {
console.log("Start to execute SQL : " + sql);
let url = generateUrl(server);
return axios.post(url, sql, {
headers: { 'Authorization': token(server) }
}).then(function (response) {
console.log('Get http response from taos : ' + response.data.data);
return response.data.data;
}).catch(function (error) {
console.error("Request Failed " + e);
throw new Error(response.desc);
});
}
function generateUrl(server) {
return "http://" + server.host + ":" + server.port + '/rest/sql';
}
function token(server) {
return 'Basic ' + Buffer.from(server.username + ":" + server.password).toString('base64')
}
};
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册