1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-19 19:52:20 +01:00

🏗 Merge C++ into python codebase (#504)

## Description:

Move esphome-core codebase into esphome (and a bunch of other refactors). See https://github.com/esphome/feature-requests/issues/97

Yes this is a shit ton of work and no there's no way to automate it :( But it will be worth it 👍

Progress:
- Core support (file copy etc): 80%
- Base Abstractions (light, switch): ~50%
- Integrations: ~10%
- Working? Yes, (but only with ported components).

Other refactors:
- Moves all codegen related stuff into a single class: `esphome.codegen` (imported as `cg`)
- Rework coroutine syntax
- Move from `component/platform.py` to `domain/component.py` structure as with HA
- Move all defaults out of C++ and into config validation.
- Remove `make_...` helpers from Application class. Reason: Merge conflicts with every single new integration.
- Pointer Variables are stored globally instead of locally in setup(). Reason: stack size limit.

Future work:
- Rework const.py - Move all `CONF_...` into a conf class (usage `conf.UPDATE_INTERVAL` vs `CONF_UPDATE_INTERVAL`). Reason: Less convoluted import block
- Enable loading from `custom_components` folder.

**Related issue (if applicable):** https://github.com/esphome/feature-requests/issues/97

**Pull request in [esphome-docs](https://github.com/esphome/esphome-docs) with documentation (if applicable):** esphome/esphome-docs#<esphome-docs PR number goes here>

## Checklist:
  - [ ] The code change is tested and works locally.
  - [ ] Tests have been added to verify that the new code works (under `tests/` folder).

If user exposed functionality or configuration variables are added/changed:
  - [ ] Documentation added/updated in [esphomedocs](https://github.com/OttoWinter/esphomedocs).
This commit is contained in:
Otto Winter
2019-04-17 12:06:00 +02:00
committed by GitHub
parent 049807e3ab
commit 6682c43dfa
817 changed files with 54156 additions and 10830 deletions

View File

@@ -1,58 +1,46 @@
import math
import voluptuous as vol
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import automation
from esphome.automation import CONDITION_REGISTRY
from esphome.components import mqtt
from esphome.components.mqtt import setup_mqtt_component
import esphome.config_validation as cv
from esphome.const import CONF_ABOVE, CONF_ACCURACY_DECIMALS, CONF_ALPHA, CONF_BELOW, \
CONF_CALIBRATE_LINEAR, CONF_DEBOUNCE, CONF_DELTA, CONF_EXPIRE_AFTER, \
CONF_EXPONENTIAL_MOVING_AVERAGE, CONF_FILTERS, CONF_FILTER_OUT, CONF_FROM, \
CONF_HEARTBEAT, CONF_ICON, CONF_ID, CONF_INTERNAL, CONF_LAMBDA, CONF_MQTT_ID, \
CONF_MULTIPLY, CONF_OFFSET, CONF_ON_RAW_VALUE, CONF_ON_VALUE, CONF_ON_VALUE_RANGE, CONF_OR, \
CONF_SEND_EVERY, CONF_SEND_FIRST_AT, CONF_SLIDING_WINDOW_MOVING_AVERAGE, \
CONF_THROTTLE, CONF_TO, CONF_TRIGGER_ID, CONF_UNIQUE, CONF_UNIT_OF_MEASUREMENT, \
CONF_WINDOW_SIZE
CONF_FILTERS, CONF_FROM, \
CONF_ICON, CONF_ID, CONF_INTERNAL, CONF_LAMBDA, CONF_MULTIPLY, CONF_OFFSET, \
CONF_ON_RAW_VALUE, CONF_ON_VALUE, CONF_ON_VALUE_RANGE, CONF_OR, \
CONF_SEND_EVERY, CONF_SEND_FIRST_AT, CONF_THROTTLE, CONF_TO, CONF_TRIGGER_ID, \
CONF_UNIT_OF_MEASUREMENT, \
CONF_WINDOW_SIZE, CONF_VALUE, CONF_HEARTBEAT, CONF_NAME, CONF_MQTT_ID
from esphome.core import CORE, coroutine
from esphome.cpp_generator import Pvariable, add, get_variable, process_lambda, templatable
from esphome.cpp_types import App, Component, Nameable, PollingComponent, Trigger, \
esphome_ns, float_, optional
from esphome.util import ServiceRegistry
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
})
def validate_recursive_filter(value):
return FILTERS_SCHEMA(value)
IS_PLATFORM_COMPONENT = True
def validate_send_first_at(value):
send_first_at = value.get(CONF_SEND_FIRST_AT)
send_every = value[CONF_SEND_EVERY]
if send_first_at is not None and send_first_at > send_every:
raise vol.Invalid("send_first_at must be smaller than or equal to send_every! {} <= {}"
"".format(send_first_at, send_every))
raise cv.Invalid("send_first_at must be smaller than or equal to send_every! {} <= {}"
"".format(send_first_at, send_every))
return value
FILTER_KEYS = [CONF_OFFSET, CONF_MULTIPLY, CONF_FILTER_OUT,
CONF_SLIDING_WINDOW_MOVING_AVERAGE, CONF_EXPONENTIAL_MOVING_AVERAGE, CONF_LAMBDA,
CONF_THROTTLE, CONF_DELTA, CONF_HEARTBEAT, CONF_DEBOUNCE, CONF_OR,
CONF_CALIBRATE_LINEAR]
FILTER_REGISTRY = ServiceRegistry()
validate_filters = cv.validate_registry('filter', FILTER_REGISTRY, [CONF_ID])
def validate_datapoint(value):
if isinstance(value, dict):
return cv.Schema({
vol.Required(CONF_FROM): cv.float_,
vol.Required(CONF_TO): cv.float_,
cv.Required(CONF_FROM): cv.float_,
cv.Required(CONF_TO): cv.float_,
})(value)
value = cv.string(value)
if '->' not in value:
raise vol.Invalid("Datapoint mapping must contain '->'")
raise cv.Invalid("Datapoint mapping must contain '->'")
a, b = value.split('->', 1)
a, b = a.strip(), b.strip()
return validate_datapoint({
@@ -61,47 +49,19 @@ def validate_datapoint(value):
})
FILTERS_SCHEMA = cv.ensure_list({
vol.Optional(CONF_OFFSET): cv.float_,
vol.Optional(CONF_MULTIPLY): cv.float_,
vol.Optional(CONF_FILTER_OUT): cv.float_,
vol.Optional('filter_nan'): cv.invalid("The filter_nan filter has been removed. Please use "
"'filter_out: nan' instead"),
vol.Optional(CONF_SLIDING_WINDOW_MOVING_AVERAGE): vol.All(cv.Schema({
vol.Optional(CONF_WINDOW_SIZE, default=15): cv.positive_not_null_int,
vol.Optional(CONF_SEND_EVERY, default=15): cv.positive_not_null_int,
vol.Optional(CONF_SEND_FIRST_AT): cv.positive_not_null_int,
}), validate_send_first_at),
vol.Optional(CONF_EXPONENTIAL_MOVING_AVERAGE): cv.Schema({
vol.Optional(CONF_ALPHA, default=0.1): cv.positive_float,
vol.Optional(CONF_SEND_EVERY, default=15): cv.positive_not_null_int,
}),
vol.Optional(CONF_CALIBRATE_LINEAR): vol.All(
cv.ensure_list(validate_datapoint), vol.Length(min=2)),
vol.Optional(CONF_LAMBDA): cv.lambda_,
vol.Optional(CONF_THROTTLE): cv.positive_time_period_milliseconds,
vol.Optional(CONF_DELTA): cv.float_,
vol.Optional(CONF_UNIQUE): cv.invalid("The unique filter has been removed in 1.12, please "
"replace with a delta filter with small value."),
vol.Optional(CONF_HEARTBEAT): cv.positive_time_period_milliseconds,
vol.Optional(CONF_DEBOUNCE): cv.positive_time_period_milliseconds,
vol.Optional(CONF_OR): validate_recursive_filter,
}, cv.has_exactly_one_key(*FILTER_KEYS))
# Base
sensor_ns = esphome_ns.namespace('sensor')
Sensor = sensor_ns.class_('Sensor', Nameable)
sensor_ns = cg.esphome_ns.namespace('sensor')
Sensor = sensor_ns.class_('Sensor', cg.Nameable)
SensorPtr = Sensor.operator('ptr')
MQTTSensorComponent = sensor_ns.class_('MQTTSensorComponent', mqtt.MQTTComponent)
PollingSensorComponent = sensor_ns.class_('PollingSensorComponent', PollingComponent, Sensor)
EmptySensor = sensor_ns.class_('EmptySensor', Sensor)
EmptyPollingParentSensor = sensor_ns.class_('EmptyPollingParentSensor', EmptySensor)
PollingSensorComponent = sensor_ns.class_('PollingSensorComponent', cg.PollingComponent, Sensor)
# Triggers
SensorStateTrigger = sensor_ns.class_('SensorStateTrigger', Trigger.template(float_))
SensorRawStateTrigger = sensor_ns.class_('SensorRawStateTrigger', Trigger.template(float_))
ValueRangeTrigger = sensor_ns.class_('ValueRangeTrigger', Trigger.template(float_), Component)
SensorStateTrigger = sensor_ns.class_('SensorStateTrigger', cg.Trigger.template(cg.float_))
SensorRawStateTrigger = sensor_ns.class_('SensorRawStateTrigger', cg.Trigger.template(cg.float_))
ValueRangeTrigger = sensor_ns.class_('ValueRangeTrigger', cg.Trigger.template(cg.float_),
cg.Component)
SensorPublishAction = sensor_ns.class_('SensorPublishAction', cg.Action)
# Filters
Filter = sensor_ns.class_('Filter')
@@ -112,159 +72,243 @@ OffsetFilter = sensor_ns.class_('OffsetFilter', Filter)
MultiplyFilter = sensor_ns.class_('MultiplyFilter', Filter)
FilterOutValueFilter = sensor_ns.class_('FilterOutValueFilter', Filter)
ThrottleFilter = sensor_ns.class_('ThrottleFilter', Filter)
DebounceFilter = sensor_ns.class_('DebounceFilter', Filter, Component)
HeartbeatFilter = sensor_ns.class_('HeartbeatFilter', Filter, Component)
DebounceFilter = sensor_ns.class_('DebounceFilter', Filter, cg.Component)
HeartbeatFilter = sensor_ns.class_('HeartbeatFilter', Filter, cg.Component)
DeltaFilter = sensor_ns.class_('DeltaFilter', Filter)
OrFilter = sensor_ns.class_('OrFilter', Filter)
CalibrateLinearFilter = sensor_ns.class_('CalibrateLinearFilter', Filter)
SensorInRangeCondition = sensor_ns.class_('SensorInRangeCondition', Filter)
unit_of_measurement = cv.string_strict
accuracy_decimals = cv.int_
icon = cv.icon
SENSOR_SCHEMA = cv.MQTT_COMPONENT_SCHEMA.extend({
cv.GenerateID(CONF_MQTT_ID): cv.declare_variable_id(MQTTSensorComponent),
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string_strict,
vol.Optional(CONF_ICON): cv.icon,
vol.Optional(CONF_ACCURACY_DECIMALS): vol.Coerce(int),
vol.Optional(CONF_EXPIRE_AFTER): vol.All(cv.requires_component('mqtt'),
vol.Any(None, cv.positive_time_period_milliseconds)),
vol.Optional(CONF_FILTERS): FILTERS_SCHEMA,
vol.Optional(CONF_ON_VALUE): automation.validate_automation({
cv.OnlyWith(CONF_MQTT_ID, 'mqtt'): cv.declare_variable_id(mqtt.MQTTSensorComponent),
cv.GenerateID(): cv.declare_variable_id(Sensor),
cv.Optional(CONF_UNIT_OF_MEASUREMENT): unit_of_measurement,
cv.Optional(CONF_ICON): icon,
cv.Optional(CONF_ACCURACY_DECIMALS): accuracy_decimals,
cv.Optional(CONF_EXPIRE_AFTER): cv.All(cv.requires_component('mqtt'),
cv.Any(None, cv.positive_time_period_milliseconds)),
cv.Optional(CONF_FILTERS): validate_filters,
cv.Optional(CONF_ON_VALUE): automation.validate_automation({
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(SensorStateTrigger),
}),
vol.Optional(CONF_ON_RAW_VALUE): automation.validate_automation({
cv.Optional(CONF_ON_RAW_VALUE): automation.validate_automation({
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(SensorRawStateTrigger),
}),
vol.Optional(CONF_ON_VALUE_RANGE): automation.validate_automation({
cv.Optional(CONF_ON_VALUE_RANGE): automation.validate_automation({
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(ValueRangeTrigger),
vol.Optional(CONF_ABOVE): cv.float_,
vol.Optional(CONF_BELOW): cv.float_,
cv.Optional(CONF_ABOVE): cv.float_,
cv.Optional(CONF_BELOW): cv.float_,
}, cv.has_at_least_one_key(CONF_ABOVE, CONF_BELOW)),
})
SENSOR_PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(SENSOR_SCHEMA.schema)
def sensor_schema(unit_of_measurement_, icon_, accuracy_decimals_):
# type: (str, str, int) -> cv.Schema
return SENSOR_SCHEMA.extend({
cv.Optional(CONF_UNIT_OF_MEASUREMENT, default=unit_of_measurement_): unit_of_measurement,
cv.Optional(CONF_ICON, default=icon_): icon,
cv.Optional(CONF_ACCURACY_DECIMALS, default=accuracy_decimals_): accuracy_decimals,
})
@FILTER_REGISTRY.register(CONF_OFFSET, cv.maybe_simple_value(cv.Schema({
cv.GenerateID(): cv.declare_variable_id(OffsetFilter),
cv.Required(CONF_VALUE): cv.float_,
})))
def offset_filter_to_code(config):
yield cg.new_Pvariable(config[CONF_ID], config[CONF_VALUE])
@FILTER_REGISTRY.register(CONF_MULTIPLY, cv.maybe_simple_value(cv.Schema({
cv.GenerateID(): cv.declare_variable_id(MultiplyFilter),
cv.Required(CONF_VALUE): cv.float_,
})))
def multiply_filter_to_code(config):
yield cg.new_Pvariable(config[CONF_ID], config[CONF_VALUE])
@FILTER_REGISTRY.register('filter_out', cv.maybe_simple_value(cv.Schema({
cv.GenerateID(): cv.declare_variable_id(FilterOutValueFilter),
cv.Required(CONF_VALUE): cv.float_,
})))
def filter_out_filter_to_code(config):
yield cg.new_Pvariable(config[CONF_ID], config[CONF_VALUE])
@FILTER_REGISTRY.register('sliding_window_moving_average', cv.All(cv.Schema({
cv.GenerateID():
cv.declare_variable_id(SlidingWindowMovingAverageFilter),
cv.Optional(CONF_WINDOW_SIZE, default=15): cv.positive_not_null_int,
cv.Optional(CONF_SEND_EVERY, default=15): cv.positive_not_null_int,
cv.Optional(CONF_SEND_FIRST_AT, default=1): cv.positive_not_null_int,
}), validate_send_first_at))
def sliding_window_moving_average_filter_to_code(config):
yield cg.new_Pvariable(config[CONF_ID], config[CONF_WINDOW_SIZE], config[CONF_SEND_EVERY],
config[CONF_SEND_FIRST_AT])
@FILTER_REGISTRY.register('exponential_moving_average', cv.Schema({
cv.GenerateID():
cv.declare_variable_id(ExponentialMovingAverageFilter),
cv.Optional(CONF_ALPHA, default=0.1): cv.positive_float,
cv.Optional(CONF_SEND_EVERY, default=15): cv.positive_not_null_int,
}))
def exponential_moving_average_filter_to_code(config):
yield cg.new_Pvariable(config[CONF_ID], config[CONF_ALPHA], config[CONF_SEND_EVERY])
@FILTER_REGISTRY.register(CONF_LAMBDA, cv.maybe_simple_value(cv.Schema({
cv.GenerateID(): cv.declare_variable_id(LambdaFilter),
cv.Required(CONF_VALUE): cv.lambda_,
})))
def lambda_filter_to_code(config):
lambda_ = yield cg.process_lambda(config[CONF_VALUE], [(float, 'x')],
return_type=cg.optional.template(float))
yield cg.new_Pvariable(config[CONF_ID], lambda_)
@FILTER_REGISTRY.register(CONF_DELTA, cv.maybe_simple_value(cv.Schema({
cv.GenerateID(): cv.declare_variable_id(DeltaFilter),
cv.Required(CONF_VALUE): cv.float_,
})))
def delta_filter_to_code(config):
yield cg.new_Pvariable(config[CONF_ID], config[CONF_VALUE])
@FILTER_REGISTRY.register(CONF_OR, cv.maybe_simple_value(cv.Schema({
cv.GenerateID(): cv.declare_variable_id(OrFilter),
cv.Required(CONF_VALUE): validate_filters,
})))
def or_filter_to_code(config):
filters = yield build_filters(config[CONF_VALUE])
yield cg.new_Pvariable(config[CONF_ID], filters)
@FILTER_REGISTRY.register(CONF_THROTTLE, cv.maybe_simple_value(cv.Schema({
cv.GenerateID(): cv.declare_variable_id(ThrottleFilter),
cv.Required(CONF_VALUE): cv.positive_time_period_milliseconds,
})))
def throttle_filter_to_code(config):
yield cg.new_Pvariable(config[CONF_ID], config[CONF_VALUE])
@FILTER_REGISTRY.register(CONF_HEARTBEAT, cv.maybe_simple_value(cv.Schema({
cv.GenerateID(): cv.declare_variable_id(HeartbeatFilter),
cv.Required(CONF_VALUE): cv.positive_time_period_milliseconds,
}).extend(cv.COMPONENT_SCHEMA)))
def heartbeat_filter_to_code(config):
var = cg.new_Pvariable(config[CONF_ID], config[CONF_VALUE])
yield cg.register_component(var, config)
yield var
@FILTER_REGISTRY.register(CONF_DEBOUNCE, cv.maybe_simple_value(cv.Schema({
cv.GenerateID(): cv.declare_variable_id(DebounceFilter),
cv.Required(CONF_VALUE): cv.positive_time_period_milliseconds,
}).extend(cv.COMPONENT_SCHEMA)))
def debounce_filter_to_code(config):
var = cg.new_Pvariable(config[CONF_ID], config[CONF_VALUE])
yield cg.register_component(var, config)
yield var
@FILTER_REGISTRY.register(CONF_CALIBRATE_LINEAR, cv.maybe_simple_value(cv.Schema({
cv.GenerateID(): cv.declare_variable_id(CalibrateLinearFilter),
cv.Required(CONF_VALUE): cv.All(
cv.ensure_list(validate_datapoint), cv.Length(min=2)),
}).extend(cv.COMPONENT_SCHEMA)))
def calibrate_linear_filter_to_code(config):
x = [conf[CONF_FROM] for conf in config[CONF_VALUE]]
y = [conf[CONF_TO] for conf in config[CONF_VALUE]]
k, b = fit_linear(x, y)
yield cg.new_Pvariable(config[CONF_ID], k, b)
@coroutine
def setup_filter(config):
if CONF_OFFSET in config:
yield OffsetFilter.new(config[CONF_OFFSET])
elif CONF_MULTIPLY in config:
yield MultiplyFilter.new(config[CONF_MULTIPLY])
elif CONF_FILTER_OUT in config:
yield FilterOutValueFilter.new(config[CONF_FILTER_OUT])
elif CONF_SLIDING_WINDOW_MOVING_AVERAGE in config:
conf = config[CONF_SLIDING_WINDOW_MOVING_AVERAGE]
yield SlidingWindowMovingAverageFilter.new(conf[CONF_WINDOW_SIZE], conf[CONF_SEND_EVERY],
conf.get(CONF_SEND_FIRST_AT))
elif CONF_EXPONENTIAL_MOVING_AVERAGE in config:
conf = config[CONF_EXPONENTIAL_MOVING_AVERAGE]
yield ExponentialMovingAverageFilter.new(conf[CONF_ALPHA], conf[CONF_SEND_EVERY])
elif CONF_LAMBDA in config:
lambda_ = yield process_lambda(config[CONF_LAMBDA], [(float_, 'x')],
return_type=optional.template(float_))
yield LambdaFilter.new(lambda_)
elif CONF_THROTTLE in config:
yield ThrottleFilter.new(config[CONF_THROTTLE])
elif CONF_DELTA in config:
yield DeltaFilter.new(config[CONF_DELTA])
elif CONF_OR in config:
filters = yield setup_filters(config[CONF_OR])
yield OrFilter.new(filters)
elif CONF_HEARTBEAT in config:
yield App.register_component(HeartbeatFilter.new(config[CONF_HEARTBEAT]))
elif CONF_DEBOUNCE in config:
yield App.register_component(DebounceFilter.new(config[CONF_DEBOUNCE]))
elif CONF_CALIBRATE_LINEAR in config:
x = [conf[CONF_FROM] for conf in config[CONF_CALIBRATE_LINEAR]]
y = [conf[CONF_TO] for conf in config[CONF_CALIBRATE_LINEAR]]
k, b = fit_linear(x, y)
yield CalibrateLinearFilter.new(k, b)
def build_filters(config):
yield cg.build_registry_list(FILTER_REGISTRY, config)
@coroutine
def setup_filters(config):
filters = []
for conf in config:
filters.append((yield setup_filter(conf)))
yield filters
@coroutine
def setup_sensor_core_(sensor_var, config):
def setup_sensor_core_(var, config):
if CONF_INTERNAL in config:
add(sensor_var.set_internal(config[CONF_INTERNAL]))
cg.add(var.set_internal(config[CONF_INTERNAL]))
if CONF_UNIT_OF_MEASUREMENT in config:
add(sensor_var.set_unit_of_measurement(config[CONF_UNIT_OF_MEASUREMENT]))
cg.add(var.set_unit_of_measurement(config[CONF_UNIT_OF_MEASUREMENT]))
if CONF_ICON in config:
add(sensor_var.set_icon(config[CONF_ICON]))
cg.add(var.set_icon(config[CONF_ICON]))
if CONF_ACCURACY_DECIMALS in config:
add(sensor_var.set_accuracy_decimals(config[CONF_ACCURACY_DECIMALS]))
cg.add(var.set_accuracy_decimals(config[CONF_ACCURACY_DECIMALS]))
if CONF_FILTERS in config:
filters = yield setup_filters(config[CONF_FILTERS])
add(sensor_var.set_filters(filters))
filters = yield build_filters(config[CONF_FILTERS])
cg.add(var.set_filters(filters))
for conf in config.get(CONF_ON_VALUE, []):
rhs = sensor_var.make_state_trigger()
trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs)
automation.build_automations(trigger, [(float_, 'x')], conf)
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
yield automation.build_automation(trigger, [(float, 'x')], conf)
for conf in config.get(CONF_ON_RAW_VALUE, []):
rhs = sensor_var.make_raw_state_trigger()
trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs)
automation.build_automations(trigger, [(float_, 'x')], conf)
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
yield automation.build_automation(trigger, [(float, 'x')], conf)
for conf in config.get(CONF_ON_VALUE_RANGE, []):
rhs = sensor_var.make_value_range_trigger()
trigger = Pvariable(conf[CONF_TRIGGER_ID], rhs)
add(App.register_component(trigger))
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
yield cg.register_component(trigger, conf)
if CONF_ABOVE in conf:
template_ = yield templatable(conf[CONF_ABOVE], float_, float_)
add(trigger.set_min(template_))
template_ = yield cg.templatable(conf[CONF_ABOVE], [(float, 'x')], float)
cg.add(trigger.set_min(template_))
if CONF_BELOW in conf:
template_ = yield templatable(conf[CONF_BELOW], float_, float_)
add(trigger.set_max(template_))
automation.build_automations(trigger, [(float_, 'x')], conf)
template_ = yield cg.templatable(conf[CONF_BELOW], [(float, 'x')], float)
cg.add(trigger.set_max(template_))
yield automation.build_automation(trigger, [(float, 'x')], conf)
mqtt_ = sensor_var.Pget_mqtt()
if CONF_EXPIRE_AFTER in config:
if config[CONF_EXPIRE_AFTER] is None:
add(mqtt_.disable_expire_after())
else:
add(mqtt_.set_expire_after(config[CONF_EXPIRE_AFTER]))
setup_mqtt_component(mqtt_, config)
def setup_sensor(sensor_obj, config):
if not CORE.has_id(config[CONF_ID]):
sensor_obj = Pvariable(config[CONF_ID], sensor_obj, has_side_effects=True)
CORE.add_job(setup_sensor_core_, sensor_obj, config)
if CONF_MQTT_ID in config:
mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], var)
yield mqtt.register_mqtt_component(mqtt_, config)
if CONF_EXPIRE_AFTER in config:
if config[CONF_EXPIRE_AFTER] is None:
cg.add(mqtt_.disable_expire_after())
else:
cg.add(mqtt_.set_expire_after(config[CONF_EXPIRE_AFTER]))
@coroutine
def register_sensor(var, config):
if not CORE.has_id(config[CONF_ID]):
var = Pvariable(config[CONF_ID], var, has_side_effects=True)
add(App.register_sensor(var))
CORE.add_job(setup_sensor_core_, var, config)
var = cg.Pvariable(config[CONF_ID], var)
cg.add(cg.App.register_sensor(var))
yield setup_sensor_core_(var, config)
BUILD_FLAGS = '-DUSE_SENSOR'
@coroutine
def new_sensor(config):
var = cg.new_Pvariable(config[CONF_ID], config[CONF_NAME])
yield register_sensor(var, config)
yield var
CONF_SENSOR_IN_RANGE = 'sensor.in_range'
SENSOR_IN_RANGE_CONDITION_SCHEMA = vol.All({
vol.Required(CONF_ID): cv.use_variable_id(Sensor),
vol.Optional(CONF_ABOVE): cv.float_,
vol.Optional(CONF_BELOW): cv.float_,
SENSOR_IN_RANGE_CONDITION_SCHEMA = cv.All({
cv.Required(CONF_ID): cv.use_variable_id(Sensor),
cv.Optional(CONF_ABOVE): cv.float_,
cv.Optional(CONF_BELOW): cv.float_,
}, cv.has_at_least_one_key(CONF_ABOVE, CONF_BELOW))
@CONDITION_REGISTRY.register(CONF_SENSOR_IN_RANGE, SENSOR_IN_RANGE_CONDITION_SCHEMA)
def sensor_in_range_to_code(config, condition_id, template_arg, args):
var = yield get_variable(config[CONF_ID])
var = yield cg.get_variable(config[CONF_ID])
rhs = var.make_sensor_in_range_condition(template_arg)
type = SensorInRangeCondition.template(template_arg)
cond = Pvariable(condition_id, rhs, type=type)
cond = cg.Pvariable(condition_id, rhs, type=type)
if CONF_ABOVE in config:
add(cond.set_min(config[CONF_ABOVE]))
cg.add(cond.set_min(config[CONF_ABOVE]))
if CONF_BELOW in config:
add(cond.set_max(config[CONF_BELOW]))
cg.add(cond.set_max(config[CONF_BELOW]))
yield cond
@@ -274,14 +318,14 @@ def _mean(xs):
def _std(x):
return math.sqrt(sum((x_ - _mean(x))**2 for x_ in x) / (len(x) - 1))
return math.sqrt(sum((x_ - _mean(x)) ** 2 for x_ in x) / (len(x) - 1))
def _correlation_coeff(x, y):
m_x, m_y = _mean(x), _mean(y)
s_xy = sum((x_ - m_x) * (y_ - m_y) for x_, y_ in zip(x, y))
s_sq_x = sum((x_ - m_x)**2 for x_ in x)
s_sq_y = sum((y_ - m_y)**2 for y_ in y)
s_sq_x = sum((x_ - m_x) ** 2 for x_ in x)
s_sq_y = sum((y_ - m_y) ** 2 for y_ in y)
return s_xy / math.sqrt(s_sq_x * s_sq_y)
@@ -292,3 +336,8 @@ def fit_linear(x, y):
k = r * (_std(y) / _std(x))
b = m_y - k * m_x
return k, b
def to_code(config):
cg.add_define('USE_SENSOR')
cg.add_global(sensor_ns.using)

View File

@@ -1,62 +0,0 @@
import voluptuous as vol
from esphome import pins
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import CONF_ATTENUATION, CONF_ID, CONF_NAME, CONF_PIN, CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable, add
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, global_ns
ATTENUATION_MODES = {
'0db': global_ns.ADC_0db,
'2.5db': global_ns.ADC_2_5db,
'6db': global_ns.ADC_6db,
'11db': global_ns.ADC_11db,
}
def validate_adc_pin(value):
vcc = str(value).upper()
if vcc == 'VCC':
return cv.only_on_esp8266(vcc)
return pins.analog_pin(value)
ADCSensorComponent = sensor.sensor_ns.class_('ADCSensorComponent', sensor.PollingSensorComponent)
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(ADCSensorComponent),
vol.Required(CONF_PIN): validate_adc_pin,
vol.Optional(CONF_ATTENUATION): vol.All(cv.only_on_esp32, cv.one_of(*ATTENUATION_MODES,
lower=True)),
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema))
def to_code(config):
pin = config[CONF_PIN]
if pin == 'VCC':
pin = 0
rhs = App.make_adc_sensor(config[CONF_NAME], pin,
config.get(CONF_UPDATE_INTERVAL))
adc = Pvariable(config[CONF_ID], rhs)
if CONF_ATTENUATION in config:
add(adc.set_attenuation(ATTENUATION_MODES[config[CONF_ATTENUATION]]))
sensor.setup_sensor(adc, config)
setup_component(adc, config)
BUILD_FLAGS = '-DUSE_ADC_SENSOR'
def required_build_flags(config):
if config[CONF_PIN] == 'VCC':
return '-DUSE_ADC_SENSOR_VCC'
return None
def includes(config):
if config[CONF_PIN] == 'VCC':
return 'ADC_MODE(ADC_VCC);'
return None

View File

@@ -1,71 +0,0 @@
import voluptuous as vol
from esphome.components import sensor
from esphome.components.ads1115 import ADS1115Component
import esphome.config_validation as cv
from esphome.const import CONF_ADS1115_ID, CONF_GAIN, CONF_MULTIPLEXER, CONF_NAME, \
CONF_UPDATE_INTERVAL
from esphome.cpp_generator import get_variable
from esphome.py_compat import string_types
DEPENDENCIES = ['ads1115']
ADS1115Multiplexer = sensor.sensor_ns.enum('ADS1115Multiplexer')
MUX = {
'A0_A1': ADS1115Multiplexer.ADS1115_MULTIPLEXER_P0_N1,
'A0_A3': ADS1115Multiplexer.ADS1115_MULTIPLEXER_P0_N3,
'A1_A3': ADS1115Multiplexer.ADS1115_MULTIPLEXER_P1_N3,
'A2_A3': ADS1115Multiplexer.ADS1115_MULTIPLEXER_P2_N3,
'A0_GND': ADS1115Multiplexer.ADS1115_MULTIPLEXER_P0_NG,
'A1_GND': ADS1115Multiplexer.ADS1115_MULTIPLEXER_P1_NG,
'A2_GND': ADS1115Multiplexer.ADS1115_MULTIPLEXER_P2_NG,
'A3_GND': ADS1115Multiplexer.ADS1115_MULTIPLEXER_P3_NG,
}
ADS1115Gain = sensor.sensor_ns.enum('ADS1115Gain')
GAIN = {
'6.144': ADS1115Gain.ADS1115_GAIN_6P144,
'4.096': ADS1115Gain.ADS1115_GAIN_4P096,
'2.048': ADS1115Gain.ADS1115_GAIN_2P048,
'1.024': ADS1115Gain.ADS1115_GAIN_1P024,
'0.512': ADS1115Gain.ADS1115_GAIN_0P512,
'0.256': ADS1115Gain.ADS1115_GAIN_0P256,
}
def validate_gain(value):
if isinstance(value, float):
value = u'{:0.03f}'.format(value)
elif not isinstance(value, string_types):
raise vol.Invalid('invalid gain "{}"'.format(value))
return cv.one_of(*GAIN)(value)
def validate_mux(value):
value = cv.string(value).upper()
value = value.replace(' ', '_')
return cv.one_of(*MUX)(value)
ADS1115Sensor = sensor.sensor_ns.class_('ADS1115Sensor', sensor.EmptySensor)
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(ADS1115Sensor),
vol.Required(CONF_MULTIPLEXER): validate_mux,
vol.Required(CONF_GAIN): validate_gain,
cv.GenerateID(CONF_ADS1115_ID): cv.use_variable_id(ADS1115Component),
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}))
def to_code(config):
hub = yield get_variable(config[CONF_ADS1115_ID])
mux = MUX[config[CONF_MULTIPLEXER]]
gain = GAIN[config[CONF_GAIN]]
rhs = hub.get_sensor(config[CONF_NAME], mux, gain, config.get(CONF_UPDATE_INTERVAL))
sensor.register_sensor(rhs, config)
BUILD_FLAGS = '-DUSE_ADS1115_SENSOR'

