Ваш домашний сервер снова оффлайн? IP-камера перестала транслировать видео? Интернет пропал полностью или просто не открывается один сайт? Чтобы получать ответы на эти вопросы мгновенно, можно создать простую, но эффективную систему мониторинга.
В этой статье мы настроим скрипт, который поддерживает работу на Windows, macOS и Linux. Он будет регулярно проверять доступность любых интернет-ресурсов и отправлять данные на сервер VizIoT.
Для максимально точного мониторинга наш скрипт использует три разных метода проверки. Это важно, так как устройство может «пинговаться», но при этом его конкретный сервис (например, сайт или видеотрансляция) может не работать.
554 на IP-камере (RTSP) или порт 3306 у базы данных. Если порт открыт — сервис жив.Для работы скрипта нам понадобятся две ключевые библиотеки:
ping: Это удобная обёртка, которая позволяет Node.js использовать системные утилиты проверки связи. Она избавляет нас от написания сложного кода для каждой ОС.viziot-mqtt-client-nodejs: Официальный клиент для платформы VizIoT. Он берет на себя всю работу по протоколу MQTT: шифрование, поддержку соединения и надежную отправку ваших данных на графики.Скрипт не просто отправляет «сухие» цифры, он помогает вам стать «сетевым детективом». Посмотрев на график в VizIoT, вы сможете сразу определить источник проблемы:
Для точности замеров: Скрипт делает три замера для каждой цели и высчитывает среднее арифметическое. Это исключает случайные погрешности (одиночные «вылеты» пакетов) и дает вам плавный, реалистичный график задержки.
Прежде чем мы перейдем к коду, посмотрите, как выглядит готовый виджет.
Что можно отслеживать в такой конфигурации:
Как интерпретировать график:
Такой подход позволяет мгновенно определить источник проблемы: ваша локальная сеть, интернет-провайдер или конкретный удалённый сервис.
Видеть проблему на графике — это хорошо, а получать мгновенное уведомление о ней — еще лучше. VizIoT позволяет настроить оповещения, которые придут вам в Telegram или на E-mail, как только один из ваших ресурсов станет недоступен, а также когда он вернется в онлайн.

Заинтересовались? Давайте настроим такую систему шаг за шагом.
Наш код кроссплатформенный и одинаково хорошо работает на Windows, Linux и macOS.
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
nvm install 24
Создайте папку и установите необходимые пакеты, о которых мы говорили выше:
mkdir ./VizIoTPinger && cd ./VizIoTPinger
npm init -y
npm i ping viziot-mqtt-client-nodejs
Создайте файл main.js.
nano ./main.js
Обратите внимание на функцию runMeasurements — именно она отвечает за тройную проверку для точности данных.
const net = require('net')
const ping = require('ping')
const http = require('http')
const https = require('https')
const viziotMQTT = require('viziot-mqtt-client-nodejs')
// ================= SETTINGS =================
// Paste your VizIoT device key and password here
const DEVICE_KEY = '_____________'
const DEVICE_PASSWORD = '______________________'
const CHECK_INTERVAL_SEC = 3 * 60 // Interval between checks in seconds
// ================= TARGETS =================
// key — the parameter name that will appear in VizIoT
// target — IP address, domain, or URL
// port — port (optional, for TCP ping)
const TARGETS = [
{ key: 'home_router_latency', target: '192.168.2.1' },
{ key: 'cloudflare_dns_latency', target: '1.1.1.1' },
{ key: 'google_dns_latency', target: '8.8.8.8' },
{ key: 'google_latency', target: 'google.com' },
{ key: 'ipCamera_latency', target: '192.168.0.158', port: 554 },
// { key: 'my_website', target: 'https://my-site.com' },
]
// ================= MQTT =================
const client = new viziotMQTT(DEVICE_KEY, DEVICE_PASSWORD)
// ================= UTILITIES =================
// Auxiliary function for performing measurements
async function runMeasurements(measureFn, attempts = 3) {
const results = []
for (let i = 0; i < attempts; i++) {
results.push(await measureFn())
}
const valid = results.filter((r) => r > -1)
if (valid.length === 0) {
return { latency: -1 }
}
const avg = valid.reduce((a, b) => a + b, 0) / valid.length
return { latency: Math.round(avg) }
}
// Function for checking ICMP (ping)
function checkICMP(item) {
const measure = () =>
new Promise((resolveRequest) => {
ping.promise
.probe(item.target, {
timeout: 5,
})
.then(function (res) {
resolveRequest(res.alive ? res.time : -1)
})
})
return runMeasurements(measure)
}
// Function for checking TCP
function checkTCP(item) {
const measure = () =>
new Promise((resolveRequest) => {
const socket = new net.Socket()
const start = Date.now()
socket.setTimeout(5000)
socket.connect(item.port, item.target, () => {
socket.destroy()
resolveRequest(Date.now() - start)
})
socket.on('error', (e) => {
console.log('Socket error:', e)
socket.destroy()
resolveRequest(-1)
})
socket.on('timeout', () => {
console.log('Socket timeout')
socket.destroy()
resolveRequest(-1)
})
})
return runMeasurements(measure)
}
// Function for checking HTTP/HTTPS
function checkURL(item) {
const measure = () =>
new Promise((resolveRequest) => {
const start = Date.now()
const lib = item.target.startsWith('https') ? https : http
const req = lib.get(item.target, { timeout: 5000 }, (res) => {
res.resume()
resolveRequest(Date.now() - start)
})
req.on('error', () => resolveRequest(-1))
req.on('timeout', () => {
req.destroy()
resolveRequest(-1)
})
})
return runMeasurements(measure)
}
// ================= CHECKS =================
let isWorking = false
async function runChecks() {
// Preventing overlapping launches
if (isWorking) return
isWorking = true
console.log('🔍 Starting checks...')
const payload = {}
for (const item of TARGETS) {
let result
if (item.target.startsWith('http')) {
result = await checkURL(item)
} else {
if (item.port) {
result = await checkTCP(item)
} else {
result = await checkICMP(item)
}
}
payload[item.key] = result.latency
const status = result.latency >= 0 ? '✅' : '❌'
console.log(`${status} ${item.key}: latency=${result.latency} ms`)
}
isWorking = false
console.log('📨 Sending data to VizIoT:', payload)
// client.sendDataToVizIoT(payload, (err) => {
// if (err) console.error('Error sending data:', err)
// })
}
// ================= START =================
function main() {
console.log('🔗 Try Connected to VizIoT')
// client.connect(() => {
console.log('✅ Connected')
console.log('🚀 Pinger starting…')
runChecks()
setInterval(runChecks, CHECK_INTERVAL_SEC * 1000)
// })
}
main()
Чтобы ваш скрипт работал 24/7 и запускался сам после перезагрузки компьютера, используйте менеджер процессов PM2:
npm install pm2 -g
pm2 start main.js --name "VizIoTPinger"
pm2 save
pm2 startup
Теперь, когда данные поступают, осталось настроить интерфейс.
home_router_latency, google_latency, ipCamera_latencyipCamera_latency).Подробную инструкцию по настройке уведомлений можно найти в этой статье.
Теперь, когда данные передаются, зайдите в панель VizIoT:
ipCamera_latency).Значение < 0 (это значит, что сервис недоступен).Теперь, как только ваша камера «отвалится» или сайт перестанет открываться, вы получите сообщение об этом в течение минуты!