In this example, we will create a system for automatically monitoring internet channel speed (Download, Upload, and Latency) using the Speedtest CLI, and then configure it to send data to VizIoT for building graphs and analyzing internet connection quality.
Detailed documentation: https://nodejs.org
# Install nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
# Activate without restarting the shell
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
# Install Node.js (e.g., LTS version)
nvm install --lts
# Check versions
node -v
npm -v
Documentation: https://www.speedtest.net/apps/cli
sudo apt-get install curl
curl -s https://packagecloud.io/install/repositories/ookla/speedtest-cli/script.deb.sh | sudo bash
sudo apt-get update
sudo apt-get install speedtest
Verify it's working:
speedtest
Example output:
Speedtest by Ookla
Server: My Company - City, ST (id = 12345)
ISP: My ISP
Latency: 10.12 ms (0.53 ms jitter)
Download: 851.78 Mbps (data used: 1.1 GB)
Upload: 667.39 Mbps (data used: 0.8 GB)
Packet Loss: 0.0%
Result URL: https://www.speedtest.net/result/c/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
The program will run the Speedtest CLI, get the JSON result, and send the data to the VizIoT server via MQTT.
mkdir -p /var/viziot/speedtest
cd /var/viziot/speedtest
npm init -y
npm install viziot-mqtt-client-nodejs
Create the file:
nano index.js
index.jsconst viziotMQTT = require('viziot-mqtt-client-nodejs');
const { exec } = require('child_process');
// VizIoT access key and password
let keyDevice = "__________________";
let passDevice = "______________________";
let viziotMQTTClient = new viziotMQTT(keyDevice, passDevice);
function main() {
viziotMQTTClient.connect(() => {});
let intervalTime = 60 * 60 * 1000; // 1 hour
getPacketAndSendToServer();
setInterval(() => {
getPacketAndSendToServer();
}, intervalTime);
}
main();
function getPacketAndSendToServer() {
// Specify a server ID for consistent results, e.g., "29493"
// You can find server IDs by running 'speedtest -L'
speedTest("29493").then((result) => {
if (result.success && result.data) {
const packet = {
date: Math.floor(Date.now() / 1000),
latency: result.data.latency,
download: result.data.download,
upload: result.data.upload
};
viziotMQTTClient.sendDataToVizIoT(packet, (err) => {
if (err) {
console.log("publish error:", err);
} else {
console.log("Data sent:", packet);
}
});
}
});
}
function speedTest(idServer) {
return new Promise((resolve) => {
let command = 'speedtest --json'; // Use 'speedtest' for the official CLI
if (idServer && !isNaN(idServer)) {
command += ` --server-id ${idServer}`;
}
exec(command, (error, stdout, stderr) => {
if (error || stderr) {
console.log("Speedtest error:", error || stderr);
return resolve({ success: false });
}
try {
const json = JSON.parse(stdout);
if (
json.download && json.download.bandwidth &&
json.upload && json.upload.bandwidth &&
json.ping && json.ping.latency
) {
resolve({
success: true,
data: {
latency: json.ping.latency,
download: json.download.bandwidth * 8 / 1000000, // Convert Bytes/s to Mbit/s
upload: json.upload.bandwidth * 8 / 1000000 // Convert Bytes/s to Mbit/s
}
});
} else {
console.log("Unexpected JSON format:", json);
resolve({ success: false });
}
} catch (err) {
console.log("JSON parse error:", err, "Stdout:", stdout);
resolve({ success: false });
}
});
});
}
Open crontab:
crontab -e
Add the following line:
@reboot node /var/viziot/speedtest/index.js > /var/viziot/speedtest/output.txt &
Now the script will run when the system starts.
latencydownloaduploadAfter this, data will automatically start appearing on the graph.
Now your server automatically measures the internet channel speed and sends the data to VizIoT.