mirror of
https://github.com/EyeTrackVR/OpenIris.git
synced 2025-11-04 15:39:42 +08:00
Add mode switching without reflash
This commit is contained in:
parent
5da262c8da
commit
c5906f4758
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
PythonExamples/__pycache__/mode_switch_test.cpython-311.pyc
|
||||
@ -1,10 +1,13 @@
|
||||
#include "CommandManager.hpp"
|
||||
#include "data/DeviceMode/DeviceMode.hpp"
|
||||
#include "tasks/tasks.hpp"
|
||||
|
||||
|
||||
CommandManager::CommandManager(ProjectConfig* deviceConfig)
|
||||
: deviceConfig(deviceConfig) {}
|
||||
|
||||
const CommandType CommandManager::getCommandType(JsonVariant& command) {
|
||||
if (!command.containsKey("command"))
|
||||
if (!command["command"].is<const char*>())
|
||||
return CommandType::None;
|
||||
|
||||
if (auto search = commandMap.find(command["command"]);
|
||||
@ -15,11 +18,11 @@ const CommandType CommandManager::getCommandType(JsonVariant& command) {
|
||||
}
|
||||
|
||||
bool CommandManager::hasDataField(JsonVariant& command) {
|
||||
return command.containsKey("data");
|
||||
return command["data"].is<JsonObject>();
|
||||
}
|
||||
|
||||
void CommandManager::handleCommands(CommandsPayload commandsPayload) {
|
||||
if (!commandsPayload.data.containsKey("commands")) {
|
||||
if (!commandsPayload.data["commands"].is<JsonArray>()) {
|
||||
log_e("Json data sent not supported, lacks commands field");
|
||||
return;
|
||||
}
|
||||
@ -41,12 +44,12 @@ void CommandManager::handleCommand(JsonVariant command) {
|
||||
// malformed command, lacked data field
|
||||
break;
|
||||
|
||||
if (!command["data"].containsKey("ssid") ||
|
||||
!command["data"].containsKey("password"))
|
||||
if (!command["data"]["ssid"].is<const char*>() ||
|
||||
!command["data"]["password"].is<const char*>())
|
||||
break;
|
||||
|
||||
std::string customNetworkName = "main";
|
||||
if (command["data"].containsKey("network_name"))
|
||||
if (command["data"]["network_name"].is<const char*>())
|
||||
customNetworkName = command["data"]["network_name"].as<std::string>();
|
||||
|
||||
this->deviceConfig->setWifiConfig(customNetworkName,
|
||||
@ -55,6 +58,16 @@ void CommandManager::handleCommand(JsonVariant command) {
|
||||
0, // channel, should this be zero?
|
||||
0, // power, should this be zero?
|
||||
false, false);
|
||||
|
||||
DeviceModeManager* deviceModeManager = DeviceModeManager::getInstance();
|
||||
if (deviceModeManager) {
|
||||
deviceModeManager->setHasWiFiCredentials(true);
|
||||
|
||||
deviceModeManager->setMode(DeviceMode::WIFI_MODE);
|
||||
log_i("[CommandManager] Switching to WiFi mode after receiving credentials");
|
||||
|
||||
OpenIrisTasks::ScheduleRestart(2000);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
@ -62,7 +75,7 @@ void CommandManager::handleCommand(JsonVariant command) {
|
||||
if (!this->hasDataField(command))
|
||||
break;
|
||||
|
||||
if (!command["data"].containsKey("hostname") ||
|
||||
if (!command["data"]["hostname"].is<const char*>() ||
|
||||
!strlen(command["data"]["hostname"]))
|
||||
break;
|
||||
|
||||
@ -75,6 +88,60 @@ void CommandManager::handleCommand(JsonVariant command) {
|
||||
Serial.println("PONG \n\r");
|
||||
break;
|
||||
}
|
||||
case CommandType::SWITCH_MODE: {
|
||||
if (!this->hasDataField(command))
|
||||
break;
|
||||
|
||||
if (!command["data"]["mode"].is<int>())
|
||||
break;
|
||||
|
||||
int modeValue = command["data"]["mode"];
|
||||
DeviceMode newMode = static_cast<DeviceMode>(modeValue);
|
||||
DeviceMode currentMode;
|
||||
|
||||
DeviceModeManager* deviceModeManager = DeviceModeManager::getInstance();
|
||||
if (deviceModeManager) {
|
||||
currentMode = deviceModeManager->getMode();
|
||||
|
||||
// If switching to USB mode from WiFi or AP mode, disconnect WiFi immediately
|
||||
if (newMode == DeviceMode::USB_MODE &&
|
||||
(currentMode == DeviceMode::WIFI_MODE || currentMode == DeviceMode::AP_MODE)) {
|
||||
log_i("[CommandManager] Immediately switching to USB mode");
|
||||
WiFi.disconnect(true);
|
||||
}
|
||||
|
||||
deviceModeManager->setMode(newMode);
|
||||
log_i("[CommandManager] Switching to mode: %d", modeValue);
|
||||
|
||||
// Only schedule a restart if not switching to USB mode during WiFi/AP initialization
|
||||
if (!(newMode == DeviceMode::USB_MODE &&
|
||||
(currentMode == DeviceMode::WIFI_MODE || currentMode == DeviceMode::AP_MODE) &&
|
||||
wifiStateManager.getCurrentState() == WiFiState_e::WiFiState_Connecting)) {
|
||||
OpenIrisTasks::ScheduleRestart(2000);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case CommandType::WIPE_WIFI_CREDS: {
|
||||
|
||||
auto networks = this->deviceConfig->getWifiConfigs();
|
||||
for (auto& network : networks) {
|
||||
this->deviceConfig->deleteWifiConfig(network.name, false);
|
||||
}
|
||||
|
||||
DeviceModeManager* deviceModeManager = DeviceModeManager::getInstance();
|
||||
if (deviceModeManager) {
|
||||
deviceModeManager->setHasWiFiCredentials(false);
|
||||
|
||||
deviceModeManager->setMode(DeviceMode::USB_MODE);
|
||||
log_i("[CommandManager] Switching to USB mode after wiping credentials");
|
||||
|
||||
OpenIrisTasks::ScheduleRestart(2000);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@ -10,6 +10,8 @@ enum CommandType {
|
||||
PING,
|
||||
SET_WIFI,
|
||||
SET_MDNS,
|
||||
SWITCH_MODE,
|
||||
WIPE_WIFI_CREDS,
|
||||
};
|
||||
|
||||
struct CommandsPayload {
|
||||
@ -22,6 +24,8 @@ class CommandManager {
|
||||
{"ping", CommandType::PING},
|
||||
{"set_wifi", CommandType::SET_WIFI},
|
||||
{"set_mdns", CommandType::SET_MDNS},
|
||||
{"switch_mode", CommandType::SWITCH_MODE},
|
||||
{"wipe_wifi_creds", CommandType::WIPE_WIFI_CREDS},
|
||||
};
|
||||
|
||||
ProjectConfig* deviceConfig;
|
||||
|
||||
62
ESP/lib/src/data/DeviceMode/DeviceMode.cpp
Normal file
62
ESP/lib/src/data/DeviceMode/DeviceMode.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
#include "DeviceMode.hpp"
|
||||
|
||||
DeviceModeManager* DeviceModeManager::instance = nullptr;
|
||||
|
||||
DeviceModeManager::DeviceModeManager() : currentMode(DeviceMode::USB_MODE) {}
|
||||
|
||||
DeviceModeManager::~DeviceModeManager() {
|
||||
preferences.end();
|
||||
}
|
||||
|
||||
void DeviceModeManager::init() {
|
||||
preferences.begin(PREF_NAMESPACE, false);
|
||||
|
||||
// Load the saved mode or use default (USB_MODE)
|
||||
int savedMode = preferences.getInt(MODE_KEY, static_cast<int>(DeviceMode::AUTO_MODE));
|
||||
currentMode = static_cast<DeviceMode>(savedMode);
|
||||
|
||||
// If in AUTO_MODE, determine the appropriate mode based on saved credentials
|
||||
if (currentMode == DeviceMode::AUTO_MODE) {
|
||||
currentMode = determineMode();
|
||||
}
|
||||
|
||||
log_i("[DeviceModeManager] Initialized with mode: %d", static_cast<int>(currentMode));
|
||||
}
|
||||
|
||||
DeviceMode DeviceModeManager::getMode() {
|
||||
return currentMode;
|
||||
}
|
||||
|
||||
void DeviceModeManager::setMode(DeviceMode mode) {
|
||||
currentMode = mode;
|
||||
preferences.putInt(MODE_KEY, static_cast<int>(mode));
|
||||
log_i("[DeviceModeManager] Mode set to: %d", static_cast<int>(mode));
|
||||
}
|
||||
|
||||
bool DeviceModeManager::hasWiFiCredentials() {
|
||||
return preferences.getBool(HAS_WIFI_CREDS_KEY, false);
|
||||
}
|
||||
|
||||
void DeviceModeManager::setHasWiFiCredentials(bool hasCredentials) {
|
||||
preferences.putBool(HAS_WIFI_CREDS_KEY, hasCredentials);
|
||||
log_i("[DeviceModeManager] WiFi credentials status set to: %d", hasCredentials);
|
||||
}
|
||||
|
||||
DeviceMode DeviceModeManager::determineMode() {
|
||||
// If WiFi credentials are saved, use WiFi mode, otherwise use AP mode
|
||||
return hasWiFiCredentials() ? DeviceMode::WIFI_MODE : DeviceMode::AP_MODE;
|
||||
}
|
||||
|
||||
DeviceModeManager* DeviceModeManager::getInstance() {
|
||||
if (instance == nullptr) {
|
||||
createInstance();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
void DeviceModeManager::createInstance() {
|
||||
if (instance == nullptr) {
|
||||
instance = new DeviceModeManager();
|
||||
instance->init();
|
||||
}
|
||||
}
|
||||
47
ESP/lib/src/data/DeviceMode/DeviceMode.hpp
Normal file
47
ESP/lib/src/data/DeviceMode/DeviceMode.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
#ifndef DEVICE_MODE_HPP
|
||||
#define DEVICE_MODE_HPP
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Preferences.h>
|
||||
#include <string>
|
||||
|
||||
// Enum to represent the device operating mode
|
||||
enum class DeviceMode {
|
||||
USB_MODE, // Device operates in USB mode only
|
||||
WIFI_MODE, // Device operates in WiFi mode only
|
||||
AP_MODE, // Device operates in AP mode with serial commands enabled
|
||||
AUTO_MODE // Device automatically selects mode based on saved credentials
|
||||
};
|
||||
|
||||
class DeviceModeManager {
|
||||
private:
|
||||
static DeviceModeManager* instance;
|
||||
Preferences preferences;
|
||||
DeviceMode currentMode;
|
||||
const char* PREF_NAMESPACE = "device_mode";
|
||||
const char* MODE_KEY = "mode";
|
||||
const char* HAS_WIFI_CREDS_KEY = "has_wifi_creds";
|
||||
|
||||
public:
|
||||
DeviceModeManager();
|
||||
~DeviceModeManager();
|
||||
|
||||
static DeviceModeManager* getInstance();
|
||||
|
||||
static void createInstance();
|
||||
|
||||
void init();
|
||||
|
||||
DeviceMode getMode();
|
||||
|
||||
void setMode(DeviceMode mode);
|
||||
|
||||
bool hasWiFiCredentials();
|
||||
|
||||
void setHasWiFiCredentials(bool hasCredentials);
|
||||
|
||||
DeviceMode determineMode();
|
||||
};
|
||||
|
||||
#endif // DEVICE_MODE_HPP
|
||||
@ -1,9 +1,32 @@
|
||||
#include "SerialManager.hpp"
|
||||
#include "data/DeviceMode/DeviceMode.hpp"
|
||||
|
||||
SerialManager::SerialManager(CommandManager* commandManager)
|
||||
: commandManager(commandManager) {}
|
||||
: commandManager(commandManager) {}
|
||||
|
||||
void SerialManager::sendQuery(QueryAction action,
|
||||
QueryStatus status,
|
||||
std::string additional_info) {
|
||||
JsonDocument doc;
|
||||
doc["action"] = queryActionMap.at(action);
|
||||
doc["status"] = static_cast<int>(status);
|
||||
if (!additional_info.empty()) {
|
||||
doc["info"] = additional_info;
|
||||
}
|
||||
|
||||
String output;
|
||||
serializeJson(doc, output);
|
||||
Serial.println(output);
|
||||
}
|
||||
|
||||
void SerialManager::checkUSBMode() {
|
||||
DeviceMode currentMode = DeviceModeManager::getInstance()->getMode();
|
||||
if (currentMode == DeviceMode::USB_MODE) {
|
||||
log_i("[SerialManager] USB mode active - auto-streaming enabled");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ETVR_EYE_TRACKER_USB_API
|
||||
void SerialManager::send_frame() {
|
||||
if (!last_frame)
|
||||
last_frame = esp_timer_get_time();
|
||||
@ -49,7 +72,6 @@ void SerialManager::send_frame() {
|
||||
log_d("Size: %uKB, Time: %ums (%ifps)\n", len / 1024, latency,
|
||||
1000 / latency);
|
||||
}
|
||||
#endif
|
||||
|
||||
void SerialManager::init() {
|
||||
#ifdef SERIAL_MANAGER_USE_HIGHER_FREQUENCY
|
||||
@ -58,25 +80,28 @@ void SerialManager::init() {
|
||||
if (SERIAL_FLUSH_ENABLED) {
|
||||
Serial.flush();
|
||||
}
|
||||
|
||||
// Check if we're in USB mode and set up accordingly
|
||||
checkUSBMode();
|
||||
}
|
||||
|
||||
void SerialManager::run() {
|
||||
// Process any available commands first to ensure mode changes are detected immediately
|
||||
if (Serial.available()) {
|
||||
JsonDocument doc;
|
||||
DeserializationError deserializationError = deserializeJson(doc, Serial);
|
||||
|
||||
if (deserializationError) {
|
||||
log_e("Command deserialization failed: %s", deserializationError.c_str());
|
||||
|
||||
return;
|
||||
} else {
|
||||
CommandsPayload commands = {doc};
|
||||
this->commandManager->handleCommands(commands);
|
||||
}
|
||||
|
||||
CommandsPayload commands = {doc};
|
||||
this->commandManager->handleCommands(commands);
|
||||
}
|
||||
#ifdef ETVR_EYE_TRACKER_USB_API
|
||||
else {
|
||||
|
||||
// Check if we're in USB mode and automatically send frames
|
||||
DeviceMode currentMode = DeviceModeManager::getInstance()->getMode();
|
||||
if (currentMode == DeviceMode::USB_MODE) {
|
||||
this->send_frame();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -35,12 +35,10 @@ class SerialManager {
|
||||
esp_err_t err = ESP_OK;
|
||||
CommandManager* commandManager;
|
||||
|
||||
#ifdef ETVR_EYE_TRACKER_USB_API
|
||||
int64_t last_frame = 0;
|
||||
long last_request_time = 0;
|
||||
|
||||
void send_frame();
|
||||
#endif
|
||||
|
||||
public:
|
||||
SerialManager(CommandManager* commandManager);
|
||||
@ -49,6 +47,7 @@ class SerialManager {
|
||||
std::string additional_info);
|
||||
void init();
|
||||
void run();
|
||||
void checkUSBMode();
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -2,6 +2,7 @@
|
||||
#include <WiFi.h>
|
||||
#include "data/StateManager/StateManager.hpp"
|
||||
#include "data/utilities/helpers.hpp"
|
||||
#include "data/DeviceMode/DeviceMode.hpp"
|
||||
|
||||
WiFiHandler::WiFiHandler(ProjectConfig& configManager,
|
||||
const std::string& ssid,
|
||||
@ -92,6 +93,7 @@ void WiFiHandler::begin() {
|
||||
void WiFiHandler::adhoc(const std::string& ssid,
|
||||
uint8_t channel,
|
||||
const std::string& password) {
|
||||
|
||||
wifiStateManager.setState(WiFiState_e::WiFiState_ADHOC);
|
||||
|
||||
log_i("\n[INFO]: Configuring access point...\n");
|
||||
@ -169,6 +171,20 @@ bool WiFiHandler::iniSTA(const std::string& ssid,
|
||||
currentMillis = millis();
|
||||
log_i(".");
|
||||
log_d("Progress: %d \n\r", progress);
|
||||
|
||||
// Check if mode has been changed to USB mode during connection attempt
|
||||
DeviceModeManager* deviceModeManager = DeviceModeManager::getInstance();
|
||||
if (deviceModeManager && deviceModeManager->getMode() == DeviceMode::USB_MODE) {
|
||||
log_i("[WiFiHandler] Mode changed to USB during connection, aborting WiFi setup");
|
||||
WiFi.disconnect(true);
|
||||
wifiStateManager.setState(WiFiState_e::WiFiState_Disconnected);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Serial.available()) {
|
||||
yield();
|
||||
}
|
||||
|
||||
if ((currentMillis - startingMillis) >= connectionTimeout) {
|
||||
wifiStateManager.setState(WiFiState_e::WiFiState_Error);
|
||||
log_e("Connection to: %s TIMEOUT \n\r", ssid.c_str());
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#include <openiris.hpp>
|
||||
#include "data/DeviceMode/DeviceMode.hpp"
|
||||
/**
|
||||
* @brief ProjectConfig object
|
||||
* @brief This is the main configuration object for the project
|
||||
@ -38,10 +39,34 @@ StreamServer streamServer;
|
||||
#endif // SIM_ENABLED
|
||||
|
||||
void etvr_eye_tracker_web_init() {
|
||||
// Check if mode has been changed to USB mode before starting network initialization
|
||||
DeviceModeManager* deviceModeManager = DeviceModeManager::getInstance();
|
||||
if (deviceModeManager && deviceModeManager->getMode() == DeviceMode::USB_MODE) {
|
||||
log_i("[SETUP]: Mode changed to USB before network initialization, aborting");
|
||||
WiFi.disconnect(true);
|
||||
return;
|
||||
}
|
||||
|
||||
log_d("[SETUP]: Starting Network Handler");
|
||||
deviceConfig.attach(mdnsHandler);
|
||||
|
||||
// Check mode again before starting WiFi
|
||||
if (deviceModeManager && deviceModeManager->getMode() == DeviceMode::USB_MODE) {
|
||||
log_i("[SETUP]: Mode changed to USB before WiFi initialization, aborting");
|
||||
WiFi.disconnect(true);
|
||||
return;
|
||||
}
|
||||
|
||||
log_d("[SETUP]: Starting WiFi Handler");
|
||||
wifiHandler.begin();
|
||||
|
||||
// Check mode again before starting MDNS
|
||||
if (deviceModeManager && deviceModeManager->getMode() == DeviceMode::USB_MODE) {
|
||||
log_i("[SETUP]: Mode changed to USB before MDNS initialization, aborting");
|
||||
WiFi.disconnect(true);
|
||||
return;
|
||||
}
|
||||
|
||||
log_d("[SETUP]: Starting MDNS Handler");
|
||||
mdnsHandler.startMDNS();
|
||||
|
||||
@ -85,6 +110,9 @@ void setup() {
|
||||
Serial.begin(115200);
|
||||
Logo::printASCII();
|
||||
ledManager.begin();
|
||||
|
||||
DeviceModeManager::createInstance();
|
||||
DeviceModeManager* deviceModeManager = DeviceModeManager::getInstance();
|
||||
|
||||
#ifdef CONFIG_CAMERA_MODULE_SWROOM_BABBLE_S3 // Set IR emitter strength to 100%.
|
||||
const int ledPin = 1; // Replace this with a command endpoint eventually.
|
||||
@ -104,11 +132,20 @@ void setup() {
|
||||
|
||||
serialManager.init();
|
||||
|
||||
#ifndef ETVR_EYE_TRACKER_USB_API
|
||||
etvr_eye_tracker_web_init();
|
||||
#else // ETVR_EYE_TRACKER_WEB_API
|
||||
WiFi.disconnect(true);
|
||||
#endif // ETVR_EYE_TRACKER_WEB_API
|
||||
DeviceMode currentMode = deviceModeManager->getMode();
|
||||
|
||||
if (currentMode == DeviceMode::WIFI_MODE) {
|
||||
// Initialize WiFi mode
|
||||
etvr_eye_tracker_web_init();
|
||||
log_i("[SETUP]: Initialized in WiFi mode");
|
||||
} else if (currentMode == DeviceMode::AP_MODE) {
|
||||
// Initialize AP mode with serial commands enabled
|
||||
etvr_eye_tracker_web_init();
|
||||
log_i("[SETUP]: Initialized in AP mode with serial commands enabled");
|
||||
} else {
|
||||
WiFi.disconnect(true);
|
||||
log_i("[SETUP]: Initialized in USB mode");
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
161
PythonExamples/mode_switch_test.py
Normal file
161
PythonExamples/mode_switch_test.py
Normal file
@ -0,0 +1,161 @@
|
||||
#!/usr/bin/env python3
|
||||
import serial
|
||||
import json
|
||||
import time
|
||||
import requests
|
||||
import argparse
|
||||
import socket
|
||||
|
||||
class OpenIrisModeTester:
|
||||
def __init__(self, port, baudrate=115200, timeout=5):
|
||||
self.port = port
|
||||
self.baudrate = baudrate
|
||||
self.timeout = timeout
|
||||
self.serial_conn = None
|
||||
self.device_ip = None
|
||||
self.device_port = None
|
||||
|
||||
def connect_serial(self):
|
||||
try:
|
||||
self.serial_conn = serial.Serial(self.port, self.baudrate, timeout=self.timeout)
|
||||
self.flush_serial_logs()
|
||||
print(f"Connected to {self.port} at {self.baudrate} baud")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"Error connecting to serial port: {e}")
|
||||
return False
|
||||
|
||||
def flush_serial_logs(self):
|
||||
if self.serial_conn and self.serial_conn.is_open:
|
||||
self.serial_conn.reset_input_buffer()
|
||||
self.serial_conn.reset_output_buffer()
|
||||
print("Serial logs flushed.")
|
||||
|
||||
def send_command(self, command_obj):
|
||||
if not self.serial_conn:
|
||||
print("Serial connection not established")
|
||||
return False
|
||||
|
||||
try:
|
||||
command_json = json.dumps(command_obj)
|
||||
self.serial_conn.write(command_json.encode() + b'\n')
|
||||
time.sleep(0.5)
|
||||
|
||||
response = ""
|
||||
start_time = time.time()
|
||||
while (time.time() - start_time) < self.timeout:
|
||||
if self.serial_conn.in_waiting:
|
||||
line = self.serial_conn.readline().decode('utf-8', errors='replace').strip()
|
||||
if line:
|
||||
response += line
|
||||
try:
|
||||
json.loads(response)
|
||||
return response
|
||||
except json.JSONDecodeError:
|
||||
pass
|
||||
time.sleep(0.1)
|
||||
|
||||
return response if response else None
|
||||
except Exception as e:
|
||||
print(f"Error sending command: {e}")
|
||||
return None
|
||||
|
||||
def set_wifi_credentials(self, ssid, password):
|
||||
command = {"commands": [{"command": "set_wifi", "data": {"ssid": ssid, "password": password, "network_name": "main"}}]}
|
||||
print("Sending WiFi credentials...")
|
||||
response = self.send_command(command)
|
||||
print(f"Response: {response}")
|
||||
return response
|
||||
|
||||
def wipe_wifi_credentials(self):
|
||||
command = {"commands": [{"command": "wipe_wifi_creds"}]}
|
||||
print("Wiping WiFi credentials...")
|
||||
response = self.send_command(command)
|
||||
print(f"Response: {response}")
|
||||
return response
|
||||
|
||||
def discover_device(self, hostname="openiristracker.local"):
|
||||
try:
|
||||
self.device_ip = socket.gethostbyname(hostname)
|
||||
self.device_port = 80
|
||||
print(f"Device found at {self.device_ip}:{self.device_port}")
|
||||
return True
|
||||
except socket.error as e:
|
||||
print(f"Hostname resolution failed: {e}")
|
||||
return False
|
||||
|
||||
def test_wifi_api(self):
|
||||
if not self.device_ip:
|
||||
print("Device IP not available. Discover device first.")
|
||||
return False
|
||||
|
||||
try:
|
||||
url = f"http://{self.device_ip}:81/control/builtin/command/ping"
|
||||
response = requests.get(url, timeout=5)
|
||||
if response.status_code == 200:
|
||||
print("WiFi API test successful!")
|
||||
return True
|
||||
else:
|
||||
print(f"WiFi API test failed with status code: {response.status_code}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"Error testing WiFi API: {e}")
|
||||
return False
|
||||
|
||||
def close(self):
|
||||
if self.serial_conn and self.serial_conn.is_open:
|
||||
self.serial_conn.close()
|
||||
|
||||
|
||||
def run_test(port, ssid, password):
|
||||
tester = OpenIrisModeTester(port)
|
||||
|
||||
try:
|
||||
if not tester.connect_serial():
|
||||
return
|
||||
|
||||
print("\n=== Step 1: Setting WiFi credentials ===")
|
||||
tester.set_wifi_credentials(ssid, password)
|
||||
print("Device will restart. Waiting 10 seconds...")
|
||||
time.sleep(10)
|
||||
|
||||
tester.connect_serial()
|
||||
tester.flush_serial_logs()
|
||||
|
||||
print("\n=== Step 2: Discovering device on network ===")
|
||||
if tester.discover_device():
|
||||
print("\n=== Step 3: Testing WiFi API ===")
|
||||
tester.test_wifi_api()
|
||||
|
||||
tester.flush_serial_logs()
|
||||
|
||||
print("\n=== Step 4: Wiping WiFi credentials ===")
|
||||
tester.wipe_wifi_credentials()
|
||||
print("Device will restart in USB mode. Waiting 10 seconds...")
|
||||
time.sleep(10)
|
||||
|
||||
tester.connect_serial()
|
||||
tester.flush_serial_logs()
|
||||
|
||||
print("\n=== Step 5: Verifying USB mode ===")
|
||||
ping_command = {"commands": [{"command": "ping"}]}
|
||||
print("Device is most likely booting, waiting 10 seconds...")
|
||||
time.sleep(10)
|
||||
|
||||
response = tester.send_command(ping_command)
|
||||
print(f"Response: {response}")
|
||||
|
||||
tester.flush_serial_logs()
|
||||
|
||||
finally:
|
||||
tester.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Test OpenIris mode switching functionality")
|
||||
parser.add_argument("--port", required=True, help="Serial port (e.g., COM3 or /dev/ttyUSB0)")
|
||||
parser.add_argument("--ssid", required=True, help="WiFi SSID")
|
||||
parser.add_argument("--password", required=True, help="WiFi password")
|
||||
|
||||
args = parser.parse_args()
|
||||
run_test(args.port, args.ssid, args.password)
|
||||
Loading…
Reference in New Issue
Block a user