View File

@@ -1,30 +0,0 @@
import voluptuous as vol
from esphome.components import sensor
from esphome.components.apds9960 import APDS9960, CONF_APDS9960_ID
import esphome.config_validation as cv
from esphome.const import CONF_NAME, CONF_TYPE
from esphome.cpp_generator import get_variable
DEPENDENCIES = ['apds9960']
TYPES = {
'CLEAR': 'make_clear_channel',
'RED': 'make_red_channel',
'GREEN': 'make_green_channel',
'BLUE': 'make_blue_channel',
'PROXIMITY': 'make_proximity',
}
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(sensor.Sensor),
vol.Required(CONF_TYPE): cv.one_of(*TYPES, upper=True),
cv.GenerateID(CONF_APDS9960_ID): cv.use_variable_id(APDS9960)
}))
def to_code(config):
hub = yield get_variable(config[CONF_APDS9960_ID])
func = getattr(hub, TYPES[config[CONF_TYPE]])
rhs = func(config[CONF_NAME])
sensor.register_sensor(rhs, config)

View File

@@ -0,0 +1,10 @@
#include "automation.h"
#include "esphome/core/log.h"
namespace esphome {
namespace sensor {
static const char *TAG = "sensor.automation";
} // namespace sensor
} // namespace esphome

View File

@@ -0,0 +1,113 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/core/automation.h"
#include "esphome/components/sensor/sensor.h"
namespace esphome {
namespace sensor {
class SensorStateTrigger : public Trigger<float> {
public:
explicit SensorStateTrigger(Sensor *parent) {
parent->add_on_state_callback([this](float value) { this->trigger(value); });
}
};
class SensorRawStateTrigger : public Trigger<float> {
public:
explicit SensorRawStateTrigger(Sensor *parent) {
parent->add_on_raw_state_callback([this](float value) { this->trigger(value); });
}
};
template<typename... Ts> class SensorPublishAction : public Action<Ts...> {
public:
SensorPublishAction(Sensor *sensor) : sensor_(sensor) {}
TEMPLATABLE_VALUE(float, state)
void play(Ts... x) override {
this->sensor_->publish_state(this->state_.value(x...));
this->play_next(x...);
}
protected:
Sensor *sensor_;
};
class ValueRangeTrigger : public Trigger<float>, public Component {
public:
explicit ValueRangeTrigger(Sensor *parent) : parent_(parent) {}
template<typename V> void set_min(V min) { this->min_ = min; }
template<typename V> void set_max(V max) { this->max_ = max; }
void setup() override {
this->rtc_ = global_preferences.make_preference<bool>(this->parent_->get_object_id_hash());
bool initial_state;
if (this->rtc_.load(&initial_state)) {
this->previous_in_range_ = initial_state;
}
this->parent_->add_on_state_callback([this](float state) { this->on_state_(state); });
}
float get_setup_priority() const override { return setup_priority::HARDWARE; }
protected:
void on_state_(float state) {
if (isnan(state))
return;
float local_min = this->min_.value(state);
float local_max = this->max_.value(state);
bool in_range;
if (isnan(local_min) && isnan(local_max)) {
in_range = this->previous_in_range_;
} else if (isnan(local_min)) {
in_range = state <= local_max;
} else if (isnan(local_max)) {
in_range = state >= local_min;
} else {
in_range = local_min <= state && state <= local_max;
}
if (in_range != this->previous_in_range_ && in_range) {
this->trigger(state);
}
this->previous_in_range_ = in_range;
this->rtc_.save(&in_range);
}
Sensor *parent_;
ESPPreferenceObject rtc_;
bool previous_in_range_{false};
TemplatableValue<float, float> min_{NAN};
TemplatableValue<float, float> max_{NAN};
};
template<typename... Ts> class SensorInRangeCondition : public Condition<Ts...> {
public:
SensorInRangeCondition(Sensor *parent) : parent_(parent) {}
void set_min(float min) { this->min_ = min; }
void set_max(float max) { this->max_ = max; }
bool check(Ts... x) override {
const float state = this->parent_->state;
if (isnan(this->min_)) {
return state <= this->max_;
} else if (isnan(this->max_)) {
return state >= this->min_;
} else {
return this->min_ <= state && state <= this->max_;
}
}
protected:
Sensor *parent_;
float min_{NAN};
float max_{NAN};
};
} // namespace sensor
} // namespace esphome

View File

@@ -1,41 +0,0 @@
import voluptuous as vol
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import CONF_ADDRESS, CONF_ID, CONF_NAME, CONF_RESOLUTION, \
CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable, add
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App
DEPENDENCIES = ['i2c']
BH1750Resolution = sensor.sensor_ns.enum('BH1750Resolution')
BH1750_RESOLUTIONS = {
4.0: BH1750Resolution.BH1750_RESOLUTION_4P0_LX,
1.0: BH1750Resolution.BH1750_RESOLUTION_1P0_LX,
0.5: BH1750Resolution.BH1750_RESOLUTION_0P5_LX,
}
BH1750Sensor = sensor.sensor_ns.class_('BH1750Sensor', sensor.PollingSensorComponent,
i2c.I2CDevice)
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(BH1750Sensor),
vol.Optional(CONF_ADDRESS, default=0x23): cv.i2c_address,
vol.Optional(CONF_RESOLUTION): vol.All(cv.positive_float, cv.one_of(*BH1750_RESOLUTIONS)),
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema))
def to_code(config):
rhs = App.make_bh1750_sensor(config[CONF_NAME], config[CONF_ADDRESS],
config.get(CONF_UPDATE_INTERVAL))
bh1750 = Pvariable(config[CONF_ID], rhs)
if CONF_RESOLUTION in config:
add(bh1750.set_resolution(BH1750_RESOLUTIONS[config[CONF_RESOLUTION]]))
sensor.setup_sensor(bh1750, config)
setup_component(bh1750, config)
BUILD_FLAGS = '-DUSE_BH1750'

View File

@@ -1,25 +0,0 @@
import voluptuous as vol
from esphome.components import sensor
from esphome.components.esp32_ble_tracker import CONF_ESP32_BLE_ID, ESP32BLETracker, \
make_address_array
import esphome.config_validation as cv
from esphome.const import CONF_MAC_ADDRESS, CONF_NAME
from esphome.cpp_generator import get_variable
from esphome.cpp_types import esphome_ns
DEPENDENCIES = ['esp32_ble_tracker']
ESP32BLERSSISensor = esphome_ns.class_('ESP32BLERSSISensor', sensor.Sensor)
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(ESP32BLERSSISensor),
vol.Required(CONF_MAC_ADDRESS): cv.mac_address,
cv.GenerateID(CONF_ESP32_BLE_ID): cv.use_variable_id(ESP32BLETracker)
}))
def to_code(config):
hub = yield get_variable(config[CONF_ESP32_BLE_ID])
rhs = hub.make_rssi_sensor(config[CONF_NAME], make_address_array(config[CONF_MAC_ADDRESS]))
sensor.register_sensor(rhs, config)

