ESPHome 2025.6.0
Loading...
Searching...
No Matches
modbus_switch.cpp
Go to the documentation of this file.
1
2#include "modbus_switch.h"
3#include "esphome/core/log.h"
4namespace esphome {
5namespace modbus_controller {
6
7static const char *const TAG = "modbus_controller.switch";
8
10 optional<bool> initial_state = Switch::get_initial_state_with_restore_mode();
11 if (initial_state.has_value()) {
12 // if it has a value, restore_mode is not "DISABLED", therefore act on the switch:
13 if (initial_state.value()) {
14 this->turn_on();
15 } else {
16 this->turn_off();
17 }
18 }
19}
20void ModbusSwitch::dump_config() { LOG_SWITCH(TAG, "Modbus Controller Switch", this); }
21
23
25
26void ModbusSwitch::parse_and_publish(const std::vector<uint8_t> &data) {
27 bool value = false;
28 switch (this->register_type) {
31 // offset for coil is the actual number of the coil not the byte offset
32 value = coil_from_vector(this->offset, data);
33 break;
34 default:
35 value = get_data<uint16_t>(data, this->offset) & this->bitmask;
36 break;
37 }
38
39 // Is there a lambda registered
40 // call it with the pre converted value and the raw data array
41 if (this->publish_transform_func_) {
42 // the lambda can parse the response itself
43 auto val = (*this->publish_transform_func_)(this, value, data);
44 if (val.has_value()) {
45 ESP_LOGV(TAG, "Value overwritten by lambda");
46 value = val.value();
47 }
48 }
49
50 ESP_LOGV(TAG, "Publish '%s': new value = %s type = %d address = %X offset = %x", this->get_name().c_str(),
51 ONOFF(value), (int) this->register_type, this->start_address, this->offset);
52 this->publish_state(value);
53}
54
56 // This will be called every time the user requests a state change.
58 std::vector<uint8_t> data;
59 // Is there are lambda configured?
60 if (this->write_transform_func_.has_value()) {
61 // data is passed by reference
62 // the lambda can fill the empty vector directly
63 // in that case the return value is ignored
64 auto val = (*this->write_transform_func_)(this, state, data);
65 if (val.has_value()) {
66 ESP_LOGV(TAG, "Value overwritten by lambda");
67 state = val.value();
68 } else {
69 ESP_LOGV(TAG, "Communication handled by lambda - exiting control");
70 return;
71 }
72 }
73 if (!data.empty()) {
74 ESP_LOGV(TAG, "Modbus Switch write raw: %s", format_hex_pretty(data).c_str());
76 this->parent_, data,
77 [this, cmd](ModbusRegisterType register_type, uint16_t start_address, const std::vector<uint8_t> &data) {
78 this->parent_->on_write_register_response(cmd.register_type, this->start_address, data);
79 });
80 } else {
81 ESP_LOGV(TAG, "write_state '%s': new value = %s type = %d address = %X offset = %x", this->get_name().c_str(),
82 ONOFF(state), (int) this->register_type, this->start_address, this->offset);
83 if (this->register_type == ModbusRegisterType::COIL) {
84 // offset for coil and discrete inputs is the coil/register number not bytes
85 if (this->use_write_multiple_) {
86 std::vector<bool> states{state};
88 } else {
90 }
91 } else {
92 // since offset is in bytes and a register is 16 bits we get the start by adding offset/2
93 if (this->use_write_multiple_) {
94 std::vector<uint16_t> bool_states(1, state ? (0xFFFF & this->bitmask) : 0);
96 bool_states);
97 } else {
99 state ? 0xFFFF & this->bitmask : 0u);
100 }
101 }
102 }
103 this->parent_->queue_command(cmd);
104 this->publish_state(state);
105}
106// ModbusSwitch end
107} // namespace modbus_controller
108} // namespace esphome
const StringRef & get_name() const
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
optional< write_transform_func_t > write_transform_func_
void set_assumed_state(bool assumed_state)
void parse_and_publish(const std::vector< uint8_t > &data) override
optional< transform_func_t > publish_transform_func_
bool has_value() const
Definition optional.h:87
value_type const & value() const
Definition optional.h:89
void turn_on()
Turn this switch on.
Definition switch.cpp:11
void turn_off()
Turn this switch off.
Definition switch.cpp:15
bool state
The current reported state of the binary sensor.
Definition switch.h:56
void publish_state(bool state)
Publish a state to the front-end from the back-end.
Definition switch.cpp:47
bool state
Definition fan.h:0
mopeka_std_values val[4]
bool coil_from_vector(int coil, const std::vector< uint8_t > &data)
Extract coil data from modbus response buffer Responses for coil are packed into bytes .
T get_data(const std::vector< uint8_t > &data, size_t buffer_offset)
Extract data from modbus response buffer.
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