Add WiFi/MQTT/API connected condition (#465)

* Add WiFi/MQTT/API connected condition

* Add tests

* Fix namespace
This commit is contained in:
Otto Winter 2019-03-03 16:45:56 +01:00 committed by GitHub
parent 8495ce96a3
commit 4b017e2096
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 69 additions and 29 deletions

View file

@ -48,7 +48,7 @@ def validate_recursive_condition(value):
u"".format(key, key2), path) u"".format(key, key2), path)
validator = CONDITION_REGISTRY[key][0] validator = CONDITION_REGISTRY[key][0]
try: try:
condition = validator(item[key]) condition = validator(item[key] or {})
except vol.Invalid as err: except vol.Invalid as err:
err.prepend(path) err.prepend(path)
raise err raise err
@ -83,7 +83,7 @@ def validate_recursive_action(value):
u"".format(key, key2), path) u"".format(key, key2), path)
validator = ACTION_REGISTRY[key][0] validator = ACTION_REGISTRY[key][0]
try: try:
action = validator(item[key]) action = validator(item[key] or {})
except vol.Invalid as err: except vol.Invalid as err:
err.prepend(path) err.prepend(path)
raise err raise err
@ -159,7 +159,6 @@ def validate_automation(extra_schema=None, extra_validators=None, single=False):
AUTOMATION_SCHEMA = cv.Schema({ AUTOMATION_SCHEMA = cv.Schema({
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(Trigger), cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(Trigger),
cv.GenerateID(CONF_AUTOMATION_ID): cv.declare_variable_id(Automation), cv.GenerateID(CONF_AUTOMATION_ID): cv.declare_variable_id(Automation),
vol.Optional(CONF_IF): validate_recursive_condition,
vol.Required(CONF_THEN): validate_recursive_action, vol.Required(CONF_THEN): validate_recursive_action,
}) })
@ -375,10 +374,6 @@ def build_automation_(trigger, args, config):
rhs = App.make_automation(templ, trigger) rhs = App.make_automation(templ, trigger)
type = Automation.template(templ) type = Automation.template(templ)
obj = Pvariable(config[CONF_AUTOMATION_ID], rhs, type=type) obj = Pvariable(config[CONF_AUTOMATION_ID], rhs, type=type)
if CONF_IF in config:
for conditions in build_conditions(config[CONF_IF], templ, args):
yield None
add(obj.add_conditions(conditions))
for actions in build_actions(config[CONF_THEN], templ, args): for actions in build_actions(config[CONF_THEN], templ, args):
yield None yield None
add(obj.add_actions(actions)) add(obj.add_actions(actions))

View file

@ -1,7 +1,7 @@
import voluptuous as vol import voluptuous as vol
from esphome import automation from esphome import automation
from esphome.automation import ACTION_REGISTRY from esphome.automation import ACTION_REGISTRY, CONDITION_REGISTRY, Condition
import esphome.config_validation as cv import esphome.config_validation as cv
from esphome.const import CONF_DATA, CONF_DATA_TEMPLATE, CONF_ID, CONF_PASSWORD, CONF_PORT, \ from esphome.const import CONF_DATA, CONF_DATA_TEMPLATE, CONF_ID, CONF_PASSWORD, CONF_PORT, \
CONF_REBOOT_TIMEOUT, CONF_SERVICE, CONF_VARIABLES, CONF_SERVICES, CONF_TRIGGER_ID CONF_REBOOT_TIMEOUT, CONF_SERVICE, CONF_VARIABLES, CONF_SERVICES, CONF_TRIGGER_ID
@ -16,6 +16,7 @@ APIServer = api_ns.class_('APIServer', Component, StoringController)
HomeAssistantServiceCallAction = api_ns.class_('HomeAssistantServiceCallAction', Action) HomeAssistantServiceCallAction = api_ns.class_('HomeAssistantServiceCallAction', Action)
KeyValuePair = api_ns.class_('KeyValuePair') KeyValuePair = api_ns.class_('KeyValuePair')
TemplatableKeyValuePair = api_ns.class_('TemplatableKeyValuePair') TemplatableKeyValuePair = api_ns.class_('TemplatableKeyValuePair')
APIConnectedCondition = esphome_ns.class_('APIConnectedCondition', Condition)
UserService = api_ns.class_('UserService', Trigger) UserService = api_ns.class_('UserService', Trigger)
ServiceTypeArgument = api_ns.class_('ServiceTypeArgument') ServiceTypeArgument = api_ns.class_('ServiceTypeArgument')
@ -127,3 +128,14 @@ def homeassistant_service_to_code(config, action_id, template_arg, args):
datas.append(TemplatableKeyValuePair(key, value_)) datas.append(TemplatableKeyValuePair(key, value_))
add(act.set_variables(datas)) add(act.set_variables(datas))
yield act yield act
CONF_API_CONNECTED = 'api.connected'
API_CONNECTED_CONDITION_SCHEMA = vol.Schema({})
@CONDITION_REGISTRY.register(CONF_API_CONNECTED, API_CONNECTED_CONDITION_SCHEMA)
def api_connected_to_code(config, condition_id, template_arg, args):
rhs = APIConnectedCondition.new(template_arg)
type = APIConnectedCondition.template(template_arg)
yield Pvariable(condition_id, rhs, type=type)

