mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +00:00 
			
		
		
		
	Add shutdown and safe_mode button (#2918)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Co-authored-by: Jos Suanet <jos@suanet.net>
This commit is contained in:
		| @@ -133,7 +133,7 @@ esphome/components/restart/* @esphome/core | ||||
| esphome/components/rf_bridge/* @jesserockz | ||||
| esphome/components/rgbct/* @jesserockz | ||||
| esphome/components/rtttl/* @glmnet | ||||
| esphome/components/safe_mode/* @paulmonigatti | ||||
| esphome/components/safe_mode/* @jsuanet @paulmonigatti | ||||
| esphome/components/scd4x/* @sjtrny | ||||
| esphome/components/script/* @esphome/core | ||||
| esphome/components/sdm_meter/* @jesserockz @polyfaces | ||||
| @@ -143,7 +143,7 @@ esphome/components/select/* @esphome/core | ||||
| esphome/components/sensor/* @esphome/core | ||||
| esphome/components/sgp40/* @SenexCrenshaw | ||||
| esphome/components/sht4x/* @sjtrny | ||||
| esphome/components/shutdown/* @esphome/core | ||||
| esphome/components/shutdown/* @esphome/core @jsuanet | ||||
| esphome/components/sim800l/* @glmnet | ||||
| esphome/components/sm2135/* @BoukeHaarsma23 | ||||
| esphome/components/socket/* @esphome/core | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import esphome.codegen as cg | ||||
|  | ||||
| CODEOWNERS = ["@paulmonigatti"] | ||||
| CODEOWNERS = ["@paulmonigatti", "@jsuanet"] | ||||
|  | ||||
| safe_mode_ns = cg.esphome_ns.namespace("safe_mode") | ||||
|   | ||||
							
								
								
									
										36
									
								
								esphome/components/safe_mode/button/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								esphome/components/safe_mode/button/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| import esphome.codegen as cg | ||||
| import esphome.config_validation as cv | ||||
| from esphome.components import button | ||||
| from esphome.components.ota import OTAComponent | ||||
| from esphome.const import ( | ||||
|     CONF_ID, | ||||
|     CONF_OTA, | ||||
|     DEVICE_CLASS_RESTART, | ||||
|     ENTITY_CATEGORY_CONFIG, | ||||
|     ICON_RESTART_ALERT, | ||||
| ) | ||||
|  | ||||
| DEPENDENCIES = ["ota"] | ||||
|  | ||||
| safe_mode_ns = cg.esphome_ns.namespace("safe_mode") | ||||
| SafeModeButton = safe_mode_ns.class_("SafeModeButton", button.Button, cg.Component) | ||||
|  | ||||
| CONFIG_SCHEMA = ( | ||||
|     button.button_schema( | ||||
|         device_class=DEVICE_CLASS_RESTART, | ||||
|         entity_category=ENTITY_CATEGORY_CONFIG, | ||||
|         icon=ICON_RESTART_ALERT, | ||||
|     ) | ||||
|     .extend({cv.GenerateID(): cv.declare_id(SafeModeButton)}) | ||||
|     .extend({cv.GenerateID(CONF_OTA): cv.use_id(OTAComponent)}) | ||||
|     .extend(cv.COMPONENT_SCHEMA) | ||||
| ) | ||||
|  | ||||
|  | ||||
| async def to_code(config): | ||||
|     var = cg.new_Pvariable(config[CONF_ID]) | ||||
|     await cg.register_component(var, config) | ||||
|     await button.register_button(var, config) | ||||
|  | ||||
|     ota = await cg.get_variable(config[CONF_OTA]) | ||||
|     cg.add(var.set_ota(ota)) | ||||
							
								
								
									
										25
									
								
								esphome/components/safe_mode/button/safe_mode_button.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								esphome/components/safe_mode/button/safe_mode_button.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| #include "safe_mode_button.h" | ||||
| #include "esphome/core/hal.h" | ||||
| #include "esphome/core/log.h" | ||||
| #include "esphome/core/application.h" | ||||
|  | ||||
| namespace esphome { | ||||
| namespace safe_mode { | ||||
|  | ||||
| static const char *const TAG = "safe_mode.button"; | ||||
|  | ||||
| void SafeModeButton::set_ota(ota::OTAComponent *ota) { this->ota_ = ota; } | ||||
|  | ||||
| void SafeModeButton::press_action() { | ||||
|   ESP_LOGI(TAG, "Restarting device in safe mode..."); | ||||
|   this->ota_->set_safe_mode_pending(true); | ||||
|  | ||||
|   // Let MQTT settle a bit | ||||
|   delay(100);  // NOLINT | ||||
|   App.safe_reboot(); | ||||
| } | ||||
|  | ||||
| void SafeModeButton::dump_config() { LOG_BUTTON("", "Safe Mode Button", this); } | ||||
|  | ||||
| }  // namespace safe_mode | ||||
| }  // namespace esphome | ||||
							
								
								
									
										21
									
								
								esphome/components/safe_mode/button/safe_mode_button.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								esphome/components/safe_mode/button/safe_mode_button.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "esphome/core/component.h" | ||||
| #include "esphome/components/ota/ota_component.h" | ||||
| #include "esphome/components/button/button.h" | ||||
|  | ||||
| namespace esphome { | ||||
| namespace safe_mode { | ||||
|  | ||||
| class SafeModeButton : public button::Button, public Component { | ||||
|  public: | ||||
|   void dump_config() override; | ||||
|   void set_ota(ota::OTAComponent *ota); | ||||
|  | ||||
|  protected: | ||||
|   ota::OTAComponent *ota_; | ||||
|   void press_action() override; | ||||
| }; | ||||
|  | ||||
| }  // namespace safe_mode | ||||
| }  // namespace esphome | ||||
| @@ -1 +1 @@ | ||||
| CODEOWNERS = ["@esphome/core"] | ||||
| CODEOWNERS = ["@esphome/core", "@jsuanet"] | ||||
|   | ||||
							
								
								
									
										23
									
								
								esphome/components/shutdown/button/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								esphome/components/shutdown/button/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| import esphome.codegen as cg | ||||
| import esphome.config_validation as cv | ||||
| from esphome.components import button | ||||
| from esphome.const import ( | ||||
|     CONF_ID, | ||||
|     ENTITY_CATEGORY_CONFIG, | ||||
|     ICON_POWER, | ||||
| ) | ||||
|  | ||||
| shutdown_ns = cg.esphome_ns.namespace("shutdown") | ||||
| ShutdownButton = shutdown_ns.class_("ShutdownButton", button.Button, cg.Component) | ||||
|  | ||||
| CONFIG_SCHEMA = ( | ||||
|     button.button_schema(entity_category=ENTITY_CATEGORY_CONFIG, icon=ICON_POWER) | ||||
|     .extend({cv.GenerateID(): cv.declare_id(ShutdownButton)}) | ||||
|     .extend(cv.COMPONENT_SCHEMA) | ||||
| ) | ||||
|  | ||||
|  | ||||
| async def to_code(config): | ||||
|     var = cg.new_Pvariable(config[CONF_ID]) | ||||
|     await cg.register_component(var, config) | ||||
|     await button.register_button(var, config) | ||||
							
								
								
									
										33
									
								
								esphome/components/shutdown/button/shutdown_button.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								esphome/components/shutdown/button/shutdown_button.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| #include "shutdown_button.h" | ||||
| #include "esphome/core/hal.h" | ||||
| #include "esphome/core/log.h" | ||||
| #include "esphome/core/application.h" | ||||
|  | ||||
| #ifdef USE_ESP32 | ||||
| #include <esp_sleep.h> | ||||
| #endif | ||||
| #ifdef USE_ESP8266 | ||||
| #include <Esp.h> | ||||
| #endif | ||||
|  | ||||
| namespace esphome { | ||||
| namespace shutdown { | ||||
|  | ||||
| static const char *const TAG = "shutdown.button"; | ||||
|  | ||||
| void ShutdownButton::dump_config() { LOG_BUTTON("", "Shutdown Button", this); } | ||||
| void ShutdownButton::press_action() { | ||||
|   ESP_LOGI(TAG, "Shutting down..."); | ||||
|   // Let MQTT settle a bit | ||||
|   delay(100);  // NOLINT | ||||
|   App.run_safe_shutdown_hooks(); | ||||
| #ifdef USE_ESP8266 | ||||
|   ESP.deepSleep(0);  // NOLINT(readability-static-accessed-through-instance) | ||||
| #endif | ||||
| #ifdef USE_ESP32 | ||||
|   esp_deep_sleep_start(); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| }  // namespace shutdown | ||||
| }  // namespace esphome | ||||
							
								
								
									
										18
									
								
								esphome/components/shutdown/button/shutdown_button.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								esphome/components/shutdown/button/shutdown_button.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "esphome/core/component.h" | ||||
| #include "esphome/components/button/button.h" | ||||
|  | ||||
| namespace esphome { | ||||
| namespace shutdown { | ||||
|  | ||||
| class ShutdownButton : public button::Button, public Component { | ||||
|  public: | ||||
|   void dump_config() override; | ||||
|  | ||||
|  protected: | ||||
|   void press_action() override; | ||||
| }; | ||||
|  | ||||
| }  // namespace shutdown | ||||
| }  // namespace esphome | ||||
| @@ -531,3 +531,7 @@ xpt2046: | ||||
| button: | ||||
|   - platform: restart | ||||
|     name: Restart Button | ||||
|   - platform: safe_mode | ||||
|     name: Safe Mode Button | ||||
|   - platform: shutdown | ||||
|     name: Shutdown Button | ||||
|   | ||||
		Reference in New Issue
	
	Block a user