mirror of
https://github.com/esphome/esphome.git
synced 2024-11-23 15:38:11 +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.config_validation as cv
|
||||
from esphome import pins
|
||||
from esphome.const import CONF_BAUD_RATE, CONF_ID, CONF_RX_PIN, CONF_TX_PIN, CONF_UART_ID
|
||||
from esphome import pins, automation
|
||||
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.py_compat import text_type, binary_type, char_to_byte
|
||||
|
||||
uart_ns = cg.esphome_ns.namespace('uart')
|
||||
UARTComponent = uart_ns.class_('UARTComponent', cg.Component)
|
||||
UARTDevice = uart_ns.class_('UARTDevice')
|
||||
UARTWriteAction = uart_ns.class_('UARTWriteAction', automation.Action)
|
||||
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):
|
||||
value = pins.input_pin(value)
|
||||
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])
|
||||
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.const import CONF_DATA, CONF_ID, CONF_INVERTED
|
||||
from esphome.core import HexInt
|
||||
from esphome.py_compat import text_type, binary_type, char_to_byte
|
||||
from .. import uart_ns
|
||||
from esphome.py_compat import binary_type, char_to_byte
|
||||
from .. import uart_ns, validate_raw_data
|
||||
|
||||
DEPENDENCIES = ['uart']
|
||||
|
||||
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({
|
||||
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!"),
|
||||
}).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_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);
|
||||
|
||||
|
@ -97,6 +98,7 @@ class UARTDevice : public Stream {
|
|||
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 std::vector<uint8_t> &data) { this->parent_->write_array(data); }
|
||||
|
||||
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))
|
||||
|
||||
|
||||
def maybe_simple_value(*validators):
|
||||
def maybe_simple_value(*validators, **kwargs):
|
||||
key = kwargs.pop('key', CONF_VALUE)
|
||||
validator = All(*validators)
|
||||
|
||||
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({CONF_VALUE: value})
|
||||
return validator({key: value})
|
||||
|
||||
return validate
|
||||
|
||||
|
|
|
@ -103,6 +103,12 @@ mqtt:
|
|||
- light.control:
|
||||
id: living_room_lights
|
||||
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:
|
||||
sda: 21
|
||||
|
@ -120,6 +126,7 @@ uart:
|
|||
tx_pin: GPIO22
|
||||
rx_pin: GPIO23
|
||||
baud_rate: 115200
|
||||
id: uart0
|
||||
|
||||
ota:
|
||||
safe_mode: True
|
||||
|
|
Loading…
Reference in a new issue