mirror of
https://github.com/Threnklyn/esphome-dev.git
synced 2026-05-19 20:53:26 +02:00
7708b81ef5
* Add fan speed percentage support to the API * Add float fan speed percentage * Add percentage support to automation and configuration * Update Tuya fan * Fix pylint warning * Update API to use speed levels instead of percentage * Use speed levels * Fix type warnings * MQTT component now converts between speed levels and enums * Webserver now supports speed_level * Update prometheus * Remove low/medium/high settings from speed fan * Remove unused enum * Configurable speed levels for speed fan * Remove unused import * Rename speed_level->speed and speed_levels->speed_count * Rename supported_speed_levels -> supported_speed_count in API and FanTraits Field id stays the same in the protocol, so the change is not breaking for aioesphome.
143 lines
4.5 KiB
Python
143 lines
4.5 KiB
Python
import esphome.codegen as cg
|
|
import esphome.config_validation as cv
|
|
from esphome import automation
|
|
from esphome.automation import maybe_simple_id
|
|
from esphome.components import mqtt
|
|
from esphome.const import (
|
|
CONF_ID,
|
|
CONF_INTERNAL,
|
|
CONF_MQTT_ID,
|
|
CONF_OSCILLATING,
|
|
CONF_OSCILLATION_COMMAND_TOPIC,
|
|
CONF_OSCILLATION_STATE_TOPIC,
|
|
CONF_SPEED,
|
|
CONF_SPEED_COMMAND_TOPIC,
|
|
CONF_SPEED_STATE_TOPIC,
|
|
CONF_NAME,
|
|
)
|
|
from esphome.core import CORE, coroutine, coroutine_with_priority
|
|
|
|
IS_PLATFORM_COMPONENT = True
|
|
|
|
fan_ns = cg.esphome_ns.namespace("fan")
|
|
FanState = fan_ns.class_("FanState", cg.Nameable, cg.Component)
|
|
MakeFan = cg.Application.struct("MakeFan")
|
|
|
|
# Actions
|
|
TurnOnAction = fan_ns.class_("TurnOnAction", automation.Action)
|
|
TurnOffAction = fan_ns.class_("TurnOffAction", automation.Action)
|
|
ToggleAction = fan_ns.class_("ToggleAction", automation.Action)
|
|
|
|
FAN_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend(
|
|
{
|
|
cv.GenerateID(): cv.declare_id(FanState),
|
|
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTFanComponent),
|
|
cv.Optional(CONF_OSCILLATION_STATE_TOPIC): cv.All(
|
|
cv.requires_component("mqtt"), cv.publish_topic
|
|
),
|
|
cv.Optional(CONF_OSCILLATION_COMMAND_TOPIC): cv.All(
|
|
cv.requires_component("mqtt"), cv.subscribe_topic
|
|
),
|
|
cv.Optional(CONF_SPEED_STATE_TOPIC): cv.All(
|
|
cv.requires_component("mqtt"), cv.publish_topic
|
|
),
|
|
cv.Optional(CONF_SPEED_COMMAND_TOPIC): cv.All(
|
|
cv.requires_component("mqtt"), cv.subscribe_topic
|
|
),
|
|
}
|
|
)
|
|
|
|
|
|
@coroutine
|
|
def setup_fan_core_(var, config):
|
|
cg.add(var.set_name(config[CONF_NAME]))
|
|
if CONF_INTERNAL in config:
|
|
cg.add(var.set_internal(config[CONF_INTERNAL]))
|
|
|
|
if CONF_MQTT_ID in config:
|
|
mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], var)
|
|
yield mqtt.register_mqtt_component(mqtt_, config)
|
|
|
|
if CONF_OSCILLATION_STATE_TOPIC in config:
|
|
cg.add(
|
|
mqtt_.set_custom_oscillation_state_topic(
|
|
config[CONF_OSCILLATION_STATE_TOPIC]
|
|
)
|
|
)
|
|
if CONF_OSCILLATION_COMMAND_TOPIC in config:
|
|
cg.add(
|
|
mqtt_.set_custom_oscillation_command_topic(
|
|
config[CONF_OSCILLATION_COMMAND_TOPIC]
|
|
)
|
|
)
|
|
if CONF_SPEED_STATE_TOPIC in config:
|
|
cg.add(mqtt_.set_custom_speed_state_topic(config[CONF_SPEED_STATE_TOPIC]))
|
|
if CONF_SPEED_COMMAND_TOPIC in config:
|
|
cg.add(
|
|
mqtt_.set_custom_speed_command_topic(config[CONF_SPEED_COMMAND_TOPIC])
|
|
)
|
|
|
|
|
|
@coroutine
|
|
def register_fan(var, config):
|
|
if not CORE.has_id(config[CONF_ID]):
|
|
var = cg.Pvariable(config[CONF_ID], var)
|
|
cg.add(cg.App.register_fan(var))
|
|
yield cg.register_component(var, config)
|
|
yield setup_fan_core_(var, config)
|
|
|
|
|
|
@coroutine
|
|
def create_fan_state(config):
|
|
var = cg.new_Pvariable(config[CONF_ID])
|
|
yield register_fan(var, config)
|
|
yield var
|
|
|
|
|
|
FAN_ACTION_SCHEMA = maybe_simple_id(
|
|
{
|
|
cv.Required(CONF_ID): cv.use_id(FanState),
|
|
}
|
|
)
|
|
|
|
|
|
@automation.register_action("fan.toggle", ToggleAction, FAN_ACTION_SCHEMA)
|
|
def fan_toggle_to_code(config, action_id, template_arg, args):
|
|
paren = yield cg.get_variable(config[CONF_ID])
|
|
yield cg.new_Pvariable(action_id, template_arg, paren)
|
|
|
|
|
|
@automation.register_action("fan.turn_off", TurnOffAction, FAN_ACTION_SCHEMA)
|
|
def fan_turn_off_to_code(config, action_id, template_arg, args):
|
|
paren = yield cg.get_variable(config[CONF_ID])
|
|
yield cg.new_Pvariable(action_id, template_arg, paren)
|
|
|
|
|
|
@automation.register_action(
|
|
"fan.turn_on",
|
|
TurnOnAction,
|
|
maybe_simple_id(
|
|
{
|
|
cv.Required(CONF_ID): cv.use_id(FanState),
|
|
cv.Optional(CONF_OSCILLATING): cv.templatable(cv.boolean),
|
|
cv.Optional(CONF_SPEED): cv.templatable(cv.int_range(1)),
|
|
}
|
|
),
|
|
)
|
|
def fan_turn_on_to_code(config, action_id, template_arg, args):
|
|
paren = yield cg.get_variable(config[CONF_ID])
|
|
var = cg.new_Pvariable(action_id, template_arg, paren)
|
|
if CONF_OSCILLATING in config:
|
|
template_ = yield cg.templatable(config[CONF_OSCILLATING], args, bool)
|
|
cg.add(var.set_oscillating(template_))
|
|
if CONF_SPEED in config:
|
|
template_ = yield cg.templatable(config[CONF_SPEED], args, int)
|
|
cg.add(var.set_speed(template_))
|
|
yield var
|
|
|
|
|
|
@coroutine_with_priority(100.0)
|
|
def to_code(config):
|
|
cg.add_define("USE_FAN")
|
|
cg.add_global(fan_ns.using)
|