ESPHome 2026.8.2
Loading...
Searching...
No Matches
esphome::modbus::ModbusClientDevice Class Reference

Callback contract. More...

#include <modbus.h>

Inheritance diagram for esphome::modbus::ModbusClientDevice:
esphome::modbus_client::ClientActionBase< Ts... > esphome::growatt_solar::GrowattSolar esphome::havells_solar::HavellsSolar esphome::kuntze::Kuntze esphome::modbus_client::ClientActionBase< Ts > esphome::modbus_controller::ModbusCommandItem esphome::pzemac::PZEMAC esphome::pzemdc::PZEMDC esphome::sdm_meter::SDMMeter esphome::selec_meter::SelecMeter

Public Member Functions

 ModbusClientDevice ()=default
 
 ModbusClientDevice (ModbusClientHub *parent, uint8_t address)
 
virtual ~ModbusClientDevice ()
 
 ModbusClientDevice (const ModbusClientDevice &)=delete
 
ModbusClientDeviceoperator= (const ModbusClientDevice &)=delete
 
 ModbusClientDevice (ModbusClientDevice &&)=delete
 
ModbusClientDeviceoperator= (ModbusClientDevice &&)=delete
 
void set_parent (ModbusClientHub *parent)
 
void set_address (uint8_t address)
 
virtual void on_response (std::span< const uint8_t > request_pdu, std::span< const uint8_t > response_pdu)
 Low-level response hook: called with the request PDU this device sent and the response PDU received The spans are only valid for the duration of the call - copy the bytes if they must outlive it.
 
virtual void on_error (std::span< const uint8_t > request_pdu, ExceptionCode exception_code)
 Low-level error hook: called with the request PDU and the modbus exception code from the error response.
 
virtual void on_not_sent (std::span< const uint8_t > request_pdu)
 Called when an accepted request was dropped before transmission by clear_tx_queue_for_address().
 
virtual void on_sent (std::span< const uint8_t > request_pdu)
 Called when this device's frame is actually written to the wire.
 
virtual bool on_no_response (std::span< const uint8_t > request_pdu)
 Called when no matching, uninterrupted response arrived; return true to have the hub re-queue the frame for a retry.
 
 ESPDEPRECATED ("Override on_not_sent() instead. Removed in 2027.2.0", "2026.8.0") virtual void on_modbus_not_sent()
 
 ESPDEPRECATED ("Override on_no_response() instead. Removed in 2027.2.0", "2026.8.0") virtual bool on_modbus_no_response()
 
virtual void on_read_registers (EntityType entity_type, uint16_t start_address, std::span< const uint16_t > registers, ResponseStatus status)
 High-level typed response callbacks, fired by the default on_response()/on_error() with arguments parsed from the request and response PDUs.
 
virtual void on_read_holding_registers (uint16_t start_address, std::span< const uint16_t > registers, ResponseStatus status)
 
virtual void on_read_input_registers (uint16_t start_address, std::span< const uint16_t > registers, ResponseStatus status)
 
virtual void on_read_bits (EntityType entity_type, uint16_t start_address, PackedBits bits, ResponseStatus status)
 Coil/discrete-input reads are delivered as a PackedBits view (bit 0 = the bit at start_address, bits.size() = the count requested).
 
virtual void on_read_coils (uint16_t start_address, PackedBits bits, ResponseStatus status)
 
virtual void on_read_discrete_inputs (uint16_t start_address, PackedBits bits, ResponseStatus status)
 
virtual void on_write_single_register (uint16_t address, uint16_t value, ResponseStatus status)
 Write acknowledgements.
 
virtual void on_write_single_coil (uint16_t address, bool value, ResponseStatus status)
 
virtual void on_write_multiple_registers (uint16_t start_address, std::span< const uint16_t > registers, ResponseStatus status)
 
virtual void on_write_multiple_coils (uint16_t start_address, PackedBits bits, ResponseStatus status)
 
