diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ee604d..83e18e9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,6 +53,7 @@ file(GLOB SRCFILES networkDevices/EthLan8720Device.cpp networkDevices/ClientSyncW5500.cpp networkDevices/espMqttClientW5500.cpp + networkDevices/IPConfiguration.cpp QueryCommand.h NukiWrapper.cpp NukiOpenerWrapper.cpp diff --git a/Network.cpp b/Network.cpp index 69b79d7..6d8a86c 100644 --- a/Network.cpp +++ b/Network.cpp @@ -14,7 +14,7 @@ unsigned long Network::_ignoreSubscriptionsTs = 0; RTC_NOINIT_ATTR char WiFi_fallbackDetect[14]; -Network::Network(Preferences *preferences, const String& maintenancePathPrefix) +Network::Network(Preferences *preferences, const String& maintenancePathPrefix, const bool& firstStart) : _preferences(preferences) { _inst = this; @@ -27,11 +27,13 @@ Network::Network(Preferences *preferences, const String& maintenancePathPrefix) { _maintenancePathPrefix[i] = maintenancePathPrefix.charAt(i); } - setupDevice(); + setupDevice(firstStart); } -void Network::setupDevice() +void Network::setupDevice(const bool& firstStart) { + _ipConfiguration = new IPConfiguration(_preferences, firstStart); + int hardwareDetect = _preferences->getInt(preference_network_hardware); int hardwareDetectGpio = _preferences->getInt(preference_network_hardware_gpio); @@ -93,19 +95,19 @@ void Network::setupDevice() switch (_networkDeviceType) { case NetworkDeviceType::W5500: - _device = new W5500Device(_hostname, _preferences, hardwareDetect); + _device = new W5500Device(_hostname, _preferences, _ipConfiguration, hardwareDetect); break; case NetworkDeviceType::Olimex_LAN8720: - _device = new EthLan8720Device(_hostname, _preferences, "Olimex (LAN8720)", ETH_PHY_ADDR, 12, ETH_PHY_MDC, ETH_PHY_MDIO, ETH_PHY_TYPE, ETH_CLOCK_GPIO17_OUT); + _device = new EthLan8720Device(_hostname, _preferences, _ipConfiguration, "Olimex (LAN8720)", ETH_PHY_ADDR, 12, ETH_PHY_MDC, ETH_PHY_MDIO, ETH_PHY_TYPE, ETH_CLOCK_GPIO17_OUT); break; case NetworkDeviceType::WT32_LAN8720: - _device = new EthLan8720Device(_hostname, _preferences, "WT32-ETH01", 1, 16); + _device = new EthLan8720Device(_hostname, _preferences, _ipConfiguration, "WT32-ETH01", 1, 16); break; case NetworkDeviceType::WiFi: - _device = new WifiDevice(_hostname, _preferences); + _device = new WifiDevice(_hostname, _preferences, _ipConfiguration); break; default: - _device = new WifiDevice(_hostname, _preferences); + _device = new WifiDevice(_hostname, _preferences, _ipConfiguration); break; } diff --git a/Network.h b/Network.h index 0a81a1a..ccab0ba 100644 --- a/Network.h +++ b/Network.h @@ -5,6 +5,7 @@ #include #include "networkDevices/NetworkDevice.h" #include "MqttReceiver.h" +#include "networkDevices/IPConfiguration.h" enum class NetworkDeviceType { @@ -19,7 +20,7 @@ enum class NetworkDeviceType class Network { public: - explicit Network(Preferences* preferences, const String& maintenancePathPrefix); + explicit Network(Preferences* preferences, const String& maintenancePathPrefix, const bool& firstStart); void initialize(); bool update(); @@ -66,7 +67,7 @@ public: private: static void onMqttDataReceivedCallback(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total); void onMqttDataReceived(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total); - void setupDevice(); + void setupDevice(const bool& firstStart); bool reconnect(); void publishHassTopic(const String& mqttDeviceType, @@ -92,6 +93,7 @@ private: static Network* _inst; Preferences* _preferences; + IPConfiguration* _ipConfiguration = nullptr; String _hostname; char _hostnameArr[101] = {0}; NetworkDevice* _device = nullptr; diff --git a/PreferencesKeys.h b/PreferencesKeys.h index 0403cb7..6a9d070 100644 --- a/PreferencesKeys.h +++ b/PreferencesKeys.h @@ -19,6 +19,11 @@ #define preference_mqtt_crt "mqttcrt" #define preference_mqtt_key "mqttkey" #define preference_mqtt_hass_discovery "hassdiscovery" +#define preference_ip_dhcp_enabled "dhcpena" +#define preference_ip_address "ipaddr" +#define preference_ip_subnet "ipsub" +#define preference_ip_gateway "ipgtw" +#define preference_ip_dns_server "dnssrv" #define preference_network_hardware "nwhw" #define preference_network_hardware_gpio "nwhwdt" #define preference_rssi_publish_interval "rssipb" diff --git a/WebCfgServer.cpp b/WebCfgServer.cpp index 4a43b5f..836c4ec 100644 --- a/WebCfgServer.cpp +++ b/WebCfgServer.cpp @@ -327,6 +327,31 @@ bool WebCfgServer::processArgs(String& message) _preferences->putBool(preference_mqtt_log_enabled, (value == "1")); configChanged = true; } + else if(key == "DHCPENA") + { + _preferences->putBool(preference_ip_dhcp_enabled, (value == "1")); + configChanged = true; + } + else if(key == "IPADDR") + { + _preferences->putString(preference_ip_address, value); + configChanged = true; + } + else if(key == "IPSUB") + { + _preferences->putString(preference_ip_subnet, value); + configChanged = true; + } + else if(key == "IPGTW") + { + _preferences->putString(preference_ip_gateway, value); + configChanged = true; + } + else if(key == "DNSSRV") + { + _preferences->putString(preference_ip_dns_server, value); + configChanged = true; + } else if(key == "LSTINT") { _preferences->putInt(preference_query_interval_lockstate, value.toInt()); @@ -658,6 +683,15 @@ void WebCfgServer::buildMqttConfigHtml(String &response) response.concat(""); response.concat("* If no encryption is configured for the MQTT broker, leave empty. Only supported for WiFi connections.
"); + response.concat("

IP Address assignment

"); + response.concat(""); + printCheckBox(response, "DHCPENA", "Enable DHCP", _preferences->getBool(preference_ip_dhcp_enabled)); + printInputField(response, "IPADDR", "Static IP address", _preferences->getString(preference_ip_address).c_str(), 15); + printInputField(response, "IPSUB", "Subnet", _preferences->getString(preference_ip_subnet).c_str(), 15); + printInputField(response, "IPGTW", "Default gateway", _preferences->getString(preference_ip_gateway).c_str(), 15); + printInputField(response, "DNSSRV", "DNS Server", _preferences->getString(preference_ip_dns_server).c_str(), 15); + response.concat("
"); + response.concat("
"); response.concat(""); response.concat(""); diff --git a/main.cpp b/main.cpp index 19b37eb..48529af 100644 --- a/main.cpp +++ b/main.cpp @@ -177,7 +177,7 @@ void setup() openerEnabled = preferences->getBool(preference_opener_enabled); const String mqttLockPath = preferences->getString(preference_mqtt_lock_path); - network = new Network(preferences, mqttLockPath); + network = new Network(preferences, mqttLockPath, firstStart); network->initialize(); networkLock = new NetworkLock(network, preferences); diff --git a/networkDevices/EthLan8720Device.cpp b/networkDevices/EthLan8720Device.cpp index d586d84..943b455 100644 --- a/networkDevices/EthLan8720Device.cpp +++ b/networkDevices/EthLan8720Device.cpp @@ -10,8 +10,8 @@ #include "espMqttClient.h" #include "../RestartReason.h" -EthLan8720Device::EthLan8720Device(const String& hostname, Preferences* preferences, const std::string& deviceName, uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_type_t ethtype, eth_clock_mode_t clock_mode, bool use_mac_from_efuse) -: NetworkDevice(hostname), +EthLan8720Device::EthLan8720Device(const String& hostname, Preferences* preferences, const IPConfiguration* ipConfiguration, const std::string& deviceName, uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_type_t ethtype, eth_clock_mode_t clock_mode, bool use_mac_from_efuse) +: NetworkDevice(hostname, ipConfiguration), _deviceName(deviceName), _phy_addr(phy_addr), _power(power), diff --git a/networkDevices/EthLan8720Device.h b/networkDevices/EthLan8720Device.h index 7d39b48..cc8d92e 100644 --- a/networkDevices/EthLan8720Device.h +++ b/networkDevices/EthLan8720Device.h @@ -13,6 +13,7 @@ class EthLan8720Device : public NetworkDevice public: EthLan8720Device(const String& hostname, Preferences* preferences, + const IPConfiguration* ipConfiguration, const std::string& deviceName, uint8_t phy_addr = ETH_PHY_ADDR, int power = ETH_PHY_POWER, diff --git a/networkDevices/IPConfiguration.cpp b/networkDevices/IPConfiguration.cpp new file mode 100644 index 0000000..8540c94 --- /dev/null +++ b/networkDevices/IPConfiguration.cpp @@ -0,0 +1,50 @@ +#include "IPConfiguration.h" +#include "../PreferencesKeys.h" +#include "../Logger.h" + +IPConfiguration::IPConfiguration(Preferences *preferences, const bool& firstStart) +: _preferences(preferences) +{ + if(firstStart) + { + _preferences->putBool(preference_ip_dhcp_enabled, true); + } + + Log->print(F("IP configuration: ")); + if(dhcpEnabled()) + { + Log->println(F("DHCP")); + } + else + { + Log->print(F("IP address: ")); Log->print(ipAddress()); + Log->print(F("Subnet: ")); Log->print(subnet()); + Log->print(F("Gateway: ")); Log->print(defaultGateway()); + Log->print(F("DNS: ")); Log->println(dnsServer()); + } +} + +bool IPConfiguration::dhcpEnabled() const +{ + return _preferences->getBool(preference_ip_dhcp_enabled); +} + +String IPConfiguration::ipAddress() const +{ + return _preferences->getString(preference_ip_address); +} + +String IPConfiguration::subnet() const +{ + return _preferences->getString(preference_ip_subnet); +} + +String IPConfiguration::defaultGateway() const +{ + return _preferences->getString(preference_ip_gateway); +} + +String IPConfiguration::dnsServer() const +{ + return _preferences->getString(preference_ip_dns_server); +} diff --git a/networkDevices/IPConfiguration.h b/networkDevices/IPConfiguration.h new file mode 100644 index 0000000..9a95597 --- /dev/null +++ b/networkDevices/IPConfiguration.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +class IPConfiguration +{ +public: + explicit IPConfiguration(Preferences* preferences, const bool& firstStart); + + bool dhcpEnabled() const; + String ipAddress() const; + String subnet() const; + String defaultGateway() const; + String dnsServer() const; + +private: + Preferences* _preferences = nullptr; +}; + diff --git a/networkDevices/NetworkDevice.h b/networkDevices/NetworkDevice.h index 907e18e..b73b058 100644 --- a/networkDevices/NetworkDevice.h +++ b/networkDevices/NetworkDevice.h @@ -2,6 +2,7 @@ #include "MqttClient.h" #include "MqttClientSetup.h" +#include "IPConfiguration.h" enum class ReconnectStatus { @@ -13,8 +14,9 @@ enum class ReconnectStatus class NetworkDevice { public: - explicit NetworkDevice(const String& hostname) - : _hostname(hostname) + explicit NetworkDevice(const String& hostname, const IPConfiguration* ipConfiguration) + : _hostname(hostname), + _ipConfiguration(ipConfiguration) {} virtual const String deviceName() const = 0; @@ -49,4 +51,5 @@ public: protected: const uint16_t _mqttMaxBufferSize = 6144; const String _hostname; + const IPConfiguration* _ipConfiguration = nullptr; }; \ No newline at end of file diff --git a/networkDevices/W5500Device.cpp b/networkDevices/W5500Device.cpp index 06c0f62..e343f9c 100644 --- a/networkDevices/W5500Device.cpp +++ b/networkDevices/W5500Device.cpp @@ -6,8 +6,8 @@ #include "../Logger.h" #include "../MqttTopics.h" -W5500Device::W5500Device(const String &hostname, Preferences* preferences, int variant) -: NetworkDevice(hostname), +W5500Device::W5500Device(const String &hostname, Preferences* preferences, const IPConfiguration* ipConfiguration, int variant) +: NetworkDevice(hostname, ipConfiguration), _preferences(preferences), _variant((W5500Variant)variant) { diff --git a/networkDevices/W5500Device.h b/networkDevices/W5500Device.h index 14290d0..8fa330a 100644 --- a/networkDevices/W5500Device.h +++ b/networkDevices/W5500Device.h @@ -15,7 +15,7 @@ enum class W5500Variant class W5500Device : public NetworkDevice { public: - explicit W5500Device(const String& hostname, Preferences* _preferences, int variant); + explicit W5500Device(const String& hostname, Preferences* _preferences, const IPConfiguration* ipConfiguration, int variant); ~W5500Device(); const String deviceName() const override; diff --git a/networkDevices/WifiDevice.cpp b/networkDevices/WifiDevice.cpp index ce906d0..a80e020 100644 --- a/networkDevices/WifiDevice.cpp +++ b/networkDevices/WifiDevice.cpp @@ -8,8 +8,8 @@ RTC_NOINIT_ATTR char WiFiDevice_reconfdetect[17]; -WifiDevice::WifiDevice(const String& hostname, Preferences* _preferences) -: NetworkDevice(hostname) +WifiDevice::WifiDevice(const String& hostname, Preferences* _preferences, const IPConfiguration* ipConfiguration) +: NetworkDevice(hostname, ipConfiguration) { _startAp = strcmp(WiFiDevice_reconfdetect, "reconfigure_wifi") == 0; @@ -69,6 +69,20 @@ void WifiDevice::initialize() _wm.setMenu(wm_menu); _wm.setHostname(_hostname); + if(!_ipConfiguration->dhcpEnabled()) + { + IPAddress address; + address.fromString(_ipConfiguration->ipAddress()); + IPAddress gateway; + gateway.fromString(_ipConfiguration->defaultGateway()); + IPAddress subnet; + subnet.fromString(_ipConfiguration->subnet()); + IPAddress dns; + dns.fromString(_ipConfiguration->dnsServer()); + + _wm.setSTAStaticIPConfig(address, gateway, subnet, dns); + } + _wm.setAPCallback(clearRtcInitVar); bool res = false; diff --git a/networkDevices/WifiDevice.h b/networkDevices/WifiDevice.h index e787703..3c04220 100644 --- a/networkDevices/WifiDevice.h +++ b/networkDevices/WifiDevice.h @@ -6,11 +6,12 @@ #include "NetworkDevice.h" #include "WiFiManager.h" #include "espMqttClient.h" +#include "IPConfiguration.h" class WifiDevice : public NetworkDevice { public: - WifiDevice(const String& hostname, Preferences* _preferences); + WifiDevice(const String& hostname, Preferences* _preferences, const IPConfiguration* ipConfiguration); const String deviceName() const override;