// скрипт страницы index, на которой отображаются графики // интервал обновления статуса в миллисекундах const RELOAD_STATS_INTERVAL = 10000 // интервал обновления графика - 1% показываемого времени (2 недели) // const RELOAD_CHART_INTERVAL = (3600 * 1000 * 24 * 14) / 100 // const RELOAD_CHART_INTERVAL = (3600 * 1000 * 24) / 100 const RELOAD_CHART_INTERVAL = 30000 const DATETIME_FORMAT = "DD MMM YYYY HH:mm:ss" function unpackBits(num, desc) { let out = "" for (let i = 0; i < desc.length; i++) { if (desc[i] !== null) { if ((num & (1 << i)) !== 0) { // бит установлен if (out.length === 0) { out = desc[i] } else { out += " + " out += desc[i] } } } } return out } /** * Функция для линейной аппроксимации набора точек. Для заданных точек находит коэфицент a из уравнения y=ax+b. * Уравнение подбирается при помощи метода наименьших квадратов. * @param dataset набор точек в виде [[timestamp, val], [timestamp, val], ...], где timestamp - значение по X, val - значение по Y * @returns {number}, коэфицент a */ function approximateWithTimestamps(dataset) { // для точных расчетов нужно сместить timestamp const timestamp_offset = dataset[0][0] // сумма (x[i] * y[i]) let sum_x_mul_y = 0 for (let i = 0; i < dataset.length; i++) { sum_x_mul_y += (dataset[i][0] - timestamp_offset) * dataset[i][1] } // сумма всех x[i] let sum_x = 0; for (let i = 0; i < dataset.length; i++) { sum_x += dataset[i][0] - timestamp_offset } // сумма всех y[i] let sum_y = 0; for (let i = 0; i < dataset.length; i++) { sum_y += dataset[i][1] } // сумма всех x[i]^2 let sum_x_mul_x = 0; for (let i = 0; i < dataset.length; i++) { sum_x_mul_x += Math.pow(dataset[i][0] - timestamp_offset, 2) } // вычисление коэфицента a из формулы y=ax+b // нам нужен только он return (dataset.length * sum_x_mul_y - sum_x * sum_y) / (sum_x_mul_x - Math.pow(sum_x, 2)) } async function makeRequest(url) { let response = await fetch(url) if (response.status !== 200) { console.log('fetch(' + url + ') failed. Status Code: ' + response.status); return null; } return await response.json() } async function loadAllData() { return await makeRequest('/fetch/all') } async function loadChartData() { return (await makeRequest('/fetch/tank-chart'))['tank_chart'] } async function loadLastUpdates() { return (await makeRequest('/fetch/stats'))['stats'] } async function updateStatus() { let dataset = await loadLastUpdates() // последнее обновление document.getElementById("tank-last-update").innerHTML = moment(new Date(dataset['tank']['last_update'] * 1000)).format(DATETIME_FORMAT) document.getElementById("pump-last-update").innerHTML = moment(new Date(dataset['pump']['last_update'] * 1000)).format(DATETIME_FORMAT) //

Уровень воды

const last_radar_values = dataset['tank']['last_radar_values'] if (last_radar_values.length === 0) { document.getElementById("tank-level-dir").innerHTML = "(?)"; } else { document.getElementById("tank-level-dir").innerHTML = approximateWithTimestamps(last_radar_values) < 0 ? '↘' : '↗'; } //

Текущий уровень воды: %

document.getElementById("tank-level-now").innerHTML = dataset['tank']['last_percentage'] //

Текущее значение с радара:

document.getElementById("tank-raw-now").innerHTML = dataset['tank']['last_radar'] //

Статус:

const shur_status_bits = ['нужна вода', 'поплавок нижний', 'поплавок верхний', 'поплавок аварийный'] document.getElementById("tank-status").innerHTML = unpackBits(dataset['tank']['status_reg'], shur_status_bits) + " (" + dataset['tank']['status_reg'] + ")"; //

Частота ПЧ: Гц

document.getElementById("pump-vfd-freq").innerHTML = dataset['pump']['vfd_freq'] //

Ток ПЧ: А

document.getElementById("pump-vfd-curr").innerHTML = dataset['pump']['vfd_curr'] //

Ошибка ПЧ:

document.getElementById("pump-vfd-error").innerHTML = dataset['pump']['vfd_err'] //

Регистр аварий:

document.getElementById("pump-alarms").innerHTML = dataset['pump']['alarms'] //

Состояние КА:

document.getElementById("pump-stage").innerHTML = dataset['pump']['pump_stage'] //

Текущий расход: м³

document.getElementById("pump-flow-meter").innerHTML = dataset['pump']['flow_meter'] } // состояния конченого автомата // $states = [ // 0 => "отключен", // 2 => "инициализация: установка задвижек в начальное состояние", // 21 => "инициализация: закрытие задвижек 23.5 и 23.6", // 31 => "инициализация: открытие задвижек 23.5 и 23.6", // 99 => "авария", // // 100 => "ожидание сигнала на перекачку воды", // // 102 => "запуск: открытие задвижки 23.6", // 110 => "запуск: ожидание сигнала от датчика уровня поз.36", // 121 => "запуск: открытие задвижек насоса", // 131 => "запуск: закрытие задвижки 23.6", // 141 => "запуск: пуск ПЧ", // // 200 => "работает", // // 202 => "остановка: закрытие задвижек 23.3 и 23.4", // 211 => "остановка: ожидание остановки ПЧ", // 221 => "остановка: перевод запорной арматуры в исходное состояние", // 231 => "остановка: работа компрессора", // 235 => "остановка: сброс конденсата клапанами 25.*" // ];