10#include "esphome/core/log.h"
18static const char *
const TAG =
"home_io_control.fan";
23constexpr int HEAT_STEPS = 100;
33 "Device %s is declared as %s, which a fan entity cannot drive (it drives exterior heating) — disabling it",
45 const bool has_level = this->
subtype_ != SUBTYPE_MAIN_PARAMETER_ONLY;
46 return fan::FanTraits(
false, has_level,
false, HEAT_STEPS);
50 const bool has_level = this->
get_traits().supports_speed();
51 const auto state = call.get_state();
52 const auto speed = call.get_speed();
55 if (state.has_value() && !*state) {
57 }
else if (speed.has_value() && has_level) {
58 heat = std::clamp(*speed, 0, HEAT_STEPS);
59 }
else if (state.has_value()) {
61 heat = (has_level && this->speed > 0) ? this->speed : HEAT_STEPS;
67 const auto io_position =
detail::round_percent(1.0F - (
static_cast<float>(heat) /
static_cast<float>(HEAT_STEPS)));
71 this->state = heat > 0;
72 if (heat > 0 && has_level)
74 this->publish_state();
82 const int heat = std::clamp(
static_cast<int>(std::lround(100.0F - dev.
position)), 0, HEAT_STEPS);
83 const bool on = heat > 0;
84 const bool has_level = this->
get_traits().supports_speed();
85 const int speed = (on && has_level) ? heat : this->speed;
86 if (this->state == on && this->speed == speed)
90 this->publish_state();
94 ESP_LOGCONFIG(
TAG,
"IO-Homecontrol Exterior Heating Fan:");
95 ESP_LOGCONFIG(
TAG,
" Device ID: %s", this->
device_id_.c_str());
97 ESP_LOGCONFIG(
TAG,
" Status: experimental, unvalidated on hardware");
void register_device_binding_(Component *self, bool inverted, std::function< void(const std::string &, const IoDevice &)> on_update)
Perform the shared setup() registration ritual.
void log_poll_interval_config_(const char *tag) const
Emit the shared two-branch poll-interval line for dump_config().
IOHomeControlComponent * parent_
bool passes_binary_update_filter_(const std::string &id, const IoDevice &dev) const
Shared inbound-update guard for binary endpoints.
virtual void queue_set_fan_position(const std::string &device_id, uint8_t position)
Async form of set_fan_position() that keeps radio work serialized on the main loop.
fan::FanTraits get_traits() override
Traits: a 100-step speed (the heat level) unless the device takes the main parameter only (subtype 58...
void dump_config() override
Dump configuration to the log.
void on_device_update_(const std::string &id, const IoDevice &dev)
Show a settled device status: heat level = 100 - position.
void setup() override
Register the entity with the shared hub and schedule the first status poll.
void control(const fan::FanCall &call) override
Apply a Home Assistant fan request: a heat level, or on/off.
Conversions and renderers shared by the hub and its Home Assistant entities.
uint8_t round_percent(float fraction)
Convert a 0.0-1.0 HA fraction (position, tilt, or brightness) to a 0-100 IO percent.
DeviceCapabilityClass device_capability_class(DeviceType type)
Map a raw IO‑Homecontrol type to the closest ESPHome/Home Assistant entity family.
static constexpr const char * TAG
@ UNKNOWN
Unknown/unspecified device.
@ HEATER_LEVEL
Heater with a heat level in the position field (exterior heating).
std::string format_device_kind(DeviceType type, uint8_t subtype)
Human-readable description of a (type, subtype) for logs and reports.
static const char *const TAG
The IO node-type and subtype table: names, entity class, platform and behaviour flags.
Runtime state of a paired IO‑Homecontrol device.
float position
Current position: 0=open, 100=closed, or UNKNOWN_POSITION.