mirror of
https://github.com/esphome/esphome.git
synced 2025-02-24 20:12:30 +01:00
Add automations
This commit is contained in:
parent
19b02227a2
commit
483510e018
4 changed files with 152 additions and 11 deletions
|
@ -2,7 +2,7 @@ from esphome import automation, pins
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
from esphome.components import spi
|
from esphome.components import spi
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.const import CONF_FREQUENCY, CONF_ID
|
from esphome.const import CONF_DATA, CONF_FREQUENCY, CONF_ID
|
||||||
from esphome.core import TimePeriod
|
from esphome.core import TimePeriod
|
||||||
|
|
||||||
CODEOWNERS = ["@swoboda1337"]
|
CODEOWNERS = ["@swoboda1337"]
|
||||||
|
@ -48,7 +48,7 @@ SHAPING = {
|
||||||
"GAUSSIAN_BT_0_3": SX127xPaRamp.GAUSSIAN_BT_0_3,
|
"GAUSSIAN_BT_0_3": SX127xPaRamp.GAUSSIAN_BT_0_3,
|
||||||
"GAUSSIAN_BT_0_5": SX127xPaRamp.GAUSSIAN_BT_0_5,
|
"GAUSSIAN_BT_0_5": SX127xPaRamp.GAUSSIAN_BT_0_5,
|
||||||
"GAUSSIAN_BT_1_0": SX127xPaRamp.GAUSSIAN_BT_1_0,
|
"GAUSSIAN_BT_1_0": SX127xPaRamp.GAUSSIAN_BT_1_0,
|
||||||
"NO_SHAPING": SX127xPaRamp.NO_SHAPING,
|
"NONE": SX127xPaRamp.SHAPING_NONE,
|
||||||
}
|
}
|
||||||
|
|
||||||
RAMP = {
|
RAMP = {
|
||||||
|
@ -99,6 +99,26 @@ RX_BW = {
|
||||||
"250_0kHz": SX127xRxBw.RX_BW_250_0,
|
"250_0kHz": SX127xRxBw.RX_BW_250_0,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SendPacketAction = sx127x_ns.class_(
|
||||||
|
"SendPacketAction", automation.Action, cg.Parented.template(SX127x)
|
||||||
|
)
|
||||||
|
SetModeTxAction = sx127x_ns.class_("SetModeTxAction", automation.Action)
|
||||||
|
SetModeRxAction = sx127x_ns.class_("SetModeRxAction", automation.Action)
|
||||||
|
SetModeStandbyAction = sx127x_ns.class_("SetModeStandbyAction", automation.Action)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_raw_data(value):
|
||||||
|
if isinstance(value, str):
|
||||||
|
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 = cv.Schema(
|
CONFIG_SCHEMA = cv.Schema(
|
||||||
{
|
{
|
||||||
cv.GenerateID(): cv.declare_id(SX127x),
|
cv.GenerateID(): cv.declare_id(SX127x),
|
||||||
|
@ -108,7 +128,7 @@ CONFIG_SCHEMA = cv.Schema(
|
||||||
cv.Required(CONF_NSS_PIN): pins.internal_gpio_output_pin_schema,
|
cv.Required(CONF_NSS_PIN): pins.internal_gpio_output_pin_schema,
|
||||||
cv.Required(CONF_FREQUENCY): cv.int_range(min=137000000, max=1020000000),
|
cv.Required(CONF_FREQUENCY): cv.int_range(min=137000000, max=1020000000),
|
||||||
cv.Required(CONF_MODULATION): cv.enum(MOD),
|
cv.Required(CONF_MODULATION): cv.enum(MOD),
|
||||||
cv.Optional(CONF_SHAPING, default="NO_SHAPING"): cv.enum(SHAPING),
|
cv.Optional(CONF_SHAPING, default="NONE"): cv.enum(SHAPING),
|
||||||
cv.Optional(CONF_BITRATE, default=0): cv.int_range(min=0, max=300000),
|
cv.Optional(CONF_BITRATE, default=0): cv.int_range(min=0, max=300000),
|
||||||
cv.Optional(CONF_FSK_FDEV, default=5000): cv.int_range(min=0, max=100000),
|
cv.Optional(CONF_FSK_FDEV, default=5000): cv.int_range(min=0, max=100000),
|
||||||
cv.Optional(CONF_FSK_RAMP, default="40us"): cv.enum(RAMP),
|
cv.Optional(CONF_FSK_RAMP, default="40us"): cv.enum(RAMP),
|
||||||
|
@ -170,3 +190,51 @@ async def to_code(config):
|
||||||
cg.add(var.set_pa_power(config[CONF_PA_POWER]))
|
cg.add(var.set_pa_power(config[CONF_PA_POWER]))
|
||||||
cg.add(var.set_fsk_fdev(config[CONF_FSK_FDEV]))
|
cg.add(var.set_fsk_fdev(config[CONF_FSK_FDEV]))
|
||||||
cg.add(var.set_fsk_ramp(config[CONF_FSK_RAMP]))
|
cg.add(var.set_fsk_ramp(config[CONF_FSK_RAMP]))
|
||||||
|
|
||||||
|
|
||||||
|
SET_MODE_ACTION_SCHEMA = automation.maybe_simple_id(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.use_id(SX127x),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@automation.register_action(
|
||||||
|
"sx127x.set_mode_tx", SetModeTxAction, SET_MODE_ACTION_SCHEMA
|
||||||
|
)
|
||||||
|
@automation.register_action(
|
||||||
|
"sx127x.set_mode_rx", SetModeRxAction, SET_MODE_ACTION_SCHEMA
|
||||||
|
)
|
||||||
|
@automation.register_action(
|
||||||
|
"sx127x.set_mode_standby", SetModeStandbyAction, SET_MODE_ACTION_SCHEMA
|
||||||
|
)
|
||||||
|
async def set_mode_action_to_code(config, action_id, template_arg, args):
|
||||||
|
paren = await cg.get_variable(config[CONF_ID])
|
||||||
|
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||||
|
return var
|
||||||
|
|
||||||
|
|
||||||
|
SEND_PACKET_ACTION_SCHEMA = cv.maybe_simple_value(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.use_id(SX127x),
|
||||||
|
cv.Required(CONF_DATA): cv.templatable(validate_raw_data),
|
||||||
|
},
|
||||||
|
key=CONF_DATA,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@automation.register_action(
|
||||||
|
"sx127x.send_packet", SendPacketAction, SEND_PACKET_ACTION_SCHEMA
|
||||||
|
)
|
||||||
|
async def send_packet_action_to_code(config, action_id, template_arg, args):
|
||||||
|
var = cg.new_Pvariable(action_id, template_arg)
|
||||||
|
await cg.register_parented(var, config[CONF_ID])
|
||||||
|
data = config[CONF_DATA]
|
||||||
|
if isinstance(data, bytes):
|
||||||
|
data = list(data)
|
||||||
|
if cg.is_template(data):
|
||||||
|
templ = await 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))
|
||||||
|
return var
|
||||||
|
|
66
esphome/components/sx127x/automation.h
Executable file
66
esphome/components/sx127x/automation.h
Executable file
|
@ -0,0 +1,66 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/core/automation.h"
|
||||||
|
#include "esphome/components/sx127x/sx127x.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace sx127x {
|
||||||
|
|
||||||
|
template<typename... Ts> class SendPacketAction : public Action<Ts...>, public Parented<SX127x> {
|
||||||
|
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_->transmit_packet(this->data_static_);
|
||||||
|
} else {
|
||||||
|
this->parent_->transmit_packet(this->data_func_(x...));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool static_{false};
|
||||||
|
std::function<std::vector<uint8_t>(Ts...)> data_func_{};
|
||||||
|
std::vector<uint8_t> data_static_{};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename... Ts> class SetModeTxAction : public Action<Ts...> {
|
||||||
|
public:
|
||||||
|
SetModeTxAction(SX127x *sx127x) : sx127x_(sx127x) {}
|
||||||
|
|
||||||
|
void play(Ts... x) override { this->sx127x_->set_mode_tx(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SX127x *sx127x_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename... Ts> class SetModeRxAction : public Action<Ts...> {
|
||||||
|
public:
|
||||||
|
SetModeRxAction(SX127x *sx127x) : sx127x_(sx127x) {}
|
||||||
|
|
||||||
|
void play(Ts... x) override { this->sx127x_->set_mode_rx(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SX127x *sx127x_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename... Ts> class SetModeStandbyAction : public Action<Ts...> {
|
||||||
|
public:
|
||||||
|
SetModeStandbyAction(SX127x *sx127x) : sx127x_(sx127x) {}
|
||||||
|
|
||||||
|
void play(Ts... x) override { this->sx127x_->set_mode_standby(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SX127x *sx127x_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace sx127x
|
||||||
|
} // namespace esphome
|
|
@ -8,7 +8,7 @@ namespace sx127x {
|
||||||
static const char *const TAG = "sx127x";
|
static const char *const TAG = "sx127x";
|
||||||
|
|
||||||
void IRAM_ATTR HOT SX127xStore::gpio_intr(SX127xStore *arg) {
|
void IRAM_ATTR HOT SX127xStore::gpio_intr(SX127xStore *arg) {
|
||||||
if (arg->dio2_toggle) {
|
if (arg->dio2_set && arg->dio2_toggle) {
|
||||||
arg->dio2_pin.pin_mode(gpio::FLAG_INPUT);
|
arg->dio2_pin.pin_mode(gpio::FLAG_INPUT);
|
||||||
}
|
}
|
||||||
arg->dio0_micros = micros();
|
arg->dio0_micros = micros();
|
||||||
|
@ -73,7 +73,7 @@ void SX127x::setup() {
|
||||||
this->dio2_pin_->setup();
|
this->dio2_pin_->setup();
|
||||||
this->dio2_pin_->pin_mode(gpio::FLAG_OPEN_DRAIN);
|
this->dio2_pin_->pin_mode(gpio::FLAG_OPEN_DRAIN);
|
||||||
this->store_.dio2_pin = this->dio2_pin_->to_isr();
|
this->store_.dio2_pin = this->dio2_pin_->to_isr();
|
||||||
this->store_.dio2_toggle = true;
|
this->store_.dio2_set = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// start spi
|
// start spi
|
||||||
|
@ -202,6 +202,7 @@ void SX127x::configure() {
|
||||||
|
|
||||||
// clear irq flag
|
// clear irq flag
|
||||||
this->store_.dio0_irq = false;
|
this->store_.dio0_irq = false;
|
||||||
|
this->store_.dio2_toggle = (this->rx_duration_ > 0 && this->payload_length_ == 0);
|
||||||
|
|
||||||
// enable standby mode
|
// enable standby mode
|
||||||
this->set_mode_standby();
|
this->set_mode_standby();
|
||||||
|
@ -260,7 +261,11 @@ void SX127x::set_mode_rx() {
|
||||||
if (this->dio2_pin_) {
|
if (this->dio2_pin_) {
|
||||||
this->write_register_(REG_OP_MODE, this->modulation_ | MODE_STDBY);
|
this->write_register_(REG_OP_MODE, this->modulation_ | MODE_STDBY);
|
||||||
delay(1);
|
delay(1);
|
||||||
this->dio2_pin_->pin_mode(this->modulation_ == MOD_OOK ? gpio::FLAG_INPUT : gpio::FLAG_OPEN_DRAIN);
|
if (this->rx_duration_ > 0 && this->payload_length_ == 0) {
|
||||||
|
this->dio2_pin_->pin_mode(gpio::FLAG_OPEN_DRAIN);
|
||||||
|
} else {
|
||||||
|
this->dio2_pin_->pin_mode(gpio::FLAG_INPUT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this->write_register_(REG_OP_MODE, this->modulation_ | MODE_RX_FS);
|
this->write_register_(REG_OP_MODE, this->modulation_ | MODE_RX_FS);
|
||||||
delay(1);
|
delay(1);
|
||||||
|
@ -303,11 +308,11 @@ void SX127x::dump_config() {
|
||||||
ESP_LOGCONFIG(TAG, " Sync Value: 0x%s", format_hex(this->sync_value_).c_str());
|
ESP_LOGCONFIG(TAG, " Sync Value: 0x%s", format_hex(this->sync_value_).c_str());
|
||||||
}
|
}
|
||||||
if (this->modulation_ == MOD_FSK) {
|
if (this->modulation_ == MOD_FSK) {
|
||||||
static const char *shaping_lut[4] = {"NO_SHAPING", "GAUSSIAN_BT_1_0", "GAUSSIAN_BT_0_5", "GAUSSIAN_BT_0_3"};
|
static const char *shaping_lut[4] = {"NONE", "GAUSSIAN_BT_1_0", "GAUSSIAN_BT_0_5", "GAUSSIAN_BT_0_3"};
|
||||||
ESP_LOGCONFIG(TAG, " Shaping: %s", shaping_lut[this->shaping_ >> 5]);
|
ESP_LOGCONFIG(TAG, " Shaping: %s", shaping_lut[this->shaping_ >> SHAPING_SHIFT]);
|
||||||
} else {
|
} else {
|
||||||
static const char *shaping_lut[4] = {"NO_SHAPING", "CUTOFF_BR_X_1", "CUTOFF_BR_X_2", "ERROR"};
|
static const char *shaping_lut[4] = {"NONE", "CUTOFF_BR_X_1", "CUTOFF_BR_X_2", "ERROR"};
|
||||||
ESP_LOGCONFIG(TAG, " Shaping: %s", shaping_lut[this->shaping_ >> 5]);
|
ESP_LOGCONFIG(TAG, " Shaping: %s", shaping_lut[this->shaping_ >> SHAPING_SHIFT]);
|
||||||
}
|
}
|
||||||
ESP_LOGCONFIG(TAG, " PA Pin: %s", this->pa_pin_ == PA_PIN_BOOST ? "BOOST" : "RFO");
|
ESP_LOGCONFIG(TAG, " PA Pin: %s", this->pa_pin_ == PA_PIN_BOOST ? "BOOST" : "RFO");
|
||||||
ESP_LOGCONFIG(TAG, " PA Power: %" PRIu32 " dBm", this->pa_power_);
|
ESP_LOGCONFIG(TAG, " PA Power: %" PRIu32 " dBm", this->pa_power_);
|
||||||
|
|
|
@ -183,7 +183,8 @@ enum SX127xPaRamp : uint8_t {
|
||||||
GAUSSIAN_BT_0_3 = 0x60,
|
GAUSSIAN_BT_0_3 = 0x60,
|
||||||
GAUSSIAN_BT_0_5 = 0x40,
|
GAUSSIAN_BT_0_5 = 0x40,
|
||||||
GAUSSIAN_BT_1_0 = 0x20,
|
GAUSSIAN_BT_1_0 = 0x20,
|
||||||
NO_SHAPING = 0x00,
|
SHAPING_NONE = 0x00,
|
||||||
|
SHAPING_SHIFT = 0x05,
|
||||||
PA_RAMP_10 = 0x0F,
|
PA_RAMP_10 = 0x0F,
|
||||||
PA_RAMP_12 = 0x0E,
|
PA_RAMP_12 = 0x0E,
|
||||||
PA_RAMP_15 = 0x0D,
|
PA_RAMP_15 = 0x0D,
|
||||||
|
@ -206,6 +207,7 @@ struct SX127xStore {
|
||||||
static void gpio_intr(SX127xStore *arg);
|
static void gpio_intr(SX127xStore *arg);
|
||||||
volatile uint32_t dio0_micros{0};
|
volatile uint32_t dio0_micros{0};
|
||||||
volatile bool dio0_irq{false};
|
volatile bool dio0_irq{false};
|
||||||
|
volatile bool dio2_set{false};
|
||||||
volatile bool dio2_toggle{false};
|
volatile bool dio2_toggle{false};
|
||||||
ISRInternalGPIOPin dio2_pin;
|
ISRInternalGPIOPin dio2_pin;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue