Add demo integration (#2085)

This commit is contained in:
Otto Winter 2021-07-29 11:50:55 +02:00 committed by GitHub
parent af8d04818d
commit 16dbbfabc6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 969 additions and 0 deletions

View 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)

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View file

@ -52,6 +52,8 @@ output:
channel: 0
max_power: 0.8
demo:
esp32_ble:
esp32_ble_server:
@ -116,6 +118,7 @@ sensor:
name: "SelecEM2M Maximum Demand Reactive Power"
maximum_demand_apparent_power:
name: "SelecEM2M Maximum Demand Apparent Power"
- platform: t6615
uart_id: uart2
co2: