Skip to content

Commit

Permalink
BedJet: expose the outlet temperature on the climate and as a sensor (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
javawizard committed May 15, 2024
1 parent 1f29023 commit 773951d
Show file tree
Hide file tree
Showing 12 changed files with 168 additions and 9 deletions.
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion esphome/components/bedjet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

BEDJET_CLIENT_SCHEMA = cv.Schema(
{
cv.Required(CONF_BEDJET_ID): cv.use_id(BedJetHub),
cv.GenerateID(CONF_BEDJET_ID): cv.use_id(BedJetHub),
}
)

Expand Down
6 changes: 6 additions & 0 deletions esphome/components/bedjet/bedjet_codec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 3 additions & 0 deletions esphome/components/bedjet/bedjet_codec.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
8 changes: 8 additions & 0 deletions esphome/components/bedjet/bedjet_const.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
10 changes: 10 additions & 0 deletions esphome/components/bedjet/climate/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
CONF_HEAT_MODE,
CONF_ID,
CONF_RECEIVE_TIMEOUT,
CONF_TEMPERATURE_SOURCE,
CONF_TIME_ID,
)
from .. import (
Expand All @@ -21,10 +22,15 @@

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(
Expand All @@ -33,6 +39,9 @@
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"))
Expand Down Expand Up @@ -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]))
15 changes: 7 additions & 8 deletions esphome/components/bedjet/climate/bedjet_climate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -236,9 +230,14 @@ void BedJetClimate::on_status(const BedjetStatusPacket *data) {
if (converted_temp > 0)
this->target_temperature = converted_temp;

converted_temp = bedjet_temp_to_c(data->ambient_temp_step);
if (converted_temp > 0)
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) {
this->current_temperature = converted_temp;
}

const auto *fan_mode_name = bedjet_fan_step_to_fan_mode(data->fan_step);
if (fan_mode_name != nullptr) {
Expand Down
3 changes: 3 additions & 0 deletions esphome/components/bedjet/climate/bedjet_climate.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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_();
Expand Down
55 changes: 55 additions & 0 deletions esphome/components/bedjet/sensor/__init__.py
Original file line number Diff line number Diff line change
@@ -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 changes: 34 additions & 0 deletions esphome/components/bedjet/sensor/bedjet_sensor.cpp
Original file line number Diff line number Diff line change
@@ -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 changes: 32 additions & 0 deletions esphome/components/bedjet/sensor/bedjet_sensor.h
Original file line number Diff line number Diff line change
@@ -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
8 changes: 8 additions & 0 deletions tests/components/bedjet/common.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 773951d

Please sign in to comment.