Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Humidifier component #6591

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
ca3abc3
Add new humidifier and generic humidifier components.
Jaco1990 Apr 19, 2024
d900f2e
clean up code
Jaco1990 Apr 20, 2024
cd56f69
fix humidifier.py(generic_humidfier) & __init__.py(humidifier component)
Jaco1990 Apr 20, 2024
f63c572
correct coding test errors
Jaco1990 Apr 20, 2024
9ca9639
corrected more validation test coding errors
Jaco1990 Apr 20, 2024
a3b7d9f
Rework humidifier component to be inline with Home Assistant humidifi…
Jaco1990 Apr 20, 2024
964dc2a
Fix Actions.
Jaco1990 Apr 20, 2024
260ca20
Fix test3.yaml, run build_codeowners.py
Jaco1990 Apr 20, 2024
c33ceef
Fix test3.yaml
Jaco1990 Apr 20, 2024
908d78a
change switch to output in test3.yaml
Jaco1990 Apr 20, 2024
0e19ac4
Add humidifier.h to exclude list in ci-custom.
Jaco1990 Apr 21, 2024
a46d6f0
fixed unused variable
Jaco1990 Apr 21, 2024
cb808e8
fixed MQTT constants.
Jaco1990 Apr 21, 2024
f98855c
fixed spelling error.
Jaco1990 Apr 21, 2024
48c5117
fixed MQTT.
Jaco1990 Apr 21, 2024
672aa79
Fix errors.
Jaco1990 Apr 22, 2024
91e7139
Remove legacy away from generic humidifier.
Jaco1990 May 1, 2024
276dfed
Remove legacy away remnants from generic humidifier.
Jaco1990 May 1, 2024
5d6c0be
Extend and consolidate `script` tests (#6663)
kbx81 May 1, 2024
486c933
[nextion] Use persistent http connection for TFT upload (ESP-IDF) (#6…
edwardtfn May 1, 2024
23c120d
Add a function to return the loop_interval (#6666)
tronikos May 2, 2024
a8c3c07
Remote receiver improvements (#4642)
Mat931 May 2, 2024
8b031dd
Make fast update intervals in qmc5883l work (#6647)
tronikos May 2, 2024
0825dcb
SPI and I2C for BMP390 and BMP380 (#6652)
latonita May 2, 2024
57edba3
replaced code with previous PR request, it is more inline with requir…
Jaco1990 May 4, 2024
3dc54f1
Run api_protobuf.py
Jaco1990 May 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 7 additions & 2 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ esphome/components/bme280_base/* @esphome/core
esphome/components/bme280_spi/* @apbodrov
esphome/components/bme680_bsec/* @trvrnrth
esphome/components/bmi160/* @flaviut
esphome/components/bmp3xx/* @martgras
esphome/components/bmp3xx/* @latonita
esphome/components/bmp3xx_base/* @latonita @martgras
esphome/components/bmp3xx_i2c/* @latonita
esphome/components/bmp3xx_spi/* @latonita
esphome/components/bmp581/* @kahrendt
esphome/components/bp1658cj/* @Cossid
esphome/components/bp5758d/* @Cossid
Expand Down Expand Up @@ -132,6 +135,7 @@ esphome/components/fs3000/* @kahrendt
esphome/components/ft5x06/* @clydebarrow
esphome/components/ft63x6/* @gpambrozio
esphome/components/gcja5/* @gcormier
esphome/components/generic_humidifier/* @Jaco1990
esphome/components/globals/* @esphome/core
esphome/components/gp8403/* @jesserockz
esphome/components/gpio/* @esphome/core
Expand All @@ -158,6 +162,7 @@ esphome/components/host/* @esphome/core
esphome/components/hrxl_maxsonar_wr/* @netmikey
esphome/components/hte501/* @Stock-M
esphome/components/htu31d/* @betterengineering
esphome/components/humidifier/* @Jaco1990
esphome/components/hydreon_rgxx/* @functionpointer
esphome/components/hyt271/* @Philippe12
esphome/components/i2c/* @esphome/core
Expand Down Expand Up @@ -242,7 +247,7 @@ esphome/components/mpl3115a2/* @kbickar
esphome/components/mpu6886/* @fabaff
esphome/components/ms8607/* @e28eta
esphome/components/network/* @esphome/core
esphome/components/nextion/* @senexcrenshaw
esphome/components/nextion/* @edwardtfn @senexcrenshaw
esphome/components/nextion/binary_sensor/* @senexcrenshaw
esphome/components/nextion/sensor/* @senexcrenshaw
esphome/components/nextion/switch/* @senexcrenshaw
Expand Down
82 changes: 82 additions & 0 deletions esphome/components/api/api.proto
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ service APIConnection {
rpc switch_command (SwitchCommandRequest) returns (void) {}
rpc camera_image (CameraImageRequest) returns (void) {}
rpc climate_command (ClimateCommandRequest) returns (void) {}
rpc humidifier_command (HumidifierCommandRequest) returns (void) {}
rpc number_command (NumberCommandRequest) returns (void) {}
rpc text_command (TextCommandRequest) returns (void) {}
rpc select_command (SelectCommandRequest) returns (void) {}
Expand Down Expand Up @@ -923,6 +924,87 @@ message ClimateCommandRequest {
float target_humidity = 23;
}

// ==================== HUMIDIFIER ====================
enum HumidifierMode {
HUMIDIFIER_MODE_OFF = 0;
HUMIDIFIER_MODE_HUMIDIFY_DEHUMIDIFY = 1;
HUMIDIFIER_MODE_DEHUMIDIFY = 2;
HUMIDIFIER_MODE_HUMIDIFY = 3;
HUMIDIFIER_MODE_AUTO = 4;
}
enum HumidifierAction {
HUMIDIFIER_ACTION_OFF = 0;
// values same as mode for readability
HUMIDIFIER_ACTION_DEHUMIDIFYING = 2;
HUMIDIFIER_ACTION_HUMIDIFYING = 3;
HUMIDIFIER_ACTION_IDLE = 4;
}
enum HumidifierPreset {
HUMIDIFIER_PRESET_NORMAL = 0;
HUMIDIFIER_PRESET_HOME = 1;
HUMIDIFIER_PRESET_AWAY = 2;
HUMIDIFIER_PRESET_BOOST = 3;
HUMIDIFIER_PRESET_COMFORT = 4;
HUMIDIFIER_PRESET_ECO = 5;
HUMIDIFIER_PRESET_SLEEP = 6;
HUMIDIFIER_PRESET_ACTIVITY = 7;
}
message ListEntitiesHumidifierResponse {
option (id) = 66;
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_HUMIDIFIER";

string object_id = 1;
fixed32 key = 2;
string name = 3;
string unique_id = 4;

bool supports_current_humidity = 5;
bool supports_two_point_target_humidity = 6;
repeated HumidifierMode supported_modes = 7;
float visual_min_humidity = 8;
float visual_max_humidity = 9;
float visual_humidity_step = 10;
bool supports_action = 11;
repeated HumidifierPreset supported_presets = 12;
bool disabled_by_default = 13;
string icon = 14;
EntityCategory entity_category = 15;
}
message HumidifierStateResponse {
option (id) = 67;
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_HUMIDIFIER";
option (no_delay) = true;

fixed32 key = 1;
HumidifierMode mode = 2;
float current_humidity = 3;
float target_humidity = 4;
float target_humidity_low = 5;
float target_humidity_high = 6;
HumidifierAction action = 7;
HumidifierPreset preset = 8;
}
message HumidifierCommandRequest {
option (id) = 68;
option (source) = SOURCE_CLIENT;
option (ifdef) = "USE_HUMIDIFIER";
option (no_delay) = true;

fixed32 key = 1;
bool has_mode = 2;
HumidifierMode mode = 3;
bool has_target_humidity = 4;
float target_humidity = 5;
bool has_target_humidity_low = 6;
float target_humidity_low = 7;
bool has_target_humidity_high = 8;
float target_humidity_high = 9;
bool has_preset = 10;
HumidifierPreset preset = 11;
}

// ==================== NUMBER ====================
enum NumberMode {
NUMBER_MODE_AUTO = 0;
Expand Down
70 changes: 70 additions & 0 deletions esphome/components/api/api_connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,76 @@ void APIConnection::climate_command(const ClimateCommandRequest &msg) {
}
#endif

#ifdef USE_HUMIDIFIER
bool APIConnection::send_humidifier_state(humidifier::Humidifier *humidifier) {
if (!this->state_subscription_)
return false;

auto traits = humidifier->get_traits();
HumidifierStateResponse resp{};
resp.key = humidifier->get_object_id_hash();
resp.mode = static_cast<enums::HumidifierMode>(humidifier->mode);
resp.action = static_cast<enums::HumidifierAction>(humidifier->action);
if (traits.get_supports_current_humidity())
resp.current_humidity = humidifier->current_humidity;
if (traits.get_supports_two_point_target_humidity()) {
resp.target_humidity_low = humidifier->target_humidity_low;
resp.target_humidity_high = humidifier->target_humidity_high;
} else {
resp.target_humidity = humidifier->target_humidity;
}
if (traits.get_supports_presets() && humidifier->preset.has_value()) {
resp.preset = static_cast<enums::HumidifierPreset>(humidifier->preset.value());
}
return this->send_humidifier_state_response(resp);
}
bool APIConnection::send_humidifier_info(humidifier::Humidifier *humidifier) {
auto traits = humidifier->get_traits();
ListEntitiesHumidifierResponse msg;
msg.key = humidifier->get_object_id_hash();
msg.object_id = humidifier->get_object_id();
msg.name = humidifier->get_name();
msg.unique_id = get_default_unique_id("humidifier", humidifier);

msg.disabled_by_default = humidifier->is_disabled_by_default();
msg.icon = humidifier->get_icon();
msg.entity_category = static_cast<enums::EntityCategory>(humidifier->get_entity_category());

msg.supports_current_humidity = traits.get_supports_current_humidity();
msg.supports_two_point_target_humidity = traits.get_supports_two_point_target_humidity();

for (auto mode : traits.get_supported_modes())
msg.supported_modes.push_back(static_cast<enums::HumidifierMode>(mode));

msg.visual_min_humidity = traits.get_visual_min_humidity();
msg.visual_max_humidity = traits.get_visual_max_humidity();
msg.visual_humidity_step = traits.get_visual_humidity_step();
msg.supports_action = traits.get_supports_action();

for (auto preset : traits.get_supported_presets())
msg.supported_presets.push_back(static_cast<enums::HumidifierPreset>(preset));
return this->send_list_entities_humidifier_response(msg);
}
void APIConnection::humidifier_command(const HumidifierCommandRequest &msg) {
humidifier::Humidifier *humidifier = App.get_humidifier_by_key(msg.key);
if (humidifier == nullptr)
return;

auto call = humidifier->make_call();
if (msg.has_mode)
call.set_mode(static_cast<humidifier::HumidifierMode>(msg.mode));
if (msg.has_target_humidity)
call.set_target_humidity(msg.target_humidity);
if (msg.has_target_humidity_low)
call.set_target_humidity_low(msg.target_humidity_low);
if (msg.has_target_humidity_high)
call.set_target_humidity_high(msg.target_humidity_high);
if (msg.has_preset)
call.set_preset(static_cast<humidifier::HumidifierPreset>(msg.preset));
call.perform();
}
#endif

#ifdef USE_NUMBER
bool APIConnection::send_number_state(number::Number *number, float state) {
if (!this->state_subscription_)
Expand Down
5 changes: 5 additions & 0 deletions esphome/components/api/api_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ class APIConnection : public APIServerConnection {
bool send_climate_info(climate::Climate *climate);
void climate_command(const ClimateCommandRequest &msg) override;
#endif
#ifdef USE_HUMIDIFIER
bool send_humidifier_state(humidifier::Humidifier *humidifier);
bool send_humidifier_info(humidifier::Humidifier *humidifier);
void humidifier_command(const HumidifierCommandRequest &msg) override;
#endif
#ifdef USE_NUMBER
bool send_number_state(number::Number *number, float state);
bool send_number_info(number::Number *number);
Expand Down