From a1255e83041f4b5c46f425767552b3fcdce524e8 Mon Sep 17 00:00:00 2001 From: YoungSoo Shin Date: Tue, 9 Dec 2025 14:23:27 +0900 Subject: [PATCH] add config period Signed-off-by: YoungSoo Shin --- main/include/nconfig.h | 1 + main/nconfig/nconfig.c | 2 ++ main/service/monitor.c | 21 ++++++++++++++++++++- main/service/monitor.h | 1 + main/service/setting.c | 14 ++++++++++++++ page/index.html | 13 +++++++++++-- page/src/api.js | 20 ++++++++++++++++++-- page/src/dom.js | 3 +++ page/src/events.js | 9 ++++++++- page/src/ui.js | 22 ++++++++++++++++++++++ 10 files changed, 100 insertions(+), 6 deletions(-) diff --git a/main/include/nconfig.h b/main/include/nconfig.h index 493a0e8..dc880df 100644 --- a/main/include/nconfig.h +++ b/main/include/nconfig.h @@ -44,6 +44,7 @@ enum nconfig_type USB_CURRENT_LIMIT, ///< The maximum current limit for the USB out. PAGE_USERNAME, ///< Webpage username PAGE_PASSWORD, ///< Webpage password + SENSOR_PERIOD_MS, ///< Sensor period NCONFIG_TYPE_MAX, ///< Sentinel for the maximum number of configuration types. }; diff --git a/main/nconfig/nconfig.c b/main/nconfig/nconfig.c index 0f65043..3bc97df 100644 --- a/main/nconfig/nconfig.c +++ b/main/nconfig/nconfig.c @@ -30,6 +30,7 @@ const static char* keys[NCONFIG_TYPE_MAX] = { [USB_CURRENT_LIMIT] = "usb_climit", [PAGE_USERNAME] = "username", [PAGE_PASSWORD] = "password", + [SENSOR_PERIOD_MS] = "sensor_period", }; struct default_value @@ -54,6 +55,7 @@ struct default_value const default_values[] = { {USB_CURRENT_LIMIT, "3.0"}, {PAGE_USERNAME, "admin"}, {PAGE_PASSWORD, "password"}, + {SENSOR_PERIOD_MS, "1000"}, }; esp_err_t init_nconfig() diff --git a/main/service/monitor.c b/main/service/monitor.c index 7469dd0..fe1ac09 100644 --- a/main/service/monitor.c +++ b/main/service/monitor.c @@ -289,6 +289,25 @@ void init_status_monitor() xTaskCreate(shutdown_load_sw_task, "shutdown_sw_task", configMINIMAL_STACK_SIZE * 3, NULL, 15, &shutdown_task_handle); - ESP_ERROR_CHECK(esp_timer_start_periodic(sensor_timer, 1000000)); + nconfig_read(SENSOR_PERIOD_MS, buf, sizeof(buf)); + ESP_ERROR_CHECK(esp_timer_start_periodic(sensor_timer, strtol(buf, NULL, 10) * 1000)); ESP_ERROR_CHECK(esp_timer_start_periodic(wifi_status_timer, 1000000 * 5)); } + +esp_err_t update_sensor_period(int period) +{ + if (period < 500 || period > 10000) // 0.5 sec ~ 10 sec + { + return ESP_ERR_INVALID_ARG; + } + + char buf[10]; + sprintf(buf, "%d", period); + esp_err_t err = nconfig_write(SENSOR_PERIOD_MS, buf); + if (err != ESP_OK) { + return err; + } + + esp_timer_stop(sensor_timer); + return esp_timer_start_periodic(sensor_timer, period * 1000); +} \ No newline at end of file diff --git a/main/service/monitor.h b/main/service/monitor.h index 138b165..72e6966 100644 --- a/main/service/monitor.h +++ b/main/service/monitor.h @@ -20,5 +20,6 @@ typedef struct } sensor_data_t; void init_status_monitor(); +esp_err_t update_sensor_period(int period); #endif // ODROID_REMOTE_HTTP_MONITOR_H diff --git a/main/service/setting.c b/main/service/setting.c index cddd0fc..ac9504a 100644 --- a/main/service/setting.c +++ b/main/service/setting.c @@ -6,6 +6,7 @@ #include "esp_log.h" #include "esp_netif.h" #include "esp_timer.h" +#include "monitor.h" #include "nconfig.h" #include "webserver.h" #include "wifi.h" @@ -47,6 +48,11 @@ static esp_err_t setting_get_handler(httpd_req_t* req) cJSON_AddStringToObject(root, "baudrate", buf); } + if (nconfig_read(SENSOR_PERIOD_MS, buf, sizeof(buf)) == ESP_OK) + { + cJSON_AddStringToObject(root, "period", buf); + } + // Add current limits to the response if (nconfig_read(VIN_CURRENT_LIMIT, buf, sizeof(buf)) == ESP_OK) { @@ -174,6 +180,7 @@ static esp_err_t setting_post_handler(httpd_req_t* req) cJSON* net_type_item = cJSON_GetObjectItem(root, "net_type"); cJSON* ssid_item = cJSON_GetObjectItem(root, "ssid"); cJSON* baud_item = cJSON_GetObjectItem(root, "baudrate"); + cJSON* period_item = cJSON_GetObjectItem(root, "period"); cJSON* vin_climit_item = cJSON_GetObjectItem(root, "vin_current_limit"); cJSON* main_climit_item = cJSON_GetObjectItem(root, "main_current_limit"); cJSON* usb_climit_item = cJSON_GetObjectItem(root, "usb_current_limit"); @@ -289,6 +296,13 @@ static esp_err_t setting_post_handler(httpd_req_t* req) change_baud_rate(strtol(baudrate, NULL, 10)); httpd_resp_sendstr(req, "{\"status\":\"baudrate_updated\"}"); } + else if (period_item && cJSON_IsString(period_item)) + { + const char* period_str = period_item->valuestring; + ESP_LOGI(TAG, "Received period set request: %s", period_str); + update_sensor_period(strtol(period_str, NULL, 10)); + httpd_resp_sendstr(req, "{\"status\":\"period_updated\"}"); + } else if (vin_climit_item || main_climit_item || usb_climit_item) { char num_buf[10]; diff --git a/page/index.html b/page/index.html index 0290287..63246a1 100644 --- a/page/index.html +++ b/page/index.html @@ -359,7 +359,7 @@
-
+
+
+ +
+
+
+ + +
+ +

