ESP IDF support.
This commit is contained in:
parent
aafaf474d3
commit
f2097c76af
@ -172,7 +172,6 @@ The following [ESP Home actions](https://esphome.io/guides/automations.html#acti
|
|||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
- [ ] This file
|
- [ ] This file
|
||||||
- [ ] ESP32 IDF support
|
|
||||||
- [ ] RP2040 support
|
- [ ] RP2040 support
|
||||||
- [ ] Testing of Combi 4E / Combi 6E and Alde devices (I only have access to an Combi 4)
|
- [ ] Testing of Combi 4E / Combi 6E and Alde devices (I only have access to an Combi 4)
|
||||||
- [ ] More Testing
|
- [ ] More Testing
|
||||||
|
|||||||
@ -21,11 +21,11 @@ void LinBusListener::dump_config() {
|
|||||||
|
|
||||||
void LinBusListener::setup() {
|
void LinBusListener::setup() {
|
||||||
ESP_LOGCONFIG(TAG, "Setting up LIN BUS...");
|
ESP_LOGCONFIG(TAG, "Setting up LIN BUS...");
|
||||||
this->time_per_baud_ = (1000.0f * 1000.0f / this->parent_->get_baud_rate());
|
// this->time_per_baud_ = (1000.0f * 1000.0f / this->parent_->get_baud_rate());
|
||||||
this->time_per_lin_break_ = this->time_per_baud_ * this->lin_break_length * 1.1;
|
// this->time_per_lin_break_ = this->time_per_baud_ * this->lin_break_length * 1.1;
|
||||||
this->time_per_pid_ = this->time_per_baud_ * this->frame_length_ * 1.1;
|
// this->time_per_pid_ = this->time_per_baud_ * this->frame_length_ * 1.1;
|
||||||
this->time_per_first_byte_ = this->time_per_baud_ * this->frame_length_ * 3.0;
|
// this->time_per_first_byte_ = this->time_per_baud_ * this->frame_length_ * 3.0;
|
||||||
this->time_per_byte_ = this->time_per_baud_ * this->frame_length_ * 1.1;
|
// this->time_per_byte_ = this->time_per_baud_ * this->frame_length_ * 1.1;
|
||||||
|
|
||||||
// call device specific function
|
// call device specific function
|
||||||
this->setup_framework();
|
this->setup_framework();
|
||||||
@ -55,6 +55,12 @@ void LinBusListener::write_lin_answer_(const u_int8_t *data, size_t len) {
|
|||||||
data_CRC = data_checksum(data, len, this->current_PID_with_parity_);
|
data_CRC = data_checksum(data, len, this->current_PID_with_parity_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// I am answering too quick ~50-60us after stop bit. Normal communication has a ~100us pause (second stop bits).
|
||||||
|
// The heater is answering after ~500-600us.
|
||||||
|
// If there is any issue I might have to add a delay here.
|
||||||
|
// Check when last byte was read from buffer and wait at least one baud time.
|
||||||
|
// It is working when I answer quicker.
|
||||||
|
|
||||||
if (!this->observer_mode_) {
|
if (!this->observer_mode_) {
|
||||||
this->write_array(data, len);
|
this->write_array(data, len);
|
||||||
this->write(data_CRC);
|
this->write(data_CRC);
|
||||||
@ -63,6 +69,30 @@ void LinBusListener::write_lin_answer_(const u_int8_t *data, size_t len) {
|
|||||||
ESP_LOGV(TAG, "RESPONSE %02x %s %02x", this->current_PID_, format_hex_pretty(data, len).c_str(), data_CRC);
|
ESP_LOGV(TAG, "RESPONSE %02x %s %02x", this->current_PID_, format_hex_pretty(data, len).c_str(), data_CRC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LinBusListener::onReceive_() {
|
||||||
|
// Check if Lin Bus is faulty.
|
||||||
|
if (this->fault_pin_ != nullptr) {
|
||||||
|
if (!this->fault_pin_->digital_read()) {
|
||||||
|
if (!this->fault_on_lin_bus_reported_) {
|
||||||
|
this->fault_on_lin_bus_reported_ = true;
|
||||||
|
ESP_LOGE(TAG, "Fault on LIN BUS detected.");
|
||||||
|
}
|
||||||
|
// Ignore any data present in buffer
|
||||||
|
this->clear_uart_buffer_();
|
||||||
|
} else if (this->fault_on_lin_bus_reported_) {
|
||||||
|
this->fault_on_lin_bus_reported_ = false;
|
||||||
|
ESP_LOGI(TAG, "Fault on LIN BUS fixed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this->fault_on_lin_bus_reported_) {
|
||||||
|
while (this->available()) {
|
||||||
|
// this->last_data_recieved_ = micros();
|
||||||
|
this->read_lin_frame_();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LinBusListener::read_lin_frame_() {
|
void LinBusListener::read_lin_frame_() {
|
||||||
u_int8_t buf;
|
u_int8_t buf;
|
||||||
switch (this->current_state_) {
|
switch (this->current_state_) {
|
||||||
@ -128,6 +158,8 @@ void LinBusListener::read_lin_frame_() {
|
|||||||
this->current_state_ = READ_STATE_ACT;
|
this->current_state_ = READ_STATE_ACT;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->current_state_ == READ_STATE_ACT && this->current_data_count_ > 1) {
|
if (this->current_state_ == READ_STATE_ACT && this->current_data_count_ > 1) {
|
||||||
|
|||||||
@ -4,6 +4,11 @@
|
|||||||
#include "esphome/core/component.h"
|
#include "esphome/core/component.h"
|
||||||
#include "esphome/components/uart/uart.h"
|
#include "esphome/components/uart/uart.h"
|
||||||
|
|
||||||
|
#ifdef USE_ESP32_FRAMEWORK_ESP_IDF
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#endif // USE_ESP32_FRAMEWORK_ESP_IDF
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace truma_inetbox {
|
namespace truma_inetbox {
|
||||||
|
|
||||||
@ -34,19 +39,19 @@ class LinBusListener : public PollingComponent, public uart::UARTDevice {
|
|||||||
virtual void lin_message_recieved_(const u_int8_t pid, const u_int8_t *message, u_int8_t length) = 0;
|
virtual void lin_message_recieved_(const u_int8_t pid, const u_int8_t *message, u_int8_t length) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Microseconds per UART Baud
|
// // Microseconds per UART Baud
|
||||||
u_int32_t time_per_baud_;
|
// u_int32_t time_per_baud_;
|
||||||
// 9.. 15
|
// // 9.. 15
|
||||||
u_int8_t lin_break_length = 13;
|
// u_int8_t lin_break_length = 13;
|
||||||
// Microseconds per LIN Break
|
// // Microseconds per LIN Break
|
||||||
u_int32_t time_per_lin_break_;
|
// u_int32_t time_per_lin_break_;
|
||||||
u_int8_t frame_length_ = (8 /* bits */ + 1 /* Start bit */ + 2 /* Stop bits */);
|
// u_int8_t frame_length_ = (8 /* bits */ + 1 /* Start bit */ + 2 /* Stop bits */);
|
||||||
// Microseconds per UART Byte (UART Frame)
|
// // Microseconds per UART Byte (UART Frame)
|
||||||
u_int32_t time_per_pid_;
|
// u_int32_t time_per_pid_;
|
||||||
// Microseconds per UART Byte (UART Frame)
|
// // Microseconds per UART Byte (UART Frame)
|
||||||
u_int32_t time_per_first_byte_;
|
// u_int32_t time_per_first_byte_;
|
||||||
// Microseconds per UART Byte (UART Frame)
|
// // Microseconds per UART Byte (UART Frame)
|
||||||
u_int32_t time_per_byte_;
|
// u_int32_t time_per_byte_;
|
||||||
|
|
||||||
bool fault_on_lin_bus_reported_ = false;
|
bool fault_on_lin_bus_reported_ = false;
|
||||||
bool can_write_lin_answer_ = false;
|
bool can_write_lin_answer_ = false;
|
||||||
@ -66,11 +71,17 @@ class LinBusListener : public PollingComponent, public uart::UARTDevice {
|
|||||||
// up to 8 byte data frame + CRC
|
// up to 8 byte data frame + CRC
|
||||||
u_int8_t current_data_[9] = {};
|
u_int8_t current_data_[9] = {};
|
||||||
// // Time when the last LIN data was available.
|
// // Time when the last LIN data was available.
|
||||||
// int64_t last_data_recieved_;
|
// uint32_t last_data_recieved_;
|
||||||
|
|
||||||
|
void onReceive_();
|
||||||
void read_lin_frame_();
|
void read_lin_frame_();
|
||||||
void clear_uart_buffer_();
|
void clear_uart_buffer_();
|
||||||
void setup_framework();
|
void setup_framework();
|
||||||
|
|
||||||
|
#ifdef USE_ESP32_FRAMEWORK_ESP_IDF
|
||||||
|
TaskHandle_t _eventTask;
|
||||||
|
static void _uartEventTask(void *args);
|
||||||
|
#endif // USE_ESP32_FRAMEWORK_ESP_IDF
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace truma_inetbox
|
} // namespace truma_inetbox
|
||||||
|
|||||||
@ -16,7 +16,7 @@ void LinBusListener::setup_framework() {
|
|||||||
auto uartComp = static_cast<esphome::uart::truma_ESP32ArduinoUARTComponent *>(this->parent_);
|
auto uartComp = static_cast<esphome::uart::truma_ESP32ArduinoUARTComponent *>(this->parent_);
|
||||||
|
|
||||||
auto uart_num = uartComp->get_hw_serial_number();
|
auto uart_num = uartComp->get_hw_serial_number();
|
||||||
auto hwSerial = uartComp->get_hw_serial();
|
auto hw_serial = uartComp->get_hw_serial();
|
||||||
|
|
||||||
// Extract from `uartSetFastReading` - Can't call it because I don't have access to `uart_t` object.
|
// Extract from `uartSetFastReading` - Can't call it because I don't have access to `uart_t` object.
|
||||||
|
|
||||||
@ -34,32 +34,10 @@ void LinBusListener::setup_framework() {
|
|||||||
uart_intr.txfifo_empty_intr_thresh = 10; // UART_EMPTY_THRESH_DEFAULT
|
uart_intr.txfifo_empty_intr_thresh = 10; // UART_EMPTY_THRESH_DEFAULT
|
||||||
uart_intr_config(uart_num, &uart_intr);
|
uart_intr_config(uart_num, &uart_intr);
|
||||||
|
|
||||||
hwSerial->onReceive(
|
hw_serial->onReceive([this]() { this->onReceive_(); }, false);
|
||||||
[this]() {
|
hw_serial->onReceiveError([this](hardwareSerial_error_t val) {
|
||||||
// Check if Lin Bus is faulty.
|
|
||||||
if (this->fault_pin_ != nullptr) {
|
|
||||||
if (!this->fault_pin_->digital_read()) {
|
|
||||||
if (!this->fault_on_lin_bus_reported_) {
|
|
||||||
this->fault_on_lin_bus_reported_ = true;
|
|
||||||
ESP_LOGE(TAG, "Fault on LIN BUS detected.");
|
|
||||||
}
|
|
||||||
// Ignore any data present in buffer
|
// Ignore any data present in buffer
|
||||||
this->clear_uart_buffer_();
|
this->clear_uart_buffer_();
|
||||||
} else if (this->fault_on_lin_bus_reported_) {
|
|
||||||
this->fault_on_lin_bus_reported_ = false;
|
|
||||||
ESP_LOGI(TAG, "Fault on LIN BUS fixed.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->fault_on_lin_bus_reported_) {
|
|
||||||
while (this->available()) {
|
|
||||||
// this->last_data_recieved_ = esp_timer_get_time();
|
|
||||||
this->read_lin_frame_();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
false);
|
|
||||||
hwSerial->onReceiveError([this](hardwareSerial_error_t val) {
|
|
||||||
if (val == UART_BREAK_ERROR) {
|
if (val == UART_BREAK_ERROR) {
|
||||||
// If the break is valid the `onReceive` is called first and the break is handeld. Therfore the expectation is
|
// If the break is valid the `onReceive` is called first and the break is handeld. Therfore the expectation is
|
||||||
// that the state should be in waiting for `SYNC`.
|
// that the state should be in waiting for `SYNC`.
|
||||||
@ -67,14 +45,6 @@ void LinBusListener::setup_framework() {
|
|||||||
this->current_state_ = READ_STATE_BREAK;
|
this->current_state_ = READ_STATE_BREAK;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else if (val == UART_BUFFER_FULL_ERROR) {
|
|
||||||
ESP_LOGW(TAG, "UART_BUFFER_FULL_ERROR");
|
|
||||||
} else if (val == UART_FIFO_OVF_ERROR) {
|
|
||||||
ESP_LOGW(TAG, "UART_FIFO_OVF_ERROR");
|
|
||||||
} else if (val == UART_FRAME_ERROR) {
|
|
||||||
ESP_LOGW(TAG, "UART_FRAME_ERROR");
|
|
||||||
} else if (val == UART_PARITY_ERROR) {
|
|
||||||
ESP_LOGW(TAG, "UART_PARITY_ERROR");
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#ifdef USE_ESP32_FRAMEWORK_ESP_IDF
|
#ifdef USE_ESP32_FRAMEWORK_ESP_IDF
|
||||||
#include "LinBusListener.h"
|
#include "LinBusListener.h"
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
|
#include "soc/uart_reg.h"
|
||||||
#include "esphome/components/uart/truma_uart_component_esp_idf.h"
|
#include "esphome/components/uart/truma_uart_component_esp_idf.h"
|
||||||
#include "esphome/components/uart/uart_component_esp_idf.h"
|
#include "esphome/components/uart/uart_component_esp_idf.h"
|
||||||
|
|
||||||
@ -11,20 +12,59 @@ static const char *const TAG = "truma_inetbox.LinBusListener";
|
|||||||
|
|
||||||
void LinBusListener::setup_framework() {
|
void LinBusListener::setup_framework() {
|
||||||
// uartSetFastReading
|
// uartSetFastReading
|
||||||
auto uartComp = ((*uart::truma_IDFUARTComponent) this->parent_);
|
auto uartComp = static_cast<uart::truma_IDFUARTComponent *>(this->parent_);
|
||||||
|
|
||||||
|
auto uart_num = uartComp->get_hw_serial_number();
|
||||||
|
|
||||||
// Tweak the fifo settings so data is available as soon as the first byte is recieved.
|
// Tweak the fifo settings so data is available as soon as the first byte is recieved.
|
||||||
// If not it will wait either until fifo is filled or a certain time has passed.
|
// If not it will wait either until fifo is filled or a certain time has passed.
|
||||||
uart_intr_config_t uart_intr;
|
uart_intr_config_t uart_intr;
|
||||||
uart_intr.intr_enable_mask = 0; // UART_RXFIFO_FULL_INT_ENA_M | UART_RXFIFO_TOUT_INT_ENA_M | UART_FRM_ERR_INT_ENA_M |
|
uart_intr.intr_enable_mask =
|
||||||
// UART_RXFIFO_OVF_INT_ENA_M | UART_BRK_DET_INT_ENA_M | UART_PARITY_ERR_INT_ENA_M;
|
UART_RXFIFO_FULL_INT_ENA_M | UART_RXFIFO_TOUT_INT_ENA_M; // only these IRQs - no BREAK, PARITY or OVERFLOW
|
||||||
uart_intr.rxfifo_full_thresh =
|
uart_intr.rxfifo_full_thresh =
|
||||||
1; // UART_FULL_THRESH_DEFAULT, //120 default!! aghh! need receive 120 chars before we see them
|
1; // UART_FULL_THRESH_DEFAULT, //120 default!! aghh! need receive 120 chars before we see them
|
||||||
uart_intr.rx_timeout_thresh =
|
uart_intr.rx_timeout_thresh =
|
||||||
1; // UART_TOUT_THRESH_DEFAULT, //10 works well for my short messages I need send/receive
|
10; // UART_TOUT_THRESH_DEFAULT, //10 works well for my short messages I need send/receive
|
||||||
uart_intr.txfifo_empty_intr_thresh = 10; // UART_EMPTY_THRESH_DEFAULT
|
uart_intr.txfifo_empty_intr_thresh = 10; // UART_EMPTY_THRESH_DEFAULT
|
||||||
uart_intr_config(uartComp->get_hw_serial_number(), &uart_intr);
|
uart_intr_config(uart_num, &uart_intr);
|
||||||
|
|
||||||
|
// Creating UART event Task
|
||||||
|
xTaskCreatePinnedToCore(LinBusListener::_uartEventTask,
|
||||||
|
"uart_event_task", // name
|
||||||
|
ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE, // stack size (in words)
|
||||||
|
this, // input params
|
||||||
|
24, // priority
|
||||||
|
&_eventTask, // handle
|
||||||
|
ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE // core
|
||||||
|
);
|
||||||
|
if (_eventTask == NULL) {
|
||||||
|
ESP_LOGE(TAG, " -- UART%d Event Task not Created!", uart_num);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LinBusListener::_uartEventTask(void *args) {
|
||||||
|
LinBusListener *instance = (LinBusListener *) args;
|
||||||
|
auto uartComp = static_cast<uart::truma_IDFUARTComponent *>(instance->parent_);
|
||||||
|
auto uart_num = uartComp->get_hw_serial_number();
|
||||||
|
auto uartEventQueue = uartComp->get_uart_event_queue();
|
||||||
|
uart_event_t event;
|
||||||
|
for (;;) {
|
||||||
|
// Waiting for UART event.
|
||||||
|
if (xQueueReceive(*uartEventQueue, (void *) &event, (portTickType) portMAX_DELAY)) {
|
||||||
|
if (event.type == UART_DATA && instance->available() > 0) {
|
||||||
|
instance->onReceive_();
|
||||||
|
} else if (event.type == UART_BREAK) {
|
||||||
|
// If the break is valid the `onReceive` is called first and the break is handeld. Therfore the expectation is
|
||||||
|
// that the state should be in waiting for `SYNC`.
|
||||||
|
if (instance->current_state_ != READ_STATE_SYNC) {
|
||||||
|
instance->current_state_ = READ_STATE_BREAK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace truma_inetbox
|
} // namespace truma_inetbox
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
||||||
|
|||||||
@ -66,7 +66,7 @@ const std::array<uint8_t, 4> TrumaiNetBoxApp::lin_identifier() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TrumaiNetBoxApp::lin_reset_device() {
|
void TrumaiNetBoxApp::lin_reset_device() {
|
||||||
this->device_registered_ = esp_timer_get_time();
|
this->device_registered_ = micros();
|
||||||
this->init_recieved_ = 0;
|
this->init_recieved_ = 0;
|
||||||
|
|
||||||
this->status_heater_valid_ = false;
|
this->status_heater_valid_ = false;
|
||||||
@ -90,9 +90,8 @@ void TrumaiNetBoxApp::lin_reset_device() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TrumaiNetBoxApp::register_listener(const std::function<void(const StatusFrameHeater *)> &func) {
|
void TrumaiNetBoxApp::register_listener(const std::function<void(const StatusFrameHeater *)> &func) {
|
||||||
auto listener = StatusFrameListener{
|
StatusFrameListener listener = {};
|
||||||
.on_heater_change = func,
|
listener.on_heater_change = func;
|
||||||
};
|
|
||||||
this->listeners_heater_.push_back(std::move(listener));
|
this->listeners_heater_.push_back(std::move(listener));
|
||||||
|
|
||||||
if (this->status_heater_valid_) {
|
if (this->status_heater_valid_) {
|
||||||
@ -100,9 +99,8 @@ void TrumaiNetBoxApp::register_listener(const std::function<void(const StatusFra
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
void TrumaiNetBoxApp::register_listener(const std::function<void(const StatusFrameTimer *)> &func) {
|
void TrumaiNetBoxApp::register_listener(const std::function<void(const StatusFrameTimer *)> &func) {
|
||||||
auto listener = StatusFrameListener{
|
StatusFrameListener listener = {};
|
||||||
.on_timer_change = func,
|
listener.on_timer_change = func;
|
||||||
};
|
|
||||||
this->listeners_heater_.push_back(std::move(listener));
|
this->listeners_heater_.push_back(std::move(listener));
|
||||||
|
|
||||||
if (this->status_timer_valid_) {
|
if (this->status_timer_valid_) {
|
||||||
@ -110,9 +108,8 @@ void TrumaiNetBoxApp::register_listener(const std::function<void(const StatusFra
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
void TrumaiNetBoxApp::register_listener(const std::function<void(const StatusFrameClock *)> &func) {
|
void TrumaiNetBoxApp::register_listener(const std::function<void(const StatusFrameClock *)> &func) {
|
||||||
auto listener = StatusFrameListener{
|
StatusFrameListener listener = {};
|
||||||
.on_clock_change = func,
|
listener.on_clock_change = func;
|
||||||
};
|
|
||||||
this->listeners_heater_.push_back(std::move(listener));
|
this->listeners_heater_.push_back(std::move(listener));
|
||||||
|
|
||||||
if (this->status_clock_valid_) {
|
if (this->status_clock_valid_) {
|
||||||
@ -120,9 +117,8 @@ void TrumaiNetBoxApp::register_listener(const std::function<void(const StatusFra
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
void TrumaiNetBoxApp::register_listener(const std::function<void(const StatusFrameConfig *)> &func) {
|
void TrumaiNetBoxApp::register_listener(const std::function<void(const StatusFrameConfig *)> &func) {
|
||||||
auto listener = StatusFrameListener{
|
StatusFrameListener listener = {};
|
||||||
.on_config_change = func,
|
listener.on_config_change = func;
|
||||||
};
|
|
||||||
this->listeners_heater_.push_back(std::move(listener));
|
this->listeners_heater_.push_back(std::move(listener));
|
||||||
|
|
||||||
if (this->status_config_valid_) {
|
if (this->status_config_valid_) {
|
||||||
@ -190,7 +186,7 @@ bool TrumaiNetBoxApp::answer_lin_order_(const u_int8_t pid) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool TrumaiNetBoxApp::lin_read_field_by_identifier_(u_int8_t identifier, std::array<u_int8_t, 5> *response) {
|
bool TrumaiNetBoxApp::lin_read_field_by_identifier_(u_int8_t identifier, std::array<u_int8_t, 5> *response) {
|
||||||
this->device_registered_ = esp_timer_get_time();
|
this->device_registered_ = micros();
|
||||||
if (identifier == 0x00 /* LIN Product Identification */) {
|
if (identifier == 0x00 /* LIN Product Identification */) {
|
||||||
auto lin_identifier = this->lin_identifier();
|
auto lin_identifier = this->lin_identifier();
|
||||||
(*response)[0] = lin_identifier[0];
|
(*response)[0] = lin_identifier[0];
|
||||||
@ -389,7 +385,7 @@ const u_int8_t *TrumaiNetBoxApp::lin_multiframe_recieved(const u_int8_t *message
|
|||||||
// BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.0C.0B.00.27.02.01.01.00.40.03.22.02.00.01.00.00 - H2.00.01 0340.22
|
// BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.0C.0B.00.27.02.01.01.00.40.03.22.02.00.01.00.00 - H2.00.01 0340.22
|
||||||
auto device = statusFrame->inner.device;
|
auto device = statusFrame->inner.device;
|
||||||
|
|
||||||
this->init_recieved_ = esp_timer_get_time();
|
this->init_recieved_ = micros();
|
||||||
|
|
||||||
ESP_LOGV(TAG, "StatusFrameDevice %d/%d - %d.%02d.%02d %04x.%02x", device.device_id + 1, device.device_count,
|
ESP_LOGV(TAG, "StatusFrameDevice %d/%d - %d.%02d.%02d %04x.%02x", device.device_id + 1, device.device_count,
|
||||||
device.software_revision[0], device.software_revision[1], device.software_revision[2],
|
device.software_revision[0], device.software_revision[1], device.software_revision[2],
|
||||||
@ -405,28 +401,28 @@ const u_int8_t *TrumaiNetBoxApp::lin_multiframe_recieved(const u_int8_t *message
|
|||||||
|
|
||||||
bool TrumaiNetBoxApp::has_update_to_submit_() {
|
bool TrumaiNetBoxApp::has_update_to_submit_() {
|
||||||
if (this->init_requested_ == 0) {
|
if (this->init_requested_ == 0) {
|
||||||
this->init_requested_ = esp_timer_get_time();
|
this->init_requested_ = micros();
|
||||||
ESP_LOGV(TAG, "Requesting initial data.");
|
ESP_LOGV(TAG, "Requesting initial data.");
|
||||||
return true;
|
return true;
|
||||||
} else if (this->init_recieved_ == 0) {
|
} else if (this->init_recieved_ == 0) {
|
||||||
auto init_wait_time = esp_timer_get_time() - this->init_requested_;
|
auto init_wait_time = micros() - this->init_requested_;
|
||||||
// it has been 5 seconds and i am still awaiting the init data.
|
// it has been 5 seconds and i am still awaiting the init data.
|
||||||
if (init_wait_time > 1000 * 1000 * 5) {
|
if (init_wait_time > 1000 * 1000 * 5) {
|
||||||
ESP_LOGV(TAG, "Requesting initial data again.");
|
ESP_LOGV(TAG, "Requesting initial data again.");
|
||||||
this->init_requested_ = esp_timer_get_time();
|
this->init_requested_ = micros();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (this->update_status_heater_unsubmitted_ || this->update_status_timer_unsubmitted_ ||
|
} else if (this->update_status_heater_unsubmitted_ || this->update_status_timer_unsubmitted_ ||
|
||||||
this->update_status_clock_unsubmitted_) {
|
this->update_status_clock_unsubmitted_) {
|
||||||
if (this->update_time_ == 0) {
|
if (this->update_time_ == 0) {
|
||||||
ESP_LOGV(TAG, "Notify CP Plus I got updates.");
|
ESP_LOGV(TAG, "Notify CP Plus I got updates.");
|
||||||
this->update_time_ = esp_timer_get_time();
|
this->update_time_ = micros();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
auto update_wait_time = esp_timer_get_time() - this->update_time_;
|
auto update_wait_time = micros() - this->update_time_;
|
||||||
if (update_wait_time > 1000 * 1000 * 5) {
|
if (update_wait_time > 1000 * 1000 * 5) {
|
||||||
ESP_LOGV(TAG, "Notify CP Plus again I still got updates.");
|
ESP_LOGV(TAG, "Notify CP Plus again I still got updates.");
|
||||||
this->update_time_ = esp_timer_get_time();
|
this->update_time_ = micros();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -326,10 +326,10 @@ union StatusFrame { // NOLINT(altera-struct-pack-align)
|
|||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct StatusFrameListener {
|
struct StatusFrameListener {
|
||||||
std::function<void(const StatusFrameHeater *)> on_heater_change;
|
std::function<void(const StatusFrameHeater *)> on_heater_change = nullptr;
|
||||||
std::function<void(const StatusFrameTimer *)> on_timer_change;
|
std::function<void(const StatusFrameTimer *)> on_timer_change = nullptr;
|
||||||
std::function<void(const StatusFrameClock *)> on_clock_change;
|
std::function<void(const StatusFrameClock *)> on_clock_change = nullptr;
|
||||||
std::function<void(const StatusFrameConfig *)> on_config_change;
|
std::function<void(const StatusFrameConfig *)> on_config_change = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TrumaiNetBoxApp : public LinBusProtocol {
|
class TrumaiNetBoxApp : public LinBusProtocol {
|
||||||
@ -395,9 +395,9 @@ class TrumaiNetBoxApp : public LinBusProtocol {
|
|||||||
time::RealTimeClock *time_;
|
time::RealTimeClock *time_;
|
||||||
|
|
||||||
// Truma CP Plus needs init (reset). This device is not registered.
|
// Truma CP Plus needs init (reset). This device is not registered.
|
||||||
int64_t device_registered_ = 0;
|
uint32_t device_registered_ = 0;
|
||||||
int64_t init_requested_ = 0;
|
uint32_t init_requested_ = 0;
|
||||||
int64_t init_recieved_ = 0;
|
uint32_t init_recieved_ = 0;
|
||||||
u_int8_t message_counter = 1;
|
u_int8_t message_counter = 1;
|
||||||
|
|
||||||
std::vector<StatusFrameListener> listeners_heater_;
|
std::vector<StatusFrameListener> listeners_heater_;
|
||||||
@ -424,7 +424,7 @@ class TrumaiNetBoxApp : public LinBusProtocol {
|
|||||||
StatusFrameConfig status_config_;
|
StatusFrameConfig status_config_;
|
||||||
|
|
||||||
// last time CP plus was informed I got an update msg.
|
// last time CP plus was informed I got an update msg.
|
||||||
int64_t update_time_ = 0;
|
uint32_t update_time_ = 0;
|
||||||
// Prepared means `update_status_heater_` was copied from `status_heater_`.
|
// Prepared means `update_status_heater_` was copied from `status_heater_`.
|
||||||
bool update_status_heater_prepared_ = false;
|
bool update_status_heater_prepared_ = false;
|
||||||
// Prepared means an update is already awating fetch from CP plus.
|
// Prepared means an update is already awating fetch from CP plus.
|
||||||
|
|||||||
@ -6,7 +6,6 @@ from esphome.const import (
|
|||||||
CONF_ID,
|
CONF_ID,
|
||||||
CONF_CS_PIN,
|
CONF_CS_PIN,
|
||||||
CONF_TEMPERATURE,
|
CONF_TEMPERATURE,
|
||||||
CONF_ON_MESSAGE,
|
|
||||||
CONF_TRIGGER_ID,
|
CONF_TRIGGER_ID,
|
||||||
CONF_STOP,
|
CONF_STOP,
|
||||||
CONF_TIME_ID,
|
CONF_TIME_ID,
|
||||||
@ -62,7 +61,6 @@ CONFIG_SCHEMA = cv.All(
|
|||||||
# Reading and communication is done in a seperate thread/core.
|
# Reading and communication is done in a seperate thread/core.
|
||||||
.extend(cv.polling_component_schema("500ms"))
|
.extend(cv.polling_component_schema("500ms"))
|
||||||
.extend(uart.UART_DEVICE_SCHEMA),
|
.extend(uart.UART_DEVICE_SCHEMA),
|
||||||
cv.only_with_arduino,
|
|
||||||
cv.only_on(["esp32"]),
|
cv.only_on(["esp32"]),
|
||||||
)
|
)
|
||||||
FINAL_VALIDATE_SCHEMA = cv.All(
|
FINAL_VALIDATE_SCHEMA = cv.All(
|
||||||
|
|||||||
@ -13,7 +13,7 @@ void TrumaCpPlusBinarySensor::update() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto timeout = this->parent_->get_last_cp_plus_request() + 30 * 1000 * 1000 /* 30 seconds*/;
|
auto timeout = this->parent_->get_last_cp_plus_request() + 30 * 1000 * 1000 /* 30 seconds*/;
|
||||||
this->publish_state(esp_timer_get_time() < timeout);
|
this->publish_state(micros() < timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrumaCpPlusBinarySensor::dump_config() { ESP_LOGCONFIG("", "Truma CP Plus Binary Sensor"); }
|
void TrumaCpPlusBinarySensor::dump_config() { ESP_LOGCONFIG("", "Truma CP Plus Binary Sensor"); }
|
||||||
|
|||||||
@ -30,6 +30,8 @@ void TrumaHeaterBinarySensor::setup() {
|
|||||||
case TRUMA_BINARY_SENSOR_TYPE::HEATER_ELECTRICITY:
|
case TRUMA_BINARY_SENSOR_TYPE::HEATER_ELECTRICITY:
|
||||||
this->publish_state(status_heater->energy_mix_a == EnergyMix::ENERGY_MIX_ELECTRICITY);
|
this->publish_state(status_heater->energy_mix_a == EnergyMix::ENERGY_MIX_ELECTRICITY);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,6 +19,8 @@ void TrumaTimerBinarySensor::setup() {
|
|||||||
case TRUMA_BINARY_SENSOR_TYPE::TIMER_WATER:
|
case TRUMA_BINARY_SENSOR_TYPE::TIMER_WATER:
|
||||||
this->publish_state(status_timer->timer_target_temp_water != TargetTemp::TARGET_TEMP_OFF);
|
this->publish_state(status_timer->timer_target_temp_water != TargetTemp::TARGET_TEMP_OFF);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -89,7 +89,7 @@ const std::string operating_status_to_str(OperatingStatus val) {
|
|||||||
} else if (val == OperatingStatus::OPERATING_STATUS_ON_9) {
|
} else if (val == OperatingStatus::OPERATING_STATUS_ON_9) {
|
||||||
return "ON (9)";
|
return "ON (9)";
|
||||||
} else {
|
} else {
|
||||||
return str_snprintf("ON %x", (uint8_t) val);
|
return esphome::str_snprintf("ON %u", 6, (uint8_t) val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,6 @@ namespace uart {
|
|||||||
|
|
||||||
class truma_ESP32ArduinoUARTComponent : public ESP32ArduinoUARTComponent {
|
class truma_ESP32ArduinoUARTComponent : public ESP32ArduinoUARTComponent {
|
||||||
public:
|
public:
|
||||||
bool is_hw_serial() { return true; }
|
|
||||||
HardwareSerial *get_hw_serial() { return this->hw_serial_; }
|
HardwareSerial *get_hw_serial() { return this->hw_serial_; }
|
||||||
uint8_t get_hw_serial_number() { return this->number_; }
|
uint8_t get_hw_serial_number() { return this->number_; }
|
||||||
};
|
};
|
||||||
|
|||||||
@ -9,8 +9,9 @@ namespace uart {
|
|||||||
|
|
||||||
class truma_IDFUARTComponent : public IDFUARTComponent {
|
class truma_IDFUARTComponent : public IDFUARTComponent {
|
||||||
public:
|
public:
|
||||||
bool is_hw_serial() { return true; }
|
|
||||||
uint8_t get_hw_serial_number() { return this->uart_num_; }
|
uint8_t get_hw_serial_number() { return this->uart_num_; }
|
||||||
|
// `QueueHandle_t uart_event_queue_;` is also added to base class.
|
||||||
|
QueueHandle_t *get_uart_event_queue() { return &this->uart_event_queue_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace uart
|
} // namespace uart
|
||||||
|
|||||||
@ -79,7 +79,11 @@ void IDFUARTComponent::setup() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = uart_driver_install(this->uart_num_, this->rx_buffer_size_, 0, 0, nullptr, 0);
|
err = uart_driver_install(this->uart_num_, this->rx_buffer_size_,
|
||||||
|
0, // UART TX ring buffer size.
|
||||||
|
// If set to zero, driver will not use TX buffer, TX function will block task until all
|
||||||
|
// data have been sent out.
|
||||||
|
20, &(this->uart_event_queue_), 0);
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
ESP_LOGW(TAG, "uart_driver_install failed: %s", esp_err_to_name(err));
|
ESP_LOGW(TAG, "uart_driver_install failed: %s", esp_err_to_name(err));
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
|
|||||||
@ -26,6 +26,7 @@ class IDFUARTComponent : public UARTComponent, public Component {
|
|||||||
protected:
|
protected:
|
||||||
void check_logger_conflict() override;
|
void check_logger_conflict() override;
|
||||||
uart_port_t uart_num_;
|
uart_port_t uart_num_;
|
||||||
|
QueueHandle_t uart_event_queue_;
|
||||||
uart_config_t get_config_();
|
uart_config_t get_config_();
|
||||||
SemaphoreHandle_t lock_;
|
SemaphoreHandle_t lock_;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user