feat(get_thresholds): add handler
This commit is contained in:
parent
c57020067a
commit
e1cd3daba3
@ -318,13 +318,10 @@
|
|||||||
const saveBtn = document.getElementById('saveButton');
|
const saveBtn = document.getElementById('saveButton');
|
||||||
const toast = document.getElementById('toastMsg');
|
const toast = document.getElementById('toastMsg');
|
||||||
|
|
||||||
// --- Состояние прибора (тёмная адаптация) ---
|
|
||||||
let minThreshold = 1.4;
|
let minThreshold = 1.4;
|
||||||
let maxThreshold = 6.2;
|
let maxThreshold = 6.2;
|
||||||
let currentPressure = 2.7;
|
let currentPressure = 0;
|
||||||
let pressureDirection = 1; // 1 = рост, -1 = падение
|
let pollingInterval = null;
|
||||||
let animationFrameId = null;
|
|
||||||
let lastTimestamp = 0;
|
|
||||||
|
|
||||||
let cachedScale = null;
|
let cachedScale = null;
|
||||||
let canvasWidth = 500, canvasHeight = 500;
|
let canvasWidth = 500, canvasHeight = 500;
|
||||||
@ -513,7 +510,75 @@
|
|||||||
ctx.stroke();
|
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() {
|
function drawGauge() {
|
||||||
if (!ctx) return;
|
if (!ctx) return;
|
||||||
const w = canvas.width, h = canvas.height;
|
const w = canvas.width, h = canvas.height;
|
||||||
@ -586,32 +651,6 @@
|
|||||||
ctx.fill();
|
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() {
|
function updateUI() {
|
||||||
minSlider.value = minThreshold;
|
minSlider.value = minThreshold;
|
||||||
maxSlider.value = maxThreshold;
|
maxSlider.value = maxThreshold;
|
||||||
@ -644,62 +683,45 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
saveBtn.addEventListener('click', () => {
|
saveBtn.addEventListener('click', () => {
|
||||||
minSpan.innerText = minThreshold.toFixed(2);
|
saveThresholds();
|
||||||
maxSpan.innerText = maxThreshold.toFixed(2);
|
|
||||||
drawGauge();
|
|
||||||
|
|
||||||
toast.innerText = "✓ Пороги сохранены";
|
|
||||||
toast.classList.add('show');
|
|
||||||
setTimeout(() => toast.classList.remove('show'), 1600);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// function controlGPIO(state) {
|
function startPolling() {
|
||||||
// fetch('/gpio?state=' + state)
|
// Запускаем опрос давления каждые 500 мс
|
||||||
// .then(response => response.json())
|
pollingInterval = setInterval(fetchPressure, 500);
|
||||||
// .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 + '<br>' +
|
|
||||||
// '📝 Сообщение: ' + 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 stopPolling() {
|
||||||
|
if (pollingInterval) {
|
||||||
|
clearInterval(pollingInterval);
|
||||||
|
pollingInterval = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function init() {
|
async function init() {
|
||||||
canvasWidth = canvas.width;
|
canvasWidth = canvas.width;
|
||||||
canvasHeight = canvas.height;
|
canvasHeight = canvas.height;
|
||||||
cachedScale = buildScaleCache();
|
cachedScale = buildScaleCache();
|
||||||
|
|
||||||
|
// Загружаем начальные данные
|
||||||
|
await fetchThresholds();
|
||||||
|
await fetchPressure();
|
||||||
|
|
||||||
initEvents();
|
initEvents();
|
||||||
updateUI();
|
updateUI();
|
||||||
animationFrameId = requestAnimationFrame(updatePressure);
|
startPolling();
|
||||||
|
|
||||||
window.addEventListener('resize', () => {
|
window.addEventListener('resize', () => {
|
||||||
drawGauge();
|
drawGauge();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Очистка интервала при выгрузке страницы
|
||||||
|
window.addEventListener('beforeunload', () => {
|
||||||
|
stopPolling();
|
||||||
|
});
|
||||||
|
|
||||||
init();
|
init();
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
25
main/main.c
25
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);
|
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) {
|
static esp_err_t set_thresholds_handler(httpd_req_t *req) {
|
||||||
char *content = NULL;
|
char *content = NULL;
|
||||||
if (receive_http_content(req, &content) != ESP_OK) {
|
if (receive_http_content(req, &content) != ESP_OK) {
|
||||||
@ -405,7 +412,7 @@ static void register_http_handlers(httpd_handle_t server) {
|
|||||||
.user_ctx = NULL
|
.user_ctx = NULL
|
||||||
};
|
};
|
||||||
if (httpd_register_uri_handler(server, &root) != ESP_OK) {
|
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 = {
|
httpd_uri_t pressure = {
|
||||||
@ -415,7 +422,17 @@ static void register_http_handlers(httpd_handle_t server) {
|
|||||||
.user_ctx = NULL
|
.user_ctx = NULL
|
||||||
};
|
};
|
||||||
if (httpd_register_uri_handler(server, &pressure) != ESP_OK) {
|
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 = {
|
httpd_uri_t set_thresholds = {
|
||||||
@ -425,7 +442,7 @@ static void register_http_handlers(httpd_handle_t server) {
|
|||||||
.user_ctx = NULL
|
.user_ctx = NULL
|
||||||
};
|
};
|
||||||
if (httpd_register_uri_handler(server, &set_thresholds) != ESP_OK) {
|
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 = {
|
httpd_uri_t save_thresholds = {
|
||||||
@ -435,7 +452,7 @@ static void register_http_handlers(httpd_handle_t server) {
|
|||||||
.user_ctx = NULL
|
.user_ctx = NULL
|
||||||
};
|
};
|
||||||
if (httpd_register_uri_handler(server, &save_thresholds) != ESP_OK) {
|
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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user