diff --git a/assets/index.html b/assets/index.html
index 594b95e..587eaff 100644
--- a/assets/index.html
+++ b/assets/index.html
@@ -318,13 +318,10 @@
const saveBtn = document.getElementById('saveButton');
const toast = document.getElementById('toastMsg');
- // --- Состояние прибора (тёмная адаптация) ---
let minThreshold = 1.4;
let maxThreshold = 6.2;
- let currentPressure = 2.7;
- let pressureDirection = 1; // 1 = рост, -1 = падение
- let animationFrameId = null;
- let lastTimestamp = 0;
+ let currentPressure = 0;
+ let pollingInterval = null;
let cachedScale = null;
let canvasWidth = 500, canvasHeight = 500;
@@ -513,7 +510,75 @@
ctx.stroke();
}
- // Основной рендер манометра – тёмная эстетика
+ async function fetchPressure() {
+ try {
+ const response = await fetch('/pressure');
+ if (!response.ok) {
+ throw new Error('Failed to fetch pressure');
+ }
+ const data = await response.json();
+ const pressure = typeof data === 'number' ? data : data.value;
+ if (typeof pressure === 'number' && !isNaN(pressure)) {
+ currentPressure = Math.min(Math.max(pressure, MIN_PRESSURE), MAX_PRESSURE);
+ pressureDisplay.innerText = currentPressure.toFixed(2) + " атм";
+ drawGauge();
+ }
+ } catch (error) {
+ console.error('Error fetching pressure:', error);
+ }
+ }
+
+ async function fetchThresholds() {
+ try {
+ const response = await fetch('/thresholds');
+ if (!response.ok) {
+ throw new Error('Failed to fetch thresholds');
+ }
+ const data = await response.json();
+ if (typeof data.low === 'number' && typeof data.up === 'number') {
+ minThreshold = Math.min(Math.max(data.low, MIN_PRESSURE), MAX_PRESSURE);
+ maxThreshold = Math.min(Math.max(data.up, MIN_PRESSURE), MAX_PRESSURE);
+ updateUI();
+ }
+ } catch (error) {
+ console.error('Error fetching thresholds:', error);
+ }
+ }
+
+ async function saveThresholds() {
+ try {
+ const response = await fetch('/thresholds', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ low: parseFloat(minThreshold.toFixed(2)),
+ up: parseFloat(maxThreshold.toFixed(2))
+ })
+ });
+
+ if (!response.ok) {
+ throw new Error('Failed to save thresholds');
+ }
+
+ const data = await response.json();
+ console.log('Thresholds saved:', data);
+
+ toast.innerText = "✓ Пороги сохранены";
+ toast.classList.add('show');
+ setTimeout(() => toast.classList.remove('show'), 1600);
+
+ // После сохранения обновляем пороги с сервера для синхронизации
+ await fetchThresholds();
+ } catch (error) {
+ console.error('Error saving thresholds:', error);
+ toast.innerText = "✗ Ошибка сохранения порогов";
+ toast.classList.add('show');
+ setTimeout(() => toast.classList.remove('show'), 1600);
+ }
+ }
+
function drawGauge() {
if (!ctx) return;
const w = canvas.width, h = canvas.height;
@@ -586,32 +651,6 @@
ctx.fill();
}
- // симуляция давления с сохранением плавности и пределов
- function updatePressure(timestamp) {
- if (!lastTimestamp) {
- lastTimestamp = timestamp;
- animationFrameId = requestAnimationFrame(updatePressure);
- return;
- }
-
- const delta = Math.min(timestamp - lastTimestamp, 45) / 1000;
- lastTimestamp = timestamp;
- const step = 0.42 * delta; // скорость ~0.42 атм/сек
-
- if (pressureDirection === 1) {
- currentPressure = Math.min(currentPressure + step, maxThreshold);
- if (currentPressure >= maxThreshold) pressureDirection = -1;
- } else {
- currentPressure = Math.max(currentPressure - step, minThreshold);
- if (currentPressure <= minThreshold) pressureDirection = 1;
- }
-
- currentPressure = Math.min(Math.max(currentPressure, MIN_PRESSURE), MAX_PRESSURE);
- pressureDisplay.innerText = currentPressure.toFixed(2) + " атм";
- drawGauge();
- animationFrameId = requestAnimationFrame(updatePressure);
- }
-
function updateUI() {
minSlider.value = minThreshold;
maxSlider.value = maxThreshold;
@@ -644,62 +683,45 @@
});
saveBtn.addEventListener('click', () => {
- minSpan.innerText = minThreshold.toFixed(2);
- maxSpan.innerText = maxThreshold.toFixed(2);
- drawGauge();
-
- toast.innerText = "✓ Пороги сохранены";
- toast.classList.add('show');
- setTimeout(() => toast.classList.remove('show'), 1600);
+ saveThresholds();
});
}
- // function controlGPIO(state) {
- // fetch('/gpio?state=' + state)
- // .then(response => response.json())
- // .then(data => {
- // const indicator = document.getElementById('ledIndicator');
- // if(data.status === 'on') {
- // indicator.className = 'led-status led-on';
- // } else {
- // indicator.className = 'led-status led-off';
- // }
- // });
- // }
- // function getSensorData() {
- // fetch('/sensor')
- // .then(response => response.json())
- // .then(data => {
- // document.getElementById('sensorData').innerHTML =
- // '📊 Значение: ' + data.value + '
' +
- // '📝 Сообщение: ' + data.message;
- // });
- // }
- // function updateStats() {
- // fetch('/stats')
- // .then(response => response.json())
- // .then(data => {
- // document.getElementById('heap').innerText = data.free_heap;
- // document.getElementById('uptime').innerText = data.uptime;
- // });
- // }
- // setInterval(updateStats, 2000);
- // getSensorData();
+ function startPolling() {
+ // Запускаем опрос давления каждые 500 мс
+ pollingInterval = setInterval(fetchPressure, 500);
+ }
+ function stopPolling() {
+ if (pollingInterval) {
+ clearInterval(pollingInterval);
+ pollingInterval = null;
+ }
+ }
- function init() {
+ async function init() {
canvasWidth = canvas.width;
canvasHeight = canvas.height;
cachedScale = buildScaleCache();
+
+ // Загружаем начальные данные
+ await fetchThresholds();
+ await fetchPressure();
+
initEvents();
updateUI();
- animationFrameId = requestAnimationFrame(updatePressure);
+ startPolling();
window.addEventListener('resize', () => {
drawGauge();
});
}
+ // Очистка интервала при выгрузке страницы
+ window.addEventListener('beforeunload', () => {
+ stopPolling();
+ });
+
init();
})();
diff --git a/main/main.c b/main/main.c
index f528271..5f34ca8 100644
--- a/main/main.c
+++ b/main/main.c
@@ -283,6 +283,13 @@ static esp_err_t save_thresholds_handler(httpd_req_t *req) {
return send_json_response(req, "{\"success\":true,\"low\":%d,\"up\":%d}", low_value, up_value);
}
+static esp_err_t get_thresholds_handler(httpd_req_t *req) {
+ int low_threshold = atomic_load(&g_threshold_low);
+ int up_threshold = atomic_load(&g_threshold_up);
+
+ return send_json_response(req, "{\"low\":%d,\"up\":%d}", low_threshold, up_threshold);
+}
+
static esp_err_t set_thresholds_handler(httpd_req_t *req) {
char *content = NULL;
if (receive_http_content(req, &content) != ESP_OK) {
@@ -405,7 +412,7 @@ static void register_http_handlers(httpd_handle_t server) {
.user_ctx = NULL
};
if (httpd_register_uri_handler(server, &root) != ESP_OK) {
- ESP_LOGE(TAG, "Failed to register / handler");
+ ESP_LOGE(TAG, "Failed to register GET / handler");
}
httpd_uri_t pressure = {
@@ -415,7 +422,17 @@ static void register_http_handlers(httpd_handle_t server) {
.user_ctx = NULL
};
if (httpd_register_uri_handler(server, &pressure) != ESP_OK) {
- ESP_LOGE(TAG, "Failed to register / handler");
+ ESP_LOGE(TAG, "Failed to register GET /pressure handler");
+ }
+
+ httpd_uri_t get_thresholds = {
+ .uri = "/thresholds",
+ .method = HTTP_GET,
+ .handler = get_thresholds_handler,
+ .user_ctx = NULL
+ };
+ if (httpd_register_uri_handler(server, &get_thresholds) != ESP_OK) {
+ ESP_LOGE(TAG, "Failed to register GET /thresholds handler");
}
httpd_uri_t set_thresholds = {
@@ -425,7 +442,7 @@ static void register_http_handlers(httpd_handle_t server) {
.user_ctx = NULL
};
if (httpd_register_uri_handler(server, &set_thresholds) != ESP_OK) {
- ESP_LOGE(TAG, "Failed to register / handler");
+ ESP_LOGE(TAG, "Failed to register POST /thresholds handler");
}
httpd_uri_t save_thresholds = {
@@ -435,7 +452,7 @@ static void register_http_handlers(httpd_handle_t server) {
.user_ctx = NULL
};
if (httpd_register_uri_handler(server, &save_thresholds) != ESP_OK) {
- ESP_LOGE(TAG, "Failed to register / handler");
+ ESP_LOGE(TAG, "Failed to register POST /persist_thresholds handler");
}
}