mirror of
https://github.com/esphome/esphome.git
synced 2024-12-29 00:41:44 +01:00
Trial this
This commit is contained in:
parent
113ed8d48f
commit
4c0772a8f1
8 changed files with 105 additions and 187 deletions
|
@ -4,31 +4,21 @@ from esphome import pins
|
|||
from esphome.components import sensor, text_sensor, uart
|
||||
from esphome.const import *
|
||||
|
||||
DEPENDENCIES = ["uart"]
|
||||
MULTI_CONF = True
|
||||
|
||||
lora_ns = cg.esphome_ns.namespace("lora")
|
||||
Lora = lora_ns.class_("Lora", cg.Component, uart.UARTDevice)
|
||||
|
||||
DEPENDENCIES = ["uart"]
|
||||
AUTO_LOAD = ["uart", "sensor", "text_sensor"]
|
||||
|
||||
LoraGPIOPin = lora_ns.class_("LoraGPIOPin", cg.GPIOPin)
|
||||
CONF_PIN_AUX = "pin_aux"
|
||||
CONF_PIN_M0 = "pin_m0"
|
||||
CONF_PIN_M1 = "pin_m1"
|
||||
CONF_LORA_MESSAGE = "lora_message"
|
||||
CONF_LORA_RSSI = "lora_rssi"
|
||||
|
||||
CONF_LORA = "lora"
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
# if you send gps locations over lora, this will be able to read it
|
||||
cv.Optional(CONF_LATITUDE): sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_DEGREES,
|
||||
accuracy_decimals=6,
|
||||
),
|
||||
# if you send gps locations over lora, this will be able to read it
|
||||
cv.Optional(CONF_LONGITUDE): sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_DEGREES,
|
||||
accuracy_decimals=6,
|
||||
),
|
||||
cv.GenerateID(): cv.declare_id(Lora),
|
||||
# for communication to let us know that we can receive data
|
||||
cv.Required(CONF_PIN_AUX): pins.gpio_input_pin_schema,
|
||||
|
@ -54,6 +44,27 @@ CONFIG_SCHEMA = (
|
|||
)
|
||||
|
||||
|
||||
def validate_mode(value):
|
||||
if not (value[CONF_OUTPUT]):
|
||||
raise cv.Invalid("Mode must be output")
|
||||
if value[CONF_INPUT] and value[CONF_OUTPUT]:
|
||||
raise cv.Invalid("Mode must be output")
|
||||
return value
|
||||
|
||||
|
||||
Lora_PIN_SCHEMA = pins.gpio_base_schema(
|
||||
LoraGPIOPin,
|
||||
cv.int_range(min=0, max=17),
|
||||
modes=[CONF_OUTPUT],
|
||||
mode_validator=validate_mode,
|
||||
invertable=True,
|
||||
).extend(
|
||||
{
|
||||
cv.Required(CONF_LORA): cv.use_id(Lora),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
|
@ -74,3 +85,17 @@ async def to_code(config):
|
|||
if CONF_LORA_RSSI in config:
|
||||
sens = await sensor.new_sensor(config[CONF_LORA_RSSI])
|
||||
cg.add(var.set_rssi_sensor(sens))
|
||||
|
||||
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(CONF_LORA, Lora_PIN_SCHEMA)
|
||||
async def lora_pin_to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
parent = await cg.get_variable(config[CONF_LORA])
|
||||
|
||||
cg.add(var.set_parent(parent))
|
||||
|
||||
num = config[CONF_NUMBER]
|
||||
cg.add(var.set_pin(num))
|
||||
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||
cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE])))
|
||||
return var
|
||||
|
|
|
@ -124,7 +124,10 @@ void Lora::dump_config() {
|
|||
LOG_PIN("M0 Pin:", this->pin_m0);
|
||||
LOG_PIN("M1 Pin:", this->pin_m1);
|
||||
};
|
||||
|
||||
void Lora::digital_write(uint8_t pin, bool value) {
|
||||
std::string message = str_snprintf("%02x%02x", 12, pin, value);
|
||||
sendMessage(message);
|
||||
}
|
||||
bool Lora::sendMessage(std::string message) {
|
||||
uint8_t size = message.length();
|
||||
char messageFixed[size];
|
||||
|
|
|
@ -33,8 +33,12 @@ class Lora : public PollingComponent, public uart::UARTDevice {
|
|||
void loop() override;
|
||||
void dump_config() override;
|
||||
// local
|
||||
void set_latitude_sensor(sensor::Sensor *latitude_sensor) { latitude_sensor_ = latitude_sensor; }
|
||||
void set_longitude_sensor(sensor::Sensor *longitude_sensor) { longitude_sensor_ = longitude_sensor; }
|
||||
/// Helper function to read the value of a pin.
|
||||
bool digital_read(uint8_t pin);
|
||||
/// Helper function to write the value of a pin.
|
||||
void digital_write(uint8_t pin, bool value);
|
||||
/// Helper function to set the pin mode of a pin.
|
||||
void pin_mode(uint8_t pin, gpio::Flags flags);
|
||||
void set_message_sensor(text_sensor::TextSensor *s) { message_text_sensor = s; }
|
||||
void set_rssi_sensor(sensor::Sensor *s) { rssi_sensor = s; }
|
||||
void set_pin_aux(GPIOPin *s) { pin_aux = s; }
|
||||
|
@ -54,8 +58,6 @@ class Lora : public PollingComponent, public uart::UARTDevice {
|
|||
float latitude_ = -1;
|
||||
float longitude_ = -1;
|
||||
std::string raw_message_;
|
||||
sensor::Sensor *latitude_sensor_{nullptr};
|
||||
sensor::Sensor *longitude_sensor_{nullptr};
|
||||
text_sensor::TextSensor *message_text_sensor{nullptr};
|
||||
sensor::Sensor *rssi_sensor{nullptr};
|
||||
GPIOPin *pin_aux{nullptr};
|
||||
|
|
22
esphome/components/lora/lora_pin.cpp
Normal file
22
esphome/components/lora/lora_pin.cpp
Normal file
|
@ -0,0 +1,22 @@
|
|||
#include "lora_pin.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace lora {
|
||||
|
||||
static const char *const TAG = "lora.pin";
|
||||
void LoraGPIOPin::setup() { pin_mode(flags_); }
|
||||
void LoraGPIOPin::pin_mode(gpio::Flags flags) {
|
||||
if (flags != gpio::FLAG_OUTPUT) {
|
||||
ESP_LOGD(TAG, "Output only supported");
|
||||
}
|
||||
}
|
||||
bool LoraGPIOPin::digital_read() { return false; }
|
||||
void LoraGPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); }
|
||||
std::string LoraGPIOPin::dump_summary() const {
|
||||
char buffer[32];
|
||||
snprintf(buffer, sizeof(buffer), "%u via Lora", pin_);
|
||||
return buffer;
|
||||
}
|
||||
} // namespace lora
|
||||
} // namespace esphome
|
33
esphome/components/lora/lora_pin.h
Normal file
33
esphome/components/lora/lora_pin.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "./lora.h"
|
||||
|
||||
#include <cinttypes>
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace lora {
|
||||
|
||||
class LoraGPIOPin : public GPIOPin {
|
||||
public:
|
||||
void setup() override;
|
||||
void pin_mode(gpio::Flags flags) override;
|
||||
bool digital_read() override;
|
||||
void digital_write(bool value) override;
|
||||
std::string dump_summary() const override;
|
||||
|
||||
void set_parent(Lora *parent) { parent_ = parent; }
|
||||
void set_pin(uint8_t pin) { pin_ = pin; }
|
||||
void set_inverted(bool inverted) { inverted_ = inverted; }
|
||||
void set_flags(gpio::Flags flags) { flags_ = flags; }
|
||||
|
||||
protected:
|
||||
Lora *parent_;
|
||||
uint8_t pin_;
|
||||
bool inverted_;
|
||||
gpio::Flags flags_;
|
||||
};
|
||||
|
||||
} // namespace lora
|
||||
} // namespace esphome
|
|
@ -1,71 +0,0 @@
|
|||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import switch, uart
|
||||
from esphome.const import CONF_DATA, CONF_SEND_EVERY
|
||||
from esphome.core import HexInt
|
||||
from .. import lora_ns
|
||||
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
|
||||
DEPENDENCIES = ["uart"]
|
||||
|
||||
LoraSwitch = lora_ns.class_("LoraSwitch", switch.Switch, uart.UARTDevice, cg.Component)
|
||||
|
||||
CONF_TURN_OFF = "turn_off"
|
||||
CONF_TURN_ON = "turn_on"
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
switch.switch_schema(LoraSwitch, block_inverted=True)
|
||||
.extend(
|
||||
{
|
||||
cv.Required(CONF_DATA): cv.Any(
|
||||
validate_raw_data,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Optional(CONF_TURN_OFF): validate_raw_data,
|
||||
cv.Optional(CONF_TURN_ON): validate_raw_data,
|
||||
}
|
||||
),
|
||||
),
|
||||
cv.Optional(CONF_SEND_EVERY): cv.positive_time_period_milliseconds,
|
||||
},
|
||||
)
|
||||
.extend(uart.UART_DEVICE_SCHEMA)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = await switch.new_switch(config)
|
||||
await cg.register_component(var, config)
|
||||
await uart.register_uart_device(var, config)
|
||||
|
||||
data = config[CONF_DATA]
|
||||
if isinstance(data, dict):
|
||||
if data_on := data.get(CONF_TURN_ON):
|
||||
if isinstance(data_on, bytes):
|
||||
data_on = [HexInt(x) for x in data_on]
|
||||
cg.add(var.set_data_on(data_on))
|
||||
if data_off := data.get(CONF_TURN_OFF):
|
||||
if isinstance(data_off, bytes):
|
||||
data_off = [HexInt(x) for x in data_off]
|
||||
cg.add(var.set_data_off(data_off))
|
||||
else:
|
||||
data = config[CONF_DATA]
|
||||
if isinstance(data, bytes):
|
||||
data = [HexInt(x) for x in data]
|
||||
cg.add(var.set_data_on(data))
|
||||
cg.add(var.set_single_state(True))
|
||||
if CONF_SEND_EVERY in config:
|
||||
cg.add(var.set_send_every(config[CONF_SEND_EVERY]))
|
|
@ -1,61 +0,0 @@
|
|||
#include "lora_switch.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace lora {
|
||||
|
||||
static const char *const TAG = "lora.switch";
|
||||
|
||||
void LoraSwitch::loop() {
|
||||
if (this->send_every_) {
|
||||
const uint32_t now = millis();
|
||||
if (now - this->last_transmission_ > this->send_every_) {
|
||||
this->write_command_(this->state);
|
||||
this->last_transmission_ = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LoraSwitch::write_command_(bool state) {
|
||||
if (state && !this->data_on_.empty()) {
|
||||
ESP_LOGD(TAG, "'%s': Sending on data...", this->get_name().c_str());
|
||||
this->write_array(this->data_on_.data(), this->data_on_.size());
|
||||
}
|
||||
if (!state && !this->data_off_.empty()) {
|
||||
ESP_LOGD(TAG, "'%s': Sending off data...", this->get_name().c_str());
|
||||
this->write_array(this->data_off_.data(), this->data_off_.size());
|
||||
}
|
||||
}
|
||||
|
||||
void LoraSwitch::write_state(bool state) {
|
||||
if (!this->single_state_) {
|
||||
this->publish_state(state);
|
||||
this->write_command_(state);
|
||||
this->last_transmission_ = millis();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!state) {
|
||||
this->publish_state(false);
|
||||
return;
|
||||
}
|
||||
|
||||
this->publish_state(true);
|
||||
this->write_command_(true);
|
||||
|
||||
if (this->send_every_ == 0) {
|
||||
this->publish_state(false);
|
||||
} else {
|
||||
this->last_transmission_ = millis();
|
||||
}
|
||||
}
|
||||
|
||||
void LoraSwitch::dump_config() {
|
||||
LOG_SWITCH("", "UART Switch", this);
|
||||
if (this->send_every_) {
|
||||
ESP_LOGCONFIG(TAG, " Send Every: %" PRIu32, this->send_every_);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace lora
|
||||
} // namespace esphome
|
|
@ -1,35 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/uart/uart.h"
|
||||
#include "esphome/components/switch/switch.h"
|
||||
|
||||
#include <cinttypes>
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace lora {
|
||||
|
||||
class LoraSwitch : public switch_::Switch, public uart::UARTDevice, public Component {
|
||||
public:
|
||||
void loop() override;
|
||||
|
||||
void set_data_on(const std::vector<uint8_t> &data) { this->data_on_ = data; }
|
||||
void set_data_off(const std::vector<uint8_t> &data) { this->data_off_ = data; }
|
||||
void set_send_every(uint32_t send_every) { this->send_every_ = send_every; }
|
||||
void set_single_state(bool single) { this->single_state_ = single; }
|
||||
|
||||
void dump_config() override;
|
||||
|
||||
protected:
|
||||
void write_command_(bool state);
|
||||
void write_state(bool state) override;
|
||||
std::vector<uint8_t> data_on_;
|
||||
std::vector<uint8_t> data_off_;
|
||||
bool single_state_{false};
|
||||
uint32_t send_every_;
|
||||
uint32_t last_transmission_;
|
||||
};
|
||||
|
||||
} // namespace lora
|
||||
} // namespace esphome
|
Loading…
Reference in a new issue