UNPKG

domotz-remote-pawn

Version:

Domotz Agent

166 lines (143 loc) 5.91 kB
/** This file is part of Domotz Agent. * Copyright (C) 2023 Domotz Ltd * * Domotz Agent is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Domotz Agent is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Domotz Agent. If not, see <http://www.gnu.org/licenses/>. * * * Sends the counters of DHCP requests to the cloud, * Created by Stefano Cicero <stefano.cicero@domotz.com> on 29/06/23. */ var latencyData = { download_loaded: [], upload_loaded: [], unloaded: [] }; function speedTestLatency(resourceLocator) { var rtdScan = resourceLocator.networkTools.rtd; var ping = resourceLocator.netPing; var session; var q = resourceLocator.q; var async = resourceLocator.async; var myConsole = resourceLocator.log.decorateLogs(); var latencyUtils = require('../latency/utils')(resourceLocator); var engineClient = resourceLocator.engineRequest; var initialStage = null; var lodash = resourceLocator.lodash; const settings = latencyUtils.getSettings(resourceLocator.settingsManager); const namePhaseConversion = { download: 'download_loaded', upload: 'upload_loaded', unloaded: 'unloaded', }; function performPingForState(currentStage, samples) { var deferred = q.defer(); if (!canPerformLatencyMeasurement()) { return q.reject('latency measurement not enabled'); } var pingCount = 0; const stageNameConverted = namePhaseConversion[currentStage]; initialStage = currentStage; if (stageNameConverted === undefined) { return q.resolve(); } if (currentStage !== 'unloaded') { latencyData[stageNameConverted] = []; } myConsole.info('Start latency measurement for stage %s', currentStage); session = ping.createSession({ networkProtocol: ping.NetworkProtocol.IPv4, packetSize: settings.packetSize, retries: 0, timeout: settings.timeout, }); function run() { latencyUtils .serverLookup(settings.server) .then(function (serverIP) { var samplesLen = samples || settings.maxPingNumber; async.whilst( function test() { return initialStage === currentStage && pingCount < samplesLen; }, function iter(callback) { pingCount++; rtdScan.pingDevice(serverIP, 0, session, function (error, resultMs) { if (stageNameConverted in latencyData && !error) { myConsole.debug('%s %s rtt: %sms', stageNameConverted, pingCount, resultMs); latencyData[stageNameConverted].push(resultMs); } setTimeout(function () { callback(null, pingCount); }, settings.interPingDelay); }); }, function () { deferred.resolve(); } ); }) .catch(function (error) { deferred.reject(error); }); } setTimeout(run, settings.warmupPeriod); return deferred.promise; } function filterValidSamples(samples) { var maxPingNumber = settings.maxPingNumber; var l = lodash.filter(samples, function (o) { return o !== null; }); l = lodash.map(l, function (elem) { //replace sub-ms values with 1 return elem === 0 ? 1 : elem; }); return l.slice(-maxPingNumber); } function reportData() { initialStage = null; var reportData = { download_loaded: filterValidSamples(latencyData.download_loaded), upload_loaded: filterValidSamples(latencyData.upload_loaded), unloaded: filterValidSamples(latencyData.unloaded), }; myConsole.debug('Latency samples: %s', JSON.stringify(latencyData)); if (reportData.download_loaded.length > 0 && reportData.upload_loaded.length > 0 && reportData.unloaded.length > 0) { engineClient.sendWithPromise('/latency', 'POST', reportData).catch(function () { myConsole.error('Error reporting latency data'); }); } else { myConsole.info('Latency data not sent, missing valid samples'); } } function _setLatencyData(fakeData) { latencyData = fakeData; } function canPerformLatencyMeasurement() { if (!settings.isLatencyMeasurementActive) { myConsole.info('latency measurement is disabled by settings'); return false; } else if (!ping) { myConsole.info('net-ping is unsupported on this platform'); return false; } return true; } return { performPingForState: performPingForState, reportData: reportData, settings: settings, canPerformLatencyMeasurement: canPerformLatencyMeasurement, _setLatencyData: _setLatencyData, }; } module.exports = { speedTestLatency: speedTestLatency, };