4 Commits

7 changed files with 210 additions and 14 deletions

182
main/service/dbg_console.c Normal file
View File

@@ -0,0 +1,182 @@
#include "dbg_console.h"
#include <stdio.h>
#include <string.h>
#include "argtable3/argtable3.h"
#include "esp_console.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_system.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "wifi.h"
/* 'wifi_scan' command */
static int wifi_scan_handler(int argc, char** argv)
{
printf("Scanning for Wi-Fi networks...\n");
wifi_ap_record_t* ap_records;
uint16_t count = 0;
wifi_scan_aps(&ap_records, &count);
if (count == 0)
{
printf("No APs found.\n");
return 0;
}
printf("Found %d APs:\n", count);
printf(" %-32s %-4s %s\n", "SSID", "RSSI", "Auth Mode");
for (int i = 0; i < count; i++)
{
printf(" %-32s %-4d %s\n", ap_records[i].ssid, ap_records[i].rssi, auth_mode_str(ap_records[i].authmode));
}
if (count > 0)
{
free(ap_records);
}
return 0;
}
static void register_wifi_scan(void)
{
const esp_console_cmd_t cmd = {
.command = "wifi_scan",
.help = "Scan for available Wi-Fi networks",
.hint = NULL,
.func = &wifi_scan_handler,
};
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
}
static struct
{
struct arg_str* ssid;
struct arg_str* password;
struct arg_end* end;
} wifi_connect_args;
static int wifi_connect_handler(int argc, char** argv)
{
int nerrors = arg_parse(argc, argv, (void**)&wifi_connect_args);
if (nerrors != 0)
{
arg_print_errors(stderr, wifi_connect_args.end, argv[0]);
return 1;
}
const char* ssid = wifi_connect_args.ssid->sval[0];
char password[64] = "";
if (wifi_connect_args.password->count != 0)
strncpy(password, wifi_connect_args.password->sval[0], sizeof(password));
printf("Attempting to connect to SSID: %s\n", ssid);
esp_err_t err = wifi_sta_set_ap(ssid, password);
if (err == ESP_OK)
{
printf("Wi-Fi credentials set. The device will attempt to connect.\n");
}
else
{
printf("Failed to set Wi-Fi credentials.\n");
}
return 0;
}
static void register_wifi_connect(void)
{
wifi_connect_args.ssid = arg_str1(NULL, NULL, "<ssid>", "SSID of the network to connect to");
wifi_connect_args.password = arg_str0(NULL, NULL, "<password>", "Password of the network");
wifi_connect_args.end = arg_end(2);
const esp_console_cmd_t cmd = {.command = "wifi_connect",
.help = "Connect to a Wi-Fi network",
.hint = NULL,
.func = &wifi_connect_handler,
.argtable = &wifi_connect_args};
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
}
/* 'wifi_status' command */
static int wifi_status_handler(int argc, char** argv)
{
wifi_ap_record_t ap_info;
esp_err_t err = wifi_get_current_ap_info(&ap_info);
if (err == ESP_OK)
{
printf("Connected to AP:\n");
printf(" SSID: %s\n", (char*)ap_info.ssid);
printf(" RSSI: %d\n", ap_info.rssi);
esp_netif_ip_info_t ip_info;
err = wifi_get_current_ip_info(&ip_info);
if (err == ESP_OK)
{
char ip_str[16];
esp_ip4addr_ntoa(&ip_info.ip, ip_str, sizeof(ip_str));
printf(" IP Address: %s\n", ip_str);
esp_ip4addr_ntoa(&ip_info.gw, ip_str, sizeof(ip_str));
printf(" Gateway: %s\n", ip_str);
esp_ip4addr_ntoa(&ip_info.netmask, ip_str, sizeof(ip_str));
printf(" Subnet Mask: %s\n", ip_str);
}
else
{
printf(" Could not get IP information: %s\n", esp_err_to_name(err));
}
}
else
{
printf("Not connected to any AP.\n");
}
return 0;
}
static void register_wifi_status(void)
{
const esp_console_cmd_t cmd = {
.command = "wifi_status",
.help = "Get current Wi-Fi connection status and IP information",
.hint = NULL,
.func = &wifi_status_handler,
};
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
}
esp_err_t initialize_dbg_console(void)
{
esp_console_repl_t* repl = NULL;
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
repl_config.prompt = "powermate >";
repl_config.max_cmdline_length = 512;
esp_console_dev_usb_serial_jtag_config_t hw_config = ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_console_new_repl_usb_serial_jtag(&hw_config, &repl_config, &repl));
esp_console_register_help_command();
register_wifi_scan();
register_wifi_connect();
register_wifi_status();
printf("Debug console initialized.\n");
esp_console_start_repl(repl);
return ESP_OK;
}

View File

