mirror of
https://github.com/esphome/esphome.git
synced 2026-10-06 02:51:29 +00:00
[modbus] Finalize unreleased API surface before 2026.7 (#17434)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
731e9fda03
commit
731486d9b0
@@ -56,8 +56,7 @@ void ModbusClientHub::loop() {
|
||||
(this->rx_buffer_.empty() || this->rx_buffer_[0] != expected_address)) {
|
||||
ESP_LOGW(TAG, "Stop waiting for response from %" PRIu8 " %" PRIu32 "ms after last send", expected_address,
|
||||
this->last_receive_check_ - this->last_send_);
|
||||
if (wfr.device)
|
||||
wfr.device->on_modbus_no_response();
|
||||
this->notify_no_response_(wfr);
|
||||
this->waiting_for_response_.reset();
|
||||
}
|
||||
}
|
||||
@@ -278,11 +277,10 @@ void ModbusClientHub::process_modbus_server_frame(uint8_t address, uint8_t funct
|
||||
"ms after last send",
|
||||
address, expected_address, (function_code & FUNCTION_CODE_MASK), expected_function_code,
|
||||
this->last_modbus_byte_ - this->last_send_);
|
||||
// Invalidate the waiting device so it won't process this response.
|
||||
if (wfr.device)
|
||||
wfr.device->on_modbus_no_response();
|
||||
// Invalidate the device; the entry survives as an interrupted shell so the late response is ignored.
|
||||
// A retry requested here stays queued behind the shell until the send-wait timeout clears it.
|
||||
this->notify_no_response_(wfr);
|
||||
wfr.interrupted = true;
|
||||
wfr.device = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -564,6 +562,30 @@ void ModbusServerHub::send_exception_(uint8_t address, uint8_t function_code, Mo
|
||||
}
|
||||
|
||||
// Raw send for client: pushes to tx queue. Everything except the CRC must be contained in payload.
|
||||
void ModbusClientHub::notify_no_response_(ModbusDeviceCommand &wfr) {
|
||||
if (wfr.device == nullptr)
|
||||
return;
|
||||
const bool retry = wfr.device->on_modbus_no_response();
|
||||
// The callback may have detached the device (e.g. clear_tx_queue_for_device()); honor the detach
|
||||
// over the retry request rather than re-queueing a frame that can no longer be routed.
|
||||
if (retry && wfr.device != nullptr)
|
||||
this->requeue_waiting_frame_(wfr);
|
||||
// The old transaction is over either way; never deliver anything else to the device through it.
|
||||
wfr.device = nullptr;
|
||||
}
|
||||
|
||||
void ModbusClientHub::requeue_waiting_frame_(ModbusDeviceCommand &wfr) {
|
||||
const ModbusFrame &frame = wfr.frame;
|
||||
if (this->tx_buffer_.size() >= MODBUS_TX_BUFFER_SIZE) {
|
||||
ESP_LOGE(TAG, "Write buffer full, dropped retry for address %" PRIu8, frame.data.data()[0]);
|
||||
if (wfr.device != nullptr)
|
||||
wfr.device->on_modbus_not_sent();
|
||||
return;
|
||||
}
|
||||
// Re-queue a copy (not a move): the waiting entry may have to survive as an interrupted shell.
|
||||
this->tx_buffer_.emplace_back(wfr.device, frame.data.data()[0], frame.data.data() + 1, frame.size() - 3);
|
||||
}
|
||||
|
||||
void ModbusClientHub::queue_raw_(uint8_t address, const uint8_t *pdu, uint16_t pdu_len, ModbusClientDevice *device) {
|
||||
if (pdu_len == 0) {
|
||||
if (device)
|
||||
|
||||
Reference in New Issue
Block a user