View File

@@ -1,87 +0,0 @@
import voluptuous as vol
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import CONF_ADDRESS, CONF_HUMIDITY, CONF_ID, CONF_IIR_FILTER, CONF_NAME, \
CONF_OVERSAMPLING, CONF_PRESSURE, CONF_TEMPERATURE, CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable, add
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, PollingComponent
DEPENDENCIES = ['i2c']
BME280Oversampling = sensor.sensor_ns.enum('BME280Oversampling')
OVERSAMPLING_OPTIONS = {
'NONE': BME280Oversampling.BME280_OVERSAMPLING_NONE,
'1X': BME280Oversampling.BME280_OVERSAMPLING_1X,
'2X': BME280Oversampling.BME280_OVERSAMPLING_2X,
'4X': BME280Oversampling.BME280_OVERSAMPLING_4X,
'8X': BME280Oversampling.BME280_OVERSAMPLING_8X,
'16X': BME280Oversampling.BME280_OVERSAMPLING_16X,
}
BME280IIRFilter = sensor.sensor_ns.enum('BME280IIRFilter')
IIR_FILTER_OPTIONS = {
'OFF': BME280IIRFilter.BME280_IIR_FILTER_OFF,
'2X': BME280IIRFilter.BME280_IIR_FILTER_2X,
'4X': BME280IIRFilter.BME280_IIR_FILTER_4X,
'8X': BME280IIRFilter.BME280_IIR_FILTER_8X,
'16X': BME280IIRFilter.BME280_IIR_FILTER_16X,
}
BME280_OVERSAMPLING_SENSOR_SCHEMA = sensor.SENSOR_SCHEMA.extend({
vol.Optional(CONF_OVERSAMPLING): cv.one_of(*OVERSAMPLING_OPTIONS, upper=True),
})
BME280Component = sensor.sensor_ns.class_('BME280Component', PollingComponent, i2c.I2CDevice)
BME280TemperatureSensor = sensor.sensor_ns.class_('BME280TemperatureSensor',
sensor.EmptyPollingParentSensor)
BME280PressureSensor = sensor.sensor_ns.class_('BME280PressureSensor',
sensor.EmptyPollingParentSensor)
BME280HumiditySensor = sensor.sensor_ns.class_('BME280HumiditySensor',
sensor.EmptyPollingParentSensor)
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(BME280Component),
vol.Optional(CONF_ADDRESS, default=0x77): cv.i2c_address,
vol.Required(CONF_TEMPERATURE): cv.nameable(BME280_OVERSAMPLING_SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(BME280TemperatureSensor),
})),
vol.Required(CONF_PRESSURE): cv.nameable(BME280_OVERSAMPLING_SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(BME280PressureSensor),
})),
vol.Required(CONF_HUMIDITY): cv.nameable(BME280_OVERSAMPLING_SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(BME280HumiditySensor),
})),
vol.Optional(CONF_IIR_FILTER): cv.one_of(*IIR_FILTER_OPTIONS, upper=True),
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema)
def to_code(config):
rhs = App.make_bme280_sensor(config[CONF_TEMPERATURE][CONF_NAME],
config[CONF_PRESSURE][CONF_NAME],
config[CONF_HUMIDITY][CONF_NAME],
config[CONF_ADDRESS],
config.get(CONF_UPDATE_INTERVAL))
bme280 = Pvariable(config[CONF_ID], rhs)
if CONF_OVERSAMPLING in config[CONF_TEMPERATURE]:
constant = OVERSAMPLING_OPTIONS[config[CONF_TEMPERATURE][CONF_OVERSAMPLING]]
add(bme280.set_temperature_oversampling(constant))
if CONF_OVERSAMPLING in config[CONF_PRESSURE]:
constant = OVERSAMPLING_OPTIONS[config[CONF_PRESSURE][CONF_OVERSAMPLING]]
add(bme280.set_pressure_oversampling(constant))
if CONF_OVERSAMPLING in config[CONF_HUMIDITY]:
constant = OVERSAMPLING_OPTIONS[config[CONF_HUMIDITY][CONF_OVERSAMPLING]]
add(bme280.set_humidity_oversampling(constant))
if CONF_IIR_FILTER in config:
constant = IIR_FILTER_OPTIONS[config[CONF_IIR_FILTER]]
add(bme280.set_iir_filter(constant))
sensor.setup_sensor(bme280.Pget_temperature_sensor(), config[CONF_TEMPERATURE])
sensor.setup_sensor(bme280.Pget_pressure_sensor(), config[CONF_PRESSURE])
sensor.setup_sensor(bme280.Pget_humidity_sensor(), config[CONF_HUMIDITY])
setup_component(bme280, config)
BUILD_FLAGS = '-DUSE_BME280'

View File

@@ -1,110 +0,0 @@
import voluptuous as vol
from esphome import core
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import CONF_ADDRESS, CONF_DURATION, CONF_GAS_RESISTANCE, CONF_HEATER, \
CONF_HUMIDITY, CONF_ID, CONF_IIR_FILTER, CONF_NAME, CONF_OVERSAMPLING, CONF_PRESSURE, \
CONF_TEMPERATURE, CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable, add
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, PollingComponent
DEPENDENCIES = ['i2c']
BME680Oversampling = sensor.sensor_ns.enum('BME680Oversampling')
OVERSAMPLING_OPTIONS = {
'NONE': BME680Oversampling.BME680_OVERSAMPLING_NONE,
'1X': BME680Oversampling.BME680_OVERSAMPLING_1X,
'2X': BME680Oversampling.BME680_OVERSAMPLING_2X,
'4X': BME680Oversampling.BME680_OVERSAMPLING_4X,
'8X': BME680Oversampling.BME680_OVERSAMPLING_8X,
'16X': BME680Oversampling.BME680_OVERSAMPLING_16X,
}
BME680IIRFilter = sensor.sensor_ns.enum('BME680IIRFilter')
IIR_FILTER_OPTIONS = {
'OFF': BME680IIRFilter.BME680_IIR_FILTER_OFF,
'1X': BME680IIRFilter.BME680_IIR_FILTER_1X,
'3X': BME680IIRFilter.BME680_IIR_FILTER_3X,
'7X': BME680IIRFilter.BME680_IIR_FILTER_7X,
'15X': BME680IIRFilter.BME680_IIR_FILTER_15X,
'31X': BME680IIRFilter.BME680_IIR_FILTER_31X,
'63X': BME680IIRFilter.BME680_IIR_FILTER_63X,
'127X': BME680IIRFilter.BME680_IIR_FILTER_127X,
}
BME680_OVERSAMPLING_SENSOR_SCHEMA = sensor.SENSOR_SCHEMA.extend({
vol.Optional(CONF_OVERSAMPLING): cv.one_of(*OVERSAMPLING_OPTIONS, upper=True),
})
BME680Component = sensor.sensor_ns.class_('BME680Component', PollingComponent, i2c.I2CDevice)
BME680TemperatureSensor = sensor.sensor_ns.class_('BME680TemperatureSensor',
sensor.EmptyPollingParentSensor)
BME680PressureSensor = sensor.sensor_ns.class_('BME680PressureSensor',
sensor.EmptyPollingParentSensor)
BME680HumiditySensor = sensor.sensor_ns.class_('BME680HumiditySensor',
sensor.EmptyPollingParentSensor)
BME680GasResistanceSensor = sensor.sensor_ns.class_('BME680GasResistanceSensor',
sensor.EmptyPollingParentSensor)
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(BME680Component),
vol.Optional(CONF_ADDRESS, default=0x76): cv.i2c_address,
vol.Required(CONF_TEMPERATURE): cv.nameable(BME680_OVERSAMPLING_SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(BME680TemperatureSensor),
})),
vol.Required(CONF_PRESSURE): cv.nameable(BME680_OVERSAMPLING_SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(BME680PressureSensor),
})),
vol.Required(CONF_HUMIDITY): cv.nameable(BME680_OVERSAMPLING_SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(BME680HumiditySensor),
})),
vol.Required(CONF_GAS_RESISTANCE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(BME680GasResistanceSensor),
})),
vol.Optional(CONF_IIR_FILTER): cv.one_of(*IIR_FILTER_OPTIONS, upper=True),
vol.Optional(CONF_HEATER): vol.Any(None, vol.All(cv.Schema({
vol.Optional(CONF_TEMPERATURE, default=320): vol.All(vol.Coerce(int), vol.Range(200, 400)),
vol.Optional(CONF_DURATION, default='150ms'): vol.All(
cv.positive_time_period_milliseconds, vol.Range(max=core.TimePeriod(milliseconds=4032)))
}, cv.has_at_least_one_key(CONF_TEMPERATURE, CONF_DURATION)))),
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema)
def to_code(config):
rhs = App.make_bme680_sensor(config[CONF_TEMPERATURE][CONF_NAME],
config[CONF_PRESSURE][CONF_NAME],
config[CONF_HUMIDITY][CONF_NAME],
config[CONF_GAS_RESISTANCE][CONF_NAME],
config[CONF_ADDRESS],
config.get(CONF_UPDATE_INTERVAL))
bme680 = Pvariable(config[CONF_ID], rhs)
if CONF_OVERSAMPLING in config[CONF_TEMPERATURE]:
constant = OVERSAMPLING_OPTIONS[config[CONF_TEMPERATURE][CONF_OVERSAMPLING]]
add(bme680.set_temperature_oversampling(constant))
if CONF_OVERSAMPLING in config[CONF_PRESSURE]:
constant = OVERSAMPLING_OPTIONS[config[CONF_PRESSURE][CONF_OVERSAMPLING]]
add(bme680.set_pressure_oversampling(constant))
if CONF_OVERSAMPLING in config[CONF_HUMIDITY]:
constant = OVERSAMPLING_OPTIONS[config[CONF_HUMIDITY][CONF_OVERSAMPLING]]
add(bme680.set_humidity_oversampling(constant))
if CONF_IIR_FILTER in config:
constant = IIR_FILTER_OPTIONS[config[CONF_IIR_FILTER]]
add(bme680.set_iir_filter(constant))
if CONF_HEATER in config:
conf = config[CONF_HEATER]
if not conf:
add(bme680.set_heater(0, 0))
else:
add(bme680.set_heater(conf[CONF_TEMPERATURE], conf[CONF_DURATION]))
sensor.setup_sensor(bme680.Pget_temperature_sensor(), config[CONF_TEMPERATURE])
sensor.setup_sensor(bme680.Pget_pressure_sensor(), config[CONF_PRESSURE])
sensor.setup_sensor(bme680.Pget_humidity_sensor(), config[CONF_HUMIDITY])
sensor.setup_sensor(bme680.Pget_gas_resistance_sensor(), config[CONF_GAS_RESISTANCE])
setup_component(bme680, config)
BUILD_FLAGS = '-DUSE_BME680'

View File

@@ -1,45 +0,0 @@
import voluptuous as vol
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import CONF_ADDRESS, CONF_ID, CONF_NAME, CONF_PRESSURE, CONF_TEMPERATURE, \
CONF_UPDATE_INTERVAL
from esphome.cpp_generator import HexIntLiteral, Pvariable, add
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, PollingComponent
DEPENDENCIES = ['i2c']
BMP085Component = sensor.sensor_ns.class_('BMP085Component', PollingComponent, i2c.I2CDevice)
BMP085TemperatureSensor = sensor.sensor_ns.class_('BMP085TemperatureSensor',
sensor.EmptyPollingParentSensor)
BMP085PressureSensor = sensor.sensor_ns.class_('BMP085PressureSensor',
sensor.EmptyPollingParentSensor)
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(BMP085Component),
vol.Required(CONF_TEMPERATURE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(BMP085TemperatureSensor),
})),
vol.Required(CONF_PRESSURE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(BMP085PressureSensor),
})),
vol.Optional(CONF_ADDRESS): cv.i2c_address,
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema)
def to_code(config):
rhs = App.make_bmp085_sensor(config[CONF_TEMPERATURE][CONF_NAME],
config[CONF_PRESSURE][CONF_NAME],
config.get(CONF_UPDATE_INTERVAL))
bmp = Pvariable(config[CONF_ID], rhs)
if CONF_ADDRESS in config:
add(bmp.set_address(HexIntLiteral(config[CONF_ADDRESS])))
sensor.setup_sensor(bmp.Pget_temperature_sensor(), config[CONF_TEMPERATURE])
sensor.setup_sensor(bmp.Pget_pressure_sensor(), config[CONF_PRESSURE])
setup_component(bmp, config)
BUILD_FLAGS = '-DUSE_BMP085_SENSOR'

View File

@@ -1,77 +0,0 @@
import voluptuous as vol
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import CONF_ADDRESS, CONF_ID, CONF_IIR_FILTER, CONF_NAME, \
CONF_OVERSAMPLING, CONF_PRESSURE, CONF_TEMPERATURE, CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable, add
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, PollingComponent
DEPENDENCIES = ['i2c']
BMP280Oversampling = sensor.sensor_ns.enum('BMP280Oversampling')
OVERSAMPLING_OPTIONS = {
'NONE': BMP280Oversampling.BMP280_OVERSAMPLING_NONE,
'1X': BMP280Oversampling.BMP280_OVERSAMPLING_1X,
'2X': BMP280Oversampling.BMP280_OVERSAMPLING_2X,
'4X': BMP280Oversampling.BMP280_OVERSAMPLING_4X,
'8X': BMP280Oversampling.BMP280_OVERSAMPLING_8X,
'16X': BMP280Oversampling.BMP280_OVERSAMPLING_16X,
}
BMP280IIRFilter = sensor.sensor_ns.enum('BMP280IIRFilter')
IIR_FILTER_OPTIONS = {
'OFF': BMP280IIRFilter.BMP280_IIR_FILTER_OFF,
'2X': BMP280IIRFilter.BMP280_IIR_FILTER_2X,
'4X': BMP280IIRFilter.BMP280_IIR_FILTER_4X,
'8X': BMP280IIRFilter.BMP280_IIR_FILTER_8X,
'16X': BMP280IIRFilter.BMP280_IIR_FILTER_16X,
}
BMP280_OVERSAMPLING_SENSOR_SCHEMA = sensor.SENSOR_SCHEMA.extend({
vol.Optional(CONF_OVERSAMPLING): cv.one_of(*OVERSAMPLING_OPTIONS, upper=True),
})
BMP280Component = sensor.sensor_ns.class_('BMP280Component', PollingComponent, i2c.I2CDevice)
BMP280TemperatureSensor = sensor.sensor_ns.class_('BMP280TemperatureSensor',
sensor.EmptyPollingParentSensor)
BMP280PressureSensor = sensor.sensor_ns.class_('BMP280PressureSensor',
sensor.EmptyPollingParentSensor)
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(BMP280Component),
vol.Optional(CONF_ADDRESS, default=0x77): cv.i2c_address,
vol.Required(CONF_TEMPERATURE): cv.nameable(BMP280_OVERSAMPLING_SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(BMP280TemperatureSensor),
})),
vol.Required(CONF_PRESSURE): cv.nameable(BMP280_OVERSAMPLING_SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(BMP280PressureSensor),
})),
vol.Optional(CONF_IIR_FILTER): cv.one_of(*IIR_FILTER_OPTIONS, upper=True),
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema)
def to_code(config):
rhs = App.make_bmp280_sensor(config[CONF_TEMPERATURE][CONF_NAME],
config[CONF_PRESSURE][CONF_NAME],
config[CONF_ADDRESS],
config.get(CONF_UPDATE_INTERVAL))
bmp280 = Pvariable(config[CONF_ID], rhs)
if CONF_OVERSAMPLING in config[CONF_TEMPERATURE]:
constant = OVERSAMPLING_OPTIONS[config[CONF_TEMPERATURE][CONF_OVERSAMPLING]]
add(bmp280.set_temperature_oversampling(constant))
if CONF_OVERSAMPLING in config[CONF_PRESSURE]:
constant = OVERSAMPLING_OPTIONS[config[CONF_PRESSURE][CONF_OVERSAMPLING]]
add(bmp280.set_pressure_oversampling(constant))
if CONF_IIR_FILTER in config:
constant = IIR_FILTER_OPTIONS[config[CONF_IIR_FILTER]]
add(bmp280.set_iir_filter(constant))
sensor.setup_sensor(bmp280.Pget_temperature_sensor(), config[CONF_TEMPERATURE])
sensor.setup_sensor(bmp280.Pget_pressure_sensor(), config[CONF_PRESSURE])
setup_component(bmp280, config)
BUILD_FLAGS = '-DUSE_BMP280'

View File

@@ -1,58 +0,0 @@
import voluptuous as vol
from esphome.components import sensor, uart
from esphome.components.uart import UARTComponent
import esphome.config_validation as cv
from esphome.const import CONF_CURRENT, CONF_ID, CONF_NAME, CONF_POWER, CONF_UART_ID, \
CONF_UPDATE_INTERVAL, CONF_VOLTAGE
from esphome.cpp_generator import Pvariable, get_variable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, PollingComponent
DEPENDENCIES = ['uart']
CSE7766Component = sensor.sensor_ns.class_('CSE7766Component', PollingComponent, uart.UARTDevice)
CSE7766VoltageSensor = sensor.sensor_ns.class_('CSE7766VoltageSensor',
sensor.EmptySensor)
CSE7766CurrentSensor = sensor.sensor_ns.class_('CSE7766CurrentSensor',
sensor.EmptySensor)
CSE7766PowerSensor = sensor.sensor_ns.class_('CSE7766PowerSensor',
sensor.EmptySensor)
PLATFORM_SCHEMA = vol.All(sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(CSE7766Component),
cv.GenerateID(CONF_UART_ID): cv.use_variable_id(UARTComponent),
vol.Optional(CONF_VOLTAGE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(CSE7766VoltageSensor),
})),
vol.Optional(CONF_CURRENT): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(CSE7766CurrentSensor),
})),
vol.Optional(CONF_POWER): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(CSE7766PowerSensor),
})),
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema), cv.has_at_least_one_key(CONF_VOLTAGE, CONF_CURRENT,
CONF_POWER))
def to_code(config):
uart_ = yield get_variable(config[CONF_UART_ID])
rhs = App.make_cse7766(uart_, config.get(CONF_UPDATE_INTERVAL))
cse = Pvariable(config[CONF_ID], rhs)
if CONF_VOLTAGE in config:
conf = config[CONF_VOLTAGE]
sensor.register_sensor(cse.make_voltage_sensor(conf[CONF_NAME]), conf)
if CONF_CURRENT in config:
conf = config[CONF_CURRENT]
sensor.register_sensor(cse.make_current_sensor(conf[CONF_NAME]), conf)
if CONF_POWER in config:
conf = config[CONF_POWER]
sensor.register_sensor(cse.make_power_sensor(conf[CONF_NAME]), conf)
setup_component(cse, config)
BUILD_FLAGS = '-DUSE_CSE7766'

View File

@@ -1,32 +0,0 @@
import voluptuous as vol
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_LAMBDA, CONF_NAME, CONF_SENSORS
from esphome.cpp_generator import add, process_lambda, variable
from esphome.cpp_types import std_vector
CustomSensorConstructor = sensor.sensor_ns.class_('CustomSensorConstructor')
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(CustomSensorConstructor),
vol.Required(CONF_LAMBDA): cv.lambda_,
vol.Required(CONF_SENSORS): cv.ensure_list(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(sensor.Sensor),
})),
})
def to_code(config):
template_ = yield process_lambda(config[CONF_LAMBDA], [],
return_type=std_vector.template(sensor.SensorPtr))
rhs = CustomSensorConstructor(template_)
custom = variable(config[CONF_ID], rhs)
for i, conf in enumerate(config[CONF_SENSORS]):
rhs = custom.Pget_sensor(i)
add(rhs.set_name(conf[CONF_NAME]))
sensor.register_sensor(rhs, conf)
BUILD_FLAGS = '-DUSE_CUSTOM_SENSOR'

