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/rf_bridge/* @jesserockz | ||||||
| esphome/components/rgbct/* @jesserockz | esphome/components/rgbct/* @jesserockz | ||||||
| esphome/components/rtttl/* @glmnet | esphome/components/rtttl/* @glmnet | ||||||
| esphome/components/safe_mode/* @paulmonigatti | esphome/components/safe_mode/* @jsuanet @paulmonigatti | ||||||
| esphome/components/scd4x/* @sjtrny | esphome/components/scd4x/* @sjtrny | ||||||
| esphome/components/script/* @esphome/core | esphome/components/script/* @esphome/core | ||||||
| esphome/components/sdm_meter/* @jesserockz @polyfaces | esphome/components/sdm_meter/* @jesserockz @polyfaces | ||||||
| @@ -143,7 +143,7 @@ esphome/components/select/* @esphome/core | |||||||
| esphome/components/sensor/* @esphome/core | esphome/components/sensor/* @esphome/core | ||||||
| esphome/components/sgp40/* @SenexCrenshaw | esphome/components/sgp40/* @SenexCrenshaw | ||||||
| esphome/components/sht4x/* @sjtrny | esphome/components/sht4x/* @sjtrny | ||||||
| esphome/components/shutdown/* @esphome/core | esphome/components/shutdown/* @esphome/core @jsuanet | ||||||
| esphome/components/sim800l/* @glmnet | esphome/components/sim800l/* @glmnet | ||||||
| esphome/components/sm2135/* @BoukeHaarsma23 | esphome/components/sm2135/* @BoukeHaarsma23 | ||||||
| esphome/components/socket/* @esphome/core | esphome/components/socket/* @esphome/core | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import esphome.codegen as cg | import esphome.codegen as cg | ||||||
|  |  | ||||||
| CODEOWNERS = ["@paulmonigatti"] | CODEOWNERS = ["@paulmonigatti", "@jsuanet"] | ||||||
|  |  | ||||||
| safe_mode_ns = cg.esphome_ns.namespace("safe_mode") | 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: | button: | ||||||
|   - platform: restart |   - platform: restart | ||||||
|     name: Restart Button |     name: Restart Button | ||||||
|  |   - platform: safe_mode | ||||||
|  |     name: Safe Mode Button | ||||||
|  |   - platform: shutdown | ||||||
|  |     name: Shutdown Button | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user