mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	Fix ethernet component hostname handling (#2010)
Co-authored-by: Otto Winter <otto@otto-winter.com>
This commit is contained in:
		
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -13,6 +13,9 @@ __pycache__/ | ||||
| # Intellij Idea | ||||
| .idea | ||||
|  | ||||
| # Vim | ||||
| *.swp | ||||
|  | ||||
| # Hide some OS X stuff | ||||
| .DS_Store | ||||
| .AppleDouble | ||||
|   | ||||
| @@ -25,6 +25,13 @@ static const char *const TAG = "ethernet"; | ||||
|  | ||||
| EthernetComponent *global_eth_component; | ||||
|  | ||||
| #define ESPHL_ERROR_CHECK(err, message) \ | ||||
|   if (err != ESP_OK) { \ | ||||
|     ESP_LOGE(TAG, message ": (%d) %s", err, esp_err_to_name(err)); \ | ||||
|     this->mark_failed(); \ | ||||
|     return; \ | ||||
|   } | ||||
|  | ||||
| EthernetComponent::EthernetComponent() { global_eth_component = this; } | ||||
| void EthernetComponent::setup() { | ||||
|   ESP_LOGCONFIG(TAG, "Setting up Ethernet..."); | ||||
| @@ -36,103 +43,6 @@ void EthernetComponent::setup() { | ||||
|     this->power_pin_->setup(); | ||||
|   } | ||||
|  | ||||
|   this->start_connect_(); | ||||
|  | ||||
| #ifdef USE_MDNS | ||||
|   network_setup_mdns(); | ||||
| #endif | ||||
| } | ||||
| void EthernetComponent::loop() { | ||||
|   const uint32_t now = millis(); | ||||
|   if (!this->connected_ && !this->last_connected_ && now - this->connect_begin_ > 15000) { | ||||
|     ESP_LOGW(TAG, "Connecting via ethernet failed! Re-connecting..."); | ||||
|     this->start_connect_(); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   if (this->connected_ == this->last_connected_) | ||||
|     // nothing changed | ||||
|     return; | ||||
|  | ||||
|   if (this->connected_) { | ||||
|     // connection established | ||||
|     ESP_LOGI(TAG, "Connected via Ethernet!"); | ||||
|     this->dump_connect_params_(); | ||||
|     this->status_clear_warning(); | ||||
|   } else { | ||||
|     // connection lost | ||||
|     ESP_LOGW(TAG, "Connection via Ethernet lost! Re-connecting..."); | ||||
|     this->start_connect_(); | ||||
|   } | ||||
|  | ||||
|   this->last_connected_ = this->connected_; | ||||
|  | ||||
|   network_tick_mdns(); | ||||
| } | ||||
| void EthernetComponent::dump_config() { | ||||
|   ESP_LOGCONFIG(TAG, "Ethernet:"); | ||||
|   this->dump_connect_params_(); | ||||
|   LOG_PIN("  Power Pin: ", this->power_pin_); | ||||
|   ESP_LOGCONFIG(TAG, "  MDC Pin: %u", this->mdc_pin_); | ||||
|   ESP_LOGCONFIG(TAG, "  MDIO Pin: %u", this->mdio_pin_); | ||||
|   ESP_LOGCONFIG(TAG, "  Type: %s", this->type_ == ETHERNET_TYPE_LAN8720 ? "LAN8720" : "TLK110"); | ||||
| } | ||||
| float EthernetComponent::get_setup_priority() const { return setup_priority::WIFI; } | ||||
| bool EthernetComponent::can_proceed() { return this->is_connected(); } | ||||
| IPAddress EthernetComponent::get_ip_address() { | ||||
|   tcpip_adapter_ip_info_t ip; | ||||
|   tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip); | ||||
|   return IPAddress(ip.ip.addr); | ||||
| } | ||||
|  | ||||
| void EthernetComponent::on_wifi_event_(system_event_id_t event, system_event_info_t info) { | ||||
|   const char *event_name; | ||||
|  | ||||
|   switch (event) { | ||||
|     case SYSTEM_EVENT_ETH_START: | ||||
|       event_name = "ETH started"; | ||||
|       break; | ||||
|     case SYSTEM_EVENT_ETH_STOP: | ||||
|       event_name = "ETH stopped"; | ||||
|       this->connected_ = false; | ||||
|       break; | ||||
|     case SYSTEM_EVENT_ETH_CONNECTED: | ||||
|       event_name = "ETH connected"; | ||||
|       break; | ||||
|     case SYSTEM_EVENT_ETH_DISCONNECTED: | ||||
|       event_name = "ETH disconnected"; | ||||
|       this->connected_ = false; | ||||
|       break; | ||||
|     case SYSTEM_EVENT_ETH_GOT_IP: | ||||
|       event_name = "ETH Got IP"; | ||||
|       this->connected_ = true; | ||||
|       break; | ||||
|     default: | ||||
|       return; | ||||
|   } | ||||
|  | ||||
|   ESP_LOGV(TAG, "[Ethernet event] %s (num=%d)", event_name, event); | ||||
| } | ||||
|  | ||||
| #define ESPHL_ERROR_CHECK(err, message) \ | ||||
|   if (err != ESP_OK) { \ | ||||
|     ESP_LOGE(TAG, message ": %d", err); \ | ||||
|     this->mark_failed(); \ | ||||
|     return; \ | ||||
|   } | ||||
|  | ||||
| void EthernetComponent::start_connect_() { | ||||
|   this->connect_begin_ = millis(); | ||||
|   this->status_set_warning(); | ||||
|  | ||||
|   esp_err_t err; | ||||
|   if (this->initialized_) { | ||||
|     // already initialized | ||||
|     err = esp_eth_enable(); | ||||
|     ESPHL_ERROR_CHECK(err, "ETH enable error"); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   switch (this->type_) { | ||||
|     case ETHERNET_TYPE_LAN8720: { | ||||
|       memcpy(&this->eth_config, &phy_lan8720_default_ethernet_config, sizeof(eth_config_t)); | ||||
| @@ -160,16 +70,111 @@ void EthernetComponent::start_connect_() { | ||||
|  | ||||
|   tcpipInit(); | ||||
|  | ||||
|   esp_err_t err; | ||||
|   err = esp_eth_init(&this->eth_config); | ||||
|   if (err != ESP_OK) { | ||||
|     ESP_LOGE(TAG, "ETH init error: %d", err); | ||||
|     this->mark_failed(); | ||||
|     return; | ||||
|   ESPHL_ERROR_CHECK(err, "ETH init error"); | ||||
|   err = esp_eth_enable(); | ||||
|   ESPHL_ERROR_CHECK(err, "ETH enable error"); | ||||
|  | ||||
| #ifdef USE_MDNS | ||||
|   network_setup_mdns(); | ||||
| #endif | ||||
| } | ||||
| void EthernetComponent::loop() { | ||||
|   const uint32_t now = millis(); | ||||
|  | ||||
|   switch (this->state_) { | ||||
|     case EthernetComponentState::STOPPED: | ||||
|       if (this->started_) { | ||||
|         ESP_LOGI(TAG, "Starting ethernet connection"); | ||||
|         this->state_ = EthernetComponentState::CONNECTING; | ||||
|         this->start_connect_(); | ||||
|       } | ||||
|       break; | ||||
|     case EthernetComponentState::CONNECTING: | ||||
|       if (!this->started_) { | ||||
|         ESP_LOGI(TAG, "Stopped ethernet connection"); | ||||
|         this->state_ = EthernetComponentState::STOPPED; | ||||
|       } else if (this->connected_) { | ||||
|         // connection established | ||||
|         ESP_LOGI(TAG, "Connected via Ethernet!"); | ||||
|         this->state_ = EthernetComponentState::CONNECTED; | ||||
|  | ||||
|         this->dump_connect_params_(); | ||||
|         this->status_clear_warning(); | ||||
|  | ||||
|         network_tick_mdns(); | ||||
|       } else if (now - this->connect_begin_ > 15000) { | ||||
|         ESP_LOGW(TAG, "Connecting via ethernet failed! Re-connecting..."); | ||||
|         this->start_connect_(); | ||||
|       } | ||||
|       break; | ||||
|     case EthernetComponentState::CONNECTED: | ||||
|       if (!this->started_) { | ||||
|         ESP_LOGI(TAG, "Stopped ethernet connection"); | ||||
|         this->state_ = EthernetComponentState::STOPPED; | ||||
|       } else if (!this->connected_) { | ||||
|         ESP_LOGW(TAG, "Connection via Ethernet lost! Re-connecting..."); | ||||
|         this->state_ = EthernetComponentState::CONNECTING; | ||||
|         this->start_connect_(); | ||||
|       } | ||||
|       break; | ||||
|   } | ||||
| } | ||||
| void EthernetComponent::dump_config() { | ||||
|   ESP_LOGCONFIG(TAG, "Ethernet:"); | ||||
|   this->dump_connect_params_(); | ||||
|   LOG_PIN("  Power Pin: ", this->power_pin_); | ||||
|   ESP_LOGCONFIG(TAG, "  MDC Pin: %u", this->mdc_pin_); | ||||
|   ESP_LOGCONFIG(TAG, "  MDIO Pin: %u", this->mdio_pin_); | ||||
|   ESP_LOGCONFIG(TAG, "  Type: %s", this->type_ == ETHERNET_TYPE_LAN8720 ? "LAN8720" : "TLK110"); | ||||
| } | ||||
| float EthernetComponent::get_setup_priority() const { return setup_priority::WIFI; } | ||||
| bool EthernetComponent::can_proceed() { return this->is_connected(); } | ||||
| IPAddress EthernetComponent::get_ip_address() { | ||||
|   tcpip_adapter_ip_info_t ip; | ||||
|   tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip); | ||||
|   return IPAddress(ip.ip.addr); | ||||
| } | ||||
|  | ||||
| void EthernetComponent::on_wifi_event_(system_event_id_t event, system_event_info_t info) { | ||||
|   const char *event_name; | ||||
|  | ||||
|   switch (event) { | ||||
|     case SYSTEM_EVENT_ETH_START: | ||||
|       event_name = "ETH started"; | ||||
|       this->started_ = true; | ||||
|       break; | ||||
|     case SYSTEM_EVENT_ETH_STOP: | ||||
|       event_name = "ETH stopped"; | ||||
|       this->started_ = false; | ||||
|       this->connected_ = false; | ||||
|       break; | ||||
|     case SYSTEM_EVENT_ETH_CONNECTED: | ||||
|       event_name = "ETH connected"; | ||||
|       break; | ||||
|     case SYSTEM_EVENT_ETH_DISCONNECTED: | ||||
|       event_name = "ETH disconnected"; | ||||
|       this->connected_ = false; | ||||
|       break; | ||||
|     case SYSTEM_EVENT_ETH_GOT_IP: | ||||
|       event_name = "ETH Got IP"; | ||||
|       this->connected_ = true; | ||||
|       break; | ||||
|     default: | ||||
|       return; | ||||
|   } | ||||
|  | ||||
|   this->initialized_ = true; | ||||
|   ESP_LOGV(TAG, "[Ethernet event] %s (num=%d)", event_name, event); | ||||
| } | ||||
|  | ||||
|   tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_ETH, App.get_name().c_str()); | ||||
| void EthernetComponent::start_connect_() { | ||||
|   this->connect_begin_ = millis(); | ||||
|   this->status_set_warning(); | ||||
|  | ||||
|   esp_err_t err; | ||||
|   err = tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_ETH, App.get_name().c_str()); | ||||
|   ESPHL_ERROR_CHECK(err, "ETH set hostname error"); | ||||
|  | ||||
|   tcpip_adapter_ip_info_t info; | ||||
|   if (this->manual_ip_.has_value()) { | ||||
| @@ -220,7 +225,7 @@ void EthernetComponent::eth_phy_power_enable_(bool enable) { | ||||
|   delay(1); | ||||
|   global_eth_component->orig_power_enable_fun_(enable); | ||||
| } | ||||
| bool EthernetComponent::is_connected() { return this->connected_ && this->last_connected_; } | ||||
| bool EthernetComponent::is_connected() { return this->state_ == EthernetComponentState::CONNECTED; } | ||||
| void EthernetComponent::dump_connect_params_() { | ||||
|   tcpip_adapter_ip_info_t ip; | ||||
|   tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip); | ||||
|   | ||||
| @@ -26,6 +26,12 @@ struct ManualIP { | ||||
|   IPAddress dns2;  ///< The second DNS server. 0.0.0.0 for default. | ||||
| }; | ||||
|  | ||||
| enum class EthernetComponentState { | ||||
|   STOPPED, | ||||
|   CONNECTING, | ||||
|   CONNECTED, | ||||
| }; | ||||
|  | ||||
| class EthernetComponent : public Component { | ||||
|  public: | ||||
|   EthernetComponent(); | ||||
| @@ -65,9 +71,9 @@ class EthernetComponent : public Component { | ||||
|   eth_clock_mode_t clk_mode_{ETH_CLOCK_GPIO0_IN}; | ||||
|   optional<ManualIP> manual_ip_{}; | ||||
|  | ||||
|   bool initialized_{false}; | ||||
|   bool started_{false}; | ||||
|   bool connected_{false}; | ||||
|   bool last_connected_{false}; | ||||
|   EthernetComponentState state_{EthernetComponentState::STOPPED}; | ||||
|   uint32_t connect_begin_; | ||||
|   eth_config_t eth_config; | ||||
|   eth_phy_power_enable_func orig_power_enable_fun_; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user