View File

@@ -1,33 +0,0 @@
import voluptuous as vol
from esphome.components import sensor
from esphome.components.dallas import DallasComponent
import esphome.config_validation as cv
from esphome.const import CONF_ADDRESS, CONF_DALLAS_ID, CONF_INDEX, CONF_NAME, \
CONF_RESOLUTION
from esphome.cpp_generator import HexIntLiteral, get_variable
DallasTemperatureSensor = sensor.sensor_ns.class_('DallasTemperatureSensor',
sensor.EmptyPollingParentSensor)
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(DallasTemperatureSensor),
vol.Exclusive(CONF_ADDRESS, 'dallas'): cv.hex_int,
vol.Exclusive(CONF_INDEX, 'dallas'): cv.positive_int,
cv.GenerateID(CONF_DALLAS_ID): cv.use_variable_id(DallasComponent),
vol.Optional(CONF_RESOLUTION): vol.All(vol.Coerce(int), vol.Range(min=9, max=12)),
}), cv.has_at_least_one_key(CONF_ADDRESS, CONF_INDEX))
def to_code(config):
hub = yield get_variable(config[CONF_DALLAS_ID])
if CONF_ADDRESS in config:
address = HexIntLiteral(config[CONF_ADDRESS])
rhs = hub.Pget_sensor_by_address(config[CONF_NAME], address, config.get(CONF_RESOLUTION))
else:
rhs = hub.Pget_sensor_by_index(config[CONF_NAME], config[CONF_INDEX],
config.get(CONF_RESOLUTION))
sensor.register_sensor(rhs, config)
BUILD_FLAGS = '-DUSE_DALLAS_SENSOR'

View File

@@ -1,58 +0,0 @@
import voluptuous as vol
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import CONF_HUMIDITY, CONF_ID, CONF_MODEL, CONF_NAME, \
CONF_PIN, CONF_TEMPERATURE, CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable, add
from esphome.cpp_helpers import gpio_output_pin_expression, setup_component
from esphome.cpp_types import App, PollingComponent
from esphome.pins import gpio_input_pullup_pin_schema
DHTModel = sensor.sensor_ns.enum('DHTModel')
DHT_MODELS = {
'AUTO_DETECT': DHTModel.DHT_MODEL_AUTO_DETECT,
'DHT11': DHTModel.DHT_MODEL_DHT11,
'DHT22': DHTModel.DHT_MODEL_DHT22,
'AM2302': DHTModel.DHT_MODEL_AM2302,
'RHT03': DHTModel.DHT_MODEL_RHT03,
'SI7021': DHTModel.DHT_MODEL_SI7021,
}
DHTComponent = sensor.sensor_ns.class_('DHTComponent', PollingComponent)
DHTTemperatureSensor = sensor.sensor_ns.class_('DHTTemperatureSensor',
sensor.EmptyPollingParentSensor)
DHTHumiditySensor = sensor.sensor_ns.class_('DHTHumiditySensor',
sensor.EmptyPollingParentSensor)
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(DHTComponent),
vol.Required(CONF_PIN): gpio_input_pullup_pin_schema,
vol.Required(CONF_TEMPERATURE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(DHTTemperatureSensor),
})),
vol.Required(CONF_HUMIDITY): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(DHTHumiditySensor),
})),
vol.Optional(CONF_MODEL): cv.one_of(*DHT_MODELS, upper=True),
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema)
def to_code(config):
pin = yield gpio_output_pin_expression(config[CONF_PIN])
rhs = App.make_dht_sensor(config[CONF_TEMPERATURE][CONF_NAME],
config[CONF_HUMIDITY][CONF_NAME],
pin, config.get(CONF_UPDATE_INTERVAL))
dht = Pvariable(config[CONF_ID], rhs)
if CONF_MODEL in config:
constant = DHT_MODELS[config[CONF_MODEL]]
add(dht.set_dht_model(constant))
sensor.setup_sensor(dht.Pget_temperature_sensor(), config[CONF_TEMPERATURE])
sensor.setup_sensor(dht.Pget_humidity_sensor(), config[CONF_HUMIDITY])
setup_component(dht, config)
BUILD_FLAGS = '-DUSE_DHT_SENSOR'

View File

@@ -1,42 +0,0 @@
import voluptuous as vol
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import CONF_HUMIDITY, CONF_ID, CONF_NAME, CONF_TEMPERATURE, \
CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, PollingComponent
DEPENDENCIES = ['i2c']
DHT12Component = sensor.sensor_ns.class_('DHT12Component', PollingComponent, i2c.I2CDevice)
DHT12TemperatureSensor = sensor.sensor_ns.class_('DHT12TemperatureSensor',
sensor.EmptyPollingParentSensor)
DHT12HumiditySensor = sensor.sensor_ns.class_('DHT12HumiditySensor',
sensor.EmptyPollingParentSensor)
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(DHT12Component),
vol.Required(CONF_TEMPERATURE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(DHT12TemperatureSensor),
})),
vol.Required(CONF_HUMIDITY): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(DHT12HumiditySensor),
})),
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema)
def to_code(config):
rhs = App.make_dht12_sensor(config[CONF_TEMPERATURE][CONF_NAME],
config[CONF_HUMIDITY][CONF_NAME],
config.get(CONF_UPDATE_INTERVAL))
dht = Pvariable(config[CONF_ID], rhs)
sensor.setup_sensor(dht.Pget_temperature_sensor(), config[CONF_TEMPERATURE])
sensor.setup_sensor(dht.Pget_humidity_sensor(), config[CONF_HUMIDITY])
setup_component(dht, config)
BUILD_FLAGS = '-DUSE_DHT12_SENSOR'

View File

@@ -1,30 +0,0 @@
import voluptuous as vol
from esphome import pins
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_NAME, CONF_PIN, CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable
from esphome.cpp_helpers import gpio_input_pin_expression, setup_component
from esphome.cpp_types import App
DutyCycleSensor = sensor.sensor_ns.class_('DutyCycleSensor', sensor.PollingSensorComponent)
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(DutyCycleSensor),
vol.Required(CONF_PIN): vol.All(pins.internal_gpio_input_pin_schema,
pins.validate_has_interrupt),
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema))
def to_code(config):
pin = yield gpio_input_pin_expression(config[CONF_PIN])
rhs = App.make_duty_cycle_sensor(config[CONF_NAME], pin,
config.get(CONF_UPDATE_INTERVAL))
duty = Pvariable(config[CONF_ID], rhs)
sensor.setup_sensor(duty, config)
setup_component(duty, config)
BUILD_FLAGS = '-DUSE_DUTY_CYCLE_SENSOR'

View File

@@ -1,28 +0,0 @@
import voluptuous as vol
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_NAME, CONF_UPDATE_INTERVAL, ESP_PLATFORM_ESP32
from esphome.cpp_generator import Pvariable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, Application
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
MakeESP32HallSensor = Application.struct('MakeESP32HallSensor')
ESP32HallSensor = sensor.sensor_ns.class_('ESP32HallSensor', sensor.PollingSensorComponent)
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(ESP32HallSensor),
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema))
def to_code(config):
rhs = App.make_esp32_hall_sensor(config[CONF_NAME], config.get(CONF_UPDATE_INTERVAL))
hall = Pvariable(config[CONF_ID], rhs)
sensor.setup_sensor(hall, config)
setup_component(hall, config)
BUILD_FLAGS = '-DUSE_ESP32_HALL_SENSOR'

View File

@@ -0,0 +1,232 @@
#include "esphome/components/sensor/filter.h"
#include "esphome/components/sensor/sensor.h"
#include "esphome/core/log.h"
namespace esphome {
namespace sensor {
static const char *TAG = "sensor.filter";
// Filter
uint32_t Filter::expected_interval(uint32_t input) { return input; }
void Filter::input(float value) {
ESP_LOGVV(TAG, "Filter(%p)::input(%f)", this, value);
optional<float> out = this->new_value(value);
if (out.has_value())
this->output(*out);
}
void Filter::output(float value) {
if (this->next_ == nullptr) {
ESP_LOGVV(TAG, "Filter(%p)::output(%f) -> SENSOR", this, value);
this->parent_->internal_send_state_to_frontend(value);
} else {
ESP_LOGVV(TAG, "Filter(%p)::output(%f) -> %p", this, value, this->next_);
this->next_->input(value);
}
}
void Filter::initialize(Sensor *parent, Filter *next) {
ESP_LOGVV(TAG, "Filter(%p)::initialize(parent=%p next=%p)", this, parent, next);
this->parent_ = parent;
this->next_ = next;
}
uint32_t Filter::calculate_remaining_interval(uint32_t input) {
uint32_t this_interval = this->expected_interval(input);
ESP_LOGVV(TAG, "Filter(%p)::calculate_remaining_interval(%u) -> %u", this, input, this_interval);
if (this->next_ == nullptr) {
return this_interval;
} else {
return this->next_->calculate_remaining_interval(this_interval);
}
}
// SlidingWindowMovingAverageFilter
SlidingWindowMovingAverageFilter::SlidingWindowMovingAverageFilter(size_t window_size, size_t send_every,
size_t send_first_at)
: send_every_(send_every), send_at_(send_every - send_first_at), window_size_(window_size) {}
void SlidingWindowMovingAverageFilter::set_send_every(size_t send_every) { this->send_every_ = send_every; }
void SlidingWindowMovingAverageFilter::set_window_size(size_t window_size) { this->window_size_ = window_size; }
optional<float> SlidingWindowMovingAverageFilter::new_value(float value) {
if (!isnan(value)) {
if (this->queue_.size() == this->window_size_) {
this->sum_ -= this->queue_.front();
this->queue_.pop();
}
this->queue_.push(value);
this->sum_ += value;
}
float average;
if (this->queue_.empty())
average = 0.0f;
else
average = this->sum_ / this->queue_.size();
ESP_LOGVV(TAG, "SlidingWindowMovingAverageFilter(%p)::new_value(%f) -> %f", this, value, average);
if (++this->send_at_ >= this->send_every_) {
this->send_at_ = 0;
ESP_LOGVV(TAG, "SlidingWindowMovingAverageFilter(%p)::new_value(%f) SENDING", this, value);
return average;
}
return {};
}
uint32_t SlidingWindowMovingAverageFilter::expected_interval(uint32_t input) { return input * this->send_every_; }
// ExponentialMovingAverageFilter
ExponentialMovingAverageFilter::ExponentialMovingAverageFilter(float alpha, size_t send_every)
: send_every_(send_every), send_at_(send_every - 1), alpha_(alpha) {}
optional<float> ExponentialMovingAverageFilter::new_value(float value) {
if (!isnan(value)) {
if (this->first_value_)
this->accumulator_ = value;
else
this->accumulator_ = (this->alpha_ * value) + (1.0f - this->alpha_) * this->accumulator_;
this->first_value_ = false;
}
float average = this->accumulator_;
ESP_LOGVV(TAG, "ExponentialMovingAverageFilter(%p)::new_value(%f) -> %f", this, value, average);
if (++this->send_at_ >= this->send_every_) {
ESP_LOGVV(TAG, "ExponentialMovingAverageFilter(%p)::new_value(%f) SENDING", this, value);
this->send_at_ = 0;
return average;
}
return {};
}
void ExponentialMovingAverageFilter::set_send_every(size_t send_every) { this->send_every_ = send_every; }
void ExponentialMovingAverageFilter::set_alpha(float alpha) { this->alpha_ = alpha; }
uint32_t ExponentialMovingAverageFilter::expected_interval(uint32_t input) { return input * this->send_every_; }
// LambdaFilter
LambdaFilter::LambdaFilter(lambda_filter_t lambda_filter) : lambda_filter_(std::move(lambda_filter)) {}
const lambda_filter_t &LambdaFilter::get_lambda_filter() const { return this->lambda_filter_; }
void LambdaFilter::set_lambda_filter(const lambda_filter_t &lambda_filter) { this->lambda_filter_ = lambda_filter; }
optional<float> LambdaFilter::new_value(float value) {
auto it = this->lambda_filter_(value);
ESP_LOGVV(TAG, "LambdaFilter(%p)::new_value(%f) -> %f", this, value, it.value_or(INFINITY));
return it;
}
// OffsetFilter
OffsetFilter::OffsetFilter(float offset) : offset_(offset) {}
optional<float> OffsetFilter::new_value(float value) { return value + this->offset_; }
// MultiplyFilter
MultiplyFilter::MultiplyFilter(float multiplier) : multiplier_(multiplier) {}
optional<float> MultiplyFilter::new_value(float value) { return value * this->multiplier_; }
// FilterOutValueFilter
FilterOutValueFilter::FilterOutValueFilter(float value_to_filter_out) : value_to_filter_out_(value_to_filter_out) {}
optional<float> FilterOutValueFilter::new_value(float value) {
if (isnan(this->value_to_filter_out_)) {
if (isnan(value))
return {};
else
return value;
} else {
if (value == this->value_to_filter_out_)
return {};
else
return value;
}
}
// ThrottleFilter
ThrottleFilter::ThrottleFilter(uint32_t min_time_between_inputs)
: Filter(), min_time_between_inputs_(min_time_between_inputs) {}
optional<float> ThrottleFilter::new_value(float value) {
const uint32_t now = millis();
if (this->last_input_ == 0 || now - this->last_input_ >= min_time_between_inputs_) {
this->last_input_ = now;
return value;
}
return {};
}
// DeltaFilter
DeltaFilter::DeltaFilter(float min_delta) : min_delta_(min_delta), last_value_(NAN) {}
optional<float> DeltaFilter::new_value(float value) {
if (isnan(value))
return {};
if (isnan(this->last_value_)) {
return this->last_value_ = value;
}
if (fabsf(value - this->last_value_) >= this->min_delta_) {
return this->last_value_ = value;
}
return {};
}
// OrFilter
OrFilter::OrFilter(std::vector<Filter *> filters) : filters_(std::move(filters)), phi_(this) {}
OrFilter::PhiNode::PhiNode(OrFilter *parent) : parent_(parent) {}
optional<float> OrFilter::PhiNode::new_value(float value) {
this->parent_->output(value);
return {};
}
optional<float> OrFilter::new_value(float value) {
for (Filter *filter : this->filters_)
filter->input(value);
return {};
}
void OrFilter::initialize(Sensor *parent, Filter *next) {
Filter::initialize(parent, next);
for (Filter *filter : this->filters_) {
filter->initialize(parent, &this->phi_);
}
this->phi_.initialize(parent, nullptr);
}
uint32_t OrFilter::expected_interval(uint32_t input) {
uint32_t min_interval = UINT32_MAX;
for (Filter *filter : this->filters_) {
min_interval = std::min(min_interval, filter->calculate_remaining_interval(input));
}
return min_interval;
}
// DebounceFilter
optional<float> DebounceFilter::new_value(float value) {
this->set_timeout("debounce", this->time_period_, [this, value]() { this->output(value); });
return {};
}
DebounceFilter::DebounceFilter(uint32_t time_period) : time_period_(time_period) {}
float DebounceFilter::get_setup_priority() const { return setup_priority::HARDWARE; }
// HeartbeatFilter
HeartbeatFilter::HeartbeatFilter(uint32_t time_period) : time_period_(time_period), last_input_(NAN) {}
optional<float> HeartbeatFilter::new_value(float value) {
ESP_LOGVV(TAG, "HeartbeatFilter(%p)::new_value(value=%f)", this, value);
this->last_input_ = value;
this->has_value_ = true;
return {};
}
uint32_t HeartbeatFilter::expected_interval(uint32_t input) { return this->time_period_; }
void HeartbeatFilter::setup() {
this->set_interval("heartbeat", this->time_period_, [this]() {
ESP_LOGVV(TAG, "HeartbeatFilter(%p)::interval(has_value=%s, last_input=%f)", this, YESNO(this->has_value_),
this->last_input_);
if (!this->has_value_)
return;
this->output(this->last_input_);
});
}
float HeartbeatFilter::get_setup_priority() const { return setup_priority::HARDWARE; }
optional<float> CalibrateLinearFilter::new_value(float value) { return value * this->slope_ + this->bias_; }
CalibrateLinearFilter::CalibrateLinearFilter(float slope, float bias) : slope_(slope), bias_(bias) {}
} // namespace sensor
} // namespace esphome

View File

@@ -0,0 +1,247 @@
#pragma once
#include <queue>
#include "esphome/core/component.h"
#include "esphome/core/helpers.h"
namespace esphome {
namespace sensor {
class Sensor;
/** Apply a filter to sensor values such as moving average.
*
* This class is purposefully kept quite simple, since more complicated
* filters should really be done with the filter sensor in Home Assistant.
*/
class Filter {
public:
/** This will be called every time the filter receives a new value.
*
* It can return an empty optional to indicate that the filter chain
* should stop, otherwise the value in the filter will be passed down
* the chain.
*
* @param value The new value.
* @return An optional float, the new value that should be pushed out.
*/
virtual optional<float> new_value(float value) = 0;
/// Initialize this filter, please note this can be called more than once.
virtual void initialize(Sensor *parent, Filter *next);
void input(float value);
/// Return the amount of time that this filter is expected to take based on the input time interval.
virtual uint32_t expected_interval(uint32_t input);
uint32_t calculate_remaining_interval(uint32_t input);
void output(float value);
protected:
friend Sensor;
Filter *next_{nullptr};
Sensor *parent_{nullptr};
};
/** Simple sliding window moving average filter.
*
* Essentially just takes takes the average of the last window_size values and pushes them out
* every send_every.
*/
class SlidingWindowMovingAverageFilter : public Filter {
public:
/** Construct a SlidingWindowMovingAverageFilter.
*
* @param window_size The number of values that should be averaged.
* @param send_every After how many sensor values should a new one be pushed out.
* @param send_first_at After how many values to forward the very first value. Defaults to the first value
* on startup being published on the first *raw* value, so with no filter applied. Must be less than or equal to
* send_every.
*/
explicit SlidingWindowMovingAverageFilter(size_t window_size, size_t send_every, size_t send_first_at);
optional<float> new_value(float value) override;
void set_send_every(size_t send_every);
void set_window_size(size_t window_size);
uint32_t expected_interval(uint32_t input) override;
protected:
float sum_{0.0};
std::queue<float> queue_;
size_t send_every_;
size_t send_at_;
size_t window_size_;
};
/** Simple exponential moving average filter.
*
* Essentially just takes the average of the last few values using exponentially decaying weights.
* Use alpha to adjust decay rate.
*/
class ExponentialMovingAverageFilter : public Filter {
public:
ExponentialMovingAverageFilter(float alpha, size_t send_every);
optional<float> new_value(float value) override;
void set_send_every(size_t send_every);
void set_alpha(float alpha);
uint32_t expected_interval(uint32_t input) override;
protected:
bool first_value_{true};
float accumulator_{0.0f};
size_t send_every_;
size_t send_at_;
float alpha_;
};
using lambda_filter_t = std::function<optional<float>(float)>;
/** This class allows for creation of simple template filters.
*
* The constructor accepts a lambda of the form float -> optional<float>.
* It will be called with each new value in the filter chain and returns the modified
* value that shall be passed down the filter chain. Returning an empty Optional
* means that the value shall be discarded.
*/
class LambdaFilter : public Filter {
public:
explicit LambdaFilter(lambda_filter_t lambda_filter);
optional<float> new_value(float value) override;
const lambda_filter_t &get_lambda_filter() const;
void set_lambda_filter(const lambda_filter_t &lambda_filter);
protected:
lambda_filter_t lambda_filter_;
};
/// A simple filter that adds `offset` to each value it receives.
class OffsetFilter : public Filter {
public:
explicit OffsetFilter(float offset);
optional<float> new_value(float value) override;
protected:
float offset_;
};
/// A simple filter that multiplies to each value it receives by `multiplier`.
class MultiplyFilter : public Filter {
public:
explicit MultiplyFilter(float multiplier);
optional<float> new_value(float value) override;
protected:
float multiplier_;
};
/// A simple filter that only forwards the filter chain if it doesn't receive `value_to_filter_out`.
class FilterOutValueFilter : public Filter {
public:
explicit FilterOutValueFilter(float value_to_filter_out);
optional<float> new_value(float value) override;
protected:
float value_to_filter_out_;
};
class ThrottleFilter : public Filter {
public:
explicit ThrottleFilter(uint32_t min_time_between_inputs);
optional<float> new_value(float value) override;
protected:
uint32_t last_input_{0};
uint32_t min_time_between_inputs_;
};
class DebounceFilter : public Filter, public Component {
public:
explicit DebounceFilter(uint32_t time_period);
optional<float> new_value(float value) override;
float get_setup_priority() const override;
protected:
uint32_t time_period_;
};
class HeartbeatFilter : public Filter, public Component {
public:
explicit HeartbeatFilter(uint32_t time_period);
void setup() override;
optional<float> new_value(float value) override;
uint32_t expected_interval(uint32_t input) override;
float get_setup_priority() const override;
protected:
uint32_t time_period_;
float last_input_;
bool has_value_{false};
};
class DeltaFilter : public Filter {
public:
explicit DeltaFilter(float min_delta);
optional<float> new_value(float value) override;
protected:
float min_delta_;
float last_value_{NAN};
};
class OrFilter : public Filter {
public:
explicit OrFilter(std::vector<Filter *> filters);
void initialize(Sensor *parent, Filter *next) override;
uint32_t expected_interval(uint32_t input) override;
optional<float> new_value(float value) override;
protected:
class PhiNode : public Filter {
public:
PhiNode(OrFilter *parent);
optional<float> new_value(float value) override;
protected:
OrFilter *parent_;
};
std::vector<Filter *> filters_;
PhiNode phi_;
};
class CalibrateLinearFilter : public Filter {
public:
CalibrateLinearFilter(float slope, float bias);
optional<float> new_value(float value) override;
protected:
float slope_;
float bias_;
};
} // namespace sensor
} // namespace esphome

View File

@@ -1,42 +0,0 @@
import voluptuous as vol
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import CONF_HUMIDITY, CONF_ID, CONF_NAME, CONF_TEMPERATURE, \
CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, PollingComponent
DEPENDENCIES = ['i2c']
HDC1080Component = sensor.sensor_ns.class_('HDC1080Component', PollingComponent, i2c.I2CDevice)
HDC1080TemperatureSensor = sensor.sensor_ns.class_('HDC1080TemperatureSensor',
sensor.EmptyPollingParentSensor)
HDC1080HumiditySensor = sensor.sensor_ns.class_('HDC1080HumiditySensor',
sensor.EmptyPollingParentSensor)
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(HDC1080Component),
vol.Required(CONF_TEMPERATURE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(HDC1080TemperatureSensor),
})),
vol.Required(CONF_HUMIDITY): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(HDC1080HumiditySensor),
})),
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema)
def to_code(config):
rhs = App.make_hdc1080_sensor(config[CONF_TEMPERATURE][CONF_NAME],
config[CONF_HUMIDITY][CONF_NAME],
config.get(CONF_UPDATE_INTERVAL))
hdc1080 = Pvariable(config[CONF_ID], rhs)
sensor.setup_sensor(hdc1080.Pget_temperature_sensor(), config[CONF_TEMPERATURE])
sensor.setup_sensor(hdc1080.Pget_humidity_sensor(), config[CONF_HUMIDITY])
setup_component(hdc1080, config)
BUILD_FLAGS = '-DUSE_HDC1080_SENSOR'

View File

@@ -1,67 +0,0 @@
import voluptuous as vol
from esphome import pins
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import CONF_CF1_PIN, CONF_CF_PIN, CONF_CHANGE_MODE_EVERY, CONF_CURRENT, \
CONF_CURRENT_RESISTOR, CONF_ID, CONF_NAME, CONF_POWER, CONF_SEL_PIN, CONF_UPDATE_INTERVAL, \
CONF_VOLTAGE, CONF_VOLTAGE_DIVIDER
from esphome.cpp_generator import Pvariable, add
from esphome.cpp_helpers import gpio_output_pin_expression, setup_component
from esphome.cpp_types import App, PollingComponent
HLW8012Component = sensor.sensor_ns.class_('HLW8012Component', PollingComponent)
HLW8012VoltageSensor = sensor.sensor_ns.class_('HLW8012VoltageSensor', sensor.EmptySensor)
HLW8012CurrentSensor = sensor.sensor_ns.class_('HLW8012CurrentSensor', sensor.EmptySensor)
HLW8012PowerSensor = sensor.sensor_ns.class_('HLW8012PowerSensor', sensor.EmptyPollingParentSensor)
PLATFORM_SCHEMA = vol.All(sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(HLW8012Component),
vol.Required(CONF_SEL_PIN): pins.gpio_output_pin_schema,
vol.Required(CONF_CF_PIN): pins.input_pin,
vol.Required(CONF_CF1_PIN): pins.input_pin,
vol.Optional(CONF_VOLTAGE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(HLW8012VoltageSensor),
})),
vol.Optional(CONF_CURRENT): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(HLW8012CurrentSensor),
})),
vol.Optional(CONF_POWER): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(HLW8012PowerSensor),
})),
vol.Optional(CONF_CURRENT_RESISTOR): cv.resistance,
vol.Optional(CONF_VOLTAGE_DIVIDER): cv.positive_float,
vol.Optional(CONF_CHANGE_MODE_EVERY): vol.All(cv.uint32_t, vol.Range(min=1)),
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema), cv.has_at_least_one_key(CONF_VOLTAGE, CONF_CURRENT,
CONF_POWER))
def to_code(config):
sel = yield gpio_output_pin_expression(config[CONF_SEL_PIN])
rhs = App.make_hlw8012(sel, config[CONF_CF_PIN], config[CONF_CF1_PIN],
config.get(CONF_UPDATE_INTERVAL))
hlw = Pvariable(config[CONF_ID], rhs)
if CONF_VOLTAGE in config:
conf = config[CONF_VOLTAGE]
sensor.register_sensor(hlw.make_voltage_sensor(conf[CONF_NAME]), conf)
if CONF_CURRENT in config:
conf = config[CONF_CURRENT]
sensor.register_sensor(hlw.make_current_sensor(conf[CONF_NAME]), conf)
if CONF_POWER in config:
conf = config[CONF_POWER]
sensor.register_sensor(hlw.make_power_sensor(conf[CONF_NAME]), conf)
if CONF_CURRENT_RESISTOR in config:
add(hlw.set_current_resistor(config[CONF_CURRENT_RESISTOR]))
if CONF_VOLTAGE_DIVIDER in config:
add(hlw.set_voltage_divider(config[CONF_VOLTAGE_DIVIDER]))
if CONF_CHANGE_MODE_EVERY in config:
add(hlw.set_change_mode_every(config[CONF_CHANGE_MODE_EVERY]))
setup_component(hlw, config)
BUILD_FLAGS = '-DUSE_HLW8012'

View File

@@ -1,89 +0,0 @@
# coding=utf-8
import voluptuous as vol
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import CONF_ADDRESS, CONF_ID, CONF_NAME, CONF_RANGE, CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable, add
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, PollingComponent
DEPENDENCIES = ['i2c']
CONF_FIELD_STRENGTH_X = 'field_strength_x'
CONF_FIELD_STRENGTH_Y = 'field_strength_y'
CONF_FIELD_STRENGTH_Z = 'field_strength_z'
CONF_HEADING = 'heading'
HMC5883LComponent = sensor.sensor_ns.class_('HMC5883LComponent', PollingComponent, i2c.I2CDevice)
HMC5883LFieldStrengthSensor = sensor.sensor_ns.class_('HMC5883LFieldStrengthSensor',
sensor.EmptyPollingParentSensor)
HMC5883LHeadingSensor = sensor.sensor_ns.class_('HMC5883LHeadingSensor',
sensor.EmptyPollingParentSensor)
HMC5883LRange = sensor.sensor_ns.enum('HMC5883LRange')
HMC5883L_RANGES = {
88: HMC5883LRange.HMC5883L_RANGE_88_UT,
130: HMC5883LRange.HMC5883L_RANGE_130_UT,
190: HMC5883LRange.HMC5883L_RANGE_190_UT,
250: HMC5883LRange.HMC5883L_RANGE_250_UT,
400: HMC5883LRange.HMC5883L_RANGE_400_UT,
470: HMC5883LRange.HMC5883L_RANGE_470_UT,
560: HMC5883LRange.HMC5883L_RANGE_560_UT,
810: HMC5883LRange.HMC5883L_RANGE_810_UT,
}
def validate_range(value):
value = cv.string(value)
if value.endswith(u'µT') or value.endswith('uT'):
value = value[:-2]
return cv.one_of(*HMC5883L_RANGES, int=True)(value)
SENSOR_KEYS = [CONF_FIELD_STRENGTH_X, CONF_FIELD_STRENGTH_Y, CONF_FIELD_STRENGTH_Z,
CONF_HEADING]
PLATFORM_SCHEMA = vol.All(sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(HMC5883LComponent),
vol.Optional(CONF_ADDRESS): cv.i2c_address,
vol.Optional(CONF_FIELD_STRENGTH_X): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(HMC5883LFieldStrengthSensor),
})),
vol.Optional(CONF_FIELD_STRENGTH_Y): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(HMC5883LFieldStrengthSensor),
})),
vol.Optional(CONF_FIELD_STRENGTH_Z): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(HMC5883LFieldStrengthSensor),
})),
vol.Optional(CONF_HEADING): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(HMC5883LHeadingSensor),
})),
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
vol.Optional(CONF_RANGE): validate_range,
}).extend(cv.COMPONENT_SCHEMA.schema), cv.has_at_least_one_key(*SENSOR_KEYS))
def to_code(config):
rhs = App.make_hmc5883l(config.get(CONF_UPDATE_INTERVAL))
hmc = Pvariable(config[CONF_ID], rhs)
if CONF_ADDRESS in config:
add(hmc.set_address(config[CONF_ADDRESS]))
if CONF_RANGE in config:
add(hmc.set_range(HMC5883L_RANGES[config[CONF_RANGE]]))
if CONF_FIELD_STRENGTH_X in config:
conf = config[CONF_FIELD_STRENGTH_X]
sensor.register_sensor(hmc.Pmake_x_sensor(conf[CONF_NAME]), conf)
if CONF_FIELD_STRENGTH_Y in config:
conf = config[CONF_FIELD_STRENGTH_Y]
sensor.register_sensor(hmc.Pmake_y_sensor(conf[CONF_NAME]), conf)
if CONF_FIELD_STRENGTH_Z in config:
conf = config[CONF_FIELD_STRENGTH_Z]
sensor.register_sensor(hmc.Pmake_z_sensor(conf[CONF_NAME]), conf)
if CONF_HEADING in config:
conf = config[CONF_HEADING]
sensor.register_sensor(hmc.Pmake_heading_sensor(conf[CONF_NAME]), conf)
setup_component(hmc, config)
BUILD_FLAGS = '-DUSE_HMC5883L'

View File

@@ -1,25 +0,0 @@
import voluptuous as vol
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import CONF_ENTITY_ID, CONF_ID, CONF_NAME
from esphome.cpp_generator import Pvariable
from esphome.cpp_types import App
DEPENDENCIES = ['api']
HomeassistantSensor = sensor.sensor_ns.class_('HomeassistantSensor', sensor.Sensor)
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(HomeassistantSensor),
vol.Required(CONF_ENTITY_ID): cv.entity_id,
}))
def to_code(config):
rhs = App.make_homeassistant_sensor(config[CONF_NAME], config[CONF_ENTITY_ID])
subs = Pvariable(config[CONF_ID], rhs)
sensor.setup_sensor(subs, config)
BUILD_FLAGS = '-DUSE_HOMEASSISTANT_SENSOR'

View File

@@ -1,43 +0,0 @@
import voluptuous as vol
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import CONF_HUMIDITY, CONF_ID, CONF_NAME, CONF_TEMPERATURE, \
CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, Application, PollingComponent
DEPENDENCIES = ['i2c']
MakeHTU21DSensor = Application.struct('MakeHTU21DSensor')
HTU21DComponent = sensor.sensor_ns.class_('HTU21DComponent', PollingComponent, i2c.I2CDevice)
HTU21DTemperatureSensor = sensor.sensor_ns.class_('HTU21DTemperatureSensor',
sensor.EmptyPollingParentSensor)
HTU21DHumiditySensor = sensor.sensor_ns.class_('HTU21DHumiditySensor',
sensor.EmptyPollingParentSensor)
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(HTU21DComponent),
vol.Required(CONF_TEMPERATURE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(HTU21DTemperatureSensor),
})),
vol.Required(CONF_HUMIDITY): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(HTU21DHumiditySensor),
})),
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema)
def to_code(config):
rhs = App.make_htu21d_sensor(config[CONF_TEMPERATURE][CONF_NAME],
config[CONF_HUMIDITY][CONF_NAME],
config.get(CONF_UPDATE_INTERVAL))
htu21d = Pvariable(config[CONF_ID], rhs)
sensor.setup_sensor(htu21d.Pget_temperature_sensor(), config[CONF_TEMPERATURE])
sensor.setup_sensor(htu21d.Pget_humidity_sensor(), config[CONF_HUMIDITY])
setup_component(htu21d, config)
BUILD_FLAGS = '-DUSE_HTU21D_SENSOR'

View File

@@ -1,47 +0,0 @@
import voluptuous as vol
from esphome import pins
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import CONF_CLK_PIN, CONF_GAIN, CONF_ID, CONF_NAME, CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable, add
from esphome.cpp_helpers import gpio_input_pin_expression, setup_component
from esphome.cpp_types import App, Application
MakeHX711Sensor = Application.struct('MakeHX711Sensor')
HX711Sensor = sensor.sensor_ns.class_('HX711Sensor', sensor.PollingSensorComponent)
CONF_DOUT_PIN = 'dout_pin'
HX711Gain = sensor.sensor_ns.enum('HX711Gain')
GAINS = {
128: HX711Gain.HX711_GAIN_128,
32: HX711Gain.HX711_GAIN_32,
64: HX711Gain.HX711_GAIN_64,
}
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(HX711Sensor),
vol.Required(CONF_DOUT_PIN): pins.gpio_input_pin_schema,
vol.Required(CONF_CLK_PIN): pins.gpio_output_pin_schema,
vol.Optional(CONF_GAIN): cv.one_of(*GAINS, int=True),
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema))
def to_code(config):
dout_pin = yield gpio_input_pin_expression(config[CONF_DOUT_PIN])
sck_pin = yield gpio_input_pin_expression(config[CONF_CLK_PIN])
rhs = App.make_hx711_sensor(config[CONF_NAME], dout_pin, sck_pin,
config.get(CONF_UPDATE_INTERVAL))
hx711 = Pvariable(config[CONF_ID], rhs)
if CONF_GAIN in config:
add(hx711.set_gain(GAINS[config[CONF_GAIN]]))
sensor.setup_sensor(hx711, config)
setup_component(hx711, config)
BUILD_FLAGS = '-DUSE_HX711'

View File

@@ -1,68 +0,0 @@
# coding=utf-8
import voluptuous as vol
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import CONF_ADDRESS, CONF_BUS_VOLTAGE, CONF_CURRENT, CONF_ID, \
CONF_MAX_CURRENT, CONF_MAX_VOLTAGE, CONF_NAME, CONF_POWER, CONF_SHUNT_RESISTANCE, \
CONF_SHUNT_VOLTAGE, CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, PollingComponent
DEPENDENCIES = ['i2c']
INA219Component = sensor.sensor_ns.class_('INA219Component', PollingComponent, i2c.I2CDevice)
INA219VoltageSensor = sensor.sensor_ns.class_('INA219VoltageSensor',
sensor.EmptyPollingParentSensor)
INA219CurrentSensor = sensor.sensor_ns.class_('INA219CurrentSensor',
sensor.EmptyPollingParentSensor)
INA219PowerSensor = sensor.sensor_ns.class_('INA219PowerSensor', sensor.EmptyPollingParentSensor)
SENSOR_KEYS = [CONF_BUS_VOLTAGE, CONF_SHUNT_VOLTAGE, CONF_CURRENT,
CONF_POWER]
PLATFORM_SCHEMA = vol.All(sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(INA219Component),
vol.Optional(CONF_ADDRESS, default=0x40): cv.i2c_address,
vol.Optional(CONF_BUS_VOLTAGE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(INA219VoltageSensor),
})),
vol.Optional(CONF_SHUNT_VOLTAGE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(INA219VoltageSensor),
})),
vol.Optional(CONF_CURRENT): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(INA219CurrentSensor),
})),
vol.Optional(CONF_POWER): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(INA219PowerSensor),
})),
vol.Optional(CONF_SHUNT_RESISTANCE, default=0.1): vol.All(cv.resistance,
vol.Range(min=0.0, max=32.0)),
vol.Optional(CONF_MAX_VOLTAGE, default=32.0): vol.All(cv.voltage, vol.Range(min=0.0, max=32.0)),
vol.Optional(CONF_MAX_CURRENT, default=3.2): vol.All(cv.current, vol.Range(min=0.0)),
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema), cv.has_at_least_one_key(*SENSOR_KEYS))
def to_code(config):
rhs = App.make_ina219(config[CONF_SHUNT_RESISTANCE],
config[CONF_MAX_CURRENT], config[CONF_MAX_VOLTAGE],
config[CONF_ADDRESS], config.get(CONF_UPDATE_INTERVAL))
ina = Pvariable(config[CONF_ID], rhs)
if CONF_BUS_VOLTAGE in config:
conf = config[CONF_BUS_VOLTAGE]
sensor.register_sensor(ina.Pmake_bus_voltage_sensor(conf[CONF_NAME]), conf)
if CONF_SHUNT_VOLTAGE in config:
conf = config[CONF_SHUNT_VOLTAGE]
sensor.register_sensor(ina.Pmake_shunt_voltage_sensor(conf[CONF_NAME]), conf)
if CONF_CURRENT in config:
conf = config[CONF_CURRENT]
sensor.register_sensor(ina.Pmake_current_sensor(conf[CONF_NAME]), conf)
if CONF_POWER in config:
conf = config[CONF_POWER]
sensor.register_sensor(ina.Pmake_power_sensor(conf[CONF_NAME]), conf)
setup_component(ina, config)
BUILD_FLAGS = '-DUSE_INA219'

View File