@@ -0,0 +1,13 @@
#ifndef ODROID_POWER_MATE_DBG_CONSOLE_H
#define ODROID_POWER_MATE_DBG_CONSOLE_H
#include "esp_err.h"
/**
* @brief Initialize the debug console.
*
* @return ESP_OK on success, or an error code on failure.
*/
esp_err_t initialize_dbg_console(void);
#endif // ODROID_POWER_MATE_DBG_CONSOLE_H

View File

@@ -3,6 +3,7 @@
#include <string.h> #include <string.h>
#include "auth.h" #include "auth.h"
#include "cJSON.h" #include "cJSON.h"
#include "dbg_console.h"
#include "esp_http_server.h" #include "esp_http_server.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_wifi.h" #include "esp_wifi.h"
@@ -193,4 +194,6 @@ void start_webserver(void)
register_version_endpoint(server); register_version_endpoint(server);
init_status_monitor(); init_status_monitor();
initialize_dbg_console();
} }

View File

@@ -53,7 +53,10 @@
<span id="power-display" class="text-primary">--.-- W</span> <span id="power-display" class="text-primary">--.-- W</span>
</div> </div>
</div> </div>
<h1 class="text-primary text-center order-md-2 mx-auto">ODROID Power Mate</h1> <div class="text-center order-md-2 mx-auto">
<h1 class="text-primary mb-0">ODROID Power Mate</h1>
<small class="text-muted" id="version-info"></small>
</div>
<div class="d-flex align-items-center justify-content-end order-md-3 header-controls" style="flex: 1;"> <div class="d-flex align-items-center justify-content-end order-md-3 header-controls" style="flex: 1;">
<div class="form-check form-switch"> <div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="theme-toggle"> <input class="form-check-input" type="checkbox" role="switch" id="theme-toggle">
@@ -159,12 +162,9 @@
</div> </div>
</main> </main>
<footer class="bg-body-tertiary text-center p-3 position-relative"> <footer class="bg-body-tertiary text-center p-3">
<a href="https://www.hardkernel.com/" target="_blank" class="link-secondary text-decoration-none">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 text-decoration-none">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 -->

View File

@@ -7,10 +7,10 @@
import * as dom from './dom.js'; import * as dom from './dom.js';
import * as api from './api.js'; import * as api from './api.js';
import {getAuthHeaders, handleResponse} from './api.js'; // Import auth functions
import * as ui from './ui.js'; import * as ui from './ui.js';
import {clearTerminal, downloadTerminalOutput, fitTerminal} from './terminal.js'; import {clearTerminal, downloadTerminalOutput, fitTerminal} from './terminal.js';
import {debounce, isMobile} from './utils.js'; import {debounce, isMobile} from './utils.js';
import {getAuthHeaders, handleResponse} from './api.js'; // Import auth functions
// A flag to track if charts have been initialized // A flag to track if charts have been initialized
let chartsInitialized = false; let chartsInitialized = false;
@@ -60,7 +60,6 @@ export function setupEventListeners() {
console.log("Event listeners already attached. Skipping."); console.log("Event listeners already attached. Skipping.");
return; return;
} }
console.log("Attaching event listeners...");
// --- Terminal Controls --- // --- Terminal Controls ---
dom.clearButton.addEventListener('click', clearTerminal); dom.clearButton.addEventListener('click', clearTerminal);
@@ -189,5 +188,4 @@ export function setupEventListeners() {
window.addEventListener('resize', debounce(ui.handleResize, 150)); window.addEventListener('resize', debounce(ui.handleResize, 150));
listenersAttached = true; listenersAttached = true;
console.log("Event listeners attached successfully.");
} }

View File

@@ -55,16 +55,12 @@ const confirmPasswordInput = document.getElementById('confirm-password');
function onWsOpen() { function onWsOpen() {
updateWebsocketStatus(true); updateWebsocketStatus(true);
if (term) { console.log('Connected to WebSocket Server');
term.write('\x1b[32mConnected to WebSocket Server\x1b[0m\r\n');
}
} }
function onWsClose() { function onWsClose() {
updateWebsocketStatus(false); updateWebsocketStatus(false);
if (term) { console.warn('Connection closed. Reconnecting...');
term.write('\r\n\x1b[31mConnection closed. Reconnecting...\x1b[0m\r\n');
}
setTimeout(connect, 2000); setTimeout(connect, 2000);
} }

View File

@@ -7,7 +7,11 @@ CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_UART_ISR_IN_IRAM=y CONFIG_UART_ISR_IN_IRAM=y
CONFIG_HTTPD_MAX_REQ_HDR_LEN=2048
CONFIG_HTTPD_MAX_URI_LEN=1024
CONFIG_HTTPD_WS_SUPPORT=y CONFIG_HTTPD_WS_SUPPORT=y
CONFIG_ESP_HTTPS_SERVER_ENABLE=y
CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=20 CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=20
CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=40 CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=40
CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=40 CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=40