72 if (!this->queue_pdu(pdu))
100 void on_response(std::span<const uint8_t> request_pdu, std::span<const uint8_t> response_pdu)
override {
151 void play(
const Ts &...
x)
override {
152 const auto function_code =
178 void play(
const Ts &...
x)
override {
179 const auto function_code =
204 void play(
const Ts &...
x)
override {
226 void play(
const Ts &...
x)
override {
248 void set_values_static(const uint16_t *values,
size_t len) {
261 void play(
const Ts &...
x)
override {
262 const uint16_t start = this->start_address_.value(
x...);
265 if (this->
len_ >= 0) {
267 start, std::span<const uint16_t>(this->
values_.
data,
static_cast<size_t>(this->len_))));
270 const std::vector<uint16_t> values = this->
values_.
func(x...);
283 std::vector<uint16_t> (*
func)(Ts...);
297 void set_values_static(const uint8_t *packed,
size_t count) {
309 void play(
const Ts &...
x)
override {
310 const uint16_t start = this->start_address_.value(
x...);
312 const auto count =
static_cast<uint16_t
>(this->
count_);
331 std::vector<bool> (*
func)(Ts...);
345 void set_values_static(const uint16_t *values,
size_t len) {
357 void play(
const Ts &...
x)
override {
358 const uint16_t read_start = this->read_address_.value(
x...);
359 const uint16_t read_count = this->read_count_.value(
x...);
360 const uint16_t write_start = this->write_address_.value(
x...);
362 if (this->
len_ >= 0) {
364 read_start, read_count, write_start,
365 std::span<const uint16_t>(this->
values_.
data,
static_cast<size_t>(this->len_))));
368 const std::vector<uint16_t> values = this->
values_.
func(x...);
370 read_start, read_count, write_start, std::span<const uint16_t>(values)));
383 std::vector<uint16_t> (*
func)(Ts...);
virtual void play_complex(const Ts &...x)
Minimal static vector - saves memory by avoiding std::vector overhead.
void trigger(const Ts &...x) ESPHOME_ALWAYS_INLINE
Inform the parent automation that the event has triggered.
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 d...
void set_address(uint8_t address)
Read-only view of Modbus-packed bits: bit 0 of byte 0 is the first bit (LSB first),...
Shared base for the modbus_client actions.
Trigger< std::span< const uint8_t > > sent_trigger_
void on_sent(std::span< const uint8_t > request_pdu) override
The frame was written to the wire: fires once per transmission, before any reply, and never for a sen...
Trigger< std::span< const uint8_t >, modbus::ExceptionCode > * get_error_trigger()
Trigger< std::span< const uint8_t > > not_sent_trigger_
void play_complex(const Ts &...x) override
Stamp the templated device address before every play(): subclasses cannot forget it,...
TEMPLATABLE_VALUE(uint8_t, target_address) Trigger< std
void on_not_sent(std::span< const uint8_t > request_pdu) override
Never reached the wire, from either of two sources.
void send_or_resolve_(std::span< const uint8_t > pdu)
The hub refuses some sends at the door with no callback (a duplicate write already pending,...
bool(*)(std::span< const uint8_t >) retry_func_t
The retry decision for on_no_response: given the request PDU, return true to have the hub re-queue th...
bool on_no_response(std::span< const uint8_t > request_pdu) override
No reply within send_wait_time.
void set_retry(retry_func_t f)
Trigger< std::span< const uint8_t > > * get_no_response_trigger()
Trigger< std::span< const uint8_t >, modbus::ExceptionCode > error_trigger_
Trigger< std::span< const uint8_t > > * get_not_sent_trigger()
Trigger< std::span< const uint8_t > > no_response_trigger_
void on_error(std::span< const uint8_t > request_pdu, modbus::ExceptionCode exception_code) override
A Modbus exception reply.
modbus_client.send: fire a raw PDU (function code + data; the hub adds address and CRC).
Trigger< std::span< const uint8_t >, std::span< const uint8_t > > response_trigger_
void on_response(std::span< const uint8_t > request_pdu, std::span< const uint8_t > response_pdu) override
void play(const Ts &...x) override
TEMPLATABLE_VALUE(modbus::helpers::PduBuffer, pdu) Trigger< std
modbus_client.read_coils / read_discrete_inputs: on_response delivers the bits as a PackedBits view (...
TEMPLATABLE_VALUE(uint16_t, start_address) TEMPLATABLE_VALUE(uint16_t
void play(const Ts &...x) override
Trigger< modbus::PackedBits > response_trigger_
void on_read_bits(modbus::EntityType entity_type, uint16_t start_address, modbus::PackedBits bits, modbus::ResponseStatus status) override
ReadBitsAction(bool coils)
count Trigger< modbus::PackedBits > * get_response_trigger()
modbus_client.read_holding_registers / read_input_registers: on_response delivers the registers in ho...
count Trigger< std::span< const uint16_t > > * get_response_trigger()
void on_read_registers(modbus::EntityType entity_type, uint16_t start_address, std::span< const uint16_t > registers, modbus::ResponseStatus status) override
TEMPLATABLE_VALUE(uint16_t, start_address) TEMPLATABLE_VALUE(uint16_t
void play(const Ts &...x) override
ReadRegistersAction(bool holding)
Trigger< std::span< const uint16_t > > response_trigger_
modbus_client.read_write_multiple_registers (FC 0x17): writes one register block and reads another ba...
void on_read_registers(modbus::EntityType entity_type, uint16_t start_address, std::span< const uint16_t > registers, modbus::ResponseStatus status) override
void play(const Ts &...x) override
Trigger< std::span< const uint16_t > > response_trigger_
Trigger< std::span< const uint16_t > > * get_response_trigger()
TEMPLATABLE_VALUE(uint16_t, read_address) TEMPLATABLE_VALUE(uint16_t
void set_values_template(std::vector< uint16_t >(*func)(Ts...))
Lambda config: the write registers are only known at play() time.
union esphome::modbus_client::ReadWriteMultipleRegistersAction::Values values_
Typed actions: these do NOT override the raw on_response, so the base ModbusClientDevice default runs...
void on_custom_response(std::span< const uint8_t > request_pdu, std::span< const uint8_t > response_pdu, modbus::ResponseStatus status) override
Trigger< std::span< const uint8_t >, std::span< const uint8_t > > custom_response_trigger_
bool custom_response_handled_
Trigger< std::span< const uint8_t >, std::span< const uint8_t > > * get_custom_response_trigger()
void set_custom_response_handled()
Set by codegen when the config declares on_custom_response.
modbus_client.write_multiple_coils: on_response is the acknowledgement (no arguments).
union esphome::modbus_client::WriteMultipleCoilsAction::Values values_
TEMPLATABLE_VALUE(uint16_t, start_address) void set_values_static(const uint8_t *packed
Static config: packed is the wire layout (LSB first) held in flash, count the number of coils.
Trigger * get_response_trigger()
void on_write_multiple_coils(uint16_t start_address, modbus::PackedBits bits, modbus::ResponseStatus status) override
void set_values_template(std::vector< bool >(*func)(Ts...))
Lambda config: the coils are only known at play() time.
Trigger response_trigger_
void play(const Ts &...x) override
modbus_client.write_multiple_registers: on_response is the acknowledgement (no arguments).
Trigger response_trigger_
TEMPLATABLE_VALUE(uint16_t, start_address) void set_values_static(const uint16_t *values
Static config: the registers live in flash, so play() neither allocates nor copies.
Trigger * get_response_trigger()
void play(const Ts &...x) override
void set_values_template(std::vector< uint16_t >(*func)(Ts...))
Lambda config: the registers are only known at play() time.
union esphome::modbus_client::WriteMultipleRegistersAction::Values values_
void on_write_multiple_registers(uint16_t start_address, std::span< const uint16_t > registers, modbus::ResponseStatus status) override
modbus_client.write_single_coil: on_response is the acknowledgement (no arguments).
void on_write_single_coil(uint16_t address, bool value, modbus::ResponseStatus status) override
void play(const Ts &...x) override
value Trigger * get_response_trigger()
TEMPLATABLE_VALUE(uint16_t, start_address) TEMPLATABLE_VALUE(bool
Trigger response_trigger_
modbus_client.write_single_register: on_response is the acknowledgement (the ack only echoes the requ...
TEMPLATABLE_VALUE(uint16_t, start_address) TEMPLATABLE_VALUE(uint16_t
value Trigger * get_response_trigger()
void play(const Ts &...x) override
Trigger response_trigger_
void on_write_single_register(uint16_t address, uint16_t value, modbus::ResponseStatus status) override
PduBuffer create_write_coils_pdu(uint16_t start_address, PackedBits bits)
Create modbus write multiple coils command (function 0x0F) from bits packed as on the wire.
WriteSinglePdu create_write_single_coil_pdu(uint16_t address, bool value)
Create modbus write single coil command Function 0x05 Write Single Coil.
ReadPdu create_read_pdu(FunctionCode function_code, uint16_t start_address, uint16_t number_of_entities)
Create a modbus read request PDU.
WriteSinglePdu create_write_single_register_pdu(uint16_t start_address, uint16_t value)
Create modbus write single register command Function 0x06 Write Single Register.
PduBuffer create_write_registers_pdu(uint16_t start_address, std::span< const uint16_t > values)
Create modbus write multiple registers command Function 0x10 Write Multiple Registers.
PduBuffer create_read_write_multiple_registers_pdu(uint16_t read_start_address, uint16_t read_count, uint16_t write_start_address, std::span< const uint16_t > write_values)
Create modbus read/write multiple registers command Function 0x17 Read/Write Multiple Registers Write...
std::optional< ExceptionCode > ResponseStatus
bool succeeded(ResponseStatus status)
True when a transaction carried no exception.
constexpr size_t packed_bit_bytes(size_t bits)
Bits pack 8 per data byte, rounded up to whole bytes.
std::vector< uint16_t >(* func)(Ts...)
std::vector< bool >(* func)(Ts...)
std::vector< uint16_t >(* func)(Ts...)