mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	BedJet: expose the outlet temperature on the climate and as a sensor (#6633)
This commit is contained in:
		| @@ -51,6 +51,7 @@ esphome/components/bang_bang/* @OttoWinter | ||||
| esphome/components/bedjet/* @jhansche | ||||
| esphome/components/bedjet/climate/* @jhansche | ||||
| esphome/components/bedjet/fan/* @jhansche | ||||
| esphome/components/bedjet/sensor/* @javawizard @jhansche | ||||
| esphome/components/bh1750/* @OttoWinter | ||||
| esphome/components/binary_sensor/* @esphome/core | ||||
| esphome/components/bk72xx/* @kuba2k2 | ||||
|   | ||||
| @@ -31,7 +31,7 @@ CONFIG_SCHEMA = ( | ||||
|  | ||||
| BEDJET_CLIENT_SCHEMA = cv.Schema( | ||||
|     { | ||||
|         cv.Required(CONF_BEDJET_ID): cv.use_id(BedJetHub), | ||||
|         cv.GenerateID(CONF_BEDJET_ID): cv.use_id(BedJetHub), | ||||
|     } | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -157,5 +157,11 @@ bool BedjetCodec::compare(const uint8_t *data, uint16_t length) { | ||||
|   return explicit_fields_changed; | ||||
| } | ||||
|  | ||||
| /// Converts a BedJet temp step into degrees Celsius. | ||||
| float bedjet_temp_to_c(uint8_t temp) { | ||||
|   // BedJet temp is "C*2"; to get C, divide by 2. | ||||
|   return temp / 2.0f; | ||||
| } | ||||
|  | ||||
| }  // namespace bedjet | ||||
| }  // namespace esphome | ||||
|   | ||||
| @@ -187,5 +187,8 @@ class BedjetCodec { | ||||
|   BedjetStatusPacket buf_; | ||||
| }; | ||||
|  | ||||
| /// Converts a BedJet temp step into degrees Celsius. | ||||
| float bedjet_temp_to_c(uint8_t temp); | ||||
|  | ||||
| }  // namespace bedjet | ||||
| }  // namespace esphome | ||||
|   | ||||
| @@ -40,6 +40,14 @@ enum BedjetHeatMode { | ||||
|   HEAT_MODE_EXTENDED, | ||||
| }; | ||||
|  | ||||
| // Which temperature to use as the climate entity's current temperature reading | ||||
| enum BedjetTemperatureSource { | ||||
|   // Use the temperature of the air the BedJet is putting out | ||||
|   TEMPERATURE_SOURCE_OUTLET, | ||||
|   // Use the ambient temperature of the room the BedJet is in | ||||
|   TEMPERATURE_SOURCE_AMBIENT | ||||
| }; | ||||
|  | ||||
| enum BedjetButton : uint8_t { | ||||
|   /// Turn BedJet off | ||||
|   BTN_OFF = 0x1, | ||||
|   | ||||
| @@ -7,6 +7,7 @@ from esphome.const import ( | ||||
|     CONF_HEAT_MODE, | ||||
|     CONF_ID, | ||||
|     CONF_RECEIVE_TIMEOUT, | ||||
|     CONF_TEMPERATURE_SOURCE, | ||||
|     CONF_TIME_ID, | ||||
| ) | ||||
| from .. import ( | ||||
| @@ -21,10 +22,15 @@ DEPENDENCIES = ["bedjet"] | ||||
|  | ||||
| BedJetClimate = bedjet_ns.class_("BedJetClimate", climate.Climate, cg.PollingComponent) | ||||
| BedjetHeatMode = bedjet_ns.enum("BedjetHeatMode") | ||||
| BedjetTemperatureSource = bedjet_ns.enum("BedjetTemperatureSource") | ||||
| BEDJET_HEAT_MODES = { | ||||
|     "heat": BedjetHeatMode.HEAT_MODE_HEAT, | ||||
|     "extended": BedjetHeatMode.HEAT_MODE_EXTENDED, | ||||
| } | ||||
| BEDJET_TEMPERATURE_SOURCES = { | ||||
|     "outlet": BedjetTemperatureSource.TEMPERATURE_SOURCE_OUTLET, | ||||
|     "ambient": BedjetTemperatureSource.TEMPERATURE_SOURCE_AMBIENT, | ||||
| } | ||||
|  | ||||
| CONFIG_SCHEMA = ( | ||||
|     climate.CLIMATE_SCHEMA.extend( | ||||
| @@ -33,6 +39,9 @@ CONFIG_SCHEMA = ( | ||||
|             cv.Optional(CONF_HEAT_MODE, default="heat"): cv.enum( | ||||
|                 BEDJET_HEAT_MODES, lower=True | ||||
|             ), | ||||
|             cv.Optional(CONF_TEMPERATURE_SOURCE, default="ambient"): cv.enum( | ||||
|                 BEDJET_TEMPERATURE_SOURCES, lower=True | ||||
|             ), | ||||
|         } | ||||
|     ) | ||||
|     .extend(cv.polling_component_schema("60s")) | ||||
| @@ -63,3 +72,4 @@ async def to_code(config): | ||||
|     await register_bedjet_child(var, config) | ||||
|  | ||||
|     cg.add(var.set_heating_mode(config[CONF_HEAT_MODE])) | ||||
|     cg.add(var.set_temperature_source(config[CONF_TEMPERATURE_SOURCE])) | ||||
|   | ||||
| @@ -8,12 +8,6 @@ namespace bedjet { | ||||
|  | ||||
| using namespace esphome::climate; | ||||
|  | ||||
| /// Converts a BedJet temp step into degrees Celsius. | ||||
| float bedjet_temp_to_c(const uint8_t temp) { | ||||
|   // BedJet temp is "C*2"; to get C, divide by 2. | ||||
|   return temp / 2.0f; | ||||
| } | ||||
|  | ||||
| static const std::string *bedjet_fan_step_to_fan_mode(const uint8_t fan_step) { | ||||
|   if (fan_step < BEDJET_FAN_SPEED_COUNT) | ||||
|     return &BEDJET_FAN_STEP_NAME_STRINGS[fan_step]; | ||||
| @@ -236,9 +230,14 @@ void BedJetClimate::on_status(const BedjetStatusPacket *data) { | ||||
|   if (converted_temp > 0) | ||||
|     this->target_temperature = converted_temp; | ||||
|  | ||||
|   if (this->temperature_source_ == TEMPERATURE_SOURCE_OUTLET) { | ||||
|     converted_temp = bedjet_temp_to_c(data->actual_temp_step); | ||||
|   } else { | ||||
|     converted_temp = bedjet_temp_to_c(data->ambient_temp_step); | ||||
|   if (converted_temp > 0) | ||||
|   } | ||||
|   if (converted_temp > 0) { | ||||
|     this->current_temperature = converted_temp; | ||||
|   } | ||||
|  | ||||
|   const auto *fan_mode_name = bedjet_fan_step_to_fan_mode(data->fan_step); | ||||
|   if (fan_mode_name != nullptr) { | ||||
|   | ||||
| @@ -28,6 +28,8 @@ class BedJetClimate : public climate::Climate, public BedJetClient, public Polli | ||||
|  | ||||
|   /** Sets the default strategy to use for climate::CLIMATE_MODE_HEAT. */ | ||||
|   void set_heating_mode(BedjetHeatMode mode) { this->heating_mode_ = mode; } | ||||
|   /** Sets the temperature source to use for the climate entity's current temperature */ | ||||
|   void set_temperature_source(BedjetTemperatureSource source) { this->temperature_source_ = source; } | ||||
|  | ||||
|   climate::ClimateTraits traits() override { | ||||
|     auto traits = climate::ClimateTraits(); | ||||
| @@ -74,6 +76,7 @@ class BedJetClimate : public climate::Climate, public BedJetClient, public Polli | ||||
|   void control(const climate::ClimateCall &call) override; | ||||
|  | ||||
|   BedjetHeatMode heating_mode_ = HEAT_MODE_HEAT; | ||||
|   BedjetTemperatureSource temperature_source_ = TEMPERATURE_SOURCE_AMBIENT; | ||||
|  | ||||
|   void reset_state_(); | ||||
|   bool update_status_(); | ||||
|   | ||||
							
								
								
									
										55
									
								
								esphome/components/bedjet/sensor/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								esphome/components/bedjet/sensor/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| import logging | ||||
|  | ||||
| import esphome.codegen as cg | ||||
| import esphome.config_validation as cv | ||||
| from esphome.components import sensor | ||||
| from esphome.const import ( | ||||
|     CONF_ID, | ||||
|     DEVICE_CLASS_TEMPERATURE, | ||||
|     STATE_CLASS_MEASUREMENT, | ||||
|     UNIT_CELSIUS, | ||||
| ) | ||||
| from .. import ( | ||||
|     BEDJET_CLIENT_SCHEMA, | ||||
|     bedjet_ns, | ||||
|     register_bedjet_child, | ||||
| ) | ||||
|  | ||||
| _LOGGER = logging.getLogger(__name__) | ||||
| CODEOWNERS = ["@jhansche", "@javawizard"] | ||||
| DEPENDENCIES = ["bedjet"] | ||||
|  | ||||
| CONF_OUTLET_TEMPERATURE = "outlet_temperature" | ||||
| CONF_AMBIENT_TEMPERATURE = "ambient_temperature" | ||||
|  | ||||
| BedjetSensor = bedjet_ns.class_("BedjetSensor", cg.Component) | ||||
|  | ||||
| CONFIG_SCHEMA = cv.Schema( | ||||
|     { | ||||
|         cv.GenerateID(): cv.declare_id(BedjetSensor), | ||||
|         cv.Optional(CONF_OUTLET_TEMPERATURE): sensor.sensor_schema( | ||||
|             unit_of_measurement=UNIT_CELSIUS, | ||||
|             device_class=DEVICE_CLASS_TEMPERATURE, | ||||
|             state_class=STATE_CLASS_MEASUREMENT, | ||||
|         ), | ||||
|         cv.Optional(CONF_AMBIENT_TEMPERATURE): sensor.sensor_schema( | ||||
|             unit_of_measurement=UNIT_CELSIUS, | ||||
|             device_class=DEVICE_CLASS_TEMPERATURE, | ||||
|             state_class=STATE_CLASS_MEASUREMENT, | ||||
|         ), | ||||
|     } | ||||
| ).extend(BEDJET_CLIENT_SCHEMA) | ||||
|  | ||||
|  | ||||
| async def to_code(config): | ||||
|     var = cg.new_Pvariable(config[CONF_ID]) | ||||
|     await cg.register_component(var, config) | ||||
|     await register_bedjet_child(var, config) | ||||
|  | ||||
|     if outlet_temperature_sensor := config.get(CONF_OUTLET_TEMPERATURE): | ||||
|         sensor_var = await sensor.new_sensor(outlet_temperature_sensor) | ||||
|         cg.add(var.set_outlet_temperature_sensor(sensor_var)) | ||||
|  | ||||
|     if ambient_temperature_sensor := config.get(CONF_AMBIENT_TEMPERATURE): | ||||
|         sensor_var = await sensor.new_sensor(ambient_temperature_sensor) | ||||
|         cg.add(var.set_ambient_temperature_sensor(sensor_var)) | ||||
							
								
								
									
										34
									
								
								esphome/components/bedjet/sensor/bedjet_sensor.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								esphome/components/bedjet/sensor/bedjet_sensor.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| #include "bedjet_sensor.h" | ||||
| #include "esphome/core/log.h" | ||||
|  | ||||
| namespace esphome { | ||||
| namespace bedjet { | ||||
|  | ||||
| std::string BedjetSensor::describe() { return "BedJet Sensor"; } | ||||
|  | ||||
| void BedjetSensor::dump_config() { | ||||
|   ESP_LOGCONFIG(TAG, "BedJet Sensor:"); | ||||
|   LOG_SENSOR("  ", "Outlet Temperature", this->outlet_temperature_sensor_); | ||||
|   LOG_SENSOR("  ", "Ambient Temperature", this->ambient_temperature_sensor_); | ||||
| } | ||||
|  | ||||
| void BedjetSensor::on_bedjet_state(bool is_ready) {} | ||||
|  | ||||
| void BedjetSensor::on_status(const BedjetStatusPacket *data) { | ||||
|   if (this->outlet_temperature_sensor_ != nullptr) { | ||||
|     float converted_temp = bedjet_temp_to_c(data->actual_temp_step); | ||||
|     if (converted_temp > 0) { | ||||
|       this->outlet_temperature_sensor_->publish_state(converted_temp); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   if (this->ambient_temperature_sensor_ != nullptr) { | ||||
|     float converted_temp = bedjet_temp_to_c(data->ambient_temp_step); | ||||
|     if (converted_temp > 0) { | ||||
|       this->ambient_temperature_sensor_->publish_state(converted_temp); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| }  // namespace bedjet | ||||
| }  // namespace esphome | ||||
							
								
								
									
										32
									
								
								esphome/components/bedjet/sensor/bedjet_sensor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								esphome/components/bedjet/sensor/bedjet_sensor.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "esphome/core/component.h" | ||||
| #include "esphome/components/sensor/sensor.h" | ||||
| #include "esphome/components/bedjet/bedjet_child.h" | ||||
| #include "esphome/components/bedjet/bedjet_codec.h" | ||||
|  | ||||
| namespace esphome { | ||||
| namespace bedjet { | ||||
|  | ||||
| class BedjetSensor : public BedJetClient, public Component { | ||||
|  public: | ||||
|   void dump_config() override; | ||||
|  | ||||
|   void on_status(const BedjetStatusPacket *data) override; | ||||
|   void on_bedjet_state(bool is_ready) override; | ||||
|   std::string describe() override; | ||||
|  | ||||
|   void set_outlet_temperature_sensor(sensor::Sensor *outlet_temperature_sensor) { | ||||
|     this->outlet_temperature_sensor_ = outlet_temperature_sensor; | ||||
|   } | ||||
|   void set_ambient_temperature_sensor(sensor::Sensor *ambient_temperature_sensor) { | ||||
|     this->ambient_temperature_sensor_ = ambient_temperature_sensor; | ||||
|   } | ||||
|  | ||||
|  protected: | ||||
|   sensor::Sensor *outlet_temperature_sensor_{nullptr}; | ||||
|   sensor::Sensor *ambient_temperature_sensor_{nullptr}; | ||||
| }; | ||||
|  | ||||
| }  // namespace bedjet | ||||
| }  // namespace esphome | ||||
| @@ -26,8 +26,16 @@ climate: | ||||
|     name: My Bedjet | ||||
|     bedjet_id: bedjet_hub | ||||
|     heat_mode: extended | ||||
|     temperature_source: ambient | ||||
|  | ||||
| fan: | ||||
|   - platform: bedjet | ||||
|     name: My Bedjet fan | ||||
|     bedjet_id: bedjet_hub | ||||
|  | ||||
| sensor: | ||||
|   - platform: bedjet | ||||
|     ambient_temperature: | ||||
|       name: My BedJet Ambient Temperature | ||||
|     outlet_temperature: | ||||
|       name: My BedJet Outlet Temperature | ||||
|   | ||||
		Reference in New Issue
	
	Block a user