mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	[BedJet] Add configurable heating strategy (#3519)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
		| @@ -36,6 +36,14 @@ static uint8_t bedjet_fan_speed_to_step(const std::string &fan_step_percent) { | |||||||
|   return -1; |   return -1; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static BedjetButton heat_button(BedjetHeatMode mode) { | ||||||
|  |   BedjetButton btn = BTN_HEAT; | ||||||
|  |   if (mode == HEAT_MODE_EXTENDED) { | ||||||
|  |     btn = BTN_EXTHT; | ||||||
|  |   } | ||||||
|  |   return btn; | ||||||
|  | } | ||||||
|  |  | ||||||
| void Bedjet::upgrade_firmware() { | void Bedjet::upgrade_firmware() { | ||||||
|   auto *pkt = this->codec_->get_button_request(MAGIC_UPDATE); |   auto *pkt = this->codec_->get_button_request(MAGIC_UPDATE); | ||||||
|   auto status = this->write_bedjet_packet_(pkt); |   auto status = this->write_bedjet_packet_(pkt); | ||||||
| @@ -117,7 +125,7 @@ void Bedjet::control(const ClimateCall &call) { | |||||||
|         pkt = this->codec_->get_button_request(BTN_OFF); |         pkt = this->codec_->get_button_request(BTN_OFF); | ||||||
|         break; |         break; | ||||||
|       case climate::CLIMATE_MODE_HEAT: |       case climate::CLIMATE_MODE_HEAT: | ||||||
|         pkt = this->codec_->get_button_request(BTN_HEAT); |         pkt = this->codec_->get_button_request(heat_button(this->heating_mode_)); | ||||||
|         break; |         break; | ||||||
|       case climate::CLIMATE_MODE_FAN_ONLY: |       case climate::CLIMATE_MODE_FAN_ONLY: | ||||||
|         pkt = this->codec_->get_button_request(BTN_COOL); |         pkt = this->codec_->get_button_request(BTN_COOL); | ||||||
| @@ -186,6 +194,8 @@ void Bedjet::control(const ClimateCall &call) { | |||||||
|       pkt = this->codec_->get_button_request(BTN_M2); |       pkt = this->codec_->get_button_request(BTN_M2); | ||||||
|     } else if (preset == "M3") { |     } else if (preset == "M3") { | ||||||
|       pkt = this->codec_->get_button_request(BTN_M3); |       pkt = this->codec_->get_button_request(BTN_M3); | ||||||
|  |     } else if (preset == "LTD HT") { | ||||||
|  |       pkt = this->codec_->get_button_request(BTN_HEAT); | ||||||
|     } else if (preset == "EXT HT") { |     } else if (preset == "EXT HT") { | ||||||
|       pkt = this->codec_->get_button_request(BTN_EXTHT); |       pkt = this->codec_->get_button_request(BTN_EXTHT); | ||||||
|     } else { |     } else { | ||||||
| @@ -557,11 +567,25 @@ bool Bedjet::update_status_() { | |||||||
|       break; |       break; | ||||||
|  |  | ||||||
|     case MODE_HEAT: |     case MODE_HEAT: | ||||||
|  |       this->mode = climate::CLIMATE_MODE_HEAT; | ||||||
|  |       this->action = climate::CLIMATE_ACTION_HEATING; | ||||||
|  |       this->preset.reset(); | ||||||
|  |       if (this->heating_mode_ == HEAT_MODE_EXTENDED) { | ||||||
|  |         this->set_custom_preset_("LTD HT"); | ||||||
|  |       } else { | ||||||
|  |         this->custom_preset.reset(); | ||||||
|  |       } | ||||||
|  |       break; | ||||||
|  |  | ||||||
|     case MODE_EXTHT: |     case MODE_EXTHT: | ||||||
|       this->mode = climate::CLIMATE_MODE_HEAT; |       this->mode = climate::CLIMATE_MODE_HEAT; | ||||||
|       this->action = climate::CLIMATE_ACTION_HEATING; |       this->action = climate::CLIMATE_ACTION_HEATING; | ||||||
|       this->custom_preset.reset(); |  | ||||||
|       this->preset.reset(); |       this->preset.reset(); | ||||||
|  |       if (this->heating_mode_ == HEAT_MODE_EXTENDED) { | ||||||
|  |         this->custom_preset.reset(); | ||||||
|  |       } else { | ||||||
|  |         this->set_custom_preset_("EXT HT"); | ||||||
|  |       } | ||||||
|       break; |       break; | ||||||
|  |  | ||||||
|     case MODE_COOL: |     case MODE_COOL: | ||||||
|   | |||||||
| @@ -40,6 +40,8 @@ class Bedjet : public climate::Climate, public esphome::ble_client::BLEClientNod | |||||||
|   void set_time_id(time::RealTimeClock *time_id) { this->time_id_ = time_id; } |   void set_time_id(time::RealTimeClock *time_id) { this->time_id_ = time_id; } | ||||||
| #endif | #endif | ||||||
|   void set_status_timeout(uint32_t timeout) { this->timeout_ = timeout; } |   void set_status_timeout(uint32_t timeout) { this->timeout_ = timeout; } | ||||||
|  |   /** Sets the default strategy to use for climate::CLIMATE_MODE_HEAT. */ | ||||||
|  |   void set_heating_mode(BedjetHeatMode mode) { this->heating_mode_ = mode; } | ||||||
|  |  | ||||||
|   /** Attempts to check for and apply firmware updates. */ |   /** Attempts to check for and apply firmware updates. */ | ||||||
|   void upgrade_firmware(); |   void upgrade_firmware(); | ||||||
| @@ -68,12 +70,15 @@ class Bedjet : public climate::Climate, public esphome::ble_client::BLEClientNod | |||||||
|         // We could fetch biodata from bedjet and set these names that way. |         // We could fetch biodata from bedjet and set these names that way. | ||||||
|         // But then we have to invert the lookup in order to send the right preset. |         // But then we have to invert the lookup in order to send the right preset. | ||||||
|         // For now, we can leave them as M1-3 to match the remote buttons. |         // For now, we can leave them as M1-3 to match the remote buttons. | ||||||
|         // EXT HT added to match remote button. |  | ||||||
|         "EXT HT", |  | ||||||
|         "M1", |         "M1", | ||||||
|         "M2", |         "M2", | ||||||
|         "M3", |         "M3", | ||||||
|     }); |     }); | ||||||
|  |     if (this->heating_mode_ == HEAT_MODE_EXTENDED) { | ||||||
|  |       traits.add_supported_custom_preset("LTD HT"); | ||||||
|  |     } else { | ||||||
|  |       traits.add_supported_custom_preset("EXT HT"); | ||||||
|  |     } | ||||||
|     traits.set_visual_min_temperature(19.0); |     traits.set_visual_min_temperature(19.0); | ||||||
|     traits.set_visual_max_temperature(43.0); |     traits.set_visual_max_temperature(43.0); | ||||||
|     traits.set_visual_temperature_step(1.0); |     traits.set_visual_temperature_step(1.0); | ||||||
| @@ -90,6 +95,7 @@ class Bedjet : public climate::Climate, public esphome::ble_client::BLEClientNod | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
|   uint32_t timeout_{DEFAULT_STATUS_TIMEOUT}; |   uint32_t timeout_{DEFAULT_STATUS_TIMEOUT}; | ||||||
|  |   BedjetHeatMode heating_mode_ = HEAT_MODE_HEAT; | ||||||
|  |  | ||||||
|   static const uint32_t MIN_NOTIFY_THROTTLE = 5000; |   static const uint32_t MIN_NOTIFY_THROTTLE = 5000; | ||||||
|   static const uint32_t NOTIFY_WARN_THRESHOLD = 300000; |   static const uint32_t NOTIFY_WARN_THRESHOLD = 300000; | ||||||
|   | |||||||
| @@ -24,6 +24,14 @@ enum BedjetMode : uint8_t { | |||||||
|   MODE_WAIT = 6, |   MODE_WAIT = 6, | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | /** Optional heating strategies to use for climate::CLIMATE_MODE_HEAT. */ | ||||||
|  | enum BedjetHeatMode { | ||||||
|  |   /// HVACMode.HEAT is handled using BTN_HEAT (default) | ||||||
|  |   HEAT_MODE_HEAT, | ||||||
|  |   /// HVACMode.HEAT is handled using BTN_EXTHT | ||||||
|  |   HEAT_MODE_EXTENDED, | ||||||
|  | }; | ||||||
|  |  | ||||||
| enum BedjetButton : uint8_t { | enum BedjetButton : uint8_t { | ||||||
|   /// Turn BedJet off |   /// Turn BedJet off | ||||||
|   BTN_OFF = 0x1, |   BTN_OFF = 0x1, | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ import esphome.codegen as cg | |||||||
| import esphome.config_validation as cv | import esphome.config_validation as cv | ||||||
| from esphome.components import climate, ble_client, time | from esphome.components import climate, ble_client, time | ||||||
| from esphome.const import ( | from esphome.const import ( | ||||||
|  |     CONF_HEAT_MODE, | ||||||
|     CONF_ID, |     CONF_ID, | ||||||
|     CONF_RECEIVE_TIMEOUT, |     CONF_RECEIVE_TIMEOUT, | ||||||
|     CONF_TIME_ID, |     CONF_TIME_ID, | ||||||
| @@ -14,11 +15,19 @@ bedjet_ns = cg.esphome_ns.namespace("bedjet") | |||||||
| Bedjet = bedjet_ns.class_( | Bedjet = bedjet_ns.class_( | ||||||
|     "Bedjet", climate.Climate, ble_client.BLEClientNode, cg.PollingComponent |     "Bedjet", climate.Climate, ble_client.BLEClientNode, cg.PollingComponent | ||||||
| ) | ) | ||||||
|  | BedjetHeatMode = bedjet_ns.enum("BedjetHeatMode") | ||||||
|  | BEDJET_HEAT_MODES = { | ||||||
|  |     "heat": BedjetHeatMode.HEAT_MODE_HEAT, | ||||||
|  |     "extended": BedjetHeatMode.HEAT_MODE_EXTENDED, | ||||||
|  | } | ||||||
|  |  | ||||||
| CONFIG_SCHEMA = ( | CONFIG_SCHEMA = ( | ||||||
|     climate.CLIMATE_SCHEMA.extend( |     climate.CLIMATE_SCHEMA.extend( | ||||||
|         { |         { | ||||||
|             cv.GenerateID(): cv.declare_id(Bedjet), |             cv.GenerateID(): cv.declare_id(Bedjet), | ||||||
|  |             cv.Optional(CONF_HEAT_MODE, default="heat"): cv.enum( | ||||||
|  |                 BEDJET_HEAT_MODES, lower=True | ||||||
|  |             ), | ||||||
|             cv.Optional(CONF_TIME_ID): cv.use_id(time.RealTimeClock), |             cv.Optional(CONF_TIME_ID): cv.use_id(time.RealTimeClock), | ||||||
|             cv.Optional( |             cv.Optional( | ||||||
|                 CONF_RECEIVE_TIMEOUT, default="0s" |                 CONF_RECEIVE_TIMEOUT, default="0s" | ||||||
| @@ -35,6 +44,7 @@ async def to_code(config): | |||||||
|     await cg.register_component(var, config) |     await cg.register_component(var, config) | ||||||
|     await climate.register_climate(var, config) |     await climate.register_climate(var, config) | ||||||
|     await ble_client.register_ble_node(var, config) |     await ble_client.register_ble_node(var, config) | ||||||
|  |     cg.add(var.set_heating_mode(config[CONF_HEAT_MODE])) | ||||||
|     if CONF_TIME_ID in config: |     if CONF_TIME_ID in config: | ||||||
|         time_ = await cg.get_variable(config[CONF_TIME_ID]) |         time_ = await cg.get_variable(config[CONF_TIME_ID]) | ||||||
|         cg.add(var.set_time_id(time_)) |         cg.add(var.set_time_id(time_)) | ||||||
|   | |||||||
| @@ -1886,6 +1886,7 @@ climate: | |||||||
|   - platform: bedjet |   - platform: bedjet | ||||||
|     name: My Bedjet |     name: My Bedjet | ||||||
|     ble_client_id: my_bedjet_ble_client |     ble_client_id: my_bedjet_ble_client | ||||||
|  |     heat_mode: extended | ||||||
|  |  | ||||||
| script: | script: | ||||||
|   - id: climate_custom |   - id: climate_custom | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user