node-red-contrib-padavan 1.0.0
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/LICENSE +21 -0
- package/README.md +265 -0
- package/main.mjs +300 -0
- package/nodes/config.html +71 -0
- package/nodes/config.js +19 -0
- package/nodes/devices.html +27 -0
- package/nodes/devices.js +27 -0
- package/nodes/history.html +27 -0
- package/nodes/history.js +32 -0
- package/nodes/locales/en-US/config.html +12 -0
- package/nodes/locales/en-US/devices.html +19 -0
- package/nodes/locales/en-US/history.html +25 -0
- package/nodes/locales/en-US/params.html +39 -0
- package/nodes/locales/en-US/speedtest.html +24 -0
- package/nodes/locales/en-US/system.html +79 -0
- package/nodes/locales/en-US/upgrade.html +33 -0
- package/nodes/locales/ru/config.html +12 -0
- package/nodes/locales/ru/devices.html +19 -0
- package/nodes/locales/ru/history.html +25 -0
- package/nodes/locales/ru/params.html +39 -0
- package/nodes/locales/ru/speedtest.html +24 -0
- package/nodes/locales/ru/system.html +79 -0
- package/nodes/locales/ru/upgrade.html +33 -0
- package/nodes/params.html +60 -0
- package/nodes/params.js +35 -0
- package/nodes/speedtest.html +28 -0
- package/nodes/speedtest.js +66 -0
- package/nodes/system.html +43 -0
- package/nodes/system.js +30 -0
- package/nodes/upgrade.html +43 -0
- package/nodes/upgrade.js +47 -0
- package/package.json +41 -0
- package/services/speedtest.sh +25 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<script type="text/html" data-template-name="padavan-speedtest">
|
|
2
|
+
<div class="form-row">
|
|
3
|
+
<label for="node-input-settings"><i class="fa fa-cog"></i> Config</label>
|
|
4
|
+
<input id="node-input-settings" />
|
|
5
|
+
</div>
|
|
6
|
+
<div class="form-row">
|
|
7
|
+
<label for="node-input-name"><i class="fa fa-pencil"></i> Name</label>
|
|
8
|
+
<input type="text" id="node-input-name" />
|
|
9
|
+
</div>
|
|
10
|
+
</script>
|
|
11
|
+
<script type="text/javascript">
|
|
12
|
+
RED.nodes.registerType('padavan-speedtest', {
|
|
13
|
+
category: 'Padavan',
|
|
14
|
+
defaults: {
|
|
15
|
+
settings: { value: null, required: true, type: 'padavan-config' },
|
|
16
|
+
name: { value: '' }
|
|
17
|
+
},
|
|
18
|
+
icon: 'font-awesome/fa-tasks',
|
|
19
|
+
inputs: 1,
|
|
20
|
+
outputs: 3,
|
|
21
|
+
outputLabels: [ 'result', 'history', 'progress' ],
|
|
22
|
+
color: '#49afcd',
|
|
23
|
+
paletteLabel: 'SpeedTest',
|
|
24
|
+
label: function() {
|
|
25
|
+
return this.name || 'SpeedTest';
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
</script>
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
module.exports = function(RED) {
|
|
2
|
+
function SpeedTest(config) {
|
|
3
|
+
RED.nodes.createNode(this, config);
|
|
4
|
+
const settings = RED.nodes.getNode(config.settings);
|
|
5
|
+
this.on('input', msg => {
|
|
6
|
+
this.status({
|
|
7
|
+
fill: 'yellow',
|
|
8
|
+
shape: 'ring',
|
|
9
|
+
text: 'Start...'
|
|
10
|
+
});
|
|
11
|
+
this.send([ null, null, {
|
|
12
|
+
topic: 'networkSpeedTestInProgress',
|
|
13
|
+
payload: true
|
|
14
|
+
}]);
|
|
15
|
+
settings.getClient().then(client => client.startSpeedTest())
|
|
16
|
+
.then(payload => {
|
|
17
|
+
if (!payload)
|
|
18
|
+
return;
|
|
19
|
+
const date = new Date();
|
|
20
|
+
const timestamp = parseInt(date.getTime() / 1000);
|
|
21
|
+
this.status({
|
|
22
|
+
fill: 'green',
|
|
23
|
+
shape: 'dot',
|
|
24
|
+
text: `${payload.networkDownloadSpeedMbps}Mbps / ${payload.networkUploadSpeedMbps}Mbps`
|
|
25
|
+
});
|
|
26
|
+
this.send([{
|
|
27
|
+
topic: 'NetworkControl',
|
|
28
|
+
payload: {
|
|
29
|
+
...payload,
|
|
30
|
+
status: 'SUCCESS',
|
|
31
|
+
followUpToken: msg.params?.followUpToken
|
|
32
|
+
}
|
|
33
|
+
}, {
|
|
34
|
+
date: date.toLocaleString(),
|
|
35
|
+
payload: {
|
|
36
|
+
lastNetworkDownloadSpeedTest: {
|
|
37
|
+
downloadSpeedMbps: payload.networkDownloadSpeedMbps,
|
|
38
|
+
unixTimestampSec: timestamp,
|
|
39
|
+
status: 'SUCCESS'
|
|
40
|
+
},
|
|
41
|
+
lastNetworkUploadSpeedTest: {
|
|
42
|
+
uploadSpeedMbps: payload.networkUploadSpeedMbps,
|
|
43
|
+
unixTimestampSec: timestamp,
|
|
44
|
+
status: 'SUCCESS'
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}, null ]);
|
|
48
|
+
})
|
|
49
|
+
.catch(({ message, code }) => {
|
|
50
|
+
msg.code = code;
|
|
51
|
+
msg.payload = message;
|
|
52
|
+
this.status({
|
|
53
|
+
fill: 'red',
|
|
54
|
+
shape: 'ring',
|
|
55
|
+
text: message,
|
|
56
|
+
});
|
|
57
|
+
this.error(message, msg);
|
|
58
|
+
})
|
|
59
|
+
.then(() => this.send([ null, null, {
|
|
60
|
+
topic: 'networkSpeedTestInProgress',
|
|
61
|
+
payload: false
|
|
62
|
+
}]));
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
RED.nodes.registerType('padavan-speedtest', SpeedTest);
|
|
66
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<script type="text/html" data-template-name="padavan-system">
|
|
2
|
+
<div class="form-row">
|
|
3
|
+
<label for="node-input-settings"><i class="fa fa-cog"></i> Config</label>
|
|
4
|
+
<input id="node-input-settings" />
|
|
5
|
+
</div>
|
|
6
|
+
<div class="form-row">
|
|
7
|
+
<label for="node-input-name"><i class="fa fa-pencil"></i> Name</label>
|
|
8
|
+
<input type="text" id="node-input-name" />
|
|
9
|
+
</div>
|
|
10
|
+
<div class="form-row">
|
|
11
|
+
<label for="node-input-topic"><i class="fa fa-envelope-o"></i> Topic</label>
|
|
12
|
+
<input type="text" id="node-input-topic">
|
|
13
|
+
<input type="hidden" id="node-input-topicType">
|
|
14
|
+
</div>
|
|
15
|
+
</script>
|
|
16
|
+
<script type="text/javascript">
|
|
17
|
+
RED.nodes.registerType('padavan-system', {
|
|
18
|
+
category: 'Padavan',
|
|
19
|
+
defaults: {
|
|
20
|
+
settings: { value: null, required: true, type: 'padavan-config' },
|
|
21
|
+
name: { value: '' },
|
|
22
|
+
topic: { value: 'topic' },
|
|
23
|
+
topicType: { value: 'msg' }
|
|
24
|
+
},
|
|
25
|
+
icon: 'font-awesome/fa-power-off',
|
|
26
|
+
inputs: 1,
|
|
27
|
+
outputs: 1,
|
|
28
|
+
color: '#49afcd',
|
|
29
|
+
paletteLabel: 'System',
|
|
30
|
+
label: function() {
|
|
31
|
+
return this.name || 'System';
|
|
32
|
+
},
|
|
33
|
+
oneditprepare: function() {
|
|
34
|
+
$('#node-input-topic').typedInput({
|
|
35
|
+
types: [ 'msg', {
|
|
36
|
+
value: 'action',
|
|
37
|
+
options: [ 'status', 'log', 'reboot' ]
|
|
38
|
+
}],
|
|
39
|
+
typeField: '#node-input-topicType'
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
</script>
|
package/nodes/system.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module.exports = function(RED) {
|
|
2
|
+
function System(config) {
|
|
3
|
+
RED.nodes.createNode(this, config);
|
|
4
|
+
const settings = RED.nodes.getNode(config.settings);
|
|
5
|
+
this.on('input', msg => {
|
|
6
|
+
msg.topic = RED.util.evaluateNodeProperty(config.topic, config.topicType, this, msg);
|
|
7
|
+
if ([ 'status', 'log', 'reboot' ].includes(msg.topic))
|
|
8
|
+
settings.getClient().then(client => {
|
|
9
|
+
if (msg.topic === 'status')
|
|
10
|
+
return client.getStatus();
|
|
11
|
+
else if (msg.topic === 'log')
|
|
12
|
+
return client.getLog();
|
|
13
|
+
else if (msg.topic === 'reboot')
|
|
14
|
+
return client.startReboot();
|
|
15
|
+
})
|
|
16
|
+
.then(payload => {
|
|
17
|
+
if (!payload)
|
|
18
|
+
return;
|
|
19
|
+
msg.payload = payload;
|
|
20
|
+
this.send(msg);
|
|
21
|
+
})
|
|
22
|
+
.catch(({ message, code }) => {
|
|
23
|
+
msg.code = code;
|
|
24
|
+
msg.payload = message;
|
|
25
|
+
this.error(message, msg);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
RED.nodes.registerType('padavan-system', System);
|
|
30
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<script type="text/html" data-template-name="padavan-upgrade">
|
|
2
|
+
<div class="form-row">
|
|
3
|
+
<label for="node-input-settings"><i class="fa fa-cog"></i> Config</label>
|
|
4
|
+
<input id="node-input-settings" />
|
|
5
|
+
</div>
|
|
6
|
+
<div class="form-row">
|
|
7
|
+
<label for="node-input-name"><i class="fa fa-pencil"></i> Name</label>
|
|
8
|
+
<input type="text" id="node-input-name" />
|
|
9
|
+
</div>
|
|
10
|
+
<div class="form-row">
|
|
11
|
+
<label for="node-input-topic"><i class="fa fa-envelope-o"></i> Topic</label>
|
|
12
|
+
<input type="text" id="node-input-topic">
|
|
13
|
+
<input type="hidden" id="node-input-topicType">
|
|
14
|
+
</div>
|
|
15
|
+
</script>
|
|
16
|
+
<script type="text/javascript">
|
|
17
|
+
RED.nodes.registerType('padavan-upgrade', {
|
|
18
|
+
category: 'Padavan',
|
|
19
|
+
defaults: {
|
|
20
|
+
settings: { value: null, required: true, type: 'padavan-config' },
|
|
21
|
+
name: { value: '' },
|
|
22
|
+
topic: { value: 'topic' },
|
|
23
|
+
topicType: { value: 'msg' }
|
|
24
|
+
},
|
|
25
|
+
icon: 'font-awesome/fa-pencil-square-o',
|
|
26
|
+
inputs: 1,
|
|
27
|
+
outputs: 1,
|
|
28
|
+
color: '#49afcd',
|
|
29
|
+
paletteLabel: 'Upgrade',
|
|
30
|
+
label: function() {
|
|
31
|
+
return this.name || 'Upgrade';
|
|
32
|
+
},
|
|
33
|
+
oneditprepare: function() {
|
|
34
|
+
$('#node-input-topic').typedInput({
|
|
35
|
+
types: [ 'msg', {
|
|
36
|
+
value: 'action',
|
|
37
|
+
options: [ 'build', 'changelog', 'upgrade' ]
|
|
38
|
+
}],
|
|
39
|
+
typeField: '#node-input-topicType'
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
</script>
|
package/nodes/upgrade.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module.exports = function(RED) {
|
|
2
|
+
function Upgrade(config) {
|
|
3
|
+
RED.nodes.createNode(this, config);
|
|
4
|
+
const settings = RED.nodes.getNode(config.settings);
|
|
5
|
+
this.on('input', msg => {
|
|
6
|
+
msg.topic = RED.util.evaluateNodeProperty(config.topic, config.topicType, this, msg);
|
|
7
|
+
if ([ 'build', 'changelog', 'upgrade' ].includes(msg.topic))
|
|
8
|
+
settings.getClient().then(client => {
|
|
9
|
+
if (msg.topic === 'build')
|
|
10
|
+
return client.startBuild();
|
|
11
|
+
else if (msg.topic === 'changelog')
|
|
12
|
+
return client.getChangelog();
|
|
13
|
+
else if (msg.topic === 'upgrade')
|
|
14
|
+
return client.getArtifact().then(async artifact => {
|
|
15
|
+
const to_id = artifact.name.split('-').slice(-1)[0].slice(0, 7);
|
|
16
|
+
const from_id = await client.nvram('firmver_sub');
|
|
17
|
+
if (from_id.split('_')[1] === to_id)
|
|
18
|
+
return;
|
|
19
|
+
return client.startUpgrade(artifact.id).then(() => {
|
|
20
|
+
return new Promise(res => {
|
|
21
|
+
setTimeout(function loop() {
|
|
22
|
+
client.nvram('firmver_sub').then(firmver_sub => {
|
|
23
|
+
if (firmver_sub !== from_id)
|
|
24
|
+
return res(true);
|
|
25
|
+
setTimeout(loop, 5000);
|
|
26
|
+
}).catch(() => setTimeout(loop, 5000))
|
|
27
|
+
}, 5000);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
})
|
|
32
|
+
.then(payload => {
|
|
33
|
+
if (!payload)
|
|
34
|
+
msg.error = 'Firmware not found';
|
|
35
|
+
else
|
|
36
|
+
msg.payload = payload;
|
|
37
|
+
this.send(msg);
|
|
38
|
+
})
|
|
39
|
+
.catch(({ message, code }) => {
|
|
40
|
+
msg.code = code;
|
|
41
|
+
msg.payload = message;
|
|
42
|
+
this.error(message, msg);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
RED.nodes.registerType('padavan-upgrade', Upgrade);
|
|
47
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "node-red-contrib-padavan",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Router management with Padavan firmware",
|
|
5
|
+
"main": "main.mjs",
|
|
6
|
+
"node-red": {
|
|
7
|
+
"nodes": {
|
|
8
|
+
"config": "nodes/config.js",
|
|
9
|
+
"speedtest": "nodes/speedtest.js",
|
|
10
|
+
"devices": "nodes/devices.js",
|
|
11
|
+
"history": "nodes/history.js",
|
|
12
|
+
"upgrade": "nodes/upgrade.js",
|
|
13
|
+
"system": "nodes/system.js",
|
|
14
|
+
"params": "nodes/params.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"nodes/",
|
|
19
|
+
"services/",
|
|
20
|
+
"main.mjs"
|
|
21
|
+
],
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/alex2844/node-padavan.git"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"nodejs",
|
|
28
|
+
"node-red",
|
|
29
|
+
"iot",
|
|
30
|
+
"smart home",
|
|
31
|
+
"router",
|
|
32
|
+
"padavan"
|
|
33
|
+
],
|
|
34
|
+
"author": "Alex Smith",
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"ini": "^4.1.3",
|
|
38
|
+
"jszip": "^3.10.1",
|
|
39
|
+
"ssh2": "^1.15.0"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
size=25000000;
|
|
4
|
+
iterations=5;
|
|
5
|
+
json=$(curl -s https://www.speedtest.net/api/js/servers?limit=1);
|
|
6
|
+
url_upload=$(echo "${json}" | grep -o '"url":"[^"]*"' | sed 's/"url":"\([^"]*\)".*/\1/' | sed 's/\\//g');
|
|
7
|
+
url_download=$(echo "${url_upload}" | sed 's@\(/\([^/]*\)/\([^/]*\)/\).*@\1download?size=@');
|
|
8
|
+
speed_download=0;
|
|
9
|
+
speed_upload=0;
|
|
10
|
+
speed_upload_total=0;
|
|
11
|
+
speed_download_total=0;
|
|
12
|
+
available_space=$(df /tmp/ | awk 'NR==2 {print $4}');
|
|
13
|
+
available_space=$((available_space * 1024 - 1048576));
|
|
14
|
+
if [ -n "$available_space" ] && [ "$available_space" -lt "$size" ]; then
|
|
15
|
+
size=$available_space
|
|
16
|
+
fi
|
|
17
|
+
for i in $(seq 1 $iterations); do
|
|
18
|
+
speed_download=$(curl --connect-timeout 8 "${url_download}${size}" -w "%{speed_download}" -o /tmp/speedtest.bin -s);
|
|
19
|
+
speed_upload=$(curl --connect-timeout 8 -F "file=@/tmp/speedtest.bin" "${url_upload}" -w "%{speed_upload}" -o /dev/null -s);
|
|
20
|
+
speed_upload_total=$((speed_upload_total + speed_upload));
|
|
21
|
+
speed_download_total=$((speed_download_total + speed_download));
|
|
22
|
+
rm -f /tmp/speedtest.bin;
|
|
23
|
+
done
|
|
24
|
+
echo "download=$((speed_download_total / iterations))";
|
|
25
|
+
echo "upload=$((speed_upload_total / iterations))";
|