mirror of
https://github.com/esphome/esphome.git
synced 2024-11-14 02:58:11 +01:00
Add demo integration (#2085)
This commit is contained in:
parent
af8d04818d
commit
16dbbfabc6
11 changed files with 969 additions and 0 deletions
451
esphome/components/demo/__init__.py
Normal file
451
esphome/components/demo/__init__.py
Normal file
|
@ -0,0 +1,451 @@
|
||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.components import (
|
||||||
|
binary_sensor,
|
||||||
|
climate,
|
||||||
|
cover,
|
||||||
|
fan,
|
||||||
|
light,
|
||||||
|
number,
|
||||||
|
sensor,
|
||||||
|
switch,
|
||||||
|
text_sensor,
|
||||||
|
)
|
||||||
|
from esphome.const import (
|
||||||
|
CONF_ACCURACY_DECIMALS,
|
||||||
|
CONF_BINARY_SENSORS,
|
||||||
|
CONF_DEVICE_CLASS,
|
||||||
|
CONF_FORCE_UPDATE,
|
||||||
|
CONF_ICON,
|
||||||
|
CONF_ID,
|
||||||
|
CONF_INVERTED,
|
||||||
|
CONF_LAST_RESET_TYPE,
|
||||||
|
CONF_MAX_VALUE,
|
||||||
|
CONF_MIN_VALUE,
|
||||||
|
CONF_NAME,
|
||||||
|
CONF_OUTPUT_ID,
|
||||||
|
CONF_SENSORS,
|
||||||
|
CONF_STATE_CLASS,
|
||||||
|
CONF_STEP,
|
||||||
|
CONF_SWITCHES,
|
||||||
|
CONF_TEXT_SENSORS,
|
||||||
|
CONF_TYPE,
|
||||||
|
CONF_UNIT_OF_MEASUREMENT,
|
||||||
|
DEVICE_CLASS_ENERGY,
|
||||||
|
DEVICE_CLASS_HUMIDITY,
|
||||||
|
DEVICE_CLASS_MOISTURE,
|
||||||
|
DEVICE_CLASS_MOTION,
|
||||||
|
DEVICE_CLASS_TEMPERATURE,
|
||||||
|
ICON_BLUETOOTH,
|
||||||
|
ICON_BLUR,
|
||||||
|
ICON_EMPTY,
|
||||||
|
ICON_THERMOMETER,
|
||||||
|
LAST_RESET_TYPE_AUTO,
|
||||||
|
STATE_CLASS_MEASUREMENT,
|
||||||
|
UNIT_CELSIUS,
|
||||||
|
UNIT_EMPTY,
|
||||||
|
UNIT_PERCENT,
|
||||||
|
UNIT_WATT_HOURS,
|
||||||
|
)
|
||||||
|
|
||||||
|
AUTO_LOAD = [
|
||||||
|
"binary_sensor",
|
||||||
|
"climate",
|
||||||
|
"cover",
|
||||||
|
"fan",
|
||||||
|
"light",
|
||||||
|
"number",
|
||||||
|
"sensor",
|
||||||
|
"switch",
|
||||||
|
"text_sensor",
|
||||||
|
]
|
||||||
|
|
||||||
|
demo_ns = cg.esphome_ns.namespace("demo")
|
||||||
|
DemoBinarySensor = demo_ns.class_(
|
||||||
|
"DemoBinarySensor", binary_sensor.BinarySensor, cg.PollingComponent
|
||||||
|
)
|
||||||
|
DemoClimate = demo_ns.class_("DemoClimate", climate.Climate, cg.Component)
|
||||||
|
DemoClimateType = demo_ns.enum("DemoClimateType", is_class=True)
|
||||||
|
DemoCover = demo_ns.class_("DemoCover", cover.Cover, cg.Component)
|
||||||
|
DemoCoverType = demo_ns.enum("DemoCoverType", is_class=True)
|
||||||
|
DemoFan = demo_ns.class_("DemoFan", cg.Component)
|
||||||
|
DemoFanType = demo_ns.enum("DemoFanType", is_class=True)
|
||||||
|
DemoLight = demo_ns.class_("DemoLight", light.LightOutput, cg.Component)
|
||||||
|
DemoLightType = demo_ns.enum("DemoLightType", is_class=True)
|
||||||
|
DemoNumber = demo_ns.class_("DemoNumber", number.Number, cg.Component)
|
||||||
|
DemoNumberType = demo_ns.enum("DemoNumberType", is_class=True)
|
||||||
|
DemoSensor = demo_ns.class_("DemoSensor", sensor.Sensor, cg.PollingComponent)
|
||||||
|
DemoSwitch = demo_ns.class_("DemoSwitch", switch.Switch, cg.Component)
|
||||||
|
DemoTextSensor = demo_ns.class_(
|
||||||
|
"DemoTextSensor", text_sensor.TextSensor, cg.PollingComponent
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
CLIMATE_TYPES = {
|
||||||
|
1: DemoClimateType.TYPE_1,
|
||||||
|
2: DemoClimateType.TYPE_2,
|
||||||
|
3: DemoClimateType.TYPE_3,
|
||||||
|
}
|
||||||
|
COVER_TYPES = {
|
||||||
|
1: DemoCoverType.TYPE_1,
|
||||||
|
2: DemoCoverType.TYPE_2,
|
||||||
|
3: DemoCoverType.TYPE_3,
|
||||||
|
4: DemoCoverType.TYPE_4,
|
||||||
|
}
|
||||||
|
FAN_TYPES = {
|
||||||
|
1: DemoFanType.TYPE_1,
|
||||||
|
2: DemoFanType.TYPE_2,
|
||||||
|
3: DemoFanType.TYPE_3,
|
||||||
|
4: DemoFanType.TYPE_4,
|
||||||
|
}
|
||||||
|
LIGHT_TYPES = {
|
||||||
|
1: DemoLightType.TYPE_1,
|
||||||
|
2: DemoLightType.TYPE_2,
|
||||||
|
3: DemoLightType.TYPE_3,
|
||||||
|
4: DemoLightType.TYPE_4,
|
||||||
|
5: DemoLightType.TYPE_5,
|
||||||
|
6: DemoLightType.TYPE_6,
|
||||||
|
7: DemoLightType.TYPE_7,
|
||||||
|
}
|
||||||
|
NUMBER_TYPES = {
|
||||||
|
1: DemoNumberType.TYPE_1,
|
||||||
|
2: DemoNumberType.TYPE_2,
|
||||||
|
3: DemoNumberType.TYPE_3,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CONF_CLIMATES = "climates"
|
||||||
|
CONF_COVERS = "covers"
|
||||||
|
CONF_FANS = "fans"
|
||||||
|
CONF_LIGHTS = "lights"
|
||||||
|
CONF_NUMBERS = "numbers"
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(
|
||||||
|
CONF_BINARY_SENSORS,
|
||||||
|
default=[
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo Basement Floor Wet",
|
||||||
|
CONF_DEVICE_CLASS: DEVICE_CLASS_MOISTURE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo Movement Backyard",
|
||||||
|
CONF_DEVICE_CLASS: DEVICE_CLASS_MOTION,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
): [
|
||||||
|
binary_sensor.BINARY_SENSOR_SCHEMA.extend(
|
||||||
|
cv.polling_component_schema("60s")
|
||||||
|
).extend(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(DemoBinarySensor),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
],
|
||||||
|
cv.Optional(
|
||||||
|
CONF_CLIMATES,
|
||||||
|
default=[
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo Heatpump",
|
||||||
|
CONF_TYPE: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo HVAC",
|
||||||
|
CONF_TYPE: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo Ecobee",
|
||||||
|
CONF_TYPE: 3,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
): [
|
||||||
|
climate.CLIMATE_SCHEMA.extend(cv.COMPONENT_SCHEMA).extend(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(DemoClimate),
|
||||||
|
cv.Required(CONF_TYPE): cv.enum(CLIMATE_TYPES, int=True),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
],
|
||||||
|
cv.Optional(
|
||||||
|
CONF_COVERS,
|
||||||
|
default=[
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo Kitchen Window",
|
||||||
|
CONF_TYPE: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo Garage Door",
|
||||||
|
CONF_TYPE: 2,
|
||||||
|
CONF_DEVICE_CLASS: "garage",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo Living Room Window",
|
||||||
|
CONF_TYPE: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo Hall Window",
|
||||||
|
CONF_TYPE: 4,
|
||||||
|
CONF_DEVICE_CLASS: "window",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
): [
|
||||||
|
cover.COVER_SCHEMA.extend(cv.COMPONENT_SCHEMA).extend(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(DemoCover),
|
||||||
|
cv.Required(CONF_TYPE): cv.enum(COVER_TYPES, int=True),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
],
|
||||||
|
cv.Optional(
|
||||||
|
CONF_FANS,
|
||||||
|
default=[
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo Living Room Fan",
|
||||||
|
CONF_TYPE: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo Ceiling Fan",
|
||||||
|
CONF_TYPE: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo Percentage Limited Fan",
|
||||||
|
CONF_TYPE: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo Percentage Full Fan",
|
||||||
|
CONF_TYPE: 4,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
): [
|
||||||
|
fan.FAN_SCHEMA.extend(cv.COMPONENT_SCHEMA).extend(
|
||||||
|
{
|
||||||
|
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(DemoFan),
|
||||||
|
cv.Required(CONF_TYPE): cv.enum(FAN_TYPES, int=True),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
],
|
||||||
|
cv.Optional(
|
||||||
|
CONF_LIGHTS,
|
||||||
|
default=[
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo Binary Light",
|
||||||
|
CONF_TYPE: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo Brightness Light",
|
||||||
|
CONF_TYPE: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo RGB Light",
|
||||||
|
CONF_TYPE: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo RGBW Light",
|
||||||
|
CONF_TYPE: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo RGBWW Light",
|
||||||
|
CONF_TYPE: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo CWWW Light",
|
||||||
|
CONF_TYPE: 6,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo RGBW interlock Light",
|
||||||
|
CONF_TYPE: 7,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
): [
|
||||||
|
light.RGB_LIGHT_SCHEMA.extend(cv.COMPONENT_SCHEMA).extend(
|
||||||
|
{
|
||||||
|
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(DemoLight),
|
||||||
|
cv.Required(CONF_TYPE): cv.enum(LIGHT_TYPES, int=True),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
],
|
||||||
|
cv.Optional(
|
||||||
|
CONF_NUMBERS,
|
||||||
|
default=[
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo Number 0-100",
|
||||||
|
CONF_TYPE: 1,
|
||||||
|
CONF_MIN_VALUE: 0,
|
||||||
|
CONF_MAX_VALUE: 100,
|
||||||
|
CONF_STEP: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo Number -50-50",
|
||||||
|
CONF_TYPE: 2,
|
||||||
|
CONF_MIN_VALUE: -50,
|
||||||
|
CONF_MAX_VALUE: 50,
|
||||||
|
CONF_STEP: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo Number 40-60",
|
||||||
|
CONF_TYPE: 3,
|
||||||
|
CONF_MIN_VALUE: 40,
|
||||||
|
CONF_MAX_VALUE: 60,
|
||||||
|
CONF_STEP: 0.2,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
): [
|
||||||
|
number.NUMBER_SCHEMA.extend(cv.COMPONENT_SCHEMA).extend(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(DemoNumber),
|
||||||
|
cv.Required(CONF_TYPE): cv.enum(NUMBER_TYPES, int=True),
|
||||||
|
cv.Required(CONF_MIN_VALUE): cv.float_,
|
||||||
|
cv.Required(CONF_MAX_VALUE): cv.float_,
|
||||||
|
cv.Required(CONF_STEP): cv.float_,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
],
|
||||||
|
cv.Optional(
|
||||||
|
CONF_SENSORS,
|
||||||
|
default=[
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo Plain Sensor",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo Temperature Sensor",
|
||||||
|
CONF_UNIT_OF_MEASUREMENT: UNIT_CELSIUS,
|
||||||
|
CONF_ICON: ICON_THERMOMETER,
|
||||||
|
CONF_ACCURACY_DECIMALS: 1,
|
||||||
|
CONF_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
|
||||||
|
CONF_STATE_CLASS: STATE_CLASS_MEASUREMENT,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo Temperature Sensor",
|
||||||
|
CONF_UNIT_OF_MEASUREMENT: UNIT_CELSIUS,
|
||||||
|
CONF_ICON: ICON_THERMOMETER,
|
||||||
|
CONF_ACCURACY_DECIMALS: 1,
|
||||||
|
CONF_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
|
||||||
|
CONF_STATE_CLASS: STATE_CLASS_MEASUREMENT,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo Force Update Sensor",
|
||||||
|
CONF_UNIT_OF_MEASUREMENT: UNIT_PERCENT,
|
||||||
|
CONF_ACCURACY_DECIMALS: 0,
|
||||||
|
CONF_DEVICE_CLASS: DEVICE_CLASS_HUMIDITY,
|
||||||
|
CONF_STATE_CLASS: STATE_CLASS_MEASUREMENT,
|
||||||
|
CONF_FORCE_UPDATE: True,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo Energy Sensor",
|
||||||
|
CONF_UNIT_OF_MEASUREMENT: UNIT_WATT_HOURS,
|
||||||
|
CONF_ACCURACY_DECIMALS: 0,
|
||||||
|
CONF_DEVICE_CLASS: DEVICE_CLASS_ENERGY,
|
||||||
|
CONF_STATE_CLASS: STATE_CLASS_MEASUREMENT,
|
||||||
|
CONF_LAST_RESET_TYPE: LAST_RESET_TYPE_AUTO,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
): [
|
||||||
|
sensor.sensor_schema(UNIT_EMPTY, ICON_EMPTY, 0)
|
||||||
|
.extend(cv.polling_component_schema("60s"))
|
||||||
|
.extend(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(DemoSensor),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
],
|
||||||
|
cv.Optional(
|
||||||
|
CONF_SWITCHES,
|
||||||
|
default=[
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo Switch 1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo Switch 2",
|
||||||
|
CONF_INVERTED: True,
|
||||||
|
CONF_ICON: ICON_BLUETOOTH,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
): [
|
||||||
|
switch.SWITCH_SCHEMA.extend(cv.COMPONENT_SCHEMA).extend(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(DemoSwitch),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
],
|
||||||
|
cv.Optional(
|
||||||
|
CONF_TEXT_SENSORS,
|
||||||
|
default=[
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo Text Sensor 1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CONF_NAME: "Demo Text Sensor 2",
|
||||||
|
CONF_ICON: ICON_BLUR,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
): [
|
||||||
|
text_sensor.TEXT_SENSOR_SCHEMA.extend(
|
||||||
|
cv.polling_component_schema("60s")
|
||||||
|
).extend(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(DemoTextSensor),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def to_code(config):
|
||||||
|
for conf in config[CONF_BINARY_SENSORS]:
|
||||||
|
var = cg.new_Pvariable(conf[CONF_ID])
|
||||||
|
await cg.register_component(var, conf)
|
||||||
|
await binary_sensor.register_binary_sensor(var, conf)
|
||||||
|
|
||||||
|
for conf in config[CONF_CLIMATES]:
|
||||||
|
var = cg.new_Pvariable(conf[CONF_ID])
|
||||||
|
await cg.register_component(var, conf)
|
||||||
|
await climate.register_climate(var, conf)
|
||||||
|
cg.add(var.set_type(conf[CONF_TYPE]))
|
||||||
|
|
||||||
|
for conf in config[CONF_COVERS]:
|
||||||
|
var = cg.new_Pvariable(conf[CONF_ID])
|
||||||
|
await cg.register_component(var, conf)
|
||||||
|
await cover.register_cover(var, conf)
|
||||||
|
cg.add(var.set_type(conf[CONF_TYPE]))
|
||||||
|
|
||||||
|
for conf in config[CONF_FANS]:
|
||||||
|
var = cg.new_Pvariable(conf[CONF_OUTPUT_ID])
|
||||||
|
await cg.register_component(var, conf)
|
||||||
|
fan_ = await fan.create_fan_state(conf)
|
||||||
|
cg.add(var.set_fan(fan_))
|
||||||
|
cg.add(var.set_type(conf[CONF_TYPE]))
|
||||||
|
|
||||||
|
for conf in config[CONF_LIGHTS]:
|
||||||
|
var = cg.new_Pvariable(conf[CONF_OUTPUT_ID])
|
||||||
|
await cg.register_component(var, conf)
|
||||||
|
await light.register_light(var, conf)
|
||||||
|
cg.add(var.set_type(conf[CONF_TYPE]))
|
||||||
|
|
||||||
|
for conf in config[CONF_NUMBERS]:
|
||||||
|
var = cg.new_Pvariable(conf[CONF_ID])
|
||||||
|
await cg.register_component(var, conf)
|
||||||
|
await number.register_number(
|
||||||
|
var,
|
||||||
|
conf,
|
||||||
|
min_value=conf[CONF_MIN_VALUE],
|
||||||
|
max_value=conf[CONF_MAX_VALUE],
|
||||||
|
step=conf[CONF_STEP],
|
||||||
|
)
|
||||||
|
cg.add(var.set_type(conf[CONF_TYPE]))
|
||||||
|
|
||||||
|
for conf in config[CONF_SENSORS]:
|
||||||
|
var = cg.new_Pvariable(conf[CONF_ID])
|
||||||
|
await cg.register_component(var, conf)
|
||||||
|
await sensor.register_sensor(var, conf)
|
||||||
|
|
||||||
|
for conf in config[CONF_SWITCHES]:
|
||||||
|
var = cg.new_Pvariable(conf[CONF_ID])
|
||||||
|
await cg.register_component(var, conf)
|
||||||
|
await switch.register_switch(var, conf)
|
||||||
|
|
||||||
|
for conf in config[CONF_TEXT_SENSORS]:
|
||||||
|
var = cg.new_Pvariable(conf[CONF_ID])
|
||||||
|
await cg.register_component(var, conf)
|
||||||
|
await text_sensor.register_text_sensor(var, conf)
|
22
esphome/components/demo/demo_binary_sensor.h
Normal file
22
esphome/components/demo/demo_binary_sensor.h
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/components/binary_sensor/binary_sensor.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace demo {
|
||||||
|
|
||||||
|
class DemoBinarySensor : public binary_sensor::BinarySensor, public PollingComponent {
|
||||||
|
public:
|
||||||
|
void setup() override { this->publish_initial_state(false); }
|
||||||
|
void update() override {
|
||||||
|
bool new_state = last_state_ = !last_state_;
|
||||||
|
this->publish_state(new_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool last_state_ = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace demo
|
||||||
|
} // namespace esphome
|
157
esphome/components/demo/demo_climate.h
Normal file
157
esphome/components/demo/demo_climate.h
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/components/climate/climate.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace demo {
|
||||||
|
|
||||||
|
enum class DemoClimateType {
|
||||||
|
TYPE_1,
|
||||||
|
TYPE_2,
|
||||||
|
TYPE_3,
|
||||||
|
};
|
||||||
|
|
||||||
|
class DemoClimate : public climate::Climate, public Component {
|
||||||
|
public:
|
||||||
|
void set_type(DemoClimateType type) { type_ = type; }
|
||||||
|
void setup() override {
|
||||||
|
switch (type_) {
|
||||||
|
case DemoClimateType::TYPE_1:
|
||||||
|
this->current_temperature = 20.0;
|
||||||
|
this->target_temperature = 21.0;
|
||||||
|
this->mode = climate::CLIMATE_MODE_HEAT;
|
||||||
|
this->action = climate::CLIMATE_ACTION_HEATING;
|
||||||
|
break;
|
||||||
|
case DemoClimateType::TYPE_2:
|
||||||
|
this->target_temperature = 21.5;
|
||||||
|
this->mode = climate::CLIMATE_MODE_AUTO;
|
||||||
|
this->action = climate::CLIMATE_ACTION_COOLING;
|
||||||
|
this->fan_mode = climate::CLIMATE_FAN_HIGH;
|
||||||
|
this->custom_preset = {"My Preset"};
|
||||||
|
break;
|
||||||
|
case DemoClimateType::TYPE_3:
|
||||||
|
this->current_temperature = 21.5;
|
||||||
|
this->target_temperature_low = 21.0;
|
||||||
|
this->target_temperature_high = 22.5;
|
||||||
|
this->mode = climate::CLIMATE_MODE_HEAT_COOL;
|
||||||
|
this->custom_fan_mode = {"Auto Low"};
|
||||||
|
this->swing_mode = climate::CLIMATE_SWING_HORIZONTAL;
|
||||||
|
this->preset = climate::CLIMATE_PRESET_AWAY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this->publish_state();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(const climate::ClimateCall &call) override {
|
||||||
|
if (call.get_mode().has_value()) {
|
||||||
|
this->mode = *call.get_mode();
|
||||||
|
}
|
||||||
|
if (call.get_target_temperature().has_value()) {
|
||||||
|
this->target_temperature = *call.get_target_temperature();
|
||||||
|
}
|
||||||
|
if (call.get_target_temperature_low().has_value()) {
|
||||||
|
this->target_temperature_low = *call.get_target_temperature_low();
|
||||||
|
}
|
||||||
|
if (call.get_target_temperature_high().has_value()) {
|
||||||
|
this->target_temperature_high = *call.get_target_temperature_high();
|
||||||
|
}
|
||||||
|
if (call.get_fan_mode().has_value()) {
|
||||||
|
this->fan_mode = *call.get_fan_mode();
|
||||||
|
this->custom_fan_mode.reset();
|
||||||
|
}
|
||||||
|
if (call.get_swing_mode().has_value()) {
|
||||||
|
this->swing_mode = *call.get_swing_mode();
|
||||||
|
}
|
||||||
|
if (call.get_custom_fan_mode().has_value()) {
|
||||||
|
this->custom_fan_mode = *call.get_custom_fan_mode();
|
||||||
|
this->fan_mode.reset();
|
||||||
|
}
|
||||||
|
if (call.get_preset().has_value()) {
|
||||||
|
this->preset = *call.get_preset();
|
||||||
|
this->custom_preset.reset();
|
||||||
|
}
|
||||||
|
if (call.get_custom_preset().has_value()) {
|
||||||
|
this->custom_preset = *call.get_custom_preset();
|
||||||
|
this->preset.reset();
|
||||||
|
}
|
||||||
|
this->publish_state();
|
||||||
|
}
|
||||||
|
climate::ClimateTraits traits() override {
|
||||||
|
climate::ClimateTraits traits{};
|
||||||
|
switch (type_) {
|
||||||
|
case DemoClimateType::TYPE_1:
|
||||||
|
traits.set_supports_current_temperature(true);
|
||||||
|
traits.set_supported_modes({
|
||||||
|
climate::CLIMATE_MODE_OFF,
|
||||||
|
climate::CLIMATE_MODE_HEAT,
|
||||||
|
});
|
||||||
|
traits.set_supports_action(true);
|
||||||
|
traits.set_visual_temperature_step(0.5);
|
||||||
|
break;
|
||||||
|
case DemoClimateType::TYPE_2:
|
||||||
|
traits.set_supports_current_temperature(false);
|
||||||
|
traits.set_supported_modes({
|
||||||
|
climate::CLIMATE_MODE_OFF,
|
||||||
|
climate::CLIMATE_MODE_HEAT,
|
||||||
|
climate::CLIMATE_MODE_COOL,
|
||||||
|
climate::CLIMATE_MODE_AUTO,
|
||||||
|
climate::CLIMATE_MODE_DRY,
|
||||||
|
climate::CLIMATE_MODE_FAN_ONLY,
|
||||||
|
});
|
||||||
|
traits.set_supports_action(true);
|
||||||
|
traits.set_supported_fan_modes({
|
||||||
|
climate::CLIMATE_FAN_ON,
|
||||||
|
climate::CLIMATE_FAN_OFF,
|
||||||
|
climate::CLIMATE_FAN_AUTO,
|
||||||
|
climate::CLIMATE_FAN_LOW,
|
||||||
|
climate::CLIMATE_FAN_MEDIUM,
|
||||||
|
climate::CLIMATE_FAN_HIGH,
|
||||||
|
climate::CLIMATE_FAN_MIDDLE,
|
||||||
|
climate::CLIMATE_FAN_FOCUS,
|
||||||
|
climate::CLIMATE_FAN_DIFFUSE,
|
||||||
|
});
|
||||||
|
traits.set_supported_custom_fan_modes({"Auto Low", "Auto High"});
|
||||||
|
traits.set_supported_swing_modes({
|
||||||
|
climate::CLIMATE_SWING_OFF,
|
||||||
|
climate::CLIMATE_SWING_BOTH,
|
||||||
|
climate::CLIMATE_SWING_VERTICAL,
|
||||||
|
climate::CLIMATE_SWING_HORIZONTAL,
|
||||||
|
});
|
||||||
|
traits.set_supported_custom_presets({"My Preset"});
|
||||||
|
break;
|
||||||
|
case DemoClimateType::TYPE_3:
|
||||||
|
traits.set_supports_current_temperature(true);
|
||||||
|
traits.set_supports_two_point_target_temperature(true);
|
||||||
|
traits.set_supported_modes({
|
||||||
|
climate::CLIMATE_MODE_OFF,
|
||||||
|
climate::CLIMATE_MODE_COOL,
|
||||||
|
climate::CLIMATE_MODE_HEAT,
|
||||||
|
climate::CLIMATE_MODE_HEAT_COOL,
|
||||||
|
});
|
||||||
|
traits.set_supported_custom_fan_modes({"Auto Low", "Auto High"});
|
||||||
|
traits.set_supported_swing_modes({
|
||||||
|
climate::CLIMATE_SWING_OFF,
|
||||||
|
climate::CLIMATE_SWING_HORIZONTAL,
|
||||||
|
});
|
||||||
|
traits.set_supported_presets({
|
||||||
|
climate::CLIMATE_PRESET_NONE,
|
||||||
|
climate::CLIMATE_PRESET_HOME,
|
||||||
|
climate::CLIMATE_PRESET_AWAY,
|
||||||
|
climate::CLIMATE_PRESET_BOOST,
|
||||||
|
climate::CLIMATE_PRESET_COMFORT,
|
||||||
|
climate::CLIMATE_PRESET_ECO,
|
||||||
|
climate::CLIMATE_PRESET_SLEEP,
|
||||||
|
climate::CLIMATE_PRESET_ACTIVITY,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return traits;
|
||||||
|
}
|
||||||
|
|
||||||
|
DemoClimateType type_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace demo
|
||||||
|
} // namespace esphome
|
86
esphome/components/demo/demo_cover.h
Normal file
86
esphome/components/demo/demo_cover.h
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/components/cover/cover.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace demo {
|
||||||
|
|
||||||
|
enum class DemoCoverType {
|
||||||
|
TYPE_1,
|
||||||
|
TYPE_2,
|
||||||
|
TYPE_3,
|
||||||
|
TYPE_4,
|
||||||
|
};
|
||||||
|
|
||||||
|
class DemoCover : public cover::Cover, public Component {
|
||||||
|
public:
|
||||||
|
void set_type(DemoCoverType type) { type_ = type; }
|
||||||
|
void setup() override {
|
||||||
|
switch (type_) {
|
||||||
|
case DemoCoverType::TYPE_1:
|
||||||
|
this->position = cover::COVER_OPEN;
|
||||||
|
break;
|
||||||
|
case DemoCoverType::TYPE_2:
|
||||||
|
this->position = 0.7;
|
||||||
|
break;
|
||||||
|
case DemoCoverType::TYPE_3:
|
||||||
|
this->position = 0.1;
|
||||||
|
this->tilt = 0.8;
|
||||||
|
break;
|
||||||
|
case DemoCoverType::TYPE_4:
|
||||||
|
this->position = cover::COVER_CLOSED;
|
||||||
|
this->tilt = 1.0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this->publish_state();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(const cover::CoverCall &call) override {
|
||||||
|
if (call.get_position().has_value()) {
|
||||||
|
float target = *call.get_position();
|
||||||
|
this->current_operation =
|
||||||
|
target > this->position ? cover::COVER_OPERATION_OPENING : cover::COVER_OPERATION_CLOSING;
|
||||||
|
|
||||||
|
this->set_timeout("move", 2000, [this, target]() {
|
||||||
|
this->current_operation = cover::COVER_OPERATION_IDLE;
|
||||||
|
this->position = target;
|
||||||
|
this->publish_state();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (call.get_tilt().has_value()) {
|
||||||
|
this->tilt = *call.get_tilt();
|
||||||
|
}
|
||||||
|
if (call.get_stop()) {
|
||||||
|
this->cancel_timeout("move");
|
||||||
|
}
|
||||||
|
|
||||||
|
this->publish_state();
|
||||||
|
}
|
||||||
|
cover::CoverTraits get_traits() override {
|
||||||
|
cover::CoverTraits traits{};
|
||||||
|
switch (type_) {
|
||||||
|
case DemoCoverType::TYPE_1:
|
||||||
|
traits.set_is_assumed_state(true);
|
||||||
|
break;
|
||||||
|
case DemoCoverType::TYPE_2:
|
||||||
|
traits.set_supports_position(true);
|
||||||
|
break;
|
||||||
|
case DemoCoverType::TYPE_3:
|
||||||
|
traits.set_supports_position(true);
|
||||||
|
traits.set_supports_tilt(true);
|
||||||
|
break;
|
||||||
|
case DemoCoverType::TYPE_4:
|
||||||
|
traits.set_is_assumed_state(true);
|
||||||
|
traits.set_supports_tilt(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return traits;
|
||||||
|
}
|
||||||
|
|
||||||
|
DemoCoverType type_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace demo
|
||||||
|
} // namespace esphome
|
54
esphome/components/demo/demo_fan.h
Normal file
54
esphome/components/demo/demo_fan.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/components/fan/fan_state.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace demo {
|
||||||
|
|
||||||
|
enum class DemoFanType {
|
||||||
|
TYPE_1,
|
||||||
|
TYPE_2,
|
||||||
|
TYPE_3,
|
||||||
|
TYPE_4,
|
||||||
|
};
|
||||||
|
|
||||||
|
class DemoFan : public Component {
|
||||||
|
public:
|
||||||
|
void set_type(DemoFanType type) { type_ = type; }
|
||||||
|
void set_fan(fan::FanState *fan) { fan_ = fan; }
|
||||||
|
void setup() override {
|
||||||
|
fan::FanTraits traits{};
|
||||||
|
|
||||||
|
// oscillation
|
||||||
|
// speed
|
||||||
|
// direction
|
||||||
|
// speed_count
|
||||||
|
switch (type_) {
|
||||||
|
case DemoFanType::TYPE_1:
|
||||||
|
break;
|
||||||
|
case DemoFanType::TYPE_2:
|
||||||
|
traits.set_oscillation(true);
|
||||||
|
break;
|
||||||
|
case DemoFanType::TYPE_3:
|
||||||
|
traits.set_direction(true);
|
||||||
|
traits.set_speed(true);
|
||||||
|
traits.set_supported_speed_count(5);
|
||||||
|
break;
|
||||||
|
case DemoFanType::TYPE_4:
|
||||||
|
traits.set_direction(true);
|
||||||
|
traits.set_speed(true);
|
||||||
|
traits.set_supported_speed_count(100);
|
||||||
|
traits.set_oscillation(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->fan_->set_traits(traits);
|
||||||
|
}
|
||||||
|
|
||||||
|
fan::FanState *fan_;
|
||||||
|
DemoFanType type_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace demo
|
||||||
|
} // namespace esphome
|
82
esphome/components/demo/demo_light.h
Normal file
82
esphome/components/demo/demo_light.h
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/components/light/light_output.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace demo {
|
||||||
|
|
||||||
|
enum class DemoLightType {
|
||||||
|
// binary
|
||||||
|
TYPE_1,
|
||||||
|
// brightness
|
||||||
|
TYPE_2,
|
||||||
|
// RGB
|
||||||
|
TYPE_3,
|
||||||
|
// RGBW
|
||||||
|
TYPE_4,
|
||||||
|
// RGBWW
|
||||||
|
TYPE_5,
|
||||||
|
// CWWW
|
||||||
|
TYPE_6,
|
||||||
|
// RGBW + color_interlock
|
||||||
|
TYPE_7,
|
||||||
|
};
|
||||||
|
|
||||||
|
class DemoLight : public light::LightOutput, public Component {
|
||||||
|
public:
|
||||||
|
void set_type(DemoLightType type) { type_ = type; }
|
||||||
|
light::LightTraits get_traits() override {
|
||||||
|
light::LightTraits traits{};
|
||||||
|
// brightness
|
||||||
|
// rgb
|
||||||
|
// rgb_white_value
|
||||||
|
// color_temperature, min_mireds, max_mireds
|
||||||
|
// color_interlock
|
||||||
|
switch (type_) {
|
||||||
|
case DemoLightType::TYPE_1:
|
||||||
|
break;
|
||||||
|
case DemoLightType::TYPE_2:
|
||||||
|
traits.set_supports_brightness(true);
|
||||||
|
break;
|
||||||
|
case DemoLightType::TYPE_3:
|
||||||
|
traits.set_supports_brightness(true);
|
||||||
|
traits.set_supports_rgb(true);
|
||||||
|
break;
|
||||||
|
case DemoLightType::TYPE_4:
|
||||||
|
traits.set_supports_brightness(true);
|
||||||
|
traits.set_supports_rgb(true);
|
||||||
|
traits.set_supports_rgb_white_value(true);
|
||||||
|
break;
|
||||||
|
case DemoLightType::TYPE_5:
|
||||||
|
traits.set_supports_brightness(true);
|
||||||
|
traits.set_supports_rgb(true);
|
||||||
|
traits.set_supports_rgb_white_value(true);
|
||||||
|
traits.set_supports_color_temperature(true);
|
||||||
|
traits.set_min_mireds(153);
|
||||||
|
traits.set_max_mireds(500);
|
||||||
|
break;
|
||||||
|
case DemoLightType::TYPE_6:
|
||||||
|
traits.set_supports_brightness(true);
|
||||||
|
traits.set_supports_color_temperature(true);
|
||||||
|
traits.set_min_mireds(153);
|
||||||
|
traits.set_max_mireds(500);
|
||||||
|
break;
|
||||||
|
case DemoLightType::TYPE_7:
|
||||||
|
traits.set_supports_brightness(true);
|
||||||
|
traits.set_supports_rgb(true);
|
||||||
|
traits.set_supports_rgb_white_value(true);
|
||||||
|
traits.set_supports_color_interlock(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return traits;
|
||||||
|
}
|
||||||
|
void write_state(light::LightState *state) override {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
DemoLightType type_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace demo
|
||||||
|
} // namespace esphome
|
39
esphome/components/demo/demo_number.h
Normal file
39
esphome/components/demo/demo_number.h
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/components/number/number.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace demo {
|
||||||
|
|
||||||
|
enum class DemoNumberType {
|
||||||
|
TYPE_1,
|
||||||
|
TYPE_2,
|
||||||
|
TYPE_3,
|
||||||
|
};
|
||||||
|
|
||||||
|
class DemoNumber : public number::Number, public Component {
|
||||||
|
public:
|
||||||
|
void set_type(DemoNumberType type) { type_ = type; }
|
||||||
|
void setup() override {
|
||||||
|
switch (type_) {
|
||||||
|
case DemoNumberType::TYPE_1:
|
||||||
|
this->publish_state(50);
|
||||||
|
break;
|
||||||
|
case DemoNumberType::TYPE_2:
|
||||||
|
this->publish_state(-10);
|
||||||
|
break;
|
||||||
|
case DemoNumberType::TYPE_3:
|
||||||
|
this->publish_state(42);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(float value) override { this->publish_state(value); }
|
||||||
|
|
||||||
|
DemoNumberType type_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace demo
|
||||||
|
} // namespace esphome
|
28
esphome/components/demo/demo_sensor.h
Normal file
28
esphome/components/demo/demo_sensor.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/core/helpers.h"
|
||||||
|
#include "esphome/components/sensor/sensor.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace demo {
|
||||||
|
|
||||||
|
class DemoSensor : public sensor::Sensor, public PollingComponent {
|
||||||
|
public:
|
||||||
|
void update() override {
|
||||||
|
float val = random_float();
|
||||||
|
bool is_auto = this->last_reset_type == sensor::LAST_RESET_TYPE_AUTO;
|
||||||
|
if (is_auto) {
|
||||||
|
float base = isnan(this->state) ? 0.0f : this->state;
|
||||||
|
this->publish_state(base + val * 10);
|
||||||
|
} else {
|
||||||
|
if (val < 0.1)
|
||||||
|
this->publish_state(NAN);
|
||||||
|
else
|
||||||
|
this->publish_state(val * 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace demo
|
||||||
|
} // namespace esphome
|
22
esphome/components/demo/demo_switch.h
Normal file
22
esphome/components/demo/demo_switch.h
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/core/helpers.h"
|
||||||
|
#include "esphome/components/switch/switch.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace demo {
|
||||||
|
|
||||||
|
class DemoSwitch : public switch_::Switch, public Component {
|
||||||
|
public:
|
||||||
|
void setup() override {
|
||||||
|
bool initial = random_float() < 0.5;
|
||||||
|
this->publish_state(initial);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void write_state(bool state) override { this->publish_state(state); }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace demo
|
||||||
|
} // namespace esphome
|
25
esphome/components/demo/demo_text_sensor.h
Normal file
25
esphome/components/demo/demo_text_sensor.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/core/helpers.h"
|
||||||
|
#include "esphome/components/text_sensor/text_sensor.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace demo {
|
||||||
|
|
||||||
|
class DemoTextSensor : public text_sensor::TextSensor, public PollingComponent {
|
||||||
|
public:
|
||||||
|
void update() override {
|
||||||
|
float val = random_float();
|
||||||
|
if (val < 0.33) {
|
||||||
|
this->publish_state("foo");
|
||||||
|
} else if (val < 0.66) {
|
||||||
|
this->publish_state("bar");
|
||||||
|
} else {
|
||||||
|
this->publish_state("foobar");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace demo
|
||||||
|
} // namespace esphome
|
|
@ -52,6 +52,8 @@ output:
|
||||||
channel: 0
|
channel: 0
|
||||||
max_power: 0.8
|
max_power: 0.8
|
||||||
|
|
||||||
|
demo:
|
||||||
|
|
||||||
esp32_ble:
|
esp32_ble:
|
||||||
|
|
||||||
esp32_ble_server:
|
esp32_ble_server:
|
||||||
|
@ -116,6 +118,7 @@ sensor:
|
||||||
name: "SelecEM2M Maximum Demand Reactive Power"
|
name: "SelecEM2M Maximum Demand Reactive Power"
|
||||||
maximum_demand_apparent_power:
|
maximum_demand_apparent_power:
|
||||||
name: "SelecEM2M Maximum Demand Apparent Power"
|
name: "SelecEM2M Maximum Demand Apparent Power"
|
||||||
|
|
||||||
- platform: t6615
|
- platform: t6615
|
||||||
uart_id: uart2
|
uart_id: uart2
|
||||||
co2:
|
co2:
|
||||||
|
|
Loading…
Reference in a new issue