First step

This commit is contained in:
Daniël Koek 2024-02-20 14:51:55 +00:00
parent 746f17aea6
commit 8ded4b02f7
6 changed files with 178 additions and 38 deletions

View file

@ -4,10 +4,8 @@ from esphome import pins
from esphome.components import sensor, text_sensor, uart from esphome.components import sensor, text_sensor, uart
from esphome.const import * from esphome.const import *
ebyte_lora_e220_ns = cg.esphome_ns.namespace("ebyte_lora_e220") lora_ns = cg.esphome_ns.namespace("lora")
EbyteLoraE220 = ebyte_lora_e220_ns.class_( Lora = lora_ns.class_("Lora", cg.Component, uart.UARTDevice)
"EbyteLoraE220", cg.Component, uart.UARTDevice
)
DEPENDENCIES = ["uart"] DEPENDENCIES = ["uart"]
AUTO_LOAD = ["uart", "sensor", "text_sensor"] AUTO_LOAD = ["uart", "sensor", "text_sensor"]
@ -31,7 +29,7 @@ CONFIG_SCHEMA = (
unit_of_measurement=UNIT_DEGREES, unit_of_measurement=UNIT_DEGREES,
accuracy_decimals=6, 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 # for communication to let us know that we can receive data
cv.Required(CONF_PIN_AUX): pins.gpio_input_pin_schema, cv.Required(CONF_PIN_AUX): pins.gpio_input_pin_schema,
# for communication set the mode # for communication set the mode
@ -76,12 +74,3 @@ async def to_code(config):
if CONF_LORA_RSSI in config: if CONF_LORA_RSSI in config:
sens = await sensor.new_sensor(config[CONF_LORA_RSSI]) sens = await sensor.new_sensor(config[CONF_LORA_RSSI])
cg.add(var.set_rssi_sensor(sens)) 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))

View file

@ -1,14 +1,8 @@
#include "ebyte_lora_e220.h" #include "lora.h"
namespace esphome { namespace esphome {
namespace ebyte_lora_e220 { namespace lora {
void EbyteLoraE220::update() { void Lora::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_);
if (this->rssi_sensor != nullptr) if (this->rssi_sensor != nullptr)
this->rssi_sensor->publish_state(this->rssi_); this->rssi_sensor->publish_state(this->rssi_);
@ -16,7 +10,7 @@ void EbyteLoraE220::update() {
if (this->message_text_sensor != nullptr) if (this->message_text_sensor != nullptr)
this->message_text_sensor->publish_state(this->raw_message_); this->message_text_sensor->publish_state(this->raw_message_);
} }
void EbyteLoraE220::setup() { void Lora::setup() {
this->pin_aux->setup(); this->pin_aux->setup();
this->pin_m0->setup(); this->pin_m0->setup();
this->pin_m1->setup(); this->pin_m1->setup();
@ -41,7 +35,7 @@ void EbyteLoraE220::setup() {
else else
ESP_LOGD(TAG, "Something went wrong"); 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) // data sheet claims module needs some extra time after mode setting (2ms)
// most of my projects uses 10 ms, but 40ms is safer // most of my projects uses 10 ms, but 40ms is safer
@ -95,7 +89,7 @@ bool EbyteLoraE220::setMode(MODE_TYPE mode) {
return false; return false;
} }
} }
bool EbyteLoraE220::waitCompleteResponse(unsigned long timeout, unsigned int waitNoAux) { bool Lora::waitCompleteResponse(unsigned long timeout, unsigned int waitNoAux) {
unsigned long t = millis(); unsigned long t = millis();
// make darn sure millis() is not about to reach max data type limit and start over // 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); delay(20);
return true; return true;
} }
void EbyteLoraE220::dump_config() { void Lora::dump_config() {
ESP_LOGCONFIG(TAG, "Ebyte Lora E220"); ESP_LOGCONFIG(TAG, "Ebyte Lora E220");
LOG_PIN("Aux pin:", this->pin_aux); LOG_PIN("Aux pin:", this->pin_aux);
LOG_PIN("M0 Pin:", this->pin_m0); LOG_PIN("M0 Pin:", this->pin_m0);
LOG_PIN("M1 Pin:", this->pin_m1); LOG_PIN("M1 Pin:", this->pin_m1);
}; };
void EbyteLoraE220::loop() {
bool Lora::SendMessage(){
MAX_SIZE_TX_PACKET
}
void Lora::loop() {
if (!available()) { if (!available()) {
return; return;
} }
@ -142,7 +140,6 @@ void EbyteLoraE220::loop() {
buffer += (char) c; buffer += (char) c;
} }
} }
ESP_LOGD(TAG, "%s", buffer);
// set the rssi // set the rssi
rssi_ = atoi(buffer.substr(buffer.length() - 1, 1).c_str()); rssi_ = atoi(buffer.substr(buffer.length() - 1, 1).c_str());
// set the raw message // set the raw message
@ -162,5 +159,5 @@ void EbyteLoraE220::loop() {
} }
} }
} // namespace ebyte_lora_e220 } // namespace lora
} // namespace esphome } // namespace esphome

View file

@ -9,10 +9,10 @@
#include "esphome/core/log.h" #include "esphome/core/log.h"
namespace esphome { namespace esphome {
namespace ebyte_lora_e220 { namespace lora {
static const char *const TAG = "ebyte_lora_e220";
static const char *const TAG = "lora";
#define MAX_SIZE_TX_PACKET 200
// the mode the receiver is in // the mode the receiver is in
enum MODE_TYPE { enum MODE_TYPE {
MODE_0_NORMAL = 0, MODE_0_NORMAL = 0,
@ -26,7 +26,7 @@ enum MODE_TYPE {
MODE_3_SLEEP = 3, MODE_3_SLEEP = 3,
MODE_INIT = 0xFF MODE_INIT = 0xFF
}; };
class EbyteLoraE220 : public PollingComponent, public uart::UARTDevice { class Lora : public PollingComponent, public uart::UARTDevice {
public: public:
void setup() override; void setup() override;
void update() override; void update() override;
@ -62,5 +62,5 @@ class EbyteLoraE220 : public PollingComponent, public uart::UARTDevice {
GPIOPin *pin_m1{nullptr}; GPIOPin *pin_m1{nullptr};
}; };
} // namespace ebyte_lora_e220 } // namespace lora
} // namespace esphome } // namespace esphome

View file

@ -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]))

View file

@ -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

View file

@ -0,0 +1,35 @@
#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