From 2f960a8372fe2546537677fc656a51cdac5ca7a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Ole=20Sch=C3=BCmann?= Date: Sat, 19 Apr 2025 12:17:03 +0700 Subject: [PATCH] Add serial interface for initial configuratio (#664) * add SerialReader * fix SerialReader * add config upload script * add serial command to print ip address * update serial script to save configuration and reset after upload * fix updater * fix updater * serial config fixes * serial config fixes * fix wifi static example configuration * add readme for sendcfg.py --- .gitignore | 3 +- README.md | 2 +- clion/CMakeLists.txt | 1 + scripts/sendcfg/README.md | 47 +++ .../example_configurations/m5stack-w5500.json | 4 + .../sendcfg/example_configurations/wifi.json | 5 + .../wifi_static_ip.json | 12 + scripts/sendcfg/sendcfg.py | 57 ++++ src/Config.h | 2 +- src/RestartReason.h | 3 + src/SerialReader.cpp | 86 +++++ src/SerialReader.h | 24 ++ src/main.cpp | 11 + src/util/NetworkDeviceInstantiator.cpp | 320 +++++++++--------- 14 files changed, 414 insertions(+), 163 deletions(-) create mode 100644 scripts/sendcfg/README.md create mode 100644 scripts/sendcfg/example_configurations/m5stack-w5500.json create mode 100644 scripts/sendcfg/example_configurations/wifi.json create mode 100644 scripts/sendcfg/example_configurations/wifi_static_ip.json create mode 100644 scripts/sendcfg/sendcfg.py create mode 100644 src/SerialReader.cpp create mode 100644 src/SerialReader.h diff --git a/.gitignore b/.gitignore index 449c400..ae61ad0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .dummy .idea +scripts/.idea build debug release @@ -28,4 +29,4 @@ sdkconfig # NodeJS en pnpm .pnpm node_modules -pnpm-lock.yaml \ No newline at end of file +pnpm-lock.yaml diff --git a/README.md b/README.md index afdfc26..2b0547a 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ The Nuki Hub software runs on a ESP32 module and acts as a bridge between Nuki devices and a Home Automation platform.

It communicates with a Nuki Lock and/or Opener through Bluetooth (BLE) and uses MQTT to integrate with other systems.
-
+
It exposes the lock state (and much more) through MQTT and allows executing commands like locking and unlocking as well as changing the Nuki Lock/Opener configuration through MQTT.
***Nuki Hub does not integrate with the Nuki mobile app, it can't register itself as a bridge in the official Nuki mobile app.*** diff --git a/clion/CMakeLists.txt b/clion/CMakeLists.txt index a2cb9b9..0584701 100644 --- a/clion/CMakeLists.txt +++ b/clion/CMakeLists.txt @@ -57,6 +57,7 @@ set(SRCFILES ../src/EspMillis.h ../src/enums/NukiPinState.h ../src/networkDevices/Tlk110Definitions.h + ../src/SerialReader.cpp ) file(GLOB_RECURSE SRCFILESREC diff --git a/scripts/sendcfg/README.md b/scripts/sendcfg/README.md new file mode 100644 index 0000000..e80961c --- /dev/null +++ b/scripts/sendcfg/README.md @@ -0,0 +1,47 @@ + +## About + +sendcfg.py allows to send the initial device configuration via the serial interface.
+This allows automated configuration without prior connecting to the ESPs access point. It could be especially useful if an ESP with LAN hardware is used, and no connection via Wifi is desired. +In this case, sendcfg allows to configure the device without storing Wifi credentials on the device.
+This feature is for advanced users only. In certain cases it's necessary to check the C++ code for the desired configuration value, e. g. the network hardware setting. + +## Usage + +Calling the script itself is simple: + +sendcfg.py + +Prior to running the script, pyserial has to be installed via pip. +The ESP will only accept a configuration via serial as long as the device in not configured yet, meaning the ESP Wifi access point is open. +Once the ESP is connected to a network, it will ignore any commands send via the serial interface.

+To generate a configuration a configuration file, the export configuration function can be used. +After exporting a configuration, it can be edited to the required values. Usually only specific valus like +the IP address, Wifi credentials or network hardware are intended to be set. In that case all other configuration values can be deleted from the configuration.
+For example configurations, see the "example_configurations" subdirectory. + +## Common configuration entries + +All configuration entries are saved in JSON format. + +- wifiSSID: The SSID of the Wifi network +- wifiPass: The pre-shared key of the Wifi network +- dhcpena: Enable ("1") or disable ("0") DHCP +- hostname: Host name of the device +- mqttbroker: Address of the MQTT broker +- mqttpath: MQTT Path used for this device +- ipaddr: Static IP address +- ipsub: Subnet mask (e. g. 255.255.255.0) +- ipgtw: Gateway used to connect to the internet +- dnssrv: DNS server used to resolve domain names +- nwhw: Network hardware used. See WebCfgServer.cpp, method getNetworkDetectionOptions for possible values. +At the time of writing: 1=Wifi, 2=Generic W5500, 3 = M5Stack Atom POE (W5500), 4 = "Olimex ESP32-POE / ESP-POE-ISO, 5 = WT32-ETH01, 6 = M5STACK PoESP32 Unit, 7 = LilyGO T-ETH-POE, 8 = GL-S10, 9 = ETH01-Evo, 10 = M5Stack Atom POE S3 (W5500), 11 = Custom LAN module, 12 = LilyGO T-ETH ELite, 13 = Waveshare ESP32-S3-ETH / ESP32-S3-ETH-POE, 14 = LilyGO T-ETH-Lite-ESP32S3 + +## Serial commands + +The serial interface supports a few commands in addition to receiving the configuration: + +- uptime: Prints the uptime in seconds +- printerror: Prints the last error code returned from deserializing the configuration +- printcfgstr: Prints the raw configuration string received via the serial interface +- printcfg: Prints the deserialized configuration that is stored in RAM \ No newline at end of file diff --git a/scripts/sendcfg/example_configurations/m5stack-w5500.json b/scripts/sendcfg/example_configurations/m5stack-w5500.json new file mode 100644 index 0000000..6693d7f --- /dev/null +++ b/scripts/sendcfg/example_configurations/m5stack-w5500.json @@ -0,0 +1,4 @@ +{ + "hostname": "nuki-atom-w5500", + "nwhw": "3" +} \ No newline at end of file diff --git a/scripts/sendcfg/example_configurations/wifi.json b/scripts/sendcfg/example_configurations/wifi.json new file mode 100644 index 0000000..b650792 --- /dev/null +++ b/scripts/sendcfg/example_configurations/wifi.json @@ -0,0 +1,5 @@ +{ + "hostname": "nuki-123456", + "wifiSSID": "YOUR_SSID", + "wifiPass": "YOUR_WIFI_PRESHARED_KEY" +} \ No newline at end of file diff --git a/scripts/sendcfg/example_configurations/wifi_static_ip.json b/scripts/sendcfg/example_configurations/wifi_static_ip.json new file mode 100644 index 0000000..8596f70 --- /dev/null +++ b/scripts/sendcfg/example_configurations/wifi_static_ip.json @@ -0,0 +1,12 @@ +{ + "dhcpena": "0", + "hostname": "nuki-static", + "mqttbroker": "192.168.8.100", + "mqttpath": "nuki-1234", + "ipaddr" : "192.168.8.25", + "ipsub" : "255.255.255.0", + "ipgtw" : "192.168.8.1", + "dnssrv" : "1.1.1.1", + "wifiSSID": "YOUR_SSID", + "wifiPass": "YOUR_WIFI_PRESHARED_KEY" +} \ No newline at end of file diff --git a/scripts/sendcfg/sendcfg.py b/scripts/sendcfg/sendcfg.py new file mode 100644 index 0000000..a6206a0 --- /dev/null +++ b/scripts/sendcfg/sendcfg.py @@ -0,0 +1,57 @@ +import serial +import time +import sys +import os + +def send_configuration(file_path, port, baudrate=9600, delay=0.1): + try: + # Open serial port + with serial.Serial(port, baudrate, timeout=1) as ser: + print(f"Opened serial port {port} at {baudrate} baud.") + + ser.write("-- NUKI HUB CONFIG START --\n".encode('utf-8')) + + # Read configuration file and send line by line + with open(file_path, 'r') as file: + for line in file: + ser.write(line.encode('utf-8')) # Send line + ser.write("\n".encode('utf-8')) # Send new line + print(f"Sent: {line.strip()}") + time.sleep(delay) # Optional delay between lines + + ser.write("-- NUKI HUB CONFIG END --\n".encode('utf-8')) + time.sleep(delay) + print("Configuration sent.") + + # persist previously sent configuration + ser.write("savecfg\n".encode('utf-8')) + time.sleep(delay) + print("Configuration saved.") + + # restart ESP + ser.write("reset\n".encode('utf-8')) + print("ESP restarted.") + time.sleep(1) + + except serial.SerialException as e: + print(f"Serial error: {e}") + except FileNotFoundError: + print(f"File not found: {file_path}") + except Exception as e: + print(f"Unexpected error: {e}") + +if __name__ == "__main__": + + if(len(sys.argv) < 2): + print("Usage: sendcfg.py ") + sys.exit(1) + + config_file = sys.argv[2] + if(not os.path.isfile(config_file)): + print(f"File not found: {config_file}") + sys.exit(2) + + serial_port = sys.argv[1] + baud_rate = 115200 + + send_configuration(config_file, serial_port, baud_rate) diff --git a/src/Config.h b/src/Config.h index 95d5acd..9b19b18 100644 --- a/src/Config.h +++ b/src/Config.h @@ -5,7 +5,7 @@ #define NUKI_HUB_VERSION "9.11" #define NUKI_HUB_VERSION_INT (uint32_t)911 #define NUKI_HUB_BUILD "unknownbuildnr" -#define NUKI_HUB_DATE "2025-04-06" +#define NUKI_HUB_DATE "2025-04-19" #define GITHUB_LATEST_RELEASE_URL (char*)"https://github.com/technyon/nuki_hub/releases/latest" #define GITHUB_OTA_MANIFEST_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/manifest.json" diff --git a/src/RestartReason.h b/src/RestartReason.h index f992615..cba9a4a 100644 --- a/src/RestartReason.h +++ b/src/RestartReason.h @@ -4,6 +4,7 @@ enum class RestartReason { RequestedViaMqtt, RequestedViaWebServer, + RequestedViaSerial, BLEError, BLEBeaconWatchdog, RestartOnDisconnectWatchdog, @@ -72,6 +73,8 @@ inline static String getRestartReason() return "RequestedViaMqtt"; case RestartReason::RequestedViaWebServer: return "RequestedViaWebServer"; + case RestartReason::RequestedViaSerial: + return "RequestedViaSerial"; case RestartReason::ReconfigureWebServer: return "ReconfigureWebServer"; case RestartReason::BLEError: diff --git a/src/SerialReader.cpp b/src/SerialReader.cpp new file mode 100644 index 0000000..ac949bd --- /dev/null +++ b/src/SerialReader.cpp @@ -0,0 +1,86 @@ +#include "SerialReader.h" +#include "RestartReason.h" +#include "EspMillis.h" + +SerialReader::SerialReader(ImportExport *importExport, NukiNetwork* network) +: _importExport(importExport), + _network(network) +{ +} + + +void SerialReader::update() +{ + if(Serial.available()) + { + String line = Serial.readStringUntil('\n'); +// Serial.println(line); + + int64_t ts = espMillis(); + + if(ts - _lastCommandTs > 3000) + { + _receivingConfig = false; + } + _lastCommandTs = ts; + + + if(line == "reset") + { + restartEsp(RestartReason::RequestedViaSerial); + } + + if(line == "uptime") + { + Serial.print("Uptime (seconds): "); + Serial.println(espMillis() / 1000); + } + + if(line == "printerror") + { + Serial.println(_deserializationError); + } + + if(line == "printcfgstr") + { + Serial.println(); + Serial.println(config); + Serial.println(); + } + + if(line == "printcfg") + { + Serial.println(); + serializeJsonPretty(json, Serial); + Serial.println(); + } + + if(line == "savecfg") + { + _importExport->importJson(json); + Serial.println("Configuration saved"); + } + + if(line == "-- NUKI HUB CONFIG END --") + { + Serial.println("Receive config end"); + _receivingConfig = false; + json.clear(); + DeserializationError error = deserializeJson(json, config); + _deserializationError = (int)error.code(); + } + + if(_receivingConfig) + { + config = config + line; + } + + if(line == "-- NUKI HUB CONFIG START --") + { + Serial.println("Receive config start"); + config = ""; + _receivingConfig = true; + } + } +} + diff --git a/src/SerialReader.h b/src/SerialReader.h new file mode 100644 index 0000000..a70eef9 --- /dev/null +++ b/src/SerialReader.h @@ -0,0 +1,24 @@ +#pragma once + +#include "Arduino.h" +#include "ImportExport.h" +#include "NukiNetwork.h" +#include + +class SerialReader +{ +public: + explicit SerialReader(ImportExport* importExport, NukiNetwork* network); + + void update(); + +private: + String config = ""; + JsonDocument json; + bool _receivingConfig = false; + int64_t _lastCommandTs = 0; + int _deserializationError = -1; + + ImportExport* _importExport = nullptr; + NukiNetwork* _network = nullptr; +}; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 3bc5efd..ae1692e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -20,6 +20,7 @@ #endif #ifndef NUKI_HUB_UPDATER +#include "SerialReader.h" #include "NukiWrapper.h" #include "NukiNetworkLock.h" #include "NukiOpenerWrapper.h" @@ -50,6 +51,7 @@ NukiOpenerWrapper* nukiOpener = nullptr; NukiDeviceId* deviceIdLock = nullptr; NukiDeviceId* deviceIdOpener = nullptr; Gpio* gpio = nullptr; +SerialReader* serialReader = nullptr; bool lockEnabled = false; bool openerEnabled = false; @@ -250,6 +252,12 @@ void networkTask(void *pvParameters) } } +#ifndef NUKI_HUB_UPDATER + if(serialReader != nullptr) + { + serialReader->update(); + } +#endif network->update(); bool connected = network->isConnected(); @@ -877,6 +885,9 @@ void setup() doOta = false; lockEnabled = false; openerEnabled = false; +#ifndef NUKI_HUB_UPDATER + serialReader = new SerialReader(importExport, network); +#endif } if(lockEnabled || openerEnabled) diff --git a/src/util/NetworkDeviceInstantiator.cpp b/src/util/NetworkDeviceInstantiator.cpp index d57b6ec..05ef8c0 100644 --- a/src/util/NetworkDeviceInstantiator.cpp +++ b/src/util/NetworkDeviceInstantiator.cpp @@ -14,181 +14,181 @@ NetworkDevice *NetworkDeviceInstantiator::Create(NetworkDeviceType networkDevice switch (networkDeviceType) { - case NetworkDeviceType::W5500: - device = new EthernetDevice(hostname, preferences, ipConfiguration, "Generic W5500", - ETH_PHY_ADDR_W5500, - ETH_PHY_CS_GENERIC_W5500, - ETH_PHY_IRQ_GENERIC_W5500, - ETH_PHY_RST_GENERIC_W5500, - ETH_PHY_SPI_SCK_GENERIC_W5500, - ETH_PHY_SPI_MISO_GENERIC_W5500, - ETH_PHY_SPI_MOSI_GENERIC_W5500, - ETH_PHY_W5500); - break; - case NetworkDeviceType::W5500M5: - device = new EthernetDevice(hostname, preferences, ipConfiguration, "M5Stack Atom POE", - ETH_PHY_ADDR_W5500, - ETH_PHY_CS_M5_W5500, - ETH_PHY_IRQ_M5_W5500, - ETH_PHY_RST_M5_W5500, - ETH_PHY_SPI_SCK_M5_W5500, - ETH_PHY_SPI_MISO_M5_W5500, - ETH_PHY_SPI_MOSI_M5_W5500, - ETH_PHY_W5500); - break; - case NetworkDeviceType::W5500M5S3: - device = new EthernetDevice(hostname, preferences, ipConfiguration, "M5Stack Atom POE S3", - ETH_PHY_ADDR_W5500, - ETH_PHY_CS_M5_W5500_S3, - ETH_PHY_IRQ_M5_W5500, - ETH_PHY_RST_M5_W5500, - ETH_PHY_SPI_SCK_M5_W5500_S3, - ETH_PHY_SPI_MISO_M5_W5500_S3, - ETH_PHY_SPI_MOSI_M5_W5500_S3, - ETH_PHY_W5500); - break; - case NetworkDeviceType::Waveshare_ESP32_S3_ETH: - device = new EthernetDevice(hostname, preferences, ipConfiguration, "Waveshare ESP32-S3-ETH / ESP32-S3-ETH-POE", - ETH_ADDR_WAVESHARE_ESP32_S3_ETH, - ETH_PHY_SPI_CS_WAVESHARE_ESP32_S3_ETH, - ETH_PHY_SPI_IRQ_WAVESHARE_ESP32_S3_ETH, - ETH_PHY_SPI_RST_WAVESHARE_ESP32_S3_ETH, - ETH_PHY_SPI_SCK_WAVESHARE_ESP32_S3_ETH, - ETH_PHY_SPI_MISO_WAVESHARE_ESP32_S3_ETH, - ETH_PHY_SPI_MOSI_WAVESHARE_ESP32_S3_ETH, - ETH_PHY_W5500); - break; - case NetworkDeviceType::ETH01_Evo: - device = new EthernetDevice(hostname, preferences, ipConfiguration, "ETH01-Evo", - ETH_PHY_ADDR_ETH01EVO, - ETH_PHY_CS_ETH01EVO, - ETH_PHY_IRQ_ETH01EVO, - ETH_PHY_RST_ETH01EVO, - ETH_PHY_SPI_SCK_ETH01EVO, - ETH_PHY_SPI_MISO_ETH01EVO, - ETH_PHY_SPI_MOSI_ETH01EVO, - ETH_PHY_TYPE_DM9051); - break; - case NetworkDeviceType::LilyGO_T_ETH_ELite: - device = new EthernetDevice(hostname, preferences, ipConfiguration, "LilyGO T-ETH ELite", - ETH_PHY_ADDR_W5500, - ETH_PHY_CS_ELITE_W5500, - ETH_PHY_IRQ_ELITE_W5500, - ETH_PHY_RST_ELITE_W5500, - ETH_PHY_SPI_SCK_ELITE_W5500, - ETH_PHY_SPI_MISO_ELITE_W5500, - ETH_PHY_SPI_MOSI_ELITE_W5500, - ETH_PHY_W5500); - break; - case NetworkDeviceType::LilyGO_T_ETH_Lite_S3: - device = new EthernetDevice(hostname, preferences, ipConfiguration, "LilyGO T-ETH-Lite-ESP32S3", - ETH_PHY_ADDR_W5500, - ETH_PHY_CS_ETHLITES3_W5500, - ETH_PHY_IRQ_ETHLITES3_W5500, - ETH_PHY_RST_ETHLITES3_W5500, - ETH_PHY_SPI_SCK_ETHLITES3_W5500, - ETH_PHY_SPI_MISO_ETHLITES3_W5500, - ETH_PHY_SPI_MOSI_ETHLITES3_W5500, - ETH_PHY_W5500); - break; + case NetworkDeviceType::W5500: + device = new EthernetDevice(hostname, preferences, ipConfiguration, "Generic W5500", + ETH_PHY_ADDR_W5500, + ETH_PHY_CS_GENERIC_W5500, + ETH_PHY_IRQ_GENERIC_W5500, + ETH_PHY_RST_GENERIC_W5500, + ETH_PHY_SPI_SCK_GENERIC_W5500, + ETH_PHY_SPI_MISO_GENERIC_W5500, + ETH_PHY_SPI_MOSI_GENERIC_W5500, + ETH_PHY_W5500); + break; + case NetworkDeviceType::W5500M5: + device = new EthernetDevice(hostname, preferences, ipConfiguration, "M5Stack Atom POE", + ETH_PHY_ADDR_W5500, + ETH_PHY_CS_M5_W5500, + ETH_PHY_IRQ_M5_W5500, + ETH_PHY_RST_M5_W5500, + ETH_PHY_SPI_SCK_M5_W5500, + ETH_PHY_SPI_MISO_M5_W5500, + ETH_PHY_SPI_MOSI_M5_W5500, + ETH_PHY_W5500); + break; + case NetworkDeviceType::W5500M5S3: + device = new EthernetDevice(hostname, preferences, ipConfiguration, "M5Stack Atom POE S3", + ETH_PHY_ADDR_W5500, + ETH_PHY_CS_M5_W5500_S3, + ETH_PHY_IRQ_M5_W5500, + ETH_PHY_RST_M5_W5500, + ETH_PHY_SPI_SCK_M5_W5500_S3, + ETH_PHY_SPI_MISO_M5_W5500_S3, + ETH_PHY_SPI_MOSI_M5_W5500_S3, + ETH_PHY_W5500); + break; + case NetworkDeviceType::Waveshare_ESP32_S3_ETH: + device = new EthernetDevice(hostname, preferences, ipConfiguration, "Waveshare ESP32-S3-ETH / ESP32-S3-ETH-POE", + ETH_ADDR_WAVESHARE_ESP32_S3_ETH, + ETH_PHY_SPI_CS_WAVESHARE_ESP32_S3_ETH, + ETH_PHY_SPI_IRQ_WAVESHARE_ESP32_S3_ETH, + ETH_PHY_SPI_RST_WAVESHARE_ESP32_S3_ETH, + ETH_PHY_SPI_SCK_WAVESHARE_ESP32_S3_ETH, + ETH_PHY_SPI_MISO_WAVESHARE_ESP32_S3_ETH, + ETH_PHY_SPI_MOSI_WAVESHARE_ESP32_S3_ETH, + ETH_PHY_W5500); + break; + case NetworkDeviceType::ETH01_Evo: + device = new EthernetDevice(hostname, preferences, ipConfiguration, "ETH01-Evo", + ETH_PHY_ADDR_ETH01EVO, + ETH_PHY_CS_ETH01EVO, + ETH_PHY_IRQ_ETH01EVO, + ETH_PHY_RST_ETH01EVO, + ETH_PHY_SPI_SCK_ETH01EVO, + ETH_PHY_SPI_MISO_ETH01EVO, + ETH_PHY_SPI_MOSI_ETH01EVO, + ETH_PHY_TYPE_DM9051); + break; + case NetworkDeviceType::LilyGO_T_ETH_ELite: + device = new EthernetDevice(hostname, preferences, ipConfiguration, "LilyGO T-ETH ELite", + ETH_PHY_ADDR_W5500, + ETH_PHY_CS_ELITE_W5500, + ETH_PHY_IRQ_ELITE_W5500, + ETH_PHY_RST_ELITE_W5500, + ETH_PHY_SPI_SCK_ELITE_W5500, + ETH_PHY_SPI_MISO_ELITE_W5500, + ETH_PHY_SPI_MOSI_ELITE_W5500, + ETH_PHY_W5500); + break; + case NetworkDeviceType::LilyGO_T_ETH_Lite_S3: + device = new EthernetDevice(hostname, preferences, ipConfiguration, "LilyGO T-ETH-Lite-ESP32S3", + ETH_PHY_ADDR_W5500, + ETH_PHY_CS_ETHLITES3_W5500, + ETH_PHY_IRQ_ETHLITES3_W5500, + ETH_PHY_RST_ETHLITES3_W5500, + ETH_PHY_SPI_SCK_ETHLITES3_W5500, + ETH_PHY_SPI_MISO_ETHLITES3_W5500, + ETH_PHY_SPI_MOSI_ETHLITES3_W5500, + ETH_PHY_W5500); + break; - case NetworkDeviceType::CUSTOM: - { - int custPHY = preferences->getInt(preference_network_custom_phy, 0); - - if(custPHY >= 1 && custPHY <= 3) + case NetworkDeviceType::CUSTOM: { - std::string custName; - eth_phy_type_t custEthtype; + int custPHY = preferences->getInt(preference_network_custom_phy, 0); - switch(custPHY) + if(custPHY >= 1 && custPHY <= 3) { - case 1: - custName = "Custom (W5500)"; - custEthtype = ETH_PHY_W5500; - break; - case 2: - custName = "Custom (DN9051)"; - custEthtype = ETH_PHY_DM9051; - break; - case 3: - custName = "Custom (KSZ8851SNL)"; - custEthtype = ETH_PHY_KSZ8851; - break; - default: - custName = "Custom (W5500)"; - custEthtype = ETH_PHY_W5500; - break; + std::string custName; + eth_phy_type_t custEthtype; + + switch(custPHY) + { + case 1: + custName = "Custom (W5500)"; + custEthtype = ETH_PHY_W5500; + break; + case 2: + custName = "Custom (DN9051)"; + custEthtype = ETH_PHY_DM9051; + break; + case 3: + custName = "Custom (KSZ8851SNL)"; + custEthtype = ETH_PHY_KSZ8851; + break; + default: + custName = "Custom (W5500)"; + custEthtype = ETH_PHY_W5500; + break; + } + + device = new EthernetDevice(hostname, preferences, ipConfiguration, custName, + preferences->getInt(preference_network_custom_addr, -1), + preferences->getInt(preference_network_custom_cs, -1), + preferences->getInt(preference_network_custom_irq, -1), + preferences->getInt(preference_network_custom_rst, -1), + preferences->getInt(preference_network_custom_sck, -1), + preferences->getInt(preference_network_custom_miso, -1), + preferences->getInt(preference_network_custom_mosi, -1), + custEthtype); } - - device = new EthernetDevice(hostname, preferences, ipConfiguration, custName, - preferences->getInt(preference_network_custom_addr, -1), - preferences->getInt(preference_network_custom_cs, -1), - preferences->getInt(preference_network_custom_irq, -1), - preferences->getInt(preference_network_custom_rst, -1), - preferences->getInt(preference_network_custom_sck, -1), - preferences->getInt(preference_network_custom_miso, -1), - preferences->getInt(preference_network_custom_mosi, -1), - custEthtype); - } #if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32P4) - else if(custPHY >= 4 && custPHY <= 9) - { - int custCLKpref = preferences->getInt(preference_network_custom_clk, 0); + else if(custPHY >= 4 && custPHY <= 9) + { + int custCLKpref = preferences->getInt(preference_network_custom_clk, 0); - std::string custName = NetworkUtil::GetCustomEthernetDeviceName(custPHY); - eth_phy_type_t custEthtype = NetworkUtil::GetCustomEthernetType(custPHY); - eth_clock_mode_t custCLK = NetworkUtil::GetCustomClock(custCLKpref); + std::string custName = NetworkUtil::GetCustomEthernetDeviceName(custPHY); + eth_phy_type_t custEthtype = NetworkUtil::GetCustomEthernetType(custPHY); + eth_clock_mode_t custCLK = NetworkUtil::GetCustomClock(custCLKpref); - device = new EthernetDevice(hostname, preferences, ipConfiguration, custName, - preferences->getInt(preference_network_custom_addr, -1), - preferences->getInt(preference_network_custom_pwr, -1), - preferences->getInt(preference_network_custom_mdc, -1), - preferences->getInt(preference_network_custom_mdio, -1), - custEthtype, - custCLK); - } + device = new EthernetDevice(hostname, preferences, ipConfiguration, custName, + preferences->getInt(preference_network_custom_addr, -1), + preferences->getInt(preference_network_custom_pwr, -1), + preferences->getInt(preference_network_custom_mdc, -1), + preferences->getInt(preference_network_custom_mdio, -1), + custEthtype, + custCLK); + } #endif #ifndef CONFIG_IDF_TARGET_ESP32H2 - else - { - device = new WifiDevice(hostname, preferences, ipConfiguration); - } + else + { + device = new WifiDevice(hostname, preferences, ipConfiguration); + } #endif - } - break; + } + break; #if defined(CONFIG_IDF_TARGET_ESP32) - case NetworkDeviceType::M5STACK_PoESP32_Unit: - device = new EthernetDevice(hostname, preferences, ipConfiguration, "M5STACK PoESP32 Unit", - ETH_PHY_ADDR_M5_POESP32, - ETH_PHY_POWER_M5_POESP32, - ETH_PHY_MDC_M5_POESP32, - ETH_PHY_MDIO_M5_POESP32, - ETH_CLK_MODE_M5_TYPE, - ETH_CLK_MODE_M5_POESP32); - break; - case NetworkDeviceType::Olimex_LAN8720: - device = new EthernetDevice(hostname, preferences, ipConfiguration, "Olimex (LAN8720)", ETH_PHY_ADDR_LAN8720, 12, ETH_PHY_MDC_LAN8720, ETH_PHY_MDIO_LAN8720, ETH_PHY_TYPE_LAN8720, ETH_CLOCK_GPIO17_OUT); - break; - case NetworkDeviceType::WT32_LAN8720: - device = new EthernetDevice(hostname, preferences, ipConfiguration, "WT32-ETH01", 1, 16); - break; - case NetworkDeviceType::GL_S10: - device = new EthernetDevice(hostname, preferences, ipConfiguration, "GL-S10", 1, 5, ETH_PHY_MDC_LAN8720, ETH_PHY_MDIO_LAN8720, ETH_PHY_IP101, ETH_CLOCK_GPIO0_IN); - break; - case NetworkDeviceType::LilyGO_T_ETH_POE: - device = new EthernetDevice(hostname, preferences, ipConfiguration, "LilyGO T-ETH-POE", 0, -1, ETH_PHY_MDC_LAN8720, ETH_PHY_MDIO_LAN8720, ETH_PHY_TYPE_LAN8720, ETH_CLOCK_GPIO17_OUT); - break; + case NetworkDeviceType::M5STACK_PoESP32_Unit: + device = new EthernetDevice(hostname, preferences, ipConfiguration, "M5STACK PoESP32 Unit", + ETH_PHY_ADDR_M5_POESP32, + ETH_PHY_POWER_M5_POESP32, + ETH_PHY_MDC_M5_POESP32, + ETH_PHY_MDIO_M5_POESP32, + ETH_CLK_MODE_M5_TYPE, + ETH_CLK_MODE_M5_POESP32); + break; + case NetworkDeviceType::Olimex_LAN8720: + device = new EthernetDevice(hostname, preferences, ipConfiguration, "Olimex (LAN8720)", ETH_PHY_ADDR_LAN8720, 12, ETH_PHY_MDC_LAN8720, ETH_PHY_MDIO_LAN8720, ETH_PHY_TYPE_LAN8720, ETH_CLOCK_GPIO17_OUT); + break; + case NetworkDeviceType::WT32_LAN8720: + device = new EthernetDevice(hostname, preferences, ipConfiguration, "WT32-ETH01", 1, 16); + break; + case NetworkDeviceType::GL_S10: + device = new EthernetDevice(hostname, preferences, ipConfiguration, "GL-S10", 1, 5, ETH_PHY_MDC_LAN8720, ETH_PHY_MDIO_LAN8720, ETH_PHY_IP101, ETH_CLOCK_GPIO0_IN); + break; + case NetworkDeviceType::LilyGO_T_ETH_POE: + device = new EthernetDevice(hostname, preferences, ipConfiguration, "LilyGO T-ETH-POE", 0, -1, ETH_PHY_MDC_LAN8720, ETH_PHY_MDIO_LAN8720, ETH_PHY_TYPE_LAN8720, ETH_CLOCK_GPIO17_OUT); + break; #endif #ifndef CONFIG_IDF_TARGET_ESP32H2 - case NetworkDeviceType::WiFi: - device = new WifiDevice(hostname, preferences, ipConfiguration); - break; - default: - device = new WifiDevice(hostname, preferences, ipConfiguration); - break; + case NetworkDeviceType::WiFi: + device = new WifiDevice(hostname, preferences, ipConfiguration); + break; + default: + device = new WifiDevice(hostname, preferences, ipConfiguration); + break; #else - default: + default: device = new EthernetDevice(hostname, preferences, ipConfiguration, "Custom (W5500)", preferences->getInt(preference_network_custom_addr, -1), preferences->getInt(preference_network_custom_cs, -1),