virtual void on_custom_response (std::span< const uint8_t > request_pdu, std::span< const uint8_t > response_pdu, ResponseStatus status)
 Catch-all for custom function codes and anything that is not a standard-conformant transaction (see dispatch_response_()); on failure the response is empty and the exception code is in status.
 
 ESPDEPRECATED ("Use the typed read_*/write_* helpers or queue_pdu() instead. Removed in 2027.2.0", "2026.8.0") void send(uint8_t function
 

Data Fields

uint16_t start_address
 
uint16_t uint16_t number_of_entities
 
uint16_t uint16_t uint8_t payload_len = 0
 
uint16_t uint16_t uint8_t const uint8_t * payload
 
ModbusClientHubparent_ {nullptr}
 
uint8_t address_ {0}
 
bool custom_response_warned_ {false}
 

Detailed Description

Callback contract.

Each accepted request ends in exactly ONE terminal: on_response() (data), on_error() (exception), on_no_response() (timeout/interruption), or on_not_sent() (dropped by clear_tx_queue_for_address before transmission). A request refused at queue_pdu() (false return) gets none, and a broadcast (address 0) gets on_sent() with NO terminal, since a broadcast is never answered (Modbus 4.1). on_sent() is additional, once per transmission, never for an on_not_sent() request. on_response()/on_error() fire at parse time and on_no_response() at the send-wait watchdog, all from a quiescent hub; only on_not_sent() is delivered by the sweep. Sending or clearing from inside a callback is safe (picked up by the next sweep). Exceptions to "exactly one terminal": a broadcast is fire-and-forget (on_sent, no terminal); clear_tx_queue_for_device() drops the caller's own frames silently; a continuous poll's cycles are its own accounting (a one-shot duplicate downgrades the poll to a one-shot; a continuous duplicate merges into it).

Invariants:

  • Public entry points (queue_pdu/clear_tx_queue_*) only append to the queue or mutate an existing entry through its callback-free transition methods.
  • Public entry points can never trigger a callback synchronously.
  • Callbacks are delivered only from within loop().
  • At most one callback is ever issued between calls to sweep_(): sweep_ -> parse (response OR error) OR timeout (no_response) -> sweep_ -> send (sent) -> sweep_ (next loop)

Definition at line 440 of file modbus.h.

Constructor & Destructor Documentation

◆ ModbusClientDevice() [1/4]

esphome::modbus::ModbusClientDevice::ModbusClientDevice ( )
default

◆ ModbusClientDevice() [2/4]

esphome::modbus::ModbusClientDevice::ModbusClientDevice ( ModbusClientHub * parent,
uint8_t address )
inline

Definition at line 443 of file modbus.h.

◆ ~ModbusClientDevice()

virtual esphome::modbus::ModbusClientDevice::~ModbusClientDevice ( )
inlinevirtual

Definition at line 444 of file modbus.h.

◆ ModbusClientDevice() [3/4]

esphome::modbus::ModbusClientDevice::ModbusClientDevice ( const ModbusClientDevice & )
delete

◆ ModbusClientDevice() [4/4]

esphome::modbus::ModbusClientDevice::ModbusClientDevice ( ModbusClientDevice && )
delete

Member Function Documentation

◆ ESPDEPRECATED() [1/3]

esphome::modbus::ModbusClientDevice::ESPDEPRECATED ( "Override on_no_response() instead. Removed in 2027.2.0" ,
"2026.8.0"  )
inline

Definition at line 489 of file modbus.h.

◆ ESPDEPRECATED() [2/3]

esphome::modbus::ModbusClientDevice::ESPDEPRECATED ( "Override on_not_sent() instead. Removed in 2027.2.0" ,
"2026.8.0"  )
inline

Definition at line 486 of file modbus.h.

◆ ESPDEPRECATED() [3/3]

esphome::modbus::ModbusClientDevice::ESPDEPRECATED ( "Use the typed read_*/write_* helpers or queue_pdu() instead. Removed in 2027.2.0" ,
"2026.8.0"  )

◆ on_custom_response()

void esphome::modbus::ModbusClientDevice::on_custom_response ( std::span< const uint8_t > request_pdu,
std::span< const uint8_t > response_pdu,
ResponseStatus status )
virtual

Catch-all for custom function codes and anything that is not a standard-conformant transaction (see dispatch_response_()); on failure the response is empty and the exception code is in status.

The default implementation only logs a warning that the response is going unhandled - override it to handle custom traffic (which also silences the warning).

Reimplemented in esphome::modbus_client::TypedClientActionBase< Ts >, and esphome::modbus_client::TypedClientActionBase< Ts... >.

Definition at line 1371 of file modbus.cpp.

◆ on_error()

virtual void esphome::modbus::ModbusClientDevice::on_error ( std::span< const uint8_t > request_pdu,
ExceptionCode exception_code )
inlinevirtual

Low-level error hook: called with the request PDU and the modbus exception code from the error response.

The default implementation dispatches to the same typed callbacks with the exception code as status. Devices implementing the High-level typed callbacks see success and failure through one interface.

Reimplemented in esphome::modbus_client::ClientActionBase< Ts >, esphome::modbus_client::ClientActionBase< Ts... >, and esphome::modbus_controller::ModbusCommandItem.

Definition at line 464 of file modbus.h.

◆ on_no_response()

virtual bool esphome::modbus::ModbusClientDevice::on_no_response ( std::span< const uint8_t > request_pdu)
inlinevirtual

Called when no matching, uninterrupted response arrived; return true to have the hub re-queue the frame for a retry.

The hub does not bound retries: the device is responsible for limiting them.

Reimplemented in esphome::modbus_client::ClientActionBase< Ts >, esphome::modbus_client::ClientActionBase< Ts... >, and esphome::modbus_controller::ModbusCommandItem.

Definition at line 479 of file modbus.h.

◆ on_not_sent()

virtual void esphome::modbus::ModbusClientDevice::on_not_sent ( std::span< const uint8_t > request_pdu)
inlinevirtual

Called when an accepted request was dropped before transmission by clear_tx_queue_for_address().

(on_modbus_* below are deprecated pre-rename spellings; the defaults forward during deprecation.)

Reimplemented in esphome::modbus_client::ClientActionBase< Ts >, esphome::modbus_client::ClientActionBase< Ts... >, and esphome::modbus_controller::ModbusCommandItem.

Definition at line 469 of file modbus.h.

◆ on_read_bits()

virtual void esphome::modbus::ModbusClientDevice::on_read_bits ( EntityType entity_type,
uint16_t start_address,
PackedBits bits,
ResponseStatus status )
inlinevirtual

Coil/discrete-input reads are delivered as a PackedBits view (bit 0 = the bit at start_address, bits.size() = the count requested).

The view points into the hub's receive buffer and is only valid during the call.

Reimplemented in esphome::modbus_client::ReadBitsAction< Ts >.

Definition at line 509 of file modbus.h.

◆ on_read_coils()

virtual void esphome::modbus::ModbusClientDevice::on_read_coils ( uint16_t start_address,
PackedBits bits,
ResponseStatus status )
inlinevirtual

Definition at line 510 of file modbus.h.

◆ on_read_discrete_inputs()

virtual void esphome::modbus::ModbusClientDevice::on_read_discrete_inputs ( uint16_t start_address,
PackedBits bits,
ResponseStatus status )
inlinevirtual

Definition at line 513 of file modbus.h.

◆ on_read_holding_registers()

virtual void esphome::modbus::ModbusClientDevice::on_read_holding_registers ( uint16_t start_address,
std::span< const uint16_t > registers,
ResponseStatus status )
inlinevirtual

Definition at line 498 of file modbus.h.

◆ on_read_input_registers()

virtual void esphome::modbus::ModbusClientDevice::on_read_input_registers ( uint16_t start_address,
std::span< const uint16_t > registers,
ResponseStatus status )
inlinevirtual

Definition at line 502 of file modbus.h.

◆ on_read_registers()

virtual void esphome::modbus::ModbusClientDevice::on_read_registers ( EntityType entity_type,
uint16_t start_address,
std::span< const uint16_t > registers,
ResponseStatus status )
inlinevirtual

High-level typed response callbacks, fired by the default on_response()/on_error() with arguments parsed from the request and response PDUs.

Status is std::nullopt on success; holds the exception code on failure. Register values are in host byte order; spans are only valid for the duration of the call.

Reimplemented in esphome::modbus_client::ReadRegistersAction< Ts >, and esphome::modbus_client::ReadWriteMultipleRegistersAction< Ts >.

Definition at line 496 of file modbus.h.

◆ on_response()

virtual void esphome::modbus::ModbusClientDevice::on_response ( std::span< const uint8_t > request_pdu,
std::span< const uint8_t > response_pdu )
inlinevirtual

Low-level response hook: called with the request PDU this device sent and the response PDU received The spans are only valid for the duration of the call - copy the bytes if they must outlive it.

The default implementation decodes standard responses and dispatches to on_read_* / on_write_* callbacks below. Override it to handle raw PDUs directly.

Reimplemented in esphome::growatt_solar::GrowattSolar, esphome::havells_solar::HavellsSolar, esphome::kuntze::Kuntze, esphome::modbus_client::ModbusClientSendAction< Ts >, esphome::modbus_controller::ModbusCommandItem, esphome::pzemac::PZEMAC, esphome::pzemdc::PZEMDC, esphome::sdm_meter::SDMMeter, and esphome::selec_meter::SelecMeter.

Definition at line 458 of file modbus.h.

◆ on_sent()

virtual void esphome::modbus::ModbusClientDevice::on_sent ( std::span< const uint8_t > request_pdu)
inlinevirtual

Called when this device's frame is actually written to the wire.

Reimplemented in esphome::modbus_client::ClientActionBase< Ts >, esphome::modbus_client::ClientActionBase< Ts... >, and esphome::modbus_controller::ModbusCommandItem.

Definition at line 476 of file modbus.h.

◆ on_write_multiple_coils()

virtual void esphome::modbus::ModbusClientDevice::on_write_multiple_coils ( uint16_t start_address,
PackedBits bits,
ResponseStatus status )
inlinevirtual

Reimplemented in esphome::modbus_client::WriteMultipleCoilsAction< Ts >.

Definition at line 529 of file modbus.h.

◆ on_write_multiple_registers()

virtual void esphome::modbus::ModbusClientDevice::on_write_multiple_registers ( uint16_t start_address,
std::span< const uint16_t > registers,
ResponseStatus status )
inlinevirtual

Reimplemented in esphome::modbus_client::WriteMultipleRegistersAction< Ts >.

Definition at line 527 of file modbus.h.

◆ on_write_single_coil()

virtual void esphome::modbus::ModbusClientDevice::on_write_single_coil ( uint16_t address,
bool value,
ResponseStatus status )
inlinevirtual

Reimplemented in esphome::modbus_client::WriteSingleCoilAction< Ts >.

Definition at line 526 of file modbus.h.

◆ on_write_single_register()

virtual void esphome::modbus::ModbusClientDevice::on_write_single_register ( uint16_t address,
uint16_t value,
ResponseStatus status )
inlinevirtual

Write acknowledgements.

These deliberately mirror the read callbacks' shapes, so a write ack can be fed through the same handler as a read (registers.size() / bits.size() gives the count)

IMPORTANT - for the multi-writes these are the values that were REQUESTED, not device-confirmed state: a multi-write ack only echoes the start address and count, so the values are decoded from the request PDU, and they are delivered even when status holds an exception code. Always check status, and treat publishing them as an optimistic update rather than a read-back. The single writes are the exception: their successful ack echoes the value, so on success the delivered value is the device's echo (on an exception it falls back to the request copy).

Reimplemented in esphome::modbus_client::WriteSingleRegisterAction< Ts >.

Definition at line 525 of file modbus.h.

◆ operator=() [1/2]

ModbusClientDevice & esphome::modbus::ModbusClientDevice::operator= ( const ModbusClientDevice & )
delete

◆ operator=() [2/2]

ModbusClientDevice & esphome::modbus::ModbusClientDevice::operator= ( ModbusClientDevice && )
delete

◆ set_address()

void esphome::modbus::ModbusClientDevice::set_address ( uint8_t address)
inline

Definition at line 453 of file modbus.h.

◆ set_parent()

void esphome::modbus::ModbusClientDevice::set_parent ( ModbusClientHub * parent)
inline

Definition at line 452 of file modbus.h.

Field Documentation

◆ address_

uint8_t esphome::modbus::ModbusClientDevice::address_ {0}

Definition at line 632 of file modbus.h.

◆ custom_response_warned_

bool esphome::modbus::ModbusClientDevice::custom_response_warned_ {false}

Definition at line 633 of file modbus.h.

◆ number_of_entities

uint16_t uint16_t esphome::modbus::ModbusClientDevice::number_of_entities

Definition at line 537 of file modbus.h.

◆ parent_

ModbusClientHub* esphome::modbus::ModbusClientDevice::parent_ {nullptr}

Definition at line 631 of file modbus.h.

◆ payload

uint16_t uint16_t uint8_t const uint8_t* esphome::modbus::ModbusClientDevice::payload

Definition at line 538 of file modbus.h.

◆ payload_len

uint16_t uint16_t uint8_t esphome::modbus::ModbusClientDevice::payload_len = 0

Definition at line 537 of file modbus.h.

◆ start_address

uint16_t esphome::modbus::ModbusClientDevice::start_address

Definition at line 537 of file modbus.h.


The documentation for this class was generated from the following files: