mirror of
https://github.com/esphome/esphome.git
synced 2024-11-27 09:18:00 +01:00
parent
4b7c5aa05c
commit
3b1ba27043
6 changed files with 85 additions and 18 deletions
|
@ -1,15 +1,27 @@
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome import pins
|
from esphome import pins, automation
|
||||||
from esphome.const import CONF_BAUD_RATE, CONF_ID, CONF_RX_PIN, CONF_TX_PIN, CONF_UART_ID
|
from esphome.const import CONF_BAUD_RATE, CONF_ID, CONF_RX_PIN, CONF_TX_PIN, CONF_UART_ID, CONF_DATA
|
||||||
from esphome.core import CORE, coroutine
|
from esphome.core import CORE, coroutine
|
||||||
|
from esphome.py_compat import text_type, binary_type, char_to_byte
|
||||||
|
|
||||||
uart_ns = cg.esphome_ns.namespace('uart')
|
uart_ns = cg.esphome_ns.namespace('uart')
|
||||||
UARTComponent = uart_ns.class_('UARTComponent', cg.Component)
|
UARTComponent = uart_ns.class_('UARTComponent', cg.Component)
|
||||||
UARTDevice = uart_ns.class_('UARTDevice')
|
UARTDevice = uart_ns.class_('UARTDevice')
|
||||||
|
UARTWriteAction = uart_ns.class_('UARTWriteAction', automation.Action)
|
||||||
MULTI_CONF = True
|
MULTI_CONF = True
|
||||||
|
|
||||||
|
|
||||||
|
def validate_raw_data(value):
|
||||||
|
if isinstance(value, text_type):
|
||||||
|
return value.encode('utf-8')
|
||||||
|
if isinstance(value, str):
|
||||||
|
return value
|
||||||
|
if isinstance(value, list):
|
||||||
|
return cv.Schema([cv.hex_uint8_t])(value)
|
||||||
|
raise cv.Invalid("data must either be a string wrapped in quotes or a list of bytes")
|
||||||
|
|
||||||
|
|
||||||
def validate_rx_pin(value):
|
def validate_rx_pin(value):
|
||||||
value = pins.input_pin(value)
|
value = pins.input_pin(value)
|
||||||
if CORE.is_esp8266 and value >= 16:
|
if CORE.is_esp8266 and value >= 16:
|
||||||
|
@ -51,3 +63,22 @@ def register_uart_device(var, config):
|
||||||
"""
|
"""
|
||||||
parent = yield cg.get_variable(config[CONF_UART_ID])
|
parent = yield cg.get_variable(config[CONF_UART_ID])
|
||||||
cg.add(var.set_uart_parent(parent))
|
cg.add(var.set_uart_parent(parent))
|
||||||
|
|
||||||
|
|
||||||
|
@automation.register_action('uart.write', UARTWriteAction, cv.maybe_simple_value({
|
||||||
|
cv.GenerateID(): cv.use_id(UARTComponent),
|
||||||
|
cv.Required(CONF_DATA): cv.templatable(validate_raw_data),
|
||||||
|
}, key=CONF_DATA))
|
||||||
|
def uart_write_to_code(config, action_id, template_arg, args):
|
||||||
|
var = cg.new_Pvariable(action_id, template_arg)
|
||||||
|
yield cg.register_parented(var, config[CONF_ID])
|
||||||
|
data = config[CONF_DATA]
|
||||||
|
if isinstance(data, binary_type):
|
||||||
|
data = [char_to_byte(x) for x in data]
|
||||||
|
|
||||||
|
if cg.is_template(data):
|
||||||
|
templ = yield cg.templatable(data, args, cg.std_vector.template(cg.uint8))
|
||||||
|
cg.add(var.set_data_template(templ))
|
||||||
|
else:
|
||||||
|
cg.add(var.set_data_static(data))
|
||||||
|
yield var
|
||||||
|
|
36
esphome/components/uart/automation.h
Normal file
36
esphome/components/uart/automation.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "uart.h"
|
||||||
|
#include "esphome/core/automation.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace uart {
|
||||||
|
|
||||||
|
template<typename... Ts> class UARTWriteAction : public Action<Ts...>, public Parented<UARTComponent> {
|
||||||
|
public:
|
||||||
|
void set_data_template(std::function<std::vector<uint8_t>(Ts...)> func) {
|
||||||
|
this->data_func_ = func;
|
||||||
|
this->static_ = false;
|
||||||
|
}
|
||||||
|
void set_data_static(const std::vector<uint8_t> &data) {
|
||||||
|
this->data_static_ = data;
|
||||||
|
this->static_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void play(Ts... x) override {
|
||||||
|
if (this->static_) {
|
||||||
|
this->parent_->write_array(this->data_static_);
|
||||||
|
} else {
|
||||||
|
auto val = this->data_func_(x...);
|
||||||
|
this->parent_->write_array(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool static_{false};
|
||||||
|
std::function<std::vector<uint8_t>(Ts...)> data_func_{};
|
||||||
|
std::vector<uint8_t> data_static_{};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace uart
|
||||||
|
} // namespace esphome
|
|
@ -3,27 +3,17 @@ import esphome.config_validation as cv
|
||||||
from esphome.components import switch, uart
|
from esphome.components import switch, uart
|
||||||
from esphome.const import CONF_DATA, CONF_ID, CONF_INVERTED
|
from esphome.const import CONF_DATA, CONF_ID, CONF_INVERTED
|
||||||
from esphome.core import HexInt
|
from esphome.core import HexInt
|
||||||
from esphome.py_compat import text_type, binary_type, char_to_byte
|
from esphome.py_compat import binary_type, char_to_byte
|
||||||
from .. import uart_ns
|
from .. import uart_ns, validate_raw_data
|
||||||
|
|
||||||
DEPENDENCIES = ['uart']
|
DEPENDENCIES = ['uart']
|
||||||
|
|
||||||
UARTSwitch = uart_ns.class_('UARTSwitch', switch.Switch, uart.UARTDevice, cg.Component)
|
UARTSwitch = uart_ns.class_('UARTSwitch', switch.Switch, uart.UARTDevice, cg.Component)
|
||||||
|
|
||||||
|
|
||||||
def validate_data(value):
|
|
||||||
if isinstance(value, text_type):
|
|
||||||
return value.encode('utf-8')
|
|
||||||
if isinstance(value, str):
|
|
||||||
return value
|
|
||||||
if isinstance(value, list):
|
|
||||||
return cv.Schema([cv.hex_uint8_t])(value)
|
|
||||||
raise cv.Invalid("data must either be a string wrapped in quotes or a list of bytes")
|
|
||||||
|
|
||||||
|
|
||||||
CONFIG_SCHEMA = switch.SWITCH_SCHEMA.extend({
|
CONFIG_SCHEMA = switch.SWITCH_SCHEMA.extend({
|
||||||
cv.GenerateID(): cv.declare_id(UARTSwitch),
|
cv.GenerateID(): cv.declare_id(UARTSwitch),
|
||||||
cv.Required(CONF_DATA): validate_data,
|
cv.Required(CONF_DATA): validate_raw_data,
|
||||||
cv.Optional(CONF_INVERTED): cv.invalid("UART switches do not support inverted mode!"),
|
cv.Optional(CONF_INVERTED): cv.invalid("UART switches do not support inverted mode!"),
|
||||||
}).extend(uart.UART_DEVICE_SCHEMA).extend(cv.COMPONENT_SCHEMA)
|
}).extend(uart.UART_DEVICE_SCHEMA).extend(cv.COMPONENT_SCHEMA)
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ class UARTComponent : public Component, public Stream {
|
||||||
void write_byte(uint8_t data);
|
void write_byte(uint8_t data);
|
||||||
|
|
||||||
void write_array(const uint8_t *data, size_t len);
|
void write_array(const uint8_t *data, size_t len);
|
||||||
|
void write_array(const std::vector<uint8_t> &data) { this->write_array(&data[0], data.size()); }
|
||||||
|
|
||||||
void write_str(const char *str);
|
void write_str(const char *str);
|
||||||
|
|
||||||
|
@ -97,6 +98,7 @@ class UARTDevice : public Stream {
|
||||||
void write_byte(uint8_t data) { this->parent_->write_byte(data); }
|
void write_byte(uint8_t data) { this->parent_->write_byte(data); }
|
||||||
|
|
||||||
void write_array(const uint8_t *data, size_t len) { this->parent_->write_array(data, len); }
|
void write_array(const uint8_t *data, size_t len) { this->parent_->write_array(data, len); }
|
||||||
|
void write_array(const std::vector<uint8_t> &data) { this->parent_->write_array(data); }
|
||||||
|
|
||||||
void write_str(const char *str) { this->parent_->write_str(str); }
|
void write_str(const char *str) { this->parent_->write_str(str); }
|
||||||
|
|
||||||
|
|
|
@ -1210,13 +1210,14 @@ def validate_registry(name, registry):
|
||||||
return ensure_list(validate_registry_entry(name, registry))
|
return ensure_list(validate_registry_entry(name, registry))
|
||||||
|
|
||||||
|
|
||||||
def maybe_simple_value(*validators):
|
def maybe_simple_value(*validators, **kwargs):
|
||||||
|
key = kwargs.pop('key', CONF_VALUE)
|
||||||
validator = All(*validators)
|
validator = All(*validators)
|
||||||
|
|
||||||
def validate(value):
|
def validate(value):
|
||||||
if isinstance(value, dict) and CONF_VALUE in value:
|
if isinstance(value, dict) and key in value:
|
||||||
return validator(value)
|
return validator(value)
|
||||||
return validator({CONF_VALUE: value})
|
return validator({key: value})
|
||||||
|
|
||||||
return validate
|
return validate
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,12 @@ mqtt:
|
||||||
- light.control:
|
- light.control:
|
||||||
id: living_room_lights
|
id: living_room_lights
|
||||||
brightness: !lambda 'return id(living_room_lights).current_values.get_brightness() + 0.5;'
|
brightness: !lambda 'return id(living_room_lights).current_values.get_brightness() + 0.5;'
|
||||||
|
- uart.write:
|
||||||
|
id: uart0
|
||||||
|
data: Hello World
|
||||||
|
- uart.write: [0x00, 0x20, 0x30]
|
||||||
|
- uart.write: !lambda |-
|
||||||
|
return {};
|
||||||
|
|
||||||
i2c:
|
i2c:
|
||||||
sda: 21
|
sda: 21
|
||||||
|
@ -120,6 +126,7 @@ uart:
|
||||||
tx_pin: GPIO22
|
tx_pin: GPIO22
|
||||||
rx_pin: GPIO23
|
rx_pin: GPIO23
|
||||||
baud_rate: 115200
|
baud_rate: 115200
|
||||||
|
id: uart0
|
||||||
|
|
||||||
ota:
|
ota:
|
||||||
safe_mode: True
|
safe_mode: True
|
||||||
|
|
Loading…
Reference in a new issue