mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	Add demo integration (#2085)
This commit is contained in:
		
							
								
								
									
										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 | ||||
|     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: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user