mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	Moar Custom platforms
This commit is contained in:
		| @@ -7,7 +7,7 @@ from esphome.const import CONF_AWAY_CONFIG, CONF_COOL_ACTION, \ | |||||||
|     CONF_ID, CONF_IDLE_ACTION, CONF_SENSOR |     CONF_ID, CONF_IDLE_ACTION, CONF_SENSOR | ||||||
|  |  | ||||||
| bang_bang_ns = cg.esphome_ns.namespace('bang_bang') | bang_bang_ns = cg.esphome_ns.namespace('bang_bang') | ||||||
| BangBangClimate = bang_bang_ns.class_('BangBangClimate', climate.ClimateDevice) | BangBangClimate = bang_bang_ns.class_('BangBangClimate', climate.Climate) | ||||||
| BangBangClimateTargetTempConfig = bang_bang_ns.struct('BangBangClimateTargetTempConfig') | BangBangClimateTargetTempConfig = bang_bang_ns.struct('BangBangClimateTargetTempConfig') | ||||||
|  |  | ||||||
| CONFIG_SCHEMA = cv.All(climate.CLIMATE_SCHEMA.extend({ | CONFIG_SCHEMA = cv.All(climate.CLIMATE_SCHEMA.extend({ | ||||||
|   | |||||||
| @@ -111,7 +111,7 @@ void CCS811Component::dump_config() { | |||||||
|   ESP_LOGCONFIG(TAG, "CCS811"); |   ESP_LOGCONFIG(TAG, "CCS811"); | ||||||
|   LOG_I2C_DEVICE(this) |   LOG_I2C_DEVICE(this) | ||||||
|   LOG_UPDATE_INTERVAL(this) |   LOG_UPDATE_INTERVAL(this) | ||||||
|   LOG_SENSOR("  ", "CO2 Sesnor", this->co2_) |   LOG_SENSOR("  ", "CO2 Sensor", this->co2_) | ||||||
|   LOG_SENSOR("  ", "TVOC Sensor", this->tvoc_) |   LOG_SENSOR("  ", "TVOC Sensor", this->tvoc_) | ||||||
|   if (this->baseline_) { |   if (this->baseline_) { | ||||||
|     ESP_LOGCONFIG(TAG, "  Baseline: %04X", *this->baseline_); |     ESP_LOGCONFIG(TAG, "  Baseline: %04X", *this->baseline_); | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| import esphome.codegen as cg | import esphome.codegen as cg | ||||||
| import esphome.config_validation as cv | import esphome.config_validation as cv | ||||||
| from esphome.components import i2c, sensor | from esphome.components import i2c, sensor | ||||||
| from esphome.const import CONF_ID, ICON_GAS_CYLINDER, ICON_RADIATOR, UNIT_PARTS_PER_MILLION, \ | from esphome.const import CONF_ID, ICON_RADIATOR, UNIT_PARTS_PER_MILLION, \ | ||||||
|     UNIT_PARTS_PER_BILLION, CONF_TEMPERATURE, CONF_HUMIDITY |     UNIT_PARTS_PER_BILLION, CONF_TEMPERATURE, CONF_HUMIDITY, ICON_PERIODIC_TABLE_CO2 | ||||||
|  |  | ||||||
| DEPENDENCIES = ['i2c'] | DEPENDENCIES = ['i2c'] | ||||||
|  |  | ||||||
| @@ -15,7 +15,8 @@ CONF_BASELINE = 'baseline' | |||||||
|  |  | ||||||
| CONFIG_SCHEMA = cv.Schema({ | CONFIG_SCHEMA = cv.Schema({ | ||||||
|     cv.GenerateID(): cv.declare_id(CCS811Component), |     cv.GenerateID(): cv.declare_id(CCS811Component), | ||||||
|     cv.Required(CONF_ECO2): sensor.sensor_schema(UNIT_PARTS_PER_MILLION, ICON_GAS_CYLINDER, 0), |     cv.Required(CONF_ECO2): sensor.sensor_schema(UNIT_PARTS_PER_MILLION, ICON_PERIODIC_TABLE_CO2, | ||||||
|  |                                                  0), | ||||||
|     cv.Required(CONF_TVOC): sensor.sensor_schema(UNIT_PARTS_PER_BILLION, ICON_RADIATOR, 0), |     cv.Required(CONF_TVOC): sensor.sensor_schema(UNIT_PARTS_PER_BILLION, ICON_RADIATOR, 0), | ||||||
|  |  | ||||||
|     cv.Optional(CONF_BASELINE): cv.hex_uint16_t, |     cv.Optional(CONF_BASELINE): cv.hex_uint16_t, | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ IS_PLATFORM_COMPONENT = True | |||||||
|  |  | ||||||
| climate_ns = cg.esphome_ns.namespace('climate') | climate_ns = cg.esphome_ns.namespace('climate') | ||||||
|  |  | ||||||
| ClimateDevice = climate_ns.class_('Climate', cg.Nameable) | Climate = climate_ns.class_('Climate', cg.Nameable) | ||||||
| ClimateCall = climate_ns.class_('ClimateCall') | ClimateCall = climate_ns.class_('ClimateCall') | ||||||
| ClimateTraits = climate_ns.class_('ClimateTraits') | ClimateTraits = climate_ns.class_('ClimateTraits') | ||||||
|  |  | ||||||
| @@ -30,7 +30,7 @@ validate_climate_mode = cv.enum(CLIMATE_MODES, upper=True) | |||||||
| ControlAction = climate_ns.class_('ControlAction', automation.Action) | ControlAction = climate_ns.class_('ControlAction', automation.Action) | ||||||
|  |  | ||||||
| CLIMATE_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({ | CLIMATE_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({ | ||||||
|     cv.GenerateID(): cv.declare_id(ClimateDevice), |     cv.GenerateID(): cv.declare_id(Climate), | ||||||
|     cv.OnlyWith(CONF_MQTT_ID, 'mqtt'): cv.declare_id(mqtt.MQTTClimateComponent), |     cv.OnlyWith(CONF_MQTT_ID, 'mqtt'): cv.declare_id(mqtt.MQTTClimateComponent), | ||||||
|     cv.Optional(CONF_VISUAL, default={}): cv.Schema({ |     cv.Optional(CONF_VISUAL, default={}): cv.Schema({ | ||||||
|         cv.Optional(CONF_MIN_TEMPERATURE): cv.temperature, |         cv.Optional(CONF_MIN_TEMPERATURE): cv.temperature, | ||||||
| @@ -68,7 +68,7 @@ def register_climate(var, config): | |||||||
|  |  | ||||||
|  |  | ||||||
| CLIMATE_CONTROL_ACTION_SCHEMA = cv.Schema({ | CLIMATE_CONTROL_ACTION_SCHEMA = cv.Schema({ | ||||||
|     cv.Required(CONF_ID): cv.use_id(ClimateDevice), |     cv.Required(CONF_ID): cv.use_id(Climate), | ||||||
|     cv.Optional(CONF_MODE): cv.templatable(validate_climate_mode), |     cv.Optional(CONF_MODE): cv.templatable(validate_climate_mode), | ||||||
|     cv.Optional(CONF_TARGET_TEMPERATURE): cv.templatable(cv.temperature), |     cv.Optional(CONF_TARGET_TEMPERATURE): cv.templatable(cv.temperature), | ||||||
|     cv.Optional(CONF_TARGET_TEMPERATURE_LOW): cv.templatable(cv.temperature), |     cv.Optional(CONF_TARGET_TEMPERATURE_LOW): cv.templatable(cv.temperature), | ||||||
|   | |||||||
							
								
								
									
										26
									
								
								esphome/components/custom/climate/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								esphome/components/custom/climate/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | |||||||
|  | import esphome.codegen as cg | ||||||
|  | import esphome.config_validation as cv | ||||||
|  | from esphome.components import climate | ||||||
|  | from esphome.const import CONF_ID, CONF_LAMBDA | ||||||
|  | from .. import custom_ns | ||||||
|  |  | ||||||
|  | CustomClimateConstructor = custom_ns.class_('CustomClimateConstructor') | ||||||
|  | CONF_CLIMATES = 'climates' | ||||||
|  |  | ||||||
|  | CONFIG_SCHEMA = cv.Schema({ | ||||||
|  |     cv.GenerateID(): cv.declare_id(CustomClimateConstructor), | ||||||
|  |     cv.Required(CONF_LAMBDA): cv.returning_lambda, | ||||||
|  |     cv.Required(CONF_CLIMATES): cv.ensure_list(climate.CLIMATE_SCHEMA), | ||||||
|  | }) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def to_code(config): | ||||||
|  |     template_ = yield cg.process_lambda( | ||||||
|  |         config[CONF_LAMBDA], [], | ||||||
|  |         return_type=cg.std_vector.template(climate.Climate.operator('ptr'))) | ||||||
|  |  | ||||||
|  |     rhs = CustomClimateConstructor(template_) | ||||||
|  |     custom = cg.variable(config[CONF_ID], rhs) | ||||||
|  |     for i, conf in enumerate(config[CONF_CLIMATES]): | ||||||
|  |         rhs = custom.Pget_climate(i) | ||||||
|  |         yield climate.register_climate(rhs, conf) | ||||||
							
								
								
									
										20
									
								
								esphome/components/custom/climate/custom_climate.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								esphome/components/custom/climate/custom_climate.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "esphome/core/component.h" | ||||||
|  | #include "esphome/components/climate/climate.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace custom { | ||||||
|  |  | ||||||
|  | class CustomClimateConstructor { | ||||||
|  |  public: | ||||||
|  |   CustomClimateConstructor(const std::function<std::vector<climate::Climate *>()> &init) { this->climates_ = init(); } | ||||||
|  |  | ||||||
|  |   climate::Climate *get_climate(int i) { return this->climates_[i]; } | ||||||
|  |  | ||||||
|  |  protected: | ||||||
|  |   std::vector<climate::Climate *> climates_; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | }  // namespace custom | ||||||
|  | }  // namespace esphome | ||||||
							
								
								
									
										26
									
								
								esphome/components/custom/cover/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								esphome/components/custom/cover/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | |||||||
|  | import esphome.codegen as cg | ||||||
|  | import esphome.config_validation as cv | ||||||
|  | from esphome.components import cover | ||||||
|  | from esphome.const import CONF_ID, CONF_LAMBDA | ||||||
|  | from .. import custom_ns | ||||||
|  |  | ||||||
|  | CustomCoverConstructor = custom_ns.class_('CustomCoverConstructor') | ||||||
|  | CONF_COVERS = 'covers' | ||||||
|  |  | ||||||
|  | CONFIG_SCHEMA = cv.Schema({ | ||||||
|  |     cv.GenerateID(): cv.declare_id(CustomCoverConstructor), | ||||||
|  |     cv.Required(CONF_LAMBDA): cv.returning_lambda, | ||||||
|  |     cv.Required(CONF_COVERS): cv.ensure_list(cover.COVER_SCHEMA), | ||||||
|  | }) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def to_code(config): | ||||||
|  |     template_ = yield cg.process_lambda( | ||||||
|  |         config[CONF_LAMBDA], [], | ||||||
|  |         return_type=cg.std_vector.template(cover.Cover.operator('ptr'))) | ||||||
|  |  | ||||||
|  |     rhs = CustomCoverConstructor(template_) | ||||||
|  |     custom = cg.variable(config[CONF_ID], rhs) | ||||||
|  |     for i, conf in enumerate(config[CONF_COVERS]): | ||||||
|  |         rhs = custom.Pget_cover(i) | ||||||
|  |         yield cover.register_cover(rhs, conf) | ||||||
							
								
								
									
										19
									
								
								esphome/components/custom/cover/custom_cover.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								esphome/components/custom/cover/custom_cover.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "esphome/components/cover/cover.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace custom { | ||||||
|  |  | ||||||
|  | class CustomCoverConstructor { | ||||||
|  |  public: | ||||||
|  |   CustomCoverConstructor(const std::function<std::vector<cover::Cover *>()> &init) { this->covers_ = init(); } | ||||||
|  |  | ||||||
|  |   cover::Cover *get_cover(int i) { return this->covers_[i]; } | ||||||
|  |  | ||||||
|  |  protected: | ||||||
|  |   std::vector<cover::Cover *> covers_; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | }  // namespace custom | ||||||
|  | }  // namespace esphome | ||||||
							
								
								
									
										26
									
								
								esphome/components/custom/light/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								esphome/components/custom/light/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | |||||||
|  | import esphome.codegen as cg | ||||||
|  | import esphome.config_validation as cv | ||||||
|  | from esphome.components import light | ||||||
|  | from esphome.const import CONF_ID, CONF_LAMBDA | ||||||
|  | from .. import custom_ns | ||||||
|  |  | ||||||
|  | CustomLightOutputConstructor = custom_ns.class_('CustomLightOutputConstructor') | ||||||
|  | CONF_LIGHTS = 'lights' | ||||||
|  |  | ||||||
|  | CONFIG_SCHEMA = cv.Schema({ | ||||||
|  |     cv.GenerateID(): cv.declare_id(CustomLightOutputConstructor), | ||||||
|  |     cv.Required(CONF_LAMBDA): cv.returning_lambda, | ||||||
|  |     cv.Required(CONF_LIGHTS): cv.ensure_list(light.RGB_LIGHT_SCHEMA), | ||||||
|  | }) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def to_code(config): | ||||||
|  |     template_ = yield cg.process_lambda( | ||||||
|  |         config[CONF_LAMBDA], [], | ||||||
|  |         return_type=cg.std_vector.template(light.LightOutput.operator('ptr'))) | ||||||
|  |  | ||||||
|  |     rhs = CustomLightOutputConstructor(template_) | ||||||
|  |     custom = cg.variable(config[CONF_ID], rhs) | ||||||
|  |     for i, conf in enumerate(config[CONF_LIGHTS]): | ||||||
|  |         rhs = custom.Pget_light(i) | ||||||
|  |         yield light.register_light(rhs, conf) | ||||||
							
								
								
									
										22
									
								
								esphome/components/custom/light/custom_light_output.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								esphome/components/custom/light/custom_light_output.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "esphome/core/component.h" | ||||||
|  | #include "esphome/components/light/light_output.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace custom { | ||||||
|  |  | ||||||
|  | class CustomLightOutputConstructor { | ||||||
|  |  public: | ||||||
|  |   CustomLightOutputConstructor(const std::function<std::vector<light::LightOutput *>()> &init) { | ||||||
|  |     this->outputs_ = init(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   light::LightOutput *get_light(int i) { return this->outputs_[i]; } | ||||||
|  |  | ||||||
|  |  protected: | ||||||
|  |   std::vector<light::LightOutput *> outputs_; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | }  // namespace custom | ||||||
|  | }  // namespace esphome | ||||||
| @@ -7,42 +7,27 @@ from .. import custom_ns | |||||||
| CustomBinaryOutputConstructor = custom_ns.class_('CustomBinaryOutputConstructor') | CustomBinaryOutputConstructor = custom_ns.class_('CustomBinaryOutputConstructor') | ||||||
| CustomFloatOutputConstructor = custom_ns.class_('CustomFloatOutputConstructor') | CustomFloatOutputConstructor = custom_ns.class_('CustomFloatOutputConstructor') | ||||||
|  |  | ||||||
| BINARY_SCHEMA = cv.Schema({ | CONF_BINARY = 'binary' | ||||||
|  | CONF_FLOAT = 'float' | ||||||
|  |  | ||||||
|  | CONFIG_SCHEMA = cv.typed_schema({ | ||||||
|  |     CONF_BINARY: cv.Schema({ | ||||||
|         cv.GenerateID(): cv.declare_id(CustomBinaryOutputConstructor), |         cv.GenerateID(): cv.declare_id(CustomBinaryOutputConstructor), | ||||||
|         cv.Required(CONF_LAMBDA): cv.returning_lambda, |         cv.Required(CONF_LAMBDA): cv.returning_lambda, | ||||||
|     cv.Required(CONF_TYPE): 'binary', |  | ||||||
|         cv.Required(CONF_OUTPUTS): |         cv.Required(CONF_OUTPUTS): | ||||||
|             cv.ensure_list(output.BINARY_OUTPUT_SCHEMA.extend({ |             cv.ensure_list(output.BINARY_OUTPUT_SCHEMA.extend({ | ||||||
|                 cv.GenerateID(): cv.declare_id(output.BinaryOutput), |                 cv.GenerateID(): cv.declare_id(output.BinaryOutput), | ||||||
|             })), |             })), | ||||||
| }) |     }), | ||||||
|  |     CONF_FLOAT: cv.Schema({ | ||||||
| FLOAT_SCHEMA = cv.Schema({ |  | ||||||
|         cv.GenerateID(): cv.declare_id(CustomFloatOutputConstructor), |         cv.GenerateID(): cv.declare_id(CustomFloatOutputConstructor), | ||||||
|         cv.Required(CONF_LAMBDA): cv.returning_lambda, |         cv.Required(CONF_LAMBDA): cv.returning_lambda, | ||||||
|     cv.Required(CONF_TYPE): 'float', |  | ||||||
|         cv.Required(CONF_OUTPUTS): |         cv.Required(CONF_OUTPUTS): | ||||||
|             cv.ensure_list(output.FLOAT_OUTPUT_SCHEMA.extend({ |             cv.ensure_list(output.FLOAT_OUTPUT_SCHEMA.extend({ | ||||||
|                 cv.GenerateID(): cv.declare_id(output.FloatOutput), |                 cv.GenerateID(): cv.declare_id(output.FloatOutput), | ||||||
|             })), |             })), | ||||||
|     }) |     }) | ||||||
|  | }, lower=True) | ||||||
|  |  | ||||||
| def validate_custom_output(value): |  | ||||||
|     if not isinstance(value, dict): |  | ||||||
|         raise cv.Invalid("Value must be dict") |  | ||||||
|     if CONF_TYPE not in value: |  | ||||||
|         raise cv.Invalid("type not specified!") |  | ||||||
|     type = cv.string_strict(value[CONF_TYPE]).lower() |  | ||||||
|     value[CONF_TYPE] = type |  | ||||||
|     if type == 'binary': |  | ||||||
|         return BINARY_SCHEMA(value) |  | ||||||
|     if type == 'float': |  | ||||||
|         return FLOAT_SCHEMA(value) |  | ||||||
|     raise cv.Invalid("type must either be binary or float, not {}!".format(type)) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| CONFIG_SCHEMA = validate_custom_output |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def to_code(config): | def to_code(config): | ||||||
|   | |||||||
							
								
								
									
										35
									
								
								esphome/components/template/output/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								esphome/components/template/output/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  | import esphome.codegen as cg | ||||||
|  | import esphome.config_validation as cv | ||||||
|  | from esphome import automation | ||||||
|  | from esphome.components import output | ||||||
|  | from esphome.const import CONF_ID, CONF_TYPE | ||||||
|  | from .. import template_ns | ||||||
|  |  | ||||||
|  | TemplateBinaryOutput = template_ns.class_('TemplateBinaryOutput', output.BinaryOutput) | ||||||
|  | TemplateFloatOutput = template_ns.class_('TemplateFloatOutput', output.FloatOutput) | ||||||
|  |  | ||||||
|  | CONF_BINARY = 'binary' | ||||||
|  | CONF_FLOAT = 'float' | ||||||
|  | CONF_WRITE_ACTION = 'write_action' | ||||||
|  |  | ||||||
|  | CONFIG_SCHEMA = cv.typed_schema({ | ||||||
|  |     CONF_BINARY: output.BINARY_OUTPUT_SCHEMA.extend({ | ||||||
|  |         cv.GenerateID(): cv.declare_id(TemplateBinaryOutput), | ||||||
|  |         cv.Required(CONF_WRITE_ACTION): automation.validate_automation(single=True), | ||||||
|  |     }), | ||||||
|  |     CONF_FLOAT: output.FLOAT_OUTPUT_SCHEMA.extend({ | ||||||
|  |         cv.GenerateID(): cv.declare_id(TemplateFloatOutput), | ||||||
|  |         cv.Required(CONF_WRITE_ACTION): automation.validate_automation(single=True), | ||||||
|  |     }), | ||||||
|  | }, lower=True) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def to_code(config): | ||||||
|  |     var = cg.new_Pvariable(config[CONF_ID]) | ||||||
|  |     if config[CONF_TYPE] == CONF_BINARY: | ||||||
|  |         yield automation.build_automation(var.get_trigger(), [(bool, 'state')], | ||||||
|  |                                           config[CONF_WRITE_ACTION]) | ||||||
|  |     else: | ||||||
|  |         yield automation.build_automation(var.get_trigger(), [(float, 'state')], | ||||||
|  |                                           config[CONF_WRITE_ACTION]) | ||||||
|  |     yield output.register_output(var, config) | ||||||
							
								
								
									
										31
									
								
								esphome/components/template/output/template_output.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								esphome/components/template/output/template_output.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "esphome/core/automation.h" | ||||||
|  | #include "esphome/components/output/binary_output.h" | ||||||
|  | #include "esphome/components/output/float_output.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace template_ { | ||||||
|  |  | ||||||
|  | class TemplateBinaryOutput : public output::BinaryOutput { | ||||||
|  |  public: | ||||||
|  |   Trigger<bool> *get_trigger() const { return trigger_; } | ||||||
|  |  | ||||||
|  |  protected: | ||||||
|  |   void write_state(bool state) override { this->trigger_->trigger(state); } | ||||||
|  |  | ||||||
|  |   Trigger<bool> *trigger_ = new Trigger<bool>(); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | class TemplateFloatOutput : public output::FloatOutput { | ||||||
|  |  public: | ||||||
|  |   Trigger<float> *get_trigger() const { return trigger_; } | ||||||
|  |  | ||||||
|  |  protected: | ||||||
|  |   void write_state(float state) override { this->trigger_->trigger(state); } | ||||||
|  |  | ||||||
|  |   Trigger<float> *trigger_ = new Trigger<float>(); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | }  // namespace template_ | ||||||
|  | }  // namespace esphome | ||||||
| @@ -16,7 +16,7 @@ from esphome import core | |||||||
| from esphome.const import CONF_AVAILABILITY, CONF_COMMAND_TOPIC, CONF_DISCOVERY, CONF_ID, \ | from esphome.const import CONF_AVAILABILITY, CONF_COMMAND_TOPIC, CONF_DISCOVERY, CONF_ID, \ | ||||||
|     CONF_INTERNAL, CONF_NAME, CONF_PAYLOAD_AVAILABLE, CONF_PAYLOAD_NOT_AVAILABLE, \ |     CONF_INTERNAL, CONF_NAME, CONF_PAYLOAD_AVAILABLE, CONF_PAYLOAD_NOT_AVAILABLE, \ | ||||||
|     CONF_RETAIN, CONF_SETUP_PRIORITY, CONF_STATE_TOPIC, CONF_TOPIC, \ |     CONF_RETAIN, CONF_SETUP_PRIORITY, CONF_STATE_TOPIC, CONF_TOPIC, \ | ||||||
|     CONF_HOUR, CONF_MINUTE, CONF_SECOND, CONF_VALUE, CONF_UPDATE_INTERVAL, CONF_TYPE_ID |     CONF_HOUR, CONF_MINUTE, CONF_SECOND, CONF_VALUE, CONF_UPDATE_INTERVAL, CONF_TYPE_ID, CONF_TYPE | ||||||
| from esphome.core import CORE, HexInt, IPAddress, Lambda, TimePeriod, TimePeriodMicroseconds, \ | from esphome.core import CORE, HexInt, IPAddress, Lambda, TimePeriod, TimePeriodMicroseconds, \ | ||||||
|     TimePeriodMilliseconds, TimePeriodSeconds, TimePeriodMinutes |     TimePeriodMilliseconds, TimePeriodSeconds, TimePeriodMinutes | ||||||
| from esphome.helpers import list_starts_with | from esphome.helpers import list_starts_with | ||||||
| @@ -1078,6 +1078,24 @@ def extract_keys(schema): | |||||||
|     return keys |     return keys | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def typed_schema(schemas, **kwargs): | ||||||
|  |     """Create a schema that has a key to distinguish between schemas""" | ||||||
|  |     key = kwargs.pop('key', CONF_TYPE) | ||||||
|  |     key_validator = one_of(*schemas, **kwargs) | ||||||
|  |  | ||||||
|  |     def validator(value): | ||||||
|  |         if not isinstance(value, dict): | ||||||
|  |             raise Invalid("Value must be dict") | ||||||
|  |         if CONF_TYPE not in value: | ||||||
|  |             raise Invalid("type not specified!") | ||||||
|  |         value = value.copy() | ||||||
|  |         key_v = key_validator(value.pop(key)) | ||||||
|  |         value = schemas[key_v](value) | ||||||
|  |         value[key] = key_v | ||||||
|  |  | ||||||
|  |     return validator | ||||||
|  |  | ||||||
|  |  | ||||||
| class GenerateID(Optional): | class GenerateID(Optional): | ||||||
|     """Mark this key as being an auto-generated ID key.""" |     """Mark this key as being an auto-generated ID key.""" | ||||||
|     def __init__(self, key=CONF_ID): |     def __init__(self, key=CONF_ID): | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user