View file

@ -4,7 +4,7 @@ import re
import voluptuous as vol import voluptuous as vol
from esphome import automation from esphome import automation
from esphome.automation import ACTION_REGISTRY from esphome.automation import ACTION_REGISTRY, CONDITION_REGISTRY, Condition
from esphome.components import logger from esphome.components import logger
import esphome.config_validation as cv import esphome.config_validation as cv
from esphome.const import CONF_AVAILABILITY, CONF_BIRTH_MESSAGE, CONF_BROKER, CONF_CLIENT_ID, \ from esphome.const import CONF_AVAILABILITY, CONF_BIRTH_MESSAGE, CONF_BROKER, CONF_CLIENT_ID, \
@ -47,6 +47,7 @@ MQTTMessageTrigger = mqtt_ns.class_('MQTTMessageTrigger', Trigger.template(std_s
MQTTJsonMessageTrigger = mqtt_ns.class_('MQTTJsonMessageTrigger', MQTTJsonMessageTrigger = mqtt_ns.class_('MQTTJsonMessageTrigger',
Trigger.template(JsonObjectConstRef)) Trigger.template(JsonObjectConstRef))
MQTTComponent = mqtt_ns.class_('MQTTComponent', Component) MQTTComponent = mqtt_ns.class_('MQTTComponent', Component)
MQTTConnectedCondition = mqtt_ns.class_('MQTTConnectedCondition', Condition)
def validate_config(value): def validate_config(value):
@ -347,3 +348,13 @@ def setup_mqtt_component(obj, config):
LIB_DEPS = 'AsyncMqttClient@0.8.2' LIB_DEPS = 'AsyncMqttClient@0.8.2'
BUILD_FLAGS = '-DUSE_MQTT' BUILD_FLAGS = '-DUSE_MQTT'
CONF_MQTT_CONNECTED = 'mqtt.connected'
MQTT_CONNECTED_CONDITION_SCHEMA = vol.Schema({})
@CONDITION_REGISTRY.register(CONF_MQTT_CONNECTED, MQTT_CONNECTED_CONDITION_SCHEMA)
def mqtt_connected_to_code(config, condition_id, template_arg, args):
rhs = MQTTConnectedCondition.new(template_arg)
type = MQTTConnectedCondition.template(template_arg)
yield Pvariable(condition_id, rhs, type=type)

View file

@ -1,10 +1,11 @@
import voluptuous as vol import voluptuous as vol
from esphome.automation import CONDITION_REGISTRY, Condition
import esphome.config_validation as cv import esphome.config_validation as cv
from esphome.const import CONF_AP, CONF_BSSID, CONF_CHANNEL, CONF_DNS1, CONF_DNS2, \ from esphome.const import CONF_AP, CONF_BSSID, CONF_CHANNEL, CONF_DNS1, CONF_DNS2, CONF_DOMAIN, \
CONF_DOMAIN, CONF_FAST_CONNECT, CONF_GATEWAY, CONF_ID, CONF_MANUAL_IP, CONF_NETWORKS, \ CONF_FAST_CONNECT, CONF_GATEWAY, CONF_HIDDEN, CONF_ID, CONF_MANUAL_IP, CONF_NETWORKS, \
CONF_PASSWORD, CONF_POWER_SAVE_MODE, CONF_REBOOT_TIMEOUT, CONF_SSID, CONF_STATIC_IP, \ CONF_PASSWORD, CONF_POWER_SAVE_MODE, CONF_REBOOT_TIMEOUT, CONF_SSID, CONF_STATIC_IP, \
CONF_SUBNET, CONF_USE_ADDRESS, CONF_HIDDEN CONF_SUBNET, CONF_USE_ADDRESS
from esphome.core import CORE, HexInt from esphome.core import CORE, HexInt
from esphome.cpp_generator import Pvariable, StructInitializer, add, variable from esphome.cpp_generator import Pvariable, StructInitializer, add, variable
from esphome.cpp_types import App, Component, esphome_ns, global_ns from esphome.cpp_types import App, Component, esphome_ns, global_ns
@ -20,6 +21,7 @@ WIFI_POWER_SAVE_MODES = {
'LIGHT': WiFiPowerSaveMode.WIFI_POWER_SAVE_LIGHT, 'LIGHT': WiFiPowerSaveMode.WIFI_POWER_SAVE_LIGHT,
'HIGH': WiFiPowerSaveMode.WIFI_POWER_SAVE_HIGH, 'HIGH': WiFiPowerSaveMode.WIFI_POWER_SAVE_HIGH,
} }
WiFiConnectedCondition = esphome_ns.class_('WiFiConnectedCondition', Condition)
def validate_password(value): def validate_password(value):
@ -188,3 +190,14 @@ def lib_deps(config):
if CORE.is_esp32: if CORE.is_esp32:
return None return None
raise NotImplementedError raise NotImplementedError
CONF_WIFI_CONNECTED = 'wifi.connected'
WIFI_CONNECTED_CONDITION_SCHEMA = vol.Schema({})
@CONDITION_REGISTRY.register(CONF_WIFI_CONNECTED, WIFI_CONNECTED_CONDITION_SCHEMA)
def wifi_connected_to_code(config, condition_id, template_arg, args):
rhs = WiFiConnectedCondition.new(template_arg)
type = WiFiConnectedCondition.template(template_arg)
yield Pvariable(condition_id, rhs, type=type)

View file

@ -78,21 +78,26 @@ mqtt:
on_json_message: on_json_message:
topic: the/topic topic: the/topic
then: then:
- lambda: |- - if:
int data = x["my_data"]; condition:
ESP_LOGD("main", "The data is: %d", data); - wifi.connected:
- light.turn_on: - mqtt.connected:
id: living_room_lights then:
transition_length: !lambda |- - lambda: |-
int length = 1000; int data = x["my_data"];
if (x.containsKey("length")) ESP_LOGD("main", "The data is: %d", data);
length = x["length"]; - light.turn_on:
return length; id: living_room_lights
effect: !lambda |- transition_length: !lambda |-
const char *effect = "None"; int length = 1000;
if (x.containsKey("effect")) if (x.containsKey("length"))
effect = x["effect"]; length = x["length"];
return effect; return length;
effect: !lambda |-
const char *effect = "None";
if (x.containsKey("effect"))
effect = x["effect"];
return effect;
i2c: i2c:
sda: 21 sda: 21

View file

@ -185,8 +185,12 @@ text_sensor:
icon: mdi:icon icon: mdi:icon
id: version_sensor id: version_sensor
on_value: on_value:
- lambda: !lambda |- - if:
ESP_LOGD("main", "The state is %s=%s", x.c_str(), id(version_sensor).state.c_str()); condition:
- api.connected:
then:
- lambda: !lambda |-
ESP_LOGD("main", "The state is %s=%s", x.c_str(), id(version_sensor).state.c_str());
- script.execute: my_script - script.execute: my_script
- homeassistant.service: - homeassistant.service:
service: notify.html5 service: notify.html5