@@ -1,79 +0,0 @@
# coding=utf-8
import voluptuous as vol
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import CONF_ADDRESS, CONF_BUS_VOLTAGE, CONF_CURRENT, CONF_ID, CONF_NAME, \
CONF_POWER, CONF_SHUNT_RESISTANCE, CONF_SHUNT_VOLTAGE, CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable, add
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, PollingComponent
DEPENDENCIES = ['i2c']
CONF_CHANNEL_1 = 'channel_1'
CONF_CHANNEL_2 = 'channel_2'
CONF_CHANNEL_3 = 'channel_3'
INA3221Component = sensor.sensor_ns.class_('INA3221Component', PollingComponent, i2c.I2CDevice)
INA3221VoltageSensor = sensor.sensor_ns.class_('INA3221VoltageSensor',
sensor.EmptyPollingParentSensor)
INA3221CurrentSensor = sensor.sensor_ns.class_('INA3221CurrentSensor',
sensor.EmptyPollingParentSensor)
INA3221PowerSensor = sensor.sensor_ns.class_('INA3221PowerSensor', sensor.EmptyPollingParentSensor)
SENSOR_KEYS = [CONF_BUS_VOLTAGE, CONF_SHUNT_VOLTAGE, CONF_CURRENT, CONF_POWER]
INA3221_CHANNEL_SCHEMA = vol.All(cv.Schema({
vol.Optional(CONF_BUS_VOLTAGE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(INA3221VoltageSensor),
})),
vol.Optional(CONF_SHUNT_VOLTAGE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(INA3221VoltageSensor),
})),
vol.Optional(CONF_CURRENT): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(INA3221CurrentSensor),
})),
vol.Optional(CONF_POWER): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(INA3221PowerSensor),
})),
vol.Optional(CONF_SHUNT_RESISTANCE, default=0.1): vol.All(cv.resistance,
vol.Range(min=0.0, max=32.0)),
}).extend(cv.COMPONENT_SCHEMA.schema), cv.has_at_least_one_key(*SENSOR_KEYS))
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(INA3221Component),
vol.Optional(CONF_ADDRESS, default=0x40): cv.i2c_address,
vol.Optional(CONF_CHANNEL_1): INA3221_CHANNEL_SCHEMA,
vol.Optional(CONF_CHANNEL_2): INA3221_CHANNEL_SCHEMA,
vol.Optional(CONF_CHANNEL_3): INA3221_CHANNEL_SCHEMA,
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
})
def to_code(config):
rhs = App.make_ina3221(config[CONF_ADDRESS], config.get(CONF_UPDATE_INTERVAL))
ina = Pvariable(config[CONF_ID], rhs)
for i, channel in enumerate([CONF_CHANNEL_1, CONF_CHANNEL_2, CONF_CHANNEL_3]):
if channel not in config:
continue
conf = config[channel]
if CONF_SHUNT_RESISTANCE in conf:
add(ina.set_shunt_resistance(i, conf[CONF_SHUNT_RESISTANCE]))
if CONF_BUS_VOLTAGE in conf:
c = conf[CONF_BUS_VOLTAGE]
sensor.register_sensor(ina.Pmake_bus_voltage_sensor(i, c[CONF_NAME]), c)
if CONF_SHUNT_VOLTAGE in conf:
c = conf[CONF_SHUNT_VOLTAGE]
sensor.register_sensor(ina.Pmake_shunt_voltage_sensor(i, c[CONF_NAME]), c)
if CONF_CURRENT in conf:
c = conf[CONF_CURRENT]
sensor.register_sensor(ina.Pmake_current_sensor(i, c[CONF_NAME]), c)
if CONF_POWER in conf:
c = conf[CONF_POWER]
sensor.register_sensor(ina.Pmake_power_sensor(i, c[CONF_NAME]), c)
setup_component(ina, config)
BUILD_FLAGS = '-DUSE_INA3221'

View File

@@ -1,33 +0,0 @@
import voluptuous as vol
from esphome import pins
from esphome.components import sensor, spi
from esphome.components.spi import SPIComponent
import esphome.config_validation as cv
from esphome.const import CONF_CS_PIN, CONF_ID, CONF_NAME, CONF_SPI_ID, CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable, get_variable
from esphome.cpp_helpers import gpio_output_pin_expression, setup_component
from esphome.cpp_types import App
MAX31855Sensor = sensor.sensor_ns.class_('MAX31855Sensor', sensor.PollingSensorComponent,
spi.SPIDevice)
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(MAX31855Sensor),
cv.GenerateID(CONF_SPI_ID): cv.use_variable_id(SPIComponent),
vol.Required(CONF_CS_PIN): pins.gpio_output_pin_schema,
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema))
def to_code(config):
spi_ = yield get_variable(config[CONF_SPI_ID])
cs = yield gpio_output_pin_expression(config[CONF_CS_PIN])
rhs = App.make_max31855_sensor(config[CONF_NAME], spi_, cs,
config.get(CONF_UPDATE_INTERVAL))
max31855 = Pvariable(config[CONF_ID], rhs)
sensor.setup_sensor(max31855, config)
setup_component(max31855, config)
BUILD_FLAGS = '-DUSE_MAX31855_SENSOR'

View File

@@ -1,34 +0,0 @@
import voluptuous as vol
from esphome import pins
from esphome.components import sensor, spi
from esphome.components.spi import SPIComponent
import esphome.config_validation as cv
from esphome.const import CONF_CS_PIN, CONF_ID, CONF_NAME, CONF_SPI_ID, \
CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable, get_variable
from esphome.cpp_helpers import gpio_output_pin_expression, setup_component
from esphome.cpp_types import App
MAX6675Sensor = sensor.sensor_ns.class_('MAX6675Sensor', sensor.PollingSensorComponent,
spi.SPIDevice)
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(MAX6675Sensor),
cv.GenerateID(CONF_SPI_ID): cv.use_variable_id(SPIComponent),
vol.Required(CONF_CS_PIN): pins.gpio_output_pin_schema,
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema))
def to_code(config):
spi_ = yield get_variable(config[CONF_SPI_ID])
cs = yield gpio_output_pin_expression(config[CONF_CS_PIN])
rhs = App.make_max6675_sensor(config[CONF_NAME], spi_, cs,
config.get(CONF_UPDATE_INTERVAL))
max6675 = Pvariable(config[CONF_ID], rhs)
sensor.setup_sensor(max6675, config)
setup_component(max6675, config)
BUILD_FLAGS = '-DUSE_MAX6675_SENSOR'

View File

@@ -1,46 +0,0 @@
import voluptuous as vol
from esphome.components import sensor, uart
from esphome.components.uart import UARTComponent
import esphome.config_validation as cv
from esphome.const import CONF_CO2, CONF_ID, CONF_NAME, CONF_TEMPERATURE, CONF_UART_ID, \
CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable, get_variable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, PollingComponent
DEPENDENCIES = ['uart']
MHZ19Component = sensor.sensor_ns.class_('MHZ19Component', PollingComponent, uart.UARTDevice)
MHZ19TemperatureSensor = sensor.sensor_ns.class_('MHZ19TemperatureSensor',
sensor.EmptyPollingParentSensor)
MHZ19CO2Sensor = sensor.sensor_ns.class_('MHZ19CO2Sensor', sensor.EmptyPollingParentSensor)
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(MHZ19Component),
cv.GenerateID(CONF_UART_ID): cv.use_variable_id(UARTComponent),
vol.Required(CONF_CO2): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(MHZ19CO2Sensor),
})),
vol.Optional(CONF_TEMPERATURE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(MHZ19TemperatureSensor),
})),
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema)
def to_code(config):
uart_ = yield get_variable(config[CONF_UART_ID])
rhs = App.make_mhz19_sensor(uart_, config[CONF_CO2][CONF_NAME],
config.get(CONF_UPDATE_INTERVAL))
mhz19 = Pvariable(config[CONF_ID], rhs)
sensor.setup_sensor(mhz19.Pget_co2_sensor(), config[CONF_CO2])
if CONF_TEMPERATURE in config:
sensor.register_sensor(mhz19.Pmake_temperature_sensor(config[CONF_TEMPERATURE][CONF_NAME]),
config[CONF_TEMPERATURE])
setup_component(mhz19, config)
BUILD_FLAGS = '-DUSE_MHZ19'

View File

@@ -1,92 +0,0 @@
import voluptuous as vol
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import CONF_ADDRESS, CONF_ID, CONF_NAME, CONF_TEMPERATURE, \
CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, PollingComponent
DEPENDENCIES = ['i2c']
CONF_ACCEL_X = 'accel_x'
CONF_ACCEL_Y = 'accel_y'
CONF_ACCEL_Z = 'accel_z'
CONF_GYRO_X = 'gyro_x'
CONF_GYRO_Y = 'gyro_y'
CONF_GYRO_Z = 'gyro_z'
MPU6050Component = sensor.sensor_ns.class_('MPU6050Component', PollingComponent, i2c.I2CDevice)
MPU6050AccelSensor = sensor.sensor_ns.class_('MPU6050AccelSensor', sensor.EmptyPollingParentSensor)
MPU6050GyroSensor = sensor.sensor_ns.class_('MPU6050GyroSensor', sensor.EmptyPollingParentSensor)
MPU6050TemperatureSensor = sensor.sensor_ns.class_('MPU6050TemperatureSensor',
sensor.EmptyPollingParentSensor)
SENSOR_KEYS = [CONF_ACCEL_X, CONF_ACCEL_Y, CONF_ACCEL_Z,
CONF_GYRO_X, CONF_GYRO_Y, CONF_GYRO_Z]
PLATFORM_SCHEMA = vol.All(sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(MPU6050Component),
vol.Optional(CONF_ADDRESS, default=0x68): cv.i2c_address,
vol.Optional(CONF_ACCEL_X): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(MPU6050AccelSensor),
})),
vol.Optional(CONF_ACCEL_Y): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(MPU6050AccelSensor),
})),
vol.Optional(CONF_ACCEL_Z): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(MPU6050AccelSensor),
})),
vol.Optional(CONF_GYRO_X): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(MPU6050GyroSensor),
})),
vol.Optional(CONF_GYRO_Y): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(MPU6050GyroSensor),
})),
vol.Optional(CONF_GYRO_Z): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(MPU6050GyroSensor),
})),
vol.Optional(CONF_TEMPERATURE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(MPU6050TemperatureSensor),
})),
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema), cv.has_at_least_one_key(*SENSOR_KEYS))
def to_code(config):
rhs = App.make_mpu6050_sensor(config[CONF_ADDRESS], config.get(CONF_UPDATE_INTERVAL))
mpu = Pvariable(config[CONF_ID], rhs)
if CONF_ACCEL_X in config:
conf = config[CONF_ACCEL_X]
rhs = mpu.Pmake_accel_x_sensor(conf[CONF_NAME])
sensor.register_sensor(rhs, conf)
if CONF_ACCEL_Y in config:
conf = config[CONF_ACCEL_Y]
rhs = mpu.Pmake_accel_y_sensor(conf[CONF_NAME])
sensor.register_sensor(rhs, conf)
if CONF_ACCEL_Z in config:
conf = config[CONF_ACCEL_Z]
rhs = mpu.Pmake_accel_z_sensor(conf[CONF_NAME])
sensor.register_sensor(rhs, conf)
if CONF_GYRO_X in config:
conf = config[CONF_GYRO_X]
rhs = mpu.Pmake_gyro_x_sensor(conf[CONF_NAME])
sensor.register_sensor(rhs, conf)
if CONF_GYRO_Y in config:
conf = config[CONF_GYRO_Y]
rhs = mpu.Pmake_gyro_y_sensor(conf[CONF_NAME])
sensor.register_sensor(rhs, conf)
if CONF_GYRO_Z in config:
conf = config[CONF_GYRO_Z]
rhs = mpu.Pmake_gyro_z_sensor(conf[CONF_NAME])
sensor.register_sensor(rhs, conf)
if CONF_TEMPERATURE in config:
conf = config[CONF_TEMPERATURE]
rhs = mpu.Pmake_temperature_sensor(conf[CONF_NAME])
sensor.register_sensor(rhs, conf)
setup_component(mpu, config)
BUILD_FLAGS = '-DUSE_MPU6050'

View File

@@ -1,32 +0,0 @@
import voluptuous as vol
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_NAME, CONF_QOS, CONF_TOPIC
from esphome.cpp_generator import Pvariable, add
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, Component
DEPENDENCIES = ['mqtt']
MQTTSubscribeSensor = sensor.sensor_ns.class_('MQTTSubscribeSensor', sensor.Sensor, Component)
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(MQTTSubscribeSensor),
vol.Required(CONF_TOPIC): cv.subscribe_topic,
vol.Optional(CONF_QOS): cv.mqtt_qos,
}).extend(cv.COMPONENT_SCHEMA.schema))
def to_code(config):
rhs = App.make_mqtt_subscribe_sensor(config[CONF_NAME], config[CONF_TOPIC])
subs = Pvariable(config[CONF_ID], rhs)
if CONF_QOS in config:
add(subs.set_qos(config[CONF_QOS]))
sensor.setup_sensor(subs, config)
setup_component(subs, config)
BUILD_FLAGS = '-DUSE_MQTT_SUBSCRIBE_SENSOR'

View File

@@ -1,46 +0,0 @@
import voluptuous as vol
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import CONF_ADDRESS, CONF_ID, CONF_NAME, CONF_PRESSURE, \
CONF_TEMPERATURE, CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable, add
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, PollingComponent
DEPENDENCIES = ['i2c']
MS5611Component = sensor.sensor_ns.class_('MS5611Component', PollingComponent, i2c.I2CDevice)
MS5611TemperatureSensor = sensor.sensor_ns.class_('MS5611TemperatureSensor',
sensor.EmptyPollingParentSensor)
MS5611PressureSensor = sensor.sensor_ns.class_('MS5611PressureSensor',
sensor.EmptyPollingParentSensor)
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(MS5611Component),
vol.Optional(CONF_ADDRESS): cv.i2c_address,
vol.Required(CONF_TEMPERATURE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(MS5611TemperatureSensor),
})),
vol.Required(CONF_PRESSURE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(MS5611PressureSensor),
})),
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema)
def to_code(config):
rhs = App.make_ms5611_sensor(config[CONF_TEMPERATURE][CONF_NAME],
config[CONF_PRESSURE][CONF_NAME],
config.get(CONF_UPDATE_INTERVAL))
ms5611 = Pvariable(config[CONF_ID], rhs)
if CONF_ADDRESS in config:
add(ms5611.set_address(config[CONF_ADDRESS]))
sensor.setup_sensor(ms5611.Pget_temperature_sensor(), config[CONF_TEMPERATURE])
sensor.setup_sensor(ms5611.Pget_pressure_sensor(), config[CONF_PRESSURE])
setup_component(ms5611, config)
BUILD_FLAGS = '-DUSE_MS5611'

View File

@@ -1,96 +0,0 @@
import voluptuous as vol
from esphome.components import sensor, uart
from esphome.components.uart import UARTComponent
import esphome.config_validation as cv
from esphome.const import CONF_FORMALDEHYDE, CONF_HUMIDITY, CONF_ID, CONF_NAME, CONF_PM_10_0, \
CONF_PM_1_0, CONF_PM_2_5, CONF_TEMPERATURE, CONF_TYPE, CONF_UART_ID
from esphome.cpp_generator import Pvariable, get_variable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, Component
DEPENDENCIES = ['uart']
PMSX003Component = sensor.sensor_ns.class_('PMSX003Component', uart.UARTDevice, Component)
PMSX003Sensor = sensor.sensor_ns.class_('PMSX003Sensor', sensor.Sensor)
CONF_PMSX003 = 'PMSX003'
CONF_PMS5003T = 'PMS5003T'
CONF_PMS5003ST = 'PMS5003ST'
PMSX003Type = sensor.sensor_ns.enum('PMSX003Type')
PMSX003_TYPES = {
CONF_PMSX003: PMSX003Type.PMSX003_TYPE_X003,
CONF_PMS5003T: PMSX003Type.PMSX003_TYPE_5003T,
CONF_PMS5003ST: PMSX003Type.PMSX003_TYPE_5003ST,
}
SENSORS_TO_TYPE = {
CONF_PM_1_0: [CONF_PMSX003],
CONF_PM_2_5: [CONF_PMSX003, CONF_PMS5003T, CONF_PMS5003ST],
CONF_PM_10_0: [CONF_PMSX003],
CONF_TEMPERATURE: [CONF_PMS5003T, CONF_PMS5003ST],
CONF_HUMIDITY: [CONF_PMS5003T, CONF_PMS5003ST],
CONF_FORMALDEHYDE: [CONF_PMS5003ST],
}
def validate_pmsx003_sensors(value):
for key, types in SENSORS_TO_TYPE.items():
if key in value and value[CONF_TYPE] not in types:
raise vol.Invalid(u"{} does not have {} sensor!".format(value[CONF_TYPE], key))
return value
PMSX003_SENSOR_SCHEMA = sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(PMSX003Sensor),
})
PLATFORM_SCHEMA = vol.All(sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(PMSX003Component),
cv.GenerateID(CONF_UART_ID): cv.use_variable_id(UARTComponent),
vol.Required(CONF_TYPE): cv.one_of(*PMSX003_TYPES, upper=True),
vol.Optional(CONF_PM_1_0): cv.nameable(PMSX003_SENSOR_SCHEMA),
vol.Optional(CONF_PM_2_5): cv.nameable(PMSX003_SENSOR_SCHEMA),
vol.Optional(CONF_PM_10_0): cv.nameable(PMSX003_SENSOR_SCHEMA),
vol.Optional(CONF_TEMPERATURE): cv.nameable(PMSX003_SENSOR_SCHEMA),
vol.Optional(CONF_HUMIDITY): cv.nameable(PMSX003_SENSOR_SCHEMA),
vol.Optional(CONF_FORMALDEHYDE): cv.nameable(PMSX003_SENSOR_SCHEMA),
}).extend(cv.COMPONENT_SCHEMA.schema), cv.has_at_least_one_key(*SENSORS_TO_TYPE))
def to_code(config):
uart_ = yield get_variable(config[CONF_UART_ID])
rhs = App.make_pmsx003(uart_, PMSX003_TYPES[config[CONF_TYPE]])
pms = Pvariable(config[CONF_ID], rhs)
if CONF_PM_1_0 in config:
conf = config[CONF_PM_1_0]
sensor.register_sensor(pms.make_pm_1_0_sensor(conf[CONF_NAME]), conf)
if CONF_PM_2_5 in config:
conf = config[CONF_PM_2_5]
sensor.register_sensor(pms.make_pm_2_5_sensor(conf[CONF_NAME]), conf)
if CONF_PM_10_0 in config:
conf = config[CONF_PM_10_0]
sensor.register_sensor(pms.make_pm_10_0_sensor(conf[CONF_NAME]), conf)
if CONF_TEMPERATURE in config:
conf = config[CONF_TEMPERATURE]
sensor.register_sensor(pms.make_temperature_sensor(conf[CONF_NAME]), conf)
if CONF_HUMIDITY in config:
conf = config[CONF_HUMIDITY]
sensor.register_sensor(pms.make_humidity_sensor(conf[CONF_NAME]), conf)
if CONF_FORMALDEHYDE in config:
conf = config[CONF_FORMALDEHYDE]
sensor.register_sensor(pms.make_formaldehyde_sensor(conf[CONF_NAME]), conf)
setup_component(pms, config)
BUILD_FLAGS = '-DUSE_PMSX003'

View File

@@ -1,77 +0,0 @@
import voluptuous as vol
from esphome import pins
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import CONF_COUNT_MODE, CONF_FALLING_EDGE, CONF_ID, CONF_INTERNAL_FILTER, \
CONF_NAME, CONF_PIN, CONF_RISING_EDGE, CONF_UPDATE_INTERVAL, CONF_NUMBER
from esphome.core import CORE
from esphome.cpp_generator import Pvariable, add
from esphome.cpp_helpers import gpio_input_pin_expression, setup_component
from esphome.cpp_types import App
PulseCounterCountMode = sensor.sensor_ns.enum('PulseCounterCountMode')
COUNT_MODES = {
'DISABLE': PulseCounterCountMode.PULSE_COUNTER_DISABLE,
'INCREMENT': PulseCounterCountMode.PULSE_COUNTER_INCREMENT,
'DECREMENT': PulseCounterCountMode.PULSE_COUNTER_DECREMENT,
}
COUNT_MODE_SCHEMA = cv.one_of(*COUNT_MODES, upper=True)
PulseCounterBase = sensor.sensor_ns.class_('PulseCounterBase')
PulseCounterSensorComponent = sensor.sensor_ns.class_('PulseCounterSensorComponent',
sensor.PollingSensorComponent,
PulseCounterBase)
def validate_internal_filter(value):
if CORE.is_esp32:
if isinstance(value, int):
raise vol.Invalid("Please specify the internal filter in microseconds now "
"(since 1.7.0). For example '17ms'")
value = cv.positive_time_period_microseconds(value)
if value.total_microseconds > 13:
raise vol.Invalid("Maximum internal filter value for ESP32 is 13us")
return value
return cv.positive_time_period_microseconds(value)
def validate_pulse_counter_pin(value):
value = pins.internal_gpio_input_pin_schema(value)
if CORE.is_esp8266 and value[CONF_NUMBER] >= 16:
raise vol.Invalid("Pins GPIO16 and GPIO17 cannot be used as pulse counters on ESP8266.")
return value
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(PulseCounterSensorComponent),
vol.Required(CONF_PIN): validate_pulse_counter_pin,
vol.Optional(CONF_COUNT_MODE): cv.Schema({
vol.Required(CONF_RISING_EDGE): COUNT_MODE_SCHEMA,
vol.Required(CONF_FALLING_EDGE): COUNT_MODE_SCHEMA,
}),
vol.Optional(CONF_INTERNAL_FILTER): validate_internal_filter,
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema))
def to_code(config):
pin = yield gpio_input_pin_expression(config[CONF_PIN])
rhs = App.make_pulse_counter_sensor(config[CONF_NAME], pin,
config.get(CONF_UPDATE_INTERVAL))
pcnt = Pvariable(config[CONF_ID], rhs)
if CONF_COUNT_MODE in config:
rising_edge = COUNT_MODES[config[CONF_COUNT_MODE][CONF_RISING_EDGE]]
falling_edge = COUNT_MODES[config[CONF_COUNT_MODE][CONF_FALLING_EDGE]]
add(pcnt.set_edge_mode(rising_edge, falling_edge))
if CONF_INTERNAL_FILTER in config:
add(pcnt.set_filter_us(config[CONF_INTERNAL_FILTER]))
sensor.setup_sensor(pcnt, config)
setup_component(pcnt, config)
BUILD_FLAGS = '-DUSE_PULSE_COUNTER_SENSOR'

