mirror of
https://github.com/esphome/esphome.git
synced 2024-11-27 09:18:00 +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
|
||||
from esphome.components import spi
|
||||
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
|
||||
|
||||
CODEOWNERS = ["@swoboda1337"]
|
||||
|
@ -48,7 +48,7 @@ SHAPING = {
|
|||
"GAUSSIAN_BT_0_3": SX127xPaRamp.GAUSSIAN_BT_0_3,
|
||||
"GAUSSIAN_BT_0_5": SX127xPaRamp.GAUSSIAN_BT_0_5,
|
||||
"GAUSSIAN_BT_1_0": SX127xPaRamp.GAUSSIAN_BT_1_0,
|
||||
"NO_SHAPING": SX127xPaRamp.NO_SHAPING,
|
||||
"NONE": SX127xPaRamp.SHAPING_NONE,
|
||||
}
|
||||
|
||||
RAMP = {
|
||||
|
@ -99,6 +99,26 @@ RX_BW = {
|
|||
"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(
|
||||
{
|
||||
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_FREQUENCY): cv.int_range(min=137000000, max=1020000000),
|
||||
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_FSK_FDEV, default=5000): cv.int_range(min=0, max=100000),
|
||||
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_fsk_fdev(config[CONF_FSK_FDEV]))
|
||||
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";
|
||||
|
||||
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->dio0_micros = micros();
|
||||
|
@ -73,7 +73,7 @@ void SX127x::setup() {
|
|||
this->dio2_pin_->setup();
|
||||
this->dio2_pin_->pin_mode(gpio::FLAG_OPEN_DRAIN);
|
||||
this->store_.dio2_pin = this->dio2_pin_->to_isr();
|
||||
this->store_.dio2_toggle = true;
|
||||
this->store_.dio2_set = true;
|
||||
}
|
||||
|
||||
// start spi
|
||||
|
@ -202,6 +202,7 @@ void SX127x::configure() {
|
|||
|
||||
// clear irq flag
|
||||
this->store_.dio0_irq = false;
|
||||
this->store_.dio2_toggle = (this->rx_duration_ > 0 && this->payload_length_ == 0);
|
||||
|
||||
// enable standby mode
|
||||
this->set_mode_standby();
|
||||
|
@ -260,7 +261,11 @@ void SX127x::set_mode_rx() {
|
|||
if (this->dio2_pin_) {
|
||||
this->write_register_(REG_OP_MODE, this->modulation_ | MODE_STDBY);
|
||||
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);
|
||||
delay(1);
|
||||
|
@ -303,11 +308,11 @@ void SX127x::dump_config() {
|
|||
ESP_LOGCONFIG(TAG, " Sync Value: 0x%s", format_hex(this->sync_value_).c_str());
|
||||
}
|
||||
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"};
|
||||
ESP_LOGCONFIG(TAG, " Shaping: %s", shaping_lut[this->shaping_ >> 5]);
|
||||
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_ >> SHAPING_SHIFT]);
|
||||
} else {
|
||||
static const char *shaping_lut[4] = {"NO_SHAPING", "CUTOFF_BR_X_1", "CUTOFF_BR_X_2", "ERROR"};
|
||||
ESP_LOGCONFIG(TAG, " Shaping: %s", shaping_lut[this->shaping_ >> 5]);
|
||||
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_ >> SHAPING_SHIFT]);
|
||||
}
|
||||
ESP_LOGCONFIG(TAG, " PA Pin: %s", this->pa_pin_ == PA_PIN_BOOST ? "BOOST" : "RFO");
|
||||
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_5 = 0x40,
|
||||
GAUSSIAN_BT_1_0 = 0x20,
|
||||
NO_SHAPING = 0x00,
|
||||
SHAPING_NONE = 0x00,
|
||||
SHAPING_SHIFT = 0x05,
|
||||
PA_RAMP_10 = 0x0F,
|
||||
PA_RAMP_12 = 0x0E,
|
||||
PA_RAMP_15 = 0x0D,
|
||||
|
@ -206,6 +207,7 @@ struct SX127xStore {
|
|||
static void gpio_intr(SX127xStore *arg);
|
||||
volatile uint32_t dio0_micros{0};
|
||||
volatile bool dio0_irq{false};
|
||||
volatile bool dio2_set{false};
|
||||
volatile bool dio2_toggle{false};
|
||||
ISRInternalGPIOPin dio2_pin;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue