mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	[homeassistant] Native number entity import and control (#6455)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
		
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							1d25db491c
						
					
				
				
					commit
					a5fdcb31fc
				
			| @@ -169,6 +169,7 @@ esphome/components/heatpumpir/* @rob-deutsch | |||||||
| esphome/components/hitachi_ac424/* @sourabhjaiswal | esphome/components/hitachi_ac424/* @sourabhjaiswal | ||||||
| esphome/components/hm3301/* @freekode | esphome/components/hm3301/* @freekode | ||||||
| esphome/components/homeassistant/* @OttoWinter @esphome/core | esphome/components/homeassistant/* @OttoWinter @esphome/core | ||||||
|  | esphome/components/homeassistant/number/* @landonr | ||||||
| esphome/components/homeassistant/switch/* @Links2004 | esphome/components/homeassistant/switch/* @Links2004 | ||||||
| esphome/components/honeywell_hih_i2c/* @Benichou34 | esphome/components/honeywell_hih_i2c/* @Benichou34 | ||||||
| esphome/components/honeywellabp/* @RubyBailey | esphome/components/honeywellabp/* @RubyBailey | ||||||
|   | |||||||
							
								
								
									
										33
									
								
								esphome/components/homeassistant/number/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								esphome/components/homeassistant/number/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | |||||||
|  | import esphome.codegen as cg | ||||||
|  | from esphome.components import number | ||||||
|  | import esphome.config_validation as cv | ||||||
|  |  | ||||||
|  | from .. import ( | ||||||
|  |     HOME_ASSISTANT_IMPORT_CONTROL_SCHEMA, | ||||||
|  |     homeassistant_ns, | ||||||
|  |     setup_home_assistant_entity, | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | CODEOWNERS = ["@landonr"] | ||||||
|  | DEPENDENCIES = ["api"] | ||||||
|  |  | ||||||
|  | HomeassistantNumber = homeassistant_ns.class_( | ||||||
|  |     "HomeassistantNumber", number.Number, cg.Component | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | CONFIG_SCHEMA = ( | ||||||
|  |     number.number_schema(HomeassistantNumber) | ||||||
|  |     .extend(HOME_ASSISTANT_IMPORT_CONTROL_SCHEMA) | ||||||
|  |     .extend(cv.COMPONENT_SCHEMA) | ||||||
|  | ) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | async def to_code(config): | ||||||
|  |     var = await number.new_number( | ||||||
|  |         config, | ||||||
|  |         min_value=0, | ||||||
|  |         max_value=0, | ||||||
|  |         step=0, | ||||||
|  |     ) | ||||||
|  |     await cg.register_component(var, config) | ||||||
|  |     setup_home_assistant_entity(var, config) | ||||||
							
								
								
									
										100
									
								
								esphome/components/homeassistant/number/homeassistant_number.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								esphome/components/homeassistant/number/homeassistant_number.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,100 @@ | |||||||
|  | #include "homeassistant_number.h" | ||||||
|  |  | ||||||
|  | #include "esphome/components/api/api_pb2.h" | ||||||
|  | #include "esphome/components/api/api_server.h" | ||||||
|  | #include "esphome/core/log.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace homeassistant { | ||||||
|  |  | ||||||
|  | static const char *const TAG = "homeassistant.number"; | ||||||
|  |  | ||||||
|  | void HomeassistantNumber::state_changed_(const std::string &state) { | ||||||
|  |   auto number_value = parse_number<float>(state); | ||||||
|  |   if (!number_value.has_value()) { | ||||||
|  |     ESP_LOGW(TAG, "'%s': Can't convert '%s' to number!", this->entity_id_.c_str(), state.c_str()); | ||||||
|  |     this->publish_state(NAN); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   if (this->state == number_value.value()) { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   ESP_LOGD(TAG, "'%s': Got state %s", this->entity_id_.c_str(), state.c_str()); | ||||||
|  |   this->publish_state(number_value.value()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void HomeassistantNumber::min_retrieved_(const std::string &min) { | ||||||
|  |   auto min_value = parse_number<float>(min); | ||||||
|  |   if (!min_value.has_value()) { | ||||||
|  |     ESP_LOGE(TAG, "'%s': Can't convert 'min' value '%s' to number!", this->entity_id_.c_str(), min.c_str()); | ||||||
|  |   } | ||||||
|  |   ESP_LOGD(TAG, "'%s': Min retrieved: %s", get_name().c_str(), min.c_str()); | ||||||
|  |   this->traits.set_min_value(min_value.value()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void HomeassistantNumber::max_retrieved_(const std::string &max) { | ||||||
|  |   auto max_value = parse_number<float>(max); | ||||||
|  |   if (!max_value.has_value()) { | ||||||
|  |     ESP_LOGE(TAG, "'%s': Can't convert 'max' value '%s' to number!", this->entity_id_.c_str(), max.c_str()); | ||||||
|  |   } | ||||||
|  |   ESP_LOGD(TAG, "'%s': Max retrieved: %s", get_name().c_str(), max.c_str()); | ||||||
|  |   this->traits.set_max_value(max_value.value()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void HomeassistantNumber::step_retrieved_(const std::string &step) { | ||||||
|  |   auto step_value = parse_number<float>(step); | ||||||
|  |   if (!step_value.has_value()) { | ||||||
|  |     ESP_LOGE(TAG, "'%s': Can't convert 'step' value '%s' to number!", this->entity_id_.c_str(), step.c_str()); | ||||||
|  |   } | ||||||
|  |   ESP_LOGD(TAG, "'%s': Step Retrieved %s", get_name().c_str(), step.c_str()); | ||||||
|  |   this->traits.set_step(step_value.value()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void HomeassistantNumber::setup() { | ||||||
|  |   api::global_api_server->subscribe_home_assistant_state( | ||||||
|  |       this->entity_id_, nullopt, std::bind(&HomeassistantNumber::state_changed_, this, std::placeholders::_1)); | ||||||
|  |  | ||||||
|  |   api::global_api_server->get_home_assistant_state( | ||||||
|  |       this->entity_id_, optional<std::string>("min"), | ||||||
|  |       std::bind(&HomeassistantNumber::min_retrieved_, this, std::placeholders::_1)); | ||||||
|  |   api::global_api_server->get_home_assistant_state( | ||||||
|  |       this->entity_id_, optional<std::string>("max"), | ||||||
|  |       std::bind(&HomeassistantNumber::max_retrieved_, this, std::placeholders::_1)); | ||||||
|  |   api::global_api_server->get_home_assistant_state( | ||||||
|  |       this->entity_id_, optional<std::string>("step"), | ||||||
|  |       std::bind(&HomeassistantNumber::step_retrieved_, this, std::placeholders::_1)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void HomeassistantNumber::dump_config() { | ||||||
|  |   LOG_NUMBER("", "Homeassistant Number", this); | ||||||
|  |   ESP_LOGCONFIG(TAG, "  Entity ID: '%s'", this->entity_id_.c_str()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | float HomeassistantNumber::get_setup_priority() const { return setup_priority::AFTER_CONNECTION; } | ||||||
|  |  | ||||||
|  | void HomeassistantNumber::control(float value) { | ||||||
|  |   if (!api::global_api_server->is_connected()) { | ||||||
|  |     ESP_LOGE(TAG, "No clients connected to API server"); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   this->publish_state(value); | ||||||
|  |  | ||||||
|  |   api::HomeassistantServiceResponse resp; | ||||||
|  |   resp.service = "number.set_value"; | ||||||
|  |  | ||||||
|  |   api::HomeassistantServiceMap entity_id; | ||||||
|  |   entity_id.key = "entity_id"; | ||||||
|  |   entity_id.value = this->entity_id_; | ||||||
|  |   resp.data.push_back(entity_id); | ||||||
|  |  | ||||||
|  |   api::HomeassistantServiceMap entity_value; | ||||||
|  |   entity_value.key = "value"; | ||||||
|  |   entity_value.value = to_string(value); | ||||||
|  |   resp.data.push_back(entity_value); | ||||||
|  |  | ||||||
|  |   api::global_api_server->send_homeassistant_service_call(resp); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | }  // namespace homeassistant | ||||||
|  | }  // namespace esphome | ||||||
| @@ -0,0 +1,31 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <map> | ||||||
|  | #include <string> | ||||||
|  |  | ||||||
|  | #include "esphome/components/number/number.h" | ||||||
|  | #include "esphome/core/component.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace homeassistant { | ||||||
|  |  | ||||||
|  | class HomeassistantNumber : public number::Number, public Component { | ||||||
|  |  public: | ||||||
|  |   void set_entity_id(const std::string &entity_id) { this->entity_id_ = entity_id; } | ||||||
|  |  | ||||||
|  |   void setup() override; | ||||||
|  |   void dump_config() override; | ||||||
|  |   float get_setup_priority() const override; | ||||||
|  |  | ||||||
|  |  protected: | ||||||
|  |   void state_changed_(const std::string &state); | ||||||
|  |   void min_retrieved_(const std::string &min); | ||||||
|  |   void max_retrieved_(const std::string &max); | ||||||
|  |   void step_retrieved_(const std::string &step); | ||||||
|  |  | ||||||
|  |   void control(float value) override; | ||||||
|  |  | ||||||
|  |   std::string entity_id_; | ||||||
|  | }; | ||||||
|  | }  // namespace homeassistant | ||||||
|  | }  // namespace esphome | ||||||
| @@ -46,6 +46,11 @@ binary_sensor: | |||||||
|     attribute: world |     attribute: world | ||||||
|     id: ha_hello_world_binary_attribute |     id: ha_hello_world_binary_attribute | ||||||
|  |  | ||||||
|  | number: | ||||||
|  |   - platform: homeassistant | ||||||
|  |     entity_id: number.hello_world | ||||||
|  |     id: ha_hello_world_number | ||||||
|  |  | ||||||
| sensor: | sensor: | ||||||
|   - platform: homeassistant |   - platform: homeassistant | ||||||
|     entity_id: sensor.hello_world |     entity_id: sensor.hello_world | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user