View File

@@ -1,69 +0,0 @@
import voluptuous as vol
from esphome import pins
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_NAME, CONF_RESOLUTION, CONF_MIN_VALUE, CONF_MAX_VALUE
from esphome.cpp_generator import Pvariable, add
from esphome.cpp_helpers import gpio_input_pin_expression, setup_component
from esphome.cpp_types import App, Component
RotaryEncoderResolution = sensor.sensor_ns.enum('RotaryEncoderResolution')
RESOLUTIONS = {
1: RotaryEncoderResolution.ROTARY_ENCODER_1_PULSE_PER_CYCLE,
2: RotaryEncoderResolution.ROTARY_ENCODER_2_PULSES_PER_CYCLE,
4: RotaryEncoderResolution.ROTARY_ENCODER_4_PULSES_PER_CYCLE,
}
CONF_PIN_A = 'pin_a'
CONF_PIN_B = 'pin_b'
CONF_PIN_RESET = 'pin_reset'
RotaryEncoderSensor = sensor.sensor_ns.class_('RotaryEncoderSensor', sensor.Sensor, Component)
def validate_min_max_value(config):
if CONF_MIN_VALUE in config and CONF_MAX_VALUE in config:
min_val = config[CONF_MIN_VALUE]
max_val = config[CONF_MAX_VALUE]
if min_val >= max_val:
raise vol.Invalid("Max value {} must be smaller than min value {}"
"".format(max_val, min_val))
return config
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(RotaryEncoderSensor),
vol.Required(CONF_PIN_A): vol.All(pins.internal_gpio_input_pin_schema,
pins.validate_has_interrupt),
vol.Required(CONF_PIN_B): vol.All(pins.internal_gpio_input_pin_schema,
pins.validate_has_interrupt),
vol.Optional(CONF_PIN_RESET): pins.internal_gpio_input_pin_schema,
vol.Optional(CONF_RESOLUTION): cv.one_of(*RESOLUTIONS, int=True),
vol.Optional(CONF_MIN_VALUE): cv.int_,
vol.Optional(CONF_MAX_VALUE): cv.int_,
}).extend(cv.COMPONENT_SCHEMA.schema), validate_min_max_value)
def to_code(config):
pin_a = yield gpio_input_pin_expression(config[CONF_PIN_A])
pin_b = yield gpio_input_pin_expression(config[CONF_PIN_B])
rhs = App.make_rotary_encoder_sensor(config[CONF_NAME], pin_a, pin_b)
encoder = Pvariable(config[CONF_ID], rhs)
if CONF_PIN_RESET in config:
pin_i = yield gpio_input_pin_expression(config[CONF_PIN_RESET])
add(encoder.set_reset_pin(pin_i))
if CONF_RESOLUTION in config:
resolution = RESOLUTIONS[config[CONF_RESOLUTION]]
add(encoder.set_resolution(resolution))
if CONF_MIN_VALUE in config:
add(encoder.set_min_value(config[CONF_MIN_VALUE]))
if CONF_MAX_VALUE in config:
add(encoder.set_max_value(config[CONF_MAX_VALUE]))
sensor.setup_sensor(encoder, config)
setup_component(encoder, config)
BUILD_FLAGS = '-DUSE_ROTARY_ENCODER_SENSOR'

View File

@@ -1,69 +0,0 @@
import voluptuous as vol
from esphome.components import sensor, uart
from esphome.components.uart import UARTComponent
import esphome.config_validation as cv
from esphome.const import (CONF_ID, CONF_NAME, CONF_PM_10_0, CONF_PM_2_5, CONF_RX_ONLY,
CONF_UART_ID, CONF_UPDATE_INTERVAL)
from esphome.cpp_generator import Pvariable, add, get_variable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, Component
DEPENDENCIES = ['uart']
SDS011Component = sensor.sensor_ns.class_('SDS011Component', uart.UARTDevice, Component)
SDS011Sensor = sensor.sensor_ns.class_('SDS011Sensor', sensor.EmptySensor)
def validate_sds011_rx_mode(value):
if CONF_UPDATE_INTERVAL in value and not value.get(CONF_RX_ONLY):
update_interval = value[CONF_UPDATE_INTERVAL]
if update_interval.total_minutes > 30:
raise vol.Invalid("Maximum update interval is 30min")
elif value.get(CONF_RX_ONLY) and CONF_UPDATE_INTERVAL in value:
# update_interval does not affect anything in rx-only mode, let's warn user about
# that
raise vol.Invalid("update_interval has no effect in rx_only mode. Please remove it.",
path=['update_interval'])
return value
SDS011_SENSOR_SCHEMA = sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(SDS011Sensor),
})
PLATFORM_SCHEMA = vol.All(sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(SDS011Component),
cv.GenerateID(CONF_UART_ID): cv.use_variable_id(UARTComponent),
vol.Optional(CONF_RX_ONLY): cv.boolean,
vol.Optional(CONF_PM_2_5): cv.nameable(SDS011_SENSOR_SCHEMA),
vol.Optional(CONF_PM_10_0): cv.nameable(SDS011_SENSOR_SCHEMA),
vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_minutes,
}).extend(cv.COMPONENT_SCHEMA.schema), cv.has_at_least_one_key(CONF_PM_2_5, CONF_PM_10_0),
validate_sds011_rx_mode)
def to_code(config):
uart_ = yield get_variable(config[CONF_UART_ID])
rhs = App.make_sds011(uart_)
sds011 = Pvariable(config[CONF_ID], rhs)
if CONF_UPDATE_INTERVAL in config:
add(sds011.set_update_interval_min(config.get(CONF_UPDATE_INTERVAL)))
if CONF_RX_ONLY in config:
add(sds011.set_rx_mode_only(config[CONF_RX_ONLY]))
if CONF_PM_2_5 in config:
conf = config[CONF_PM_2_5]
sensor.register_sensor(sds011.make_pm_2_5_sensor(conf[CONF_NAME]), conf)
if CONF_PM_10_0 in config:
conf = config[CONF_PM_10_0]
sensor.register_sensor(sds011.make_pm_10_0_sensor(conf[CONF_NAME]), conf)
setup_component(sds011, config)
BUILD_FLAGS = '-DUSE_SDS011'

View File

@@ -0,0 +1,118 @@
#include "esphome/components/sensor/sensor.h"
#include "esphome/core/log.h"
namespace esphome {
namespace sensor {
static const char *TAG = "sensor";
void Sensor::publish_state(float state) {
this->raw_state = state;
this->raw_callback_.call(state);
ESP_LOGV(TAG, "'%s': Received new state %f", this->name_.c_str(), state);
if (this->filter_list_ == nullptr) {
this->internal_send_state_to_frontend(state);
} else {
this->filter_list_->input(state);
}
}
void Sensor::push_new_value(float state) { this->publish_state(state); }
std::string Sensor::unit_of_measurement() { return ""; }
std::string Sensor::icon() { return ""; }
uint32_t Sensor::update_interval() { return 0; }
int8_t Sensor::accuracy_decimals() { return 0; }
Sensor::Sensor(const std::string &name) : Nameable(name), state(NAN), raw_state(NAN) {}
Sensor::Sensor() : Sensor("") {}
void Sensor::set_unit_of_measurement(const std::string &unit_of_measurement) {
this->unit_of_measurement_ = unit_of_measurement;
}
void Sensor::set_icon(const std::string &icon) { this->icon_ = icon; }
void Sensor::set_accuracy_decimals(int8_t accuracy_decimals) { this->accuracy_decimals_ = accuracy_decimals; }
void Sensor::add_on_state_callback(std::function<void(float)> &&callback) { this->callback_.add(std::move(callback)); }
void Sensor::add_on_raw_state_callback(std::function<void(float)> &&callback) {
this->raw_callback_.add(std::move(callback));
}
std::string Sensor::get_icon() {
if (this->icon_.has_value())
return *this->icon_;
return this->icon();
}
std::string Sensor::get_unit_of_measurement() {
if (this->unit_of_measurement_.has_value())
return *this->unit_of_measurement_;
return this->unit_of_measurement();
}
int8_t Sensor::get_accuracy_decimals() {
if (this->accuracy_decimals_.has_value())
return *this->accuracy_decimals_;
return this->accuracy_decimals();
}
void Sensor::add_filter(Filter *filter) {
// inefficient, but only happens once on every sensor setup and nobody's going to have massive amounts of
// filters
ESP_LOGVV(TAG, "Sensor(%p)::add_filter(%p)", this, filter);
if (this->filter_list_ == nullptr) {
this->filter_list_ = filter;
} else {
Filter *last_filter = this->filter_list_;
while (last_filter->next_ != nullptr)
last_filter = last_filter->next_;
last_filter->initialize(this, filter);
}
filter->initialize(this, nullptr);
}
void Sensor::add_filters(const std::vector<Filter *> &filters) {
for (Filter *filter : filters) {
this->add_filter(filter);
}
}
void Sensor::set_filters(const std::vector<Filter *> &filters) {
this->clear_filters();
this->add_filters(filters);
}
void Sensor::clear_filters() {
if (this->filter_list_ != nullptr) {
ESP_LOGVV(TAG, "Sensor(%p)::clear_filters()", this);
}
this->filter_list_ = nullptr;
}
float Sensor::get_value() const { return this->state; }
float Sensor::get_state() const { return this->state; }
float Sensor::get_raw_value() const { return this->raw_state; }
float Sensor::get_raw_state() const { return this->raw_state; }
std::string Sensor::unique_id() { return ""; }
void Sensor::internal_send_state_to_frontend(float state) {
this->has_state_ = true;
this->state = state;
if (this->filter_list_ != nullptr) {
ESP_LOGD(TAG, "'%s': Sending state %.5f %s with %d decimals of accuracy", this->get_name().c_str(), state,
this->get_unit_of_measurement().c_str(), this->get_accuracy_decimals());
}
this->callback_.call(state);
}
bool Sensor::has_state() const { return this->has_state_; }
uint32_t Sensor::calculate_expected_filter_update_interval() {
uint32_t interval = this->update_interval();
if (interval == 4294967295UL)
// update_interval: never
return 0;
if (this->filter_list_ == nullptr) {
return interval;
}
return this->filter_list_->calculate_remaining_interval(interval);
}
uint32_t Sensor::hash_base() { return 2455723294UL; }
PollingSensorComponent::PollingSensorComponent(const std::string &name, uint32_t update_interval)
: PollingComponent(update_interval), Sensor(name) {}
uint32_t PollingSensorComponent::update_interval() { return this->get_update_interval(); }
} // namespace sensor
} // namespace esphome

View File

@@ -0,0 +1,187 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/core/helpers.h"
#include "esphome/components/sensor/filter.h"
namespace esphome {
namespace sensor {
#define LOG_SENSOR(prefix, type, obj) \
if (obj != nullptr) { \
ESP_LOGCONFIG(TAG, prefix type " '%s'", obj->get_name().c_str()); \
ESP_LOGCONFIG(TAG, prefix " Unit of Measurement: '%s'", obj->get_unit_of_measurement().c_str()); \
ESP_LOGCONFIG(TAG, prefix " Accuracy Decimals: %d", obj->get_accuracy_decimals()); \
if (!obj->get_icon().empty()) { \
ESP_LOGCONFIG(TAG, prefix " Icon: '%s'", obj->get_icon().c_str()); \
} \
if (!obj->unique_id().empty()) { \
ESP_LOGV(TAG, prefix " Unique ID: '%s'", obj->unique_id().c_str()); \
} \
}
/** Base-class for all sensors.
*
* A sensor has unit of measurement and can use publish_state to send out a new value with the specified accuracy.
*/
class Sensor : public Nameable {
public:
explicit Sensor(const std::string &name);
explicit Sensor();
/** Manually set the unit of measurement of this sensor. By default the sensor's default defined by
* unit_of_measurement() is used.
*
* @param unit_of_measurement The unit of measurement, "" to disable.
*/
void set_unit_of_measurement(const std::string &unit_of_measurement);
/** Manually set the icon of this sensor. By default the sensor's default defined by icon() is used.
*
* @param icon The icon, for example "mdi:flash". "" to disable.
*/
void set_icon(const std::string &icon);
/** Manually set the accuracy in decimals for this sensor. By default, the sensor's default defined by
* accuracy_decimals() is used.
*
* @param accuracy_decimals The accuracy decimal that should be used.
*/
void set_accuracy_decimals(int8_t accuracy_decimals);
/// Add a filter to the filter chain. Will be appended to the back.
void add_filter(Filter *filter);
/** Add a list of vectors to the back of the filter chain.
*
* This may look like:
*
* sensor->add_filters({
* LambdaFilter([&](float value) -> optional<float> { return 42/value; }),
* OffsetFilter(1),
* SlidingWindowMovingAverageFilter(15, 15), // average over last 15 values
* });
*/
void add_filters(const std::vector<Filter *> &filters);
/// Clear the filters and replace them by filters.
void set_filters(const std::vector<Filter *> &filters);
/// Clear the entire filter chain.
void clear_filters();
/// Getter-syntax for .value. Please use .state instead.
float get_value() const ESPDEPRECATED(".value is deprecated, please use .state");
/// Getter-syntax for .state.
float get_state() const;
/// Getter-syntax for .raw_value. Please use .raw_state instead.
float get_raw_value() const ESPDEPRECATED(".raw_value is deprecated, please use .raw_state");
/// Getter-syntax for .raw_state
float get_raw_state() const;
/// Get the accuracy in decimals. Uses the manual override if specified or the default value instead.
int8_t get_accuracy_decimals();
/// Get the unit of measurement. Uses the manual override if specified or the default value instead.
std::string get_unit_of_measurement();
/// Get the Home Assistant Icon. Uses the manual override if specified or the default value instead.
std::string get_icon();
/** Publish a new state to the front-end.
*
* First, the new state will be assigned to the raw_value. Then it's passed through all filters
* until it finally lands in the .value member variable and a callback is issued.
*
* @param state The state as a floating point number.
*/
void publish_state(float state);
/** Push a new value to the MQTT front-end.
*
* Note: deprecated, please use publish_state.
*/
void push_new_value(float state) ESPDEPRECATED("push_new_value is deprecated. Please use .publish_state instead");
// ========== INTERNAL METHODS ==========
// (In most use cases you won't need these)
/// Add a callback that will be called every time a filtered value arrives.
void add_on_state_callback(std::function<void(float)> &&callback);
/// Add a callback that will be called every time the sensor sends a raw value.
void add_on_raw_state_callback(std::function<void(float)> &&callback);
/** This member variable stores the last state that has passed through all filters.
*
* On startup, when no state is available yet, this is NAN (not-a-number) and the validity
* can be checked using has_state().
*
* This is exposed through a member variable for ease of use in esphome lambdas.
*/
float state;
/** This member variable stores the current raw state of the sensor. Unlike .state,
* this will be updated immediately when publish_state is called.
*/
float raw_state;
/// Return whether this sensor has gotten a full state (that passed through all filters) yet.
bool has_state() const;
/** A unique ID for this sensor, empty for no unique id. See unique ID requirements:
* https://developers.home-assistant.io/docs/en/entity_registry_index.html#unique-id-requirements
*
* @return The unique id as a string.
*/
virtual std::string unique_id();
/// Return with which interval the sensor is polled. Return 0 for non-polling mode.
virtual uint32_t update_interval();
/// Calculate the expected update interval for values that pass through all filters.
uint32_t calculate_expected_filter_update_interval();
void internal_send_state_to_frontend(float state);
protected:
/** Override this to set the Home Assistant unit of measurement for this sensor.
*
* Return "" to disable this feature.
*
* @return The icon of this sensor, for example "°C".
*/
virtual std::string unit_of_measurement(); // NOLINT
/** Override this to set the Home Assistant icon for this sensor.
*
* Return "" to disable this feature.
*
* @return The icon of this sensor, for example "mdi:battery".
*/
virtual std::string icon(); // NOLINT
/// Return the accuracy in decimals for this sensor.
virtual int8_t accuracy_decimals(); // NOLINT
uint32_t hash_base() override;
CallbackManager<void(float)> raw_callback_; ///< Storage for raw state callbacks.
CallbackManager<void(float)> callback_; ///< Storage for filtered state callbacks.
/// Override the unit of measurement
optional<std::string> unit_of_measurement_;
/// Override the icon advertised to Home Assistant, otherwise sensor's icon will be used.
optional<std::string> icon_;
/// Override the accuracy in decimals, otherwise the sensor's values will be used.
optional<int8_t> accuracy_decimals_;
Filter *filter_list_{nullptr}; ///< Store all active filters.
bool has_state_{false};
};
class PollingSensorComponent : public PollingComponent, public Sensor {
public:
explicit PollingSensorComponent(const std::string &name, uint32_t update_interval);
uint32_t update_interval() override;
};
} // namespace sensor
} // namespace esphome

View File

@@ -1,44 +0,0 @@
import voluptuous as vol
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import CONF_ADDRESS, CONF_HUMIDITY, CONF_ID, CONF_NAME, \
CONF_TEMPERATURE, CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, PollingComponent
DEPENDENCIES = ['i2c']
SHT3XDComponent = sensor.sensor_ns.class_('SHT3XDComponent', PollingComponent, i2c.I2CDevice)
SHT3XDTemperatureSensor = sensor.sensor_ns.class_('SHT3XDTemperatureSensor',
sensor.EmptyPollingParentSensor)
SHT3XDHumiditySensor = sensor.sensor_ns.class_('SHT3XDHumiditySensor',
sensor.EmptyPollingParentSensor)
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(SHT3XDComponent),
vol.Required(CONF_TEMPERATURE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(SHT3XDTemperatureSensor),
})),
vol.Required(CONF_HUMIDITY): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(SHT3XDHumiditySensor),
})),
vol.Optional(CONF_ADDRESS, default=0x44): cv.i2c_address,
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema)
def to_code(config):
rhs = App.make_sht3xd_sensor(config[CONF_TEMPERATURE][CONF_NAME],
config[CONF_HUMIDITY][CONF_NAME],
config[CONF_ADDRESS],
config.get(CONF_UPDATE_INTERVAL))
sht3xd = Pvariable(config[CONF_ID], rhs)
sensor.setup_sensor(sht3xd.Pget_temperature_sensor(), config[CONF_TEMPERATURE])
sensor.setup_sensor(sht3xd.Pget_humidity_sensor(), config[CONF_HUMIDITY])
setup_component(sht3xd, config)
BUILD_FLAGS = '-DUSE_SHT3XD'

View File