@@ -380,7 +390,6 @@
-
diff --git a/page/src/api.js b/page/src/api.js index 9c302ee..aac1317 100644 --- a/page/src/api.js +++ b/page/src/api.js @@ -104,7 +104,6 @@ export async function postNetworkSettings(payload) { * Posts the selected UART baud rate to the server. * @param {string} baudrate The selected baud rate. * @returns {Promise} A promise that resolves to the raw fetch response. - * @throws {Error} Throws an error if the request fails. */ export async function postBaudRateSetting(baudrate) { const response = await fetch('/api/setting', { @@ -113,7 +112,24 @@ export async function postBaudRateSetting(baudrate) { 'Content-Type': 'application/json', ...getAuthHeaders(), }, - body: JSON.stringify({baudrate}), + body: JSON.stringify({ baudrate }), + }); + return await handleResponse(response); +} + +/** + * Posts the selected sensor period to the server. + * @param {string} period The selected period in milliseconds. + * @returns {Promise} A promise that resolves to the raw fetch response. + */ +export async function postPeriodSetting(period) { + const response = await fetch('/api/setting', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + ...getAuthHeaders(), + }, + body: JSON.stringify({ period }), }); return await handleResponse(response); } diff --git a/page/src/dom.js b/page/src/dom.js index 0e1e420..f5af806 100644 --- a/page/src/dom.js +++ b/page/src/dom.js @@ -76,6 +76,9 @@ export const apPasswordInput = document.getElementById('ap-password'); // --- Device Settings Elements --- export const baudRateSelect = document.getElementById('baud-rate-select'); export const baudRateApplyButton = document.getElementById('baud-rate-apply-button'); +export const periodSlider = document.getElementById('period-slider'); +export const periodValue = document.getElementById('period-value'); +export const periodApplyButton = document.getElementById('period-apply-button'); export const rebootButton = document.getElementById('reboot-button'); // --- Current Limit Settings Elements --- diff --git a/page/src/events.js b/page/src/events.js index 75edcea..2f0bad0 100644 --- a/page/src/events.js +++ b/page/src/events.js @@ -77,8 +77,9 @@ export function setupEventListeners() { dom.networkApplyButton.addEventListener('click', ui.applyNetworkSettings); dom.apModeApplyButton.addEventListener('click', ui.applyApModeSettings); dom.baudRateApplyButton.addEventListener('click', ui.applyBaudRateSettings); + dom.periodApplyButton.addEventListener('click', ui.applyPeriodSettings); - // --- Device Settings (Reboot) --- + // --- Device Settings (Reboot & Period Slider) --- if (dom.rebootButton) { dom.rebootButton.addEventListener('click', () => { if (confirm('Are you sure you want to reboot the device?')) { @@ -101,6 +102,12 @@ export function setupEventListeners() { }); } + if (dom.periodSlider) { + dom.periodSlider.addEventListener('input', () => { + dom.periodValue.textContent = dom.periodSlider.value; + }); + } + // --- Current Limit Settings --- dom.vinSlider.addEventListener('input', () => updateSliderValue(dom.vinSlider, dom.vinValueSpan)); dom.mainSlider.addEventListener('input', () => updateSliderValue(dom.mainSlider, dom.mainValueSpan)); diff --git a/page/src/ui.js b/page/src/ui.js index 0749393..4819917 100644 --- a/page/src/ui.js +++ b/page/src/ui.js @@ -301,6 +301,24 @@ export async function applyBaudRateSettings() { } } +/** + * Applies the selected sensor period by sending it to the server. + */ +export async function applyPeriodSettings() { + const period = dom.periodSlider.value; + dom.periodApplyButton.disabled = true; + dom.periodApplyButton.innerHTML = ` Applying...`; + + try { + await api.postPeriodSetting(period); + } catch (error) { + console.error('Error applying period:', error); + } finally { + dom.periodApplyButton.disabled = false; + dom.periodApplyButton.innerHTML = 'Apply'; + } +} + /** * Fetches and displays the current network and device settings in the settings modal. */ @@ -338,6 +356,10 @@ export async function initializeSettings() { if (data.baudrate) { dom.baudRateSelect.value = data.baudrate; } + if (data.period) { + dom.periodSlider.value = data.period; + dom.periodValue.textContent = data.period; + } } catch (error) { console.error('Error initializing settings:', error);