[BedJet] Add configurable heating strategy (#3519)

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
Joe 2022-05-30 23:45:01 -04:00 committed by GitHub
parent d2cefbf224
commit 708672ec7e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 53 additions and 4 deletions

View file

@ -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:

View file

@ -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;

View file

@ -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,

View file

@ -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_))

View file

@ -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