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 and Hygrostat Components #6678

Draft
wants to merge 4 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,9 @@ 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/hygrostat/* @Jaco1990 @alevaquero
esphome/components/hyt271/* @Philippe12
esphome/components/i2c/* @esphome/core
esphome/components/i2s_audio/* @jesserockz
Expand Down
81 changes: 81 additions & 0 deletions esphome/components/api/api.proto
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,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
6 changes: 6 additions & 0 deletions esphome/components/api/api_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ 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
Loading
Loading