@@ -1,104 +0,0 @@
# coding=utf-8
import voluptuous as vol
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import CONF_ADDRESS, CONF_COLOR_TEMPERATURE, CONF_GAIN, CONF_ID, \
CONF_ILLUMINANCE, CONF_INTEGRATION_TIME, CONF_NAME, CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable, add
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, PollingComponent
DEPENDENCIES = ['i2c']
CONF_RED_CHANNEL = 'red_channel'
CONF_GREEN_CHANNEL = 'green_channel'
CONF_BLUE_CHANNEL = 'blue_channel'
CONF_CLEAR_CHANNEL = 'clear_channel'
TCS34725Component = sensor.sensor_ns.class_('TCS34725Component', PollingComponent,
i2c.I2CDevice)
TCS34725IntegrationTime = sensor.sensor_ns.enum('TCS34725IntegrationTime')
TCS34725_INTEGRATION_TIMES = {
'2.4ms': TCS34725IntegrationTime.TCS34725_INTEGRATION_TIME_2_4MS,
'24ms': TCS34725IntegrationTime.TCS34725_INTEGRATION_TIME_24MS,
'50ms': TCS34725IntegrationTime.TCS34725_INTEGRATION_TIME_50MS,
'101ms': TCS34725IntegrationTime.TCS34725_INTEGRATION_TIME_101MS,
'154ms': TCS34725IntegrationTime.TCS34725_INTEGRATION_TIME_154MS,
'700ms': TCS34725IntegrationTime.TCS34725_INTEGRATION_TIME_700MS,
}
TCS34725Gain = sensor.sensor_ns.enum('TCS34725Gain')
TCS34725_GAINS = {
'1X': TCS34725Gain.TCS34725_GAIN_1X,
'4X': TCS34725Gain.TCS34725_GAIN_4X,
'16X': TCS34725Gain.TCS34725_GAIN_16X,
'60X': TCS34725Gain.TCS34725_GAIN_60X,
}
TCS35725IlluminanceSensor = sensor.sensor_ns.class_('TCS35725IlluminanceSensor',
sensor.EmptyPollingParentSensor)
TCS35725ColorTemperatureSensor = sensor.sensor_ns.class_('TCS35725ColorTemperatureSensor',
sensor.EmptyPollingParentSensor)
TCS35725ColorChannelSensor = sensor.sensor_ns.class_('TCS35725ColorChannelSensor',
sensor.EmptyPollingParentSensor)
COLOR_CHANNEL_SENSOR_SCHEMA = sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(TCS35725ColorChannelSensor),
})
SENSOR_KEYS = [CONF_RED_CHANNEL, CONF_GREEN_CHANNEL, CONF_BLUE_CHANNEL,
CONF_CLEAR_CHANNEL, CONF_ILLUMINANCE, CONF_COLOR_TEMPERATURE]
PLATFORM_SCHEMA = vol.All(sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(TCS34725Component),
vol.Optional(CONF_ADDRESS): cv.i2c_address,
vol.Optional(CONF_RED_CHANNEL): cv.nameable(COLOR_CHANNEL_SENSOR_SCHEMA),
vol.Optional(CONF_GREEN_CHANNEL): cv.nameable(COLOR_CHANNEL_SENSOR_SCHEMA),
vol.Optional(CONF_BLUE_CHANNEL): cv.nameable(COLOR_CHANNEL_SENSOR_SCHEMA),
vol.Optional(CONF_CLEAR_CHANNEL): cv.nameable(COLOR_CHANNEL_SENSOR_SCHEMA),
vol.Optional(CONF_ILLUMINANCE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(TCS35725IlluminanceSensor),
})),
vol.Optional(CONF_COLOR_TEMPERATURE): cv.nameable(sensor.SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(TCS35725ColorTemperatureSensor),
})),
vol.Optional(CONF_INTEGRATION_TIME): cv.one_of(*TCS34725_INTEGRATION_TIMES, lower=True),
vol.Optional(CONF_GAIN): vol.All(vol.Upper, cv.one_of(*TCS34725_GAINS), upper=True),
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema), cv.has_at_least_one_key(*SENSOR_KEYS))
def to_code(config):
rhs = App.make_tcs34725(config.get(CONF_UPDATE_INTERVAL))
tcs = Pvariable(config[CONF_ID], rhs)
if CONF_ADDRESS in config:
add(tcs.set_address(config[CONF_ADDRESS]))
if CONF_INTEGRATION_TIME in config:
add(tcs.set_integration_time(TCS34725_INTEGRATION_TIMES[config[CONF_INTEGRATION_TIME]]))
if CONF_GAIN in config:
add(tcs.set_gain(TCS34725_GAINS[config[CONF_GAIN]]))
if CONF_RED_CHANNEL in config:
conf = config[CONF_RED_CHANNEL]
sensor.register_sensor(tcs.Pmake_red_sensor(conf[CONF_NAME]), conf)
if CONF_GREEN_CHANNEL in config:
conf = config[CONF_GREEN_CHANNEL]
sensor.register_sensor(tcs.Pmake_green_sensor(conf[CONF_NAME]), conf)
if CONF_BLUE_CHANNEL in config:
conf = config[CONF_BLUE_CHANNEL]
sensor.register_sensor(tcs.Pmake_blue_sensor(conf[CONF_NAME]), conf)
if CONF_CLEAR_CHANNEL in config:
conf = config[CONF_CLEAR_CHANNEL]
sensor.register_sensor(tcs.Pmake_clear_sensor(conf[CONF_NAME]), conf)
if CONF_ILLUMINANCE in config:
conf = config[CONF_ILLUMINANCE]
sensor.register_sensor(tcs.Pmake_illuminance_sensor(conf[CONF_NAME]), conf)
if CONF_COLOR_TEMPERATURE in config:
conf = config[CONF_COLOR_TEMPERATURE]
sensor.register_sensor(tcs.Pmake_color_temperature_sensor(conf[CONF_NAME]), conf)
setup_component(tcs, config)
BUILD_FLAGS = '-DUSE_TCS34725'

View File

@@ -1,51 +0,0 @@
import voluptuous as vol
from esphome.automation import ACTION_REGISTRY
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_LAMBDA, CONF_NAME, CONF_STATE, CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable, add, get_variable, process_lambda, templatable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import Action, App, float_, optional
TemplateSensor = sensor.sensor_ns.class_('TemplateSensor', sensor.PollingSensorComponent)
SensorPublishAction = sensor.sensor_ns.class_('SensorPublishAction', Action)
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(TemplateSensor),
vol.Optional(CONF_LAMBDA): cv.lambda_,
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema))
def to_code(config):
rhs = App.make_template_sensor(config[CONF_NAME], config.get(CONF_UPDATE_INTERVAL))
template = Pvariable(config[CONF_ID], rhs)
sensor.setup_sensor(template, config)
setup_component(template, config)
if CONF_LAMBDA in config:
template_ = yield process_lambda(config[CONF_LAMBDA], [],
return_type=optional.template(float_))
add(template.set_template(template_))
BUILD_FLAGS = '-DUSE_TEMPLATE_SENSOR'
CONF_SENSOR_TEMPLATE_PUBLISH = 'sensor.template.publish'
SENSOR_TEMPLATE_PUBLISH_ACTION_SCHEMA = cv.Schema({
vol.Required(CONF_ID): cv.use_variable_id(sensor.Sensor),
vol.Required(CONF_STATE): cv.templatable(cv.float_),
})
@ACTION_REGISTRY.register(CONF_SENSOR_TEMPLATE_PUBLISH, SENSOR_TEMPLATE_PUBLISH_ACTION_SCHEMA)
def sensor_template_publish_to_code(config, action_id, template_arg, args):
var = yield get_variable(config[CONF_ID])
rhs = var.make_sensor_publish_action(template_arg)
type = SensorPublishAction.template(template_arg)
action = Pvariable(action_id, rhs, type=type)
template_ = yield templatable(config[CONF_STATE], args, float_)
add(action.set_state(template_))
yield action

View File

@@ -1,32 +0,0 @@
import voluptuous as vol
from esphome.components import sensor, time
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_NAME, CONF_TIME_ID
from esphome.cpp_generator import Pvariable, get_variable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, Component
DEPENDENCIES = ['time']
CONF_POWER_ID = 'power_id'
TotalDailyEnergy = sensor.sensor_ns.class_('TotalDailyEnergy', sensor.Sensor, Component)
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(TotalDailyEnergy),
cv.GenerateID(CONF_TIME_ID): cv.use_variable_id(time.RealTimeClockComponent),
vol.Required(CONF_POWER_ID): cv.use_variable_id(sensor.Sensor),
}).extend(cv.COMPONENT_SCHEMA.schema))
def to_code(config):
time_ = yield get_variable(config[CONF_TIME_ID])
sens = yield get_variable(config[CONF_POWER_ID])
rhs = App.make_total_daily_energy_sensor(config[CONF_NAME], time_, sens)
total_energy = Pvariable(config[CONF_ID], rhs)
sensor.setup_sensor(total_energy, config)
setup_component(total_energy, config)
BUILD_FLAGS = '-DUSE_TOTAL_DAILY_ENERGY_SENSOR'

View File

@@ -1,65 +0,0 @@
import voluptuous as vol
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import CONF_ADDRESS, CONF_GAIN, CONF_ID, CONF_INTEGRATION_TIME, CONF_NAME, \
CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable, add
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App
DEPENDENCIES = ['i2c']
TSL2561IntegrationTime = sensor.sensor_ns.enum('TSL2561IntegrationTime')
INTEGRATION_TIMES = {
14: TSL2561IntegrationTime.TSL2561_INTEGRATION_14MS,
101: TSL2561IntegrationTime.TSL2561_INTEGRATION_101MS,
402: TSL2561IntegrationTime.TSL2561_INTEGRATION_402MS,
}
TSL2561Gain = sensor.sensor_ns.enum('TSL2561Gain')
GAINS = {
'1X': TSL2561Gain.TSL2561_GAIN_1X,
'16X': TSL2561Gain.TSL2561_GAIN_16X,
}
CONF_IS_CS_PACKAGE = 'is_cs_package'
def validate_integration_time(value):
value = cv.positive_time_period_milliseconds(value).total_milliseconds
if value not in INTEGRATION_TIMES:
raise vol.Invalid(u"Unsupported integration time {}.".format(value))
return value
TSL2561Sensor = sensor.sensor_ns.class_('TSL2561Sensor', sensor.PollingSensorComponent,
i2c.I2CDevice)
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(TSL2561Sensor),
vol.Optional(CONF_ADDRESS, default=0x39): cv.i2c_address,
vol.Optional(CONF_INTEGRATION_TIME): validate_integration_time,
vol.Optional(CONF_GAIN): cv.one_of(*GAINS, upper=True),
vol.Optional(CONF_IS_CS_PACKAGE): cv.boolean,
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema))
def to_code(config):
rhs = App.make_tsl2561_sensor(config[CONF_NAME], config[CONF_ADDRESS],
config.get(CONF_UPDATE_INTERVAL))
tsl2561 = Pvariable(config[CONF_ID], rhs)
if CONF_INTEGRATION_TIME in config:
add(tsl2561.set_integration_time(INTEGRATION_TIMES[config[CONF_INTEGRATION_TIME]]))
if CONF_GAIN in config:
add(tsl2561.set_gain(GAINS[config[CONF_GAIN]]))
if CONF_IS_CS_PACKAGE in config:
add(tsl2561.set_is_cs_package(config[CONF_IS_CS_PACKAGE]))
sensor.setup_sensor(tsl2561, config)
setup_component(tsl2561, config)
BUILD_FLAGS = '-DUSE_TSL2561'

View File

@@ -1,52 +0,0 @@
import voluptuous as vol
from esphome import pins
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import CONF_ECHO_PIN, CONF_ID, CONF_NAME, CONF_TRIGGER_PIN, \
CONF_UPDATE_INTERVAL, CONF_TIMEOUT
from esphome.cpp_generator import Pvariable, add
from esphome.cpp_helpers import gpio_input_pin_expression, gpio_output_pin_expression, \
setup_component
from esphome.cpp_types import App
CONF_PULSE_TIME = 'pulse_time'
UltrasonicSensorComponent = sensor.sensor_ns.class_('UltrasonicSensorComponent',
sensor.PollingSensorComponent)
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(UltrasonicSensorComponent),
vol.Required(CONF_TRIGGER_PIN): pins.gpio_output_pin_schema,
vol.Required(CONF_ECHO_PIN): pins.internal_gpio_input_pin_schema,
vol.Optional(CONF_TIMEOUT): cv.distance,
vol.Optional(CONF_PULSE_TIME): cv.positive_time_period_microseconds,
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
vol.Optional('timeout_meter'): cv.invalid("The timeout_meter option has been renamed "
"to 'timeout'."),
vol.Optional('timeout_time'): cv.invalid("The timeout_time option has been removed. Please "
"use 'timeout'."),
}))
def to_code(config):
trigger = yield gpio_output_pin_expression(config[CONF_TRIGGER_PIN])
echo = yield gpio_input_pin_expression(config[CONF_ECHO_PIN])
rhs = App.make_ultrasonic_sensor(config[CONF_NAME], trigger, echo,
config.get(CONF_UPDATE_INTERVAL))
ultrasonic = Pvariable(config[CONF_ID], rhs)
if CONF_TIMEOUT in config:
add(ultrasonic.set_timeout_us(config[CONF_TIMEOUT] / (0.000343 / 2)))
if CONF_PULSE_TIME in config:
add(ultrasonic.set_pulse_time_us(config[CONF_PULSE_TIME]))
sensor.setup_sensor(ultrasonic, config)
setup_component(ultrasonic, config)
BUILD_FLAGS = '-DUSE_ULTRASONIC_SENSOR'

View File

@@ -1,26 +0,0 @@
import voluptuous as vol
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_NAME, CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App
UptimeSensor = sensor.sensor_ns.class_('UptimeSensor', sensor.PollingSensorComponent)
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(UptimeSensor),
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema))
def to_code(config):
rhs = App.make_uptime_sensor(config[CONF_NAME], config.get(CONF_UPDATE_INTERVAL))
uptime = Pvariable(config[CONF_ID], rhs)
sensor.setup_sensor(uptime, config)
setup_component(uptime, config)
BUILD_FLAGS = '-DUSE_UPTIME_SENSOR'

View File

@@ -1,26 +0,0 @@
import voluptuous as vol
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_NAME, CONF_UPDATE_INTERVAL
from esphome.cpp_generator import Pvariable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App
WiFiSignalSensor = sensor.sensor_ns.class_('WiFiSignalSensor', sensor.PollingSensorComponent)
PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(WiFiSignalSensor),
vol.Optional(CONF_UPDATE_INTERVAL): cv.update_interval,
}).extend(cv.COMPONENT_SCHEMA.schema))
def to_code(config):
rhs = App.make_wifi_signal_sensor(config[CONF_NAME], config.get(CONF_UPDATE_INTERVAL))
wifi = Pvariable(config[CONF_ID], rhs)
sensor.setup_sensor(wifi, config)
setup_component(wifi, config)
BUILD_FLAGS = '-DUSE_WIFI_SIGNAL_SENSOR'

View File

@@ -1,43 +0,0 @@
import voluptuous as vol
from esphome.components import esp32_ble_tracker, sensor
from esphome.components.esp32_ble_tracker import CONF_ESP32_BLE_ID, ESP32BLETracker, \
make_address_array
import esphome.config_validation as cv
from esphome.const import CONF_BATTERY_LEVEL, CONF_CONDUCTIVITY, CONF_ID, CONF_ILLUMINANCE, \
CONF_MAC_ADDRESS, CONF_MOISTURE, CONF_NAME, CONF_TEMPERATURE
from esphome.cpp_generator import Pvariable, get_variable
DEPENDENCIES = ['esp32_ble_tracker']
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(): cv.declare_variable_id(esp32_ble_tracker.XiaomiDevice),
cv.GenerateID(CONF_ESP32_BLE_ID): cv.use_variable_id(ESP32BLETracker),
vol.Required(CONF_MAC_ADDRESS): cv.mac_address,
vol.Optional(CONF_TEMPERATURE): cv.nameable(esp32_ble_tracker.XIAOMI_SENSOR_SCHEMA),
vol.Optional(CONF_MOISTURE): cv.nameable(esp32_ble_tracker.XIAOMI_SENSOR_SCHEMA),
vol.Optional(CONF_ILLUMINANCE): cv.nameable(esp32_ble_tracker.XIAOMI_SENSOR_SCHEMA),
vol.Optional(CONF_CONDUCTIVITY): cv.nameable(esp32_ble_tracker.XIAOMI_SENSOR_SCHEMA),
vol.Optional(CONF_BATTERY_LEVEL): cv.nameable(esp32_ble_tracker.XIAOMI_SENSOR_SCHEMA),
})
def to_code(config):
hub = yield get_variable(config[CONF_ESP32_BLE_ID])
rhs = hub.make_xiaomi_device(make_address_array(config[CONF_MAC_ADDRESS]))
dev = Pvariable(config[CONF_ID], rhs)
if CONF_TEMPERATURE in config:
conf = config[CONF_TEMPERATURE]
sensor.register_sensor(dev.Pmake_temperature_sensor(conf[CONF_NAME]), conf)
if CONF_MOISTURE in config:
conf = config[CONF_MOISTURE]
sensor.register_sensor(dev.Pmake_moisture_sensor(conf[CONF_NAME]), conf)
if CONF_ILLUMINANCE in config:
conf = config[CONF_ILLUMINANCE]
sensor.register_sensor(dev.Pmake_illuminance_sensor(conf[CONF_NAME]), conf)
if CONF_CONDUCTIVITY in config:
conf = config[CONF_CONDUCTIVITY]
sensor.register_sensor(dev.Pmake_conductivity_sensor(conf[CONF_NAME]), conf)
if CONF_BATTERY_LEVEL in config:
conf = config[CONF_BATTERY_LEVEL]
sensor.register_sensor(dev.Pmake_battery_level_sensor(conf[CONF_NAME]), conf)

View File

@@ -1,35 +0,0 @@
import voluptuous as vol
from esphome.components import esp32_ble_tracker, sensor
from esphome.components.esp32_ble_tracker import CONF_ESP32_BLE_ID, ESP32BLETracker, \
make_address_array
import esphome.config_validation as cv
from esphome.const import CONF_BATTERY_LEVEL, CONF_HUMIDITY, CONF_MAC_ADDRESS, CONF_MAKE_ID, \
CONF_NAME, CONF_TEMPERATURE
from esphome.cpp_generator import Pvariable, get_variable
DEPENDENCIES = ['esp32_ble_tracker']
PLATFORM_SCHEMA = sensor.PLATFORM_SCHEMA.extend({
cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(esp32_ble_tracker.XiaomiDevice),
cv.GenerateID(CONF_ESP32_BLE_ID): cv.use_variable_id(ESP32BLETracker),
vol.Required(CONF_MAC_ADDRESS): cv.mac_address,
vol.Optional(CONF_TEMPERATURE): cv.nameable(esp32_ble_tracker.XIAOMI_SENSOR_SCHEMA),
vol.Optional(CONF_HUMIDITY): cv.nameable(esp32_ble_tracker.XIAOMI_SENSOR_SCHEMA),
vol.Optional(CONF_BATTERY_LEVEL): cv.nameable(esp32_ble_tracker.XIAOMI_SENSOR_SCHEMA),
})
def to_code(config):
hub = yield get_variable(config[CONF_ESP32_BLE_ID])
rhs = hub.make_xiaomi_device(make_address_array(config[CONF_MAC_ADDRESS]))
dev = Pvariable(config[CONF_MAKE_ID], rhs)
if CONF_TEMPERATURE in config:
conf = config[CONF_TEMPERATURE]
sensor.register_sensor(dev.Pmake_temperature_sensor(conf[CONF_NAME]), conf)
if CONF_HUMIDITY in config:
conf = config[CONF_HUMIDITY]
sensor.register_sensor(dev.Pmake_humidity_sensor(conf[CONF_NAME]), conf)
if CONF_BATTERY_LEVEL in config:
conf = config[CONF_BATTERY_LEVEL]
sensor.register_sensor(dev.Pmake_battery_level_sensor(conf[CONF_NAME]), conf)