Compare commits
12 Commits
5e0eb8b9db
...
v1.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
| a484db06c9 | |||
| 9e00fc1135 | |||
| 44a739a0bd | |||
| 873ccc91c5 | |||
| 39ca2d205a | |||
| 4bbf1339f1 | |||
| ae62a7c8e1 | |||
| 46b0ea7bda | |||
| 26773507d5 | |||
| 0c2b4ac07e | |||
| 557646916d | |||
| 6d83ec1b16 |
@@ -12,8 +12,8 @@
|
|||||||
|
|
||||||
The device boots in APSTA mode by default and services the following AP.
|
The device boots in APSTA mode by default and services the following AP.
|
||||||
|
|
||||||
- SSID: odroid-pm
|
- SSID: powermate
|
||||||
- Password: powermate
|
- Password: hardkernel
|
||||||
|
|
||||||
After connecting to the above AP using a smartphone, etc., you can configure the device by accessing the
|
After connecting to the above AP using a smartphone, etc., you can configure the device by accessing the
|
||||||
`http://192.168.4.1` address.
|
`http://192.168.4.1` address.
|
||||||
|
|||||||
@@ -69,3 +69,21 @@ add_custom_target(protobuf_generate ALL
|
|||||||
|
|
||||||
add_dependencies(${COMPONENT_LIB} build_web_app)
|
add_dependencies(${COMPONENT_LIB} build_web_app)
|
||||||
add_dependencies(${COMPONENT_LIB} protobuf_generate)
|
add_dependencies(${COMPONENT_LIB} protobuf_generate)
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND git rev-parse --short HEAD
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
OUTPUT_VARIABLE GIT_HASH
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
|
||||||
|
add_compile_definitions(VERSION_HASH="${GIT_HASH}")
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND git describe --tags --abbrev=0
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
OUTPUT_VARIABLE GIT_TAG
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
|
||||||
|
add_compile_definitions(VERSION_TAG="${GIT_TAG}")
|
||||||
@@ -14,8 +14,10 @@
|
|||||||
|
|
||||||
void app_main(void)
|
void app_main(void)
|
||||||
{
|
{
|
||||||
|
printf("\n\n== ODROID POWER-MATE ===\n");
|
||||||
|
printf("Version: %s-%s\n\n", VERSION_TAG, VERSION_HASH);
|
||||||
|
|
||||||
ESP_ERROR_CHECK(i2cdev_init());
|
ESP_ERROR_CHECK(i2cdev_init());
|
||||||
;
|
|
||||||
init_led();
|
init_led();
|
||||||
led_set(LED_BLU, BLINK_TRIPLE);
|
led_set(LED_BLU, BLINK_TRIPLE);
|
||||||
led_off(LED_BLU);
|
led_off(LED_BLU);
|
||||||
|
|||||||
@@ -45,6 +45,11 @@ enum nconfig_type
|
|||||||
NCONFIG_TYPE_MAX, ///< Sentinel for the maximum number of configuration types.
|
NCONFIG_TYPE_MAX, ///< Sentinel for the maximum number of configuration types.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erase all of nvs data and restart system
|
||||||
|
*/
|
||||||
|
void reset_nconfig();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks if a specific configuration value has been set.
|
* @brief Checks if a specific configuration value has been set.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
#include "nconfig.h"
|
#include "nconfig.h"
|
||||||
|
|
||||||
|
#include "indicator.h"
|
||||||
|
#include "system.h"
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "nvs_flash.h"
|
#include "nvs_flash.h"
|
||||||
|
|
||||||
@@ -43,11 +45,11 @@ struct default_value const default_values[] = {
|
|||||||
{NETIF_DNS1, "8.8.8.8"},
|
{NETIF_DNS1, "8.8.8.8"},
|
||||||
{NETIF_DNS2, "8.8.4.4"},
|
{NETIF_DNS2, "8.8.4.4"},
|
||||||
{WIFI_MODE, "apsta"},
|
{WIFI_MODE, "apsta"},
|
||||||
{AP_SSID, "odroid-pm"},
|
{AP_SSID, "powermate"},
|
||||||
{AP_PASSWORD, "powermate"},
|
{AP_PASSWORD, "hardkernel"},
|
||||||
{VIN_CURRENT_LIMIT, "8.0"},
|
{VIN_CURRENT_LIMIT, "4.0"},
|
||||||
{MAIN_CURRENT_LIMIT, "7.0"},
|
{MAIN_CURRENT_LIMIT, "3.0"},
|
||||||
{USB_CURRENT_LIMIT, "5.0"},
|
{USB_CURRENT_LIMIT, "3.0"},
|
||||||
};
|
};
|
||||||
|
|
||||||
esp_err_t init_nconfig()
|
esp_err_t init_nconfig()
|
||||||
@@ -70,6 +72,13 @@ esp_err_t init_nconfig()
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reset_nconfig()
|
||||||
|
{
|
||||||
|
nvs_erase_all(handle);
|
||||||
|
led_set(LED_RED, BLINK_FAST);
|
||||||
|
start_reboot_timer(1);
|
||||||
|
}
|
||||||
|
|
||||||
bool nconfig_value_is_not_set(enum nconfig_type type)
|
bool nconfig_value_is_not_set(enum nconfig_type type)
|
||||||
{
|
{
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ typedef struct _WifiStatus {
|
|||||||
bool connected;
|
bool connected;
|
||||||
pb_callback_t ssid;
|
pb_callback_t ssid;
|
||||||
int32_t rssi;
|
int32_t rssi;
|
||||||
|
pb_callback_t ip_address;
|
||||||
} WifiStatus;
|
} WifiStatus;
|
||||||
|
|
||||||
/* Contains raw UART data */
|
/* Contains raw UART data */
|
||||||
@@ -66,13 +67,13 @@ extern "C" {
|
|||||||
/* Initializer values for message structs */
|
/* Initializer values for message structs */
|
||||||
#define SensorChannelData_init_default {0, 0, 0}
|
#define SensorChannelData_init_default {0, 0, 0}
|
||||||
#define SensorData_init_default {false, SensorChannelData_init_default, false, SensorChannelData_init_default, false, SensorChannelData_init_default, 0, 0}
|
#define SensorData_init_default {false, SensorChannelData_init_default, false, SensorChannelData_init_default, false, SensorChannelData_init_default, 0, 0}
|
||||||
#define WifiStatus_init_default {0, {{NULL}, NULL}, 0}
|
#define WifiStatus_init_default {0, {{NULL}, NULL}, 0, {{NULL}, NULL}}
|
||||||
#define UartData_init_default {{{NULL}, NULL}}
|
#define UartData_init_default {{{NULL}, NULL}}
|
||||||
#define LoadSwStatus_init_default {0, 0}
|
#define LoadSwStatus_init_default {0, 0}
|
||||||
#define StatusMessage_init_default {0, {SensorData_init_default}}
|
#define StatusMessage_init_default {0, {SensorData_init_default}}
|
||||||
#define SensorChannelData_init_zero {0, 0, 0}
|
#define SensorChannelData_init_zero {0, 0, 0}
|
||||||
#define SensorData_init_zero {false, SensorChannelData_init_zero, false, SensorChannelData_init_zero, false, SensorChannelData_init_zero, 0, 0}
|
#define SensorData_init_zero {false, SensorChannelData_init_zero, false, SensorChannelData_init_zero, false, SensorChannelData_init_zero, 0, 0}
|
||||||
#define WifiStatus_init_zero {0, {{NULL}, NULL}, 0}
|
#define WifiStatus_init_zero {0, {{NULL}, NULL}, 0, {{NULL}, NULL}}
|
||||||
#define UartData_init_zero {{{NULL}, NULL}}
|
#define UartData_init_zero {{{NULL}, NULL}}
|
||||||
#define LoadSwStatus_init_zero {0, 0}
|
#define LoadSwStatus_init_zero {0, 0}
|
||||||
#define StatusMessage_init_zero {0, {SensorData_init_zero}}
|
#define StatusMessage_init_zero {0, {SensorData_init_zero}}
|
||||||
@@ -89,6 +90,7 @@ extern "C" {
|
|||||||
#define WifiStatus_connected_tag 1
|
#define WifiStatus_connected_tag 1
|
||||||
#define WifiStatus_ssid_tag 2
|
#define WifiStatus_ssid_tag 2
|
||||||
#define WifiStatus_rssi_tag 3
|
#define WifiStatus_rssi_tag 3
|
||||||
|
#define WifiStatus_ip_address_tag 4
|
||||||
#define UartData_data_tag 1
|
#define UartData_data_tag 1
|
||||||
#define LoadSwStatus_main_tag 1
|
#define LoadSwStatus_main_tag 1
|
||||||
#define LoadSwStatus_usb_tag 2
|
#define LoadSwStatus_usb_tag 2
|
||||||
@@ -120,7 +122,8 @@ X(a, STATIC, SINGULAR, UINT32, uptime_sec, 5)
|
|||||||
#define WifiStatus_FIELDLIST(X, a) \
|
#define WifiStatus_FIELDLIST(X, a) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, connected, 1) \
|
X(a, STATIC, SINGULAR, BOOL, connected, 1) \
|
||||||
X(a, CALLBACK, SINGULAR, STRING, ssid, 2) \
|
X(a, CALLBACK, SINGULAR, STRING, ssid, 2) \
|
||||||
X(a, STATIC, SINGULAR, INT32, rssi, 3)
|
X(a, STATIC, SINGULAR, INT32, rssi, 3) \
|
||||||
|
X(a, CALLBACK, SINGULAR, STRING, ip_address, 4)
|
||||||
#define WifiStatus_CALLBACK pb_default_field_callback
|
#define WifiStatus_CALLBACK pb_default_field_callback
|
||||||
#define WifiStatus_DEFAULT NULL
|
#define WifiStatus_DEFAULT NULL
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ static const char* TAG = "monitor";
|
|||||||
|
|
||||||
static esp_timer_handle_t sensor_timer;
|
static esp_timer_handle_t sensor_timer;
|
||||||
static esp_timer_handle_t wifi_status_timer;
|
static esp_timer_handle_t wifi_status_timer;
|
||||||
|
static esp_timer_handle_t long_press_timer;
|
||||||
// static esp_timer_handle_t shutdown_load_sw; // No longer needed
|
// static esp_timer_handle_t shutdown_load_sw; // No longer needed
|
||||||
|
|
||||||
static TaskHandle_t shutdown_task_handle = NULL; // Global task handle
|
static TaskHandle_t shutdown_task_handle = NULL; // Global task handle
|
||||||
@@ -137,6 +138,8 @@ static void status_wifi_callback(void* arg)
|
|||||||
StatusMessage message = StatusMessage_init_zero;
|
StatusMessage message = StatusMessage_init_zero;
|
||||||
message.which_payload = StatusMessage_wifi_status_tag;
|
message.which_payload = StatusMessage_wifi_status_tag;
|
||||||
WifiStatus* wifi_status = &message.payload.wifi_status;
|
WifiStatus* wifi_status = &message.payload.wifi_status;
|
||||||
|
char ip_str[16];
|
||||||
|
esp_netif_ip_info_t ip_info;
|
||||||
|
|
||||||
if (wifi_get_current_ap_info(&ap_info) == ESP_OK)
|
if (wifi_get_current_ap_info(&ap_info) == ESP_OK)
|
||||||
{
|
{
|
||||||
@@ -152,9 +155,36 @@ static void status_wifi_callback(void* arg)
|
|||||||
wifi_status->rssi = 0;
|
wifi_status->rssi = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wifi_get_current_ip_info(&ip_info) == ESP_OK)
|
||||||
|
{
|
||||||
|
esp_ip4addr_ntoa(&ip_info.ip, ip_str, sizeof(ip_str));
|
||||||
|
wifi_status->ip_address.funcs.encode = &encode_string;
|
||||||
|
wifi_status->ip_address.arg = ip_str;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wifi_status->ip_address.arg = ""; // Empty string
|
||||||
|
}
|
||||||
|
|
||||||
send_pb_message(StatusMessage_fields, &message);
|
send_pb_message(StatusMessage_fields, &message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Placeholder for long press action
|
||||||
|
static void handle_critical_long_press(void)
|
||||||
|
{
|
||||||
|
ESP_LOGW(TAG, "Config reset triggered...");
|
||||||
|
reset_nconfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timer callback for long press detection
|
||||||
|
static void long_press_timer_callback(void* arg)
|
||||||
|
{
|
||||||
|
if (gpio_get_level(PM_INT_CRITICAL) == 0)
|
||||||
|
{
|
||||||
|
handle_critical_long_press();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// New FreeRTOS task for shutdown logic
|
// New FreeRTOS task for shutdown logic
|
||||||
static void shutdown_load_sw_task(void* pvParameters)
|
static void shutdown_load_sw_task(void* pvParameters)
|
||||||
{
|
{
|
||||||
@@ -168,15 +198,26 @@ static void shutdown_load_sw_task(void* pvParameters)
|
|||||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||||
gpio_set_level(PM_EXPANDER_RST, 1);
|
gpio_set_level(PM_EXPANDER_RST, 1);
|
||||||
config_sw();
|
config_sw();
|
||||||
|
|
||||||
|
// Start a 5-second timer to check for long press
|
||||||
|
esp_timer_start_once(long_press_timer, 5000000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void IRAM_ATTR critical_isr_handler(void* arg)
|
static void IRAM_ATTR critical_isr_handler(void* arg)
|
||||||
{
|
{
|
||||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||||
if (shutdown_task_handle != NULL)
|
if (gpio_get_level(PM_INT_CRITICAL) == 0) // Falling edge
|
||||||
{
|
{
|
||||||
vTaskNotifyGiveFromISR(shutdown_task_handle, &xHigherPriorityTaskWoken);
|
if (shutdown_task_handle != NULL)
|
||||||
|
{
|
||||||
|
vTaskNotifyGiveFromISR(shutdown_task_handle, &xHigherPriorityTaskWoken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // Rising edge
|
||||||
|
{
|
||||||
|
// Stop the timer if the button is released
|
||||||
|
esp_timer_stop(long_press_timer);
|
||||||
}
|
}
|
||||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||||
}
|
}
|
||||||
@@ -184,7 +225,7 @@ static void IRAM_ATTR critical_isr_handler(void* arg)
|
|||||||
static void gpio_init()
|
static void gpio_init()
|
||||||
{
|
{
|
||||||
// critical int
|
// critical int
|
||||||
gpio_set_intr_type(PM_INT_CRITICAL, GPIO_INTR_NEGEDGE);
|
gpio_set_intr_type(PM_INT_CRITICAL, GPIO_INTR_ANYEDGE);
|
||||||
gpio_set_direction(PM_INT_CRITICAL, GPIO_MODE_INPUT);
|
gpio_set_direction(PM_INT_CRITICAL, GPIO_MODE_INPUT);
|
||||||
gpio_install_isr_service(0);
|
gpio_install_isr_service(0);
|
||||||
gpio_isr_handler_add(PM_INT_CRITICAL, critical_isr_handler, (void*)PM_INT_CRITICAL);
|
gpio_isr_handler_add(PM_INT_CRITICAL, critical_isr_handler, (void*)PM_INT_CRITICAL);
|
||||||
@@ -246,9 +287,12 @@ void init_status_monitor()
|
|||||||
const esp_timer_create_args_t sensor_timer_args = {.callback = &sensor_timer_callback,
|
const esp_timer_create_args_t sensor_timer_args = {.callback = &sensor_timer_callback,
|
||||||
.name = "sensor_reading_timer"};
|
.name = "sensor_reading_timer"};
|
||||||
const esp_timer_create_args_t wifi_timer_args = {.callback = &status_wifi_callback, .name = "wifi_status_timer"};
|
const esp_timer_create_args_t wifi_timer_args = {.callback = &status_wifi_callback, .name = "wifi_status_timer"};
|
||||||
|
const esp_timer_create_args_t long_press_timer_args = {.callback = &long_press_timer_callback,
|
||||||
|
.name = "long_press_timer"};
|
||||||
|
|
||||||
ESP_ERROR_CHECK(esp_timer_create(&sensor_timer_args, &sensor_timer));
|
ESP_ERROR_CHECK(esp_timer_create(&sensor_timer_args, &sensor_timer));
|
||||||
ESP_ERROR_CHECK(esp_timer_create(&wifi_timer_args, &wifi_status_timer));
|
ESP_ERROR_CHECK(esp_timer_create(&wifi_timer_args, &wifi_status_timer));
|
||||||
|
ESP_ERROR_CHECK(esp_timer_create(&long_press_timer_args, &long_press_timer));
|
||||||
|
|
||||||
xTaskCreate(shutdown_load_sw_task, "shutdown_sw_task", configMINIMAL_STACK_SIZE * 3, NULL, 15, &shutdown_task_handle);
|
xTaskCreate(shutdown_load_sw_task, "shutdown_sw_task", configMINIMAL_STACK_SIZE * 3, NULL, 15, &shutdown_task_handle);
|
||||||
|
|
||||||
|
|||||||
@@ -87,5 +87,7 @@ void start_webserver(void)
|
|||||||
register_ws_endpoint(server);
|
register_ws_endpoint(server);
|
||||||
register_control_endpoint(server);
|
register_control_endpoint(server);
|
||||||
register_reboot_endpoint(server);
|
register_reboot_endpoint(server);
|
||||||
|
register_version_endpoint(server);
|
||||||
|
|
||||||
init_status_monitor();
|
init_status_monitor();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,5 +15,6 @@ void register_control_endpoint(httpd_handle_t server);
|
|||||||
void push_data_to_ws(const uint8_t* data, size_t len);
|
void push_data_to_ws(const uint8_t* data, size_t len);
|
||||||
void register_reboot_endpoint(httpd_handle_t server);
|
void register_reboot_endpoint(httpd_handle_t server);
|
||||||
esp_err_t change_baud_rate(int baud_rate);
|
esp_err_t change_baud_rate(int baud_rate);
|
||||||
|
void register_version_endpoint(httpd_handle_t server);
|
||||||
|
|
||||||
#endif // ODROID_REMOTE_HTTP_WEBSERVER_H
|
#endif // ODROID_REMOTE_HTTP_WEBSERVER_H
|
||||||
|
|||||||
@@ -193,7 +193,6 @@ static void uart_event_task(void* arg)
|
|||||||
// Muting this event because it is too noisy
|
// Muting this event because it is too noisy
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ESP_LOGI(TAG, "unhandled uart event type: %d", event.type);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,3 +77,19 @@ void register_reboot_endpoint(httpd_handle_t server)
|
|||||||
.uri = "/api/reboot", .method = HTTP_POST, .handler = reboot_post_handler, .user_ctx = NULL};
|
.uri = "/api/reboot", .method = HTTP_POST, .handler = reboot_post_handler, .user_ctx = NULL};
|
||||||
httpd_register_uri_handler(server, &post_uri);
|
httpd_register_uri_handler(server, &post_uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static esp_err_t version_get_handler(httpd_req_t* req)
|
||||||
|
{
|
||||||
|
httpd_resp_set_type(req, "application/json");
|
||||||
|
char buf[100];
|
||||||
|
sprintf(buf, "{\"version\": \"%s-%s\"}", VERSION_TAG, VERSION_HASH);
|
||||||
|
httpd_resp_send(req, buf, strlen(buf));
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void register_version_endpoint(httpd_handle_t server)
|
||||||
|
{
|
||||||
|
httpd_uri_t post_uri = {
|
||||||
|
.uri = "/api/version", .method = HTTP_GET, .handler = version_get_handler, .user_ctx = NULL};
|
||||||
|
httpd_register_uri_handler(server, &post_uri);
|
||||||
|
}
|
||||||
@@ -130,9 +130,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<footer class="bg-body-tertiary text-center p-3">
|
<footer class="bg-body-tertiary text-center p-3 position-relative">
|
||||||
<a href="https://www.hardkernel.com/" target="_blank" class="link-secondary">Hardkernel</a> |
|
<a href="https://www.hardkernel.com/" target="_blank" class="link-secondary text-decoration-none">Hardkernel</a> |
|
||||||
<a href="https://wiki.odroid.com/start" target="_blank" class="link-secondary">Wiki</a>
|
<a href="https://wiki.odroid.com/start" target="_blank" class="link-secondary text-decoration-none">Wiki</a>
|
||||||
|
<div class="position-absolute end-0 top-50 translate-middle-y pe-3">
|
||||||
|
<small class="text-muted" id="version-info"></small>
|
||||||
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<!-- Settings Modal -->
|
<!-- Settings Modal -->
|
||||||
@@ -257,7 +260,7 @@
|
|||||||
<div id="ap-mode-config" style="display: none;">
|
<div id="ap-mode-config" style="display: none;">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="ap-ssid" class="form-label">AP SSID</label>
|
<label for="ap-ssid" class="form-label">AP SSID</label>
|
||||||
<input type="text" class="form-control" id="ap-ssid" placeholder="odroid-pm">
|
<input type="text" class="form-control" id="ap-ssid" placeholder="powermate">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="ap-password" class="form-label">AP Password</label>
|
<label for="ap-password" class="form-label">AP Password</label>
|
||||||
@@ -346,7 +349,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="wifi-password-connect" class="form-label">Password</label>
|
<label for="wifi-password-connect" class="form-label">Password</label>
|
||||||
<input type="password" class="form-control" id="wifi-password-connect">
|
<input type="password" class="form-control" id="wifi-password-connect" placeholder="Leave blank for open network">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
|
|||||||
@@ -110,3 +110,14 @@ export async function postControlCommand(command) {
|
|||||||
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
|
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches the firmware version from the server.
|
||||||
|
* @returns {Promise<Object>} A promise that resolves to an object containing the version.
|
||||||
|
* @throws {Error} Throws an error if the network request fails.
|
||||||
|
*/
|
||||||
|
export async function fetchVersion() {
|
||||||
|
const response = await fetch('/api/version');
|
||||||
|
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
|
return await response.json();
|
||||||
|
}
|
||||||
|
|||||||
@@ -86,3 +86,6 @@ export const mainValueSpan = document.getElementById('main-current-limit-value')
|
|||||||
export const usbSlider = document.getElementById('usb-current-limit-slider');
|
export const usbSlider = document.getElementById('usb-current-limit-slider');
|
||||||
export const usbValueSpan = document.getElementById('usb-current-limit-value');
|
export const usbValueSpan = document.getElementById('usb-current-limit-value');
|
||||||
export const currentLimitApplyButton = document.getElementById('current-limit-apply-button');
|
export const currentLimitApplyButton = document.getElementById('current-limit-apply-button');
|
||||||
|
|
||||||
|
// --- Footer ---
|
||||||
|
export const versionInfo = document.getElementById('version-info');
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import './style.css';
|
|||||||
|
|
||||||
// --- Module Imports -- -
|
// --- Module Imports -- -
|
||||||
import {StatusMessage} from './proto.js';
|
import {StatusMessage} from './proto.js';
|
||||||
|
import * as api from './api.js';
|
||||||
import {initWebSocket} from './websocket.js';
|
import {initWebSocket} from './websocket.js';
|
||||||
import {setupTerminal, term} from './terminal.js';
|
import {setupTerminal, term} from './terminal.js';
|
||||||
import {
|
import {
|
||||||
@@ -21,6 +22,7 @@ import {
|
|||||||
updateSensorUI,
|
updateSensorUI,
|
||||||
updateSwitchStatusUI,
|
updateSwitchStatusUI,
|
||||||
updateUptimeUI,
|
updateUptimeUI,
|
||||||
|
updateVersionUI,
|
||||||
updateWebsocketStatus,
|
updateWebsocketStatus,
|
||||||
updateWifiStatusUI
|
updateWifiStatusUI
|
||||||
} from './ui.js';
|
} from './ui.js';
|
||||||
@@ -112,6 +114,18 @@ function onWsMessage(event) {
|
|||||||
|
|
||||||
// --- Application Initialization ---
|
// --- Application Initialization ---
|
||||||
|
|
||||||
|
async function initializeVersion() {
|
||||||
|
try {
|
||||||
|
const versionData = await api.fetchVersion();
|
||||||
|
if (versionData && versionData.version) {
|
||||||
|
updateVersionUI(versionData.version);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching version:', error);
|
||||||
|
updateVersionUI('N/A');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function connect() {
|
function connect() {
|
||||||
updateControlStatus();
|
updateControlStatus();
|
||||||
initWebSocket({ onOpen: onWsOpen, onClose: onWsClose, onMessage: onWsMessage });
|
initWebSocket({ onOpen: onWsOpen, onClose: onWsClose, onMessage: onWsMessage });
|
||||||
@@ -120,6 +134,7 @@ function connect() {
|
|||||||
function initialize() {
|
function initialize() {
|
||||||
initUI();
|
initUI();
|
||||||
setupTerminal();
|
setupTerminal();
|
||||||
|
initializeVersion();
|
||||||
|
|
||||||
const savedTheme = localStorage.getItem('theme') || (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
|
const savedTheme = localStorage.getItem('theme') || (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
|
||||||
applyTheme(savedTheme);
|
applyTheme(savedTheme);
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ export function updateSwitchStatusUI(swStatus) {
|
|||||||
*/
|
*/
|
||||||
export function updateWifiStatusUI(data) {
|
export function updateWifiStatusUI(data) {
|
||||||
if (data.connected) {
|
if (data.connected) {
|
||||||
|
// Update header status
|
||||||
dom.wifiSsidStatus.textContent = data.ssid;
|
dom.wifiSsidStatus.textContent = data.ssid;
|
||||||
dom.wifiStatus.title = `Signal Strength: ${data.rssi} dBm`;
|
dom.wifiStatus.title = `Signal Strength: ${data.rssi} dBm`;
|
||||||
let iconClass = 'bi me-2 ';
|
let iconClass = 'bi me-2 ';
|
||||||
@@ -91,12 +92,31 @@ export function updateWifiStatusUI(data) {
|
|||||||
dom.wifiIcon.className = iconClass;
|
dom.wifiIcon.className = iconClass;
|
||||||
dom.wifiStatus.classList.replace('text-muted', 'text-success');
|
dom.wifiStatus.classList.replace('text-muted', 'text-success');
|
||||||
dom.wifiStatus.classList.remove('text-danger');
|
dom.wifiStatus.classList.remove('text-danger');
|
||||||
|
|
||||||
|
// Update settings modal
|
||||||
|
dom.currentWifiSsid.textContent = data.ssid;
|
||||||
|
dom.currentWifiIp.textContent = `IP Address: ${data.ipAddress || 'N/A'}`;
|
||||||
} else {
|
} else {
|
||||||
|
// Update header status
|
||||||
dom.wifiSsidStatus.textContent = 'Disconnected';
|
dom.wifiSsidStatus.textContent = 'Disconnected';
|
||||||
dom.wifiStatus.title = '';
|
dom.wifiStatus.title = '';
|
||||||
dom.wifiIcon.className = 'bi bi-wifi-off me-2';
|
dom.wifiIcon.className = 'bi bi-wifi-off me-2';
|
||||||
dom.wifiStatus.classList.replace('text-success', 'text-muted');
|
dom.wifiStatus.classList.replace('text-success', 'text-muted');
|
||||||
dom.wifiStatus.classList.remove('text-danger');
|
dom.wifiStatus.classList.remove('text-danger');
|
||||||
|
|
||||||
|
// Update settings modal
|
||||||
|
dom.currentWifiSsid.textContent = 'Not Connected';
|
||||||
|
dom.currentWifiIp.textContent = 'IP Address: -';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the version information in the footer.
|
||||||
|
* @param {string} version - The firmware version string.
|
||||||
|
*/
|
||||||
|
export function updateVersionUI(version) {
|
||||||
|
if (version) {
|
||||||
|
dom.versionInfo.textContent = `${version}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ message WifiStatus {
|
|||||||
bool connected = 1;
|
bool connected = 1;
|
||||||
string ssid = 2;
|
string ssid = 2;
|
||||||
int32 rssi = 3;
|
int32 rssi = 3;
|
||||||
|
string ip_address = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Contains raw UART data
|
// Contains raw UART data
|
||||||
|
|||||||
Reference in New Issue
Block a user