diff --git a/esphome/components/ebyte_lora_e220/__init__.py b/esphome/components/lora/__init__.py similarity index 82% rename from esphome/components/ebyte_lora_e220/__init__.py rename to esphome/components/lora/__init__.py index 59948e8c5e..b193a49e60 100644 --- a/esphome/components/ebyte_lora_e220/__init__.py +++ b/esphome/components/lora/__init__.py @@ -4,10 +4,8 @@ from esphome import pins from esphome.components import sensor, text_sensor, uart from esphome.const import * -ebyte_lora_e220_ns = cg.esphome_ns.namespace("ebyte_lora_e220") -EbyteLoraE220 = ebyte_lora_e220_ns.class_( - "EbyteLoraE220", cg.Component, uart.UARTDevice -) +lora_ns = cg.esphome_ns.namespace("lora") +Lora = lora_ns.class_("Lora", cg.Component, uart.UARTDevice) DEPENDENCIES = ["uart"] AUTO_LOAD = ["uart", "sensor", "text_sensor"] @@ -31,7 +29,7 @@ CONFIG_SCHEMA = ( unit_of_measurement=UNIT_DEGREES, accuracy_decimals=6, ), - cv.GenerateID(): cv.declare_id(EbyteLoraE220), + 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, # for communication set the mode @@ -76,12 +74,3 @@ 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)) - - # if you are sending gps data over lora - if CONF_LATITUDE in config: - sens = await sensor.new_sensor(config[CONF_LATITUDE]) - cg.add(var.set_latitude_sensor(sens)) - - if CONF_LONGITUDE in config: - sens = await sensor.new_sensor(config[CONF_LONGITUDE]) - cg.add(var.set_longitude_sensor(sens)) diff --git a/esphome/components/ebyte_lora_e220/ebyte_lora_e220.cpp b/esphome/components/lora/lora.cpp similarity index 86% rename from esphome/components/ebyte_lora_e220/ebyte_lora_e220.cpp rename to esphome/components/lora/lora.cpp index dbbfe26976..26eb33f491 100644 --- a/esphome/components/ebyte_lora_e220/ebyte_lora_e220.cpp +++ b/esphome/components/lora/lora.cpp @@ -1,14 +1,8 @@ -#include "ebyte_lora_e220.h" +#include "lora.h" namespace esphome { -namespace ebyte_lora_e220 { -void EbyteLoraE220::update() { - if (this->latitude_sensor_ != nullptr) - this->latitude_sensor_->publish_state(this->latitude_); - - if (this->longitude_sensor_ != nullptr) - this->longitude_sensor_->publish_state(this->longitude_); - +namespace lora { +void Lora::update() { if (this->rssi_sensor != nullptr) this->rssi_sensor->publish_state(this->rssi_); @@ -16,7 +10,7 @@ void EbyteLoraE220::update() { if (this->message_text_sensor != nullptr) this->message_text_sensor->publish_state(this->raw_message_); } -void EbyteLoraE220::setup() { +void Lora::setup() { this->pin_aux->setup(); this->pin_m0->setup(); this->pin_m1->setup(); @@ -41,7 +35,7 @@ void EbyteLoraE220::setup() { else ESP_LOGD(TAG, "Something went wrong"); } -bool EbyteLoraE220::setMode(MODE_TYPE mode) { +bool Lora::setMode(MODE_TYPE mode) { // data sheet claims module needs some extra time after mode setting (2ms) // most of my projects uses 10 ms, but 40ms is safer @@ -95,7 +89,7 @@ bool EbyteLoraE220::setMode(MODE_TYPE mode) { return false; } } -bool EbyteLoraE220::waitCompleteResponse(unsigned long timeout, unsigned int waitNoAux) { +bool Lora::waitCompleteResponse(unsigned long timeout, unsigned int waitNoAux) { unsigned long t = millis(); // make darn sure millis() is not about to reach max data type limit and start over @@ -124,13 +118,17 @@ bool EbyteLoraE220::waitCompleteResponse(unsigned long timeout, unsigned int wai delay(20); return true; } -void EbyteLoraE220::dump_config() { +void Lora::dump_config() { ESP_LOGCONFIG(TAG, "Ebyte Lora E220"); - LOG_PIN(" Aux pin: ", this->pin_aux); - LOG_PIN(" M0 Pin: ", this->pin_m0); - LOG_PIN(" M1 Pin: ", this->pin_m1); + LOG_PIN("Aux pin:", this->pin_aux); + LOG_PIN("M0 Pin:", this->pin_m0); + LOG_PIN("M1 Pin:", this->pin_m1); }; -void EbyteLoraE220::loop() { + +bool Lora::SendMessage(){ +MAX_SIZE_TX_PACKET +} +void Lora::loop() { if (!available()) { return; } @@ -142,7 +140,6 @@ void EbyteLoraE220::loop() { buffer += (char) c; } } - ESP_LOGD(TAG, "%s", buffer); // set the rssi rssi_ = atoi(buffer.substr(buffer.length() - 1, 1).c_str()); // set the raw message @@ -162,5 +159,5 @@ void EbyteLoraE220::loop() { } } -} // namespace ebyte_lora_e220 +} // namespace lora } // namespace esphome diff --git a/esphome/components/ebyte_lora_e220/ebyte_lora_e220.h b/esphome/components/lora/lora.h similarity index 91% rename from esphome/components/ebyte_lora_e220/ebyte_lora_e220.h rename to esphome/components/lora/lora.h index 3c01f0b7c0..8c7c7d4d76 100644 --- a/esphome/components/ebyte_lora_e220/ebyte_lora_e220.h +++ b/esphome/components/lora/lora.h @@ -9,10 +9,10 @@ #include "esphome/core/log.h" namespace esphome { -namespace ebyte_lora_e220 { - -static const char *const TAG = "ebyte_lora_e220"; +namespace lora { +static const char *const TAG = "lora"; +#define MAX_SIZE_TX_PACKET 200 // the mode the receiver is in enum MODE_TYPE { MODE_0_NORMAL = 0, @@ -26,7 +26,7 @@ enum MODE_TYPE { MODE_3_SLEEP = 3, MODE_INIT = 0xFF }; -class EbyteLoraE220 : public PollingComponent, public uart::UARTDevice { +class Lora : public PollingComponent, public uart::UARTDevice { public: void setup() override; void update() override; @@ -62,5 +62,5 @@ class EbyteLoraE220 : public PollingComponent, public uart::UARTDevice { GPIOPin *pin_m1{nullptr}; }; -} // namespace ebyte_lora_e220 +} // namespace lora } // namespace esphome diff --git a/esphome/components/lora/switch/__init__.py b/esphome/components/lora/switch/__init__.py new file mode 100644 index 0000000000..8853a61ae3 --- /dev/null +++ b/esphome/components/lora/switch/__init__.py @@ -0,0 +1,58 @@ +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 uart_ns, validate_raw_data + +DEPENDENCIES = ["uart"] + +UARTSwitch = uart_ns.class_("UARTSwitch", switch.Switch, uart.UARTDevice, cg.Component) + +CONF_TURN_OFF = "turn_off" +CONF_TURN_ON = "turn_on" + +CONFIG_SCHEMA = ( + switch.switch_schema(UARTSwitch, 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])) diff --git a/esphome/components/lora/switch/lora_switch.cpp b/esphome/components/lora/switch/lora_switch.cpp new file mode 100644 index 0000000000..a92eb43567 --- /dev/null +++ b/esphome/components/lora/switch/lora_switch.cpp @@ -0,0 +1,61 @@ +#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 diff --git a/esphome/components/lora/switch/lora_switch.h b/esphome/components/lora/switch/lora_switch.h new file mode 100644 index 0000000000..fc7250b353 --- /dev/null +++ b/esphome/components/lora/switch/lora_switch.h @@ -0,0 +1,35 @@ +#pragma once + +#include "esphome/core/component.h" +#include "esphome/components/uart/uart.h" +#include "esphome/components/switch/switch.h" + +#include +#include + +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 &data) { this->data_on_ = data; } + void set_data_off(const std::vector &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 data_on_; + std::vector data_off_; + bool single_state_{false}; + uint32_t send_every_; + uint32_t last_transmission_; +}; + +} // namespace lora +} // namespace esphome