ESPHome 2025.6.3
Loading...
Searching...
No Matches
modbus_output.cpp
Go to the documentation of this file.
1#include "modbus_output.h"
3#include "esphome/core/log.h"
4
5namespace esphome {
6namespace modbus_controller {
7
8static const char *const TAG = "modbus_controller.output";
9
14 std::vector<uint16_t> data;
15 auto original_value = value;
16 // Is there are lambda configured?
17 if (this->write_transform_func_.has_value()) {
18 // data is passed by reference
19 // the lambda can fill the empty vector directly
20 // in that case the return value is ignored
21 auto val = (*this->write_transform_func_)(this, value, data);
22 if (val.has_value()) {
23 ESP_LOGV(TAG, "Value overwritten by lambda");
24 value = val.value();
25 } else {
26 ESP_LOGV(TAG, "Communication handled by lambda - exiting control");
27 return;
28 }
29 } else {
30 value = this->multiply_by_ * value;
31 }
32 // lambda didn't set payload
33 if (data.empty()) {
34 data = float_to_payload(value, this->sensor_value_type);
35 }
36
37 ESP_LOGD(TAG, "Updating register: start address=0x%X register count=%d new value=%.02f (val=%.02f)",
38 this->start_address, this->register_count, value, original_value);
39
40 // Create and send the write command
41 ModbusCommandItem write_cmd;
42 if (this->register_count == 1 && !this->use_write_multiple_) {
43 write_cmd =
45 } else {
47 this->register_count, data);
48 }
49 this->parent_->queue_command(write_cmd);
50}
51
53 ESP_LOGCONFIG(TAG, "Modbus Float Output:");
54 LOG_FLOAT_OUTPUT(this);
55 ESP_LOGCONFIG(TAG,
56 " Device start address: 0x%X\n"
57 " Register count: %d\n"
58 " Value type: %d",
59 this->start_address, this->register_count, static_cast<int>(this->sensor_value_type));
60}
61
62// ModbusBinaryOutput
64 // This will be called every time the user requests a state change.
66 std::vector<uint8_t> data;
67
68 // Is there are lambda configured?
69 if (this->write_transform_func_.has_value()) {
70 // data is passed by reference
71 // the lambda can fill the empty vector directly
72 // in that case the return value is ignored
73 auto val = (*this->write_transform_func_)(this, state, data);
74 if (val.has_value()) {
75 ESP_LOGV(TAG, "Value overwritten by lambda");
76 state = val.value();
77 } else {
78 ESP_LOGV(TAG, "Communication handled by lambda - exiting control");
79 return;
80 }
81 }
82 if (!data.empty()) {
83 ESP_LOGV(TAG, "Modbus binary output write raw: %s", format_hex_pretty(data).c_str());
85 this->parent_, data,
86 [this, cmd](ModbusRegisterType register_type, uint16_t start_address, const std::vector<uint8_t> &data) {
87 this->parent_->on_write_register_response(cmd.register_type, this->start_address, data);
88 });
89 } else {
90 ESP_LOGV(TAG, "Write new state: value is %s, type is %d address = %X, offset = %x", ONOFF(state),
91 (int) this->register_type, this->start_address, this->offset);
92
93 // offset for coil and discrete inputs is the coil/register number not bytes
94 if (this->use_write_multiple_) {
95 std::vector<bool> states{state};
97 } else {
99 }
100 }
101 this->parent_->queue_command(cmd);
102}
103
105 ESP_LOGCONFIG(TAG, "Modbus Binary Output:");
106 LOG_BINARY_OUTPUT(this);
107 ESP_LOGCONFIG(TAG,
108 " Device start address: 0x%X\n"
109 " Register count: %d\n"
110 " Value type: %d",
111 this->start_address, this->register_count, static_cast<int>(this->sensor_value_type));
112}
113
114} // namespace modbus_controller
115} // namespace esphome
optional< write_transform_func_t > write_transform_func_
static ModbusCommandItem create_custom_command(ModbusController *modbusdevice, const std::vector< uint8_t > &values, std::function< void(ModbusRegisterType register_type, uint16_t start_address, const std::vector< uint8_t > &data)> &&handler=nullptr)
Create custom modbus command.
static ModbusCommandItem create_write_multiple_coils(ModbusController *modbusdevice, uint16_t start_address, const std::vector< bool > &values)
Create modbus write multiple registers command Function 15 (0Fhex) Write Multiple Coils.
static ModbusCommandItem create_write_single_coil(ModbusController *modbusdevice, uint16_t address, bool value)
Create modbus write single registers command Function 05 (05hex) Write Single Coil.
static ModbusCommandItem create_write_single_command(ModbusController *modbusdevice, uint16_t start_address, uint16_t value)
Create modbus write multiple registers command Function 16 (10hex) Write Multiple Registers.
static ModbusCommandItem create_write_multiple_command(ModbusController *modbusdevice, uint16_t start_address, uint16_t register_count, const std::vector< uint16_t > &values)
Create modbus read command Function code 02-04.
void on_write_register_response(ModbusRegisterType register_type, uint16_t start_address, const std::vector< uint8_t > &data)
default delegate called by process_modbus_data when a response for a write response has retrieved fro...
void queue_command(const ModbusCommandItem &command)
queues a modbus command in the send queue
void write_state(float value) override
Write a value to the device.
optional< write_transform_func_t > write_transform_func_
bool has_value() const
Definition optional.h:87
bool state
Definition fan.h:0
mopeka_std_values val[4]
std::vector< uint16_t > float_to_payload(float value, SensorValueType value_type)
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
std::string format_hex_pretty(const uint8_t *data, size_t length)
Format the byte array data of length len in pretty-printed, human-readable hex.
Definition helpers.cpp:372