ESPHome 2026.8.0-dev
Loading...
Searching...
No Matches
modbus_select.cpp
Go to the documentation of this file.
1#include "modbus_select.h"
2#include "esphome/core/log.h"
3
5
6static const char *const TAG = "modbus_controller.select";
7
8void ModbusSelect::dump_config() { LOG_SELECT(TAG, "Modbus Controller Select", this); }
9
10void ModbusSelect::parse_and_publish(const std::vector<uint8_t> &data) {
11 int64_t value = modbus::helpers::payload_to_number(std::span<const uint8_t>(data), this->sensor_value_type,
12 this->offset, this->bitmask)
13 .value_or(0);
14
15 ESP_LOGD(TAG, "New select value %lld from payload", value);
16
17 optional<std::string> new_state;
18
19 if (this->transform_func_.has_value()) {
20 auto val = (*this->transform_func_)(this, value, data);
21 if (val.has_value()) {
22 new_state = *val;
23 ESP_LOGV(TAG, "lambda returned option %s", new_state->c_str());
24 }
25 }
26
27 if (!new_state.has_value()) {
28 auto map_it = std::find(this->mapping_.cbegin(), this->mapping_.cend(), value);
29
30 if (map_it != this->mapping_.cend()) {
31 size_t idx = std::distance(this->mapping_.cbegin(), map_it);
32 ESP_LOGV(TAG, "Found option %s for value %lld", this->option_at(idx), value);
33 this->publish_state(idx);
34 return;
35 } else {
36 ESP_LOGE(TAG, "No option found for mapping %lld", value);
37 }
38 }
39
40 if (new_state.has_value()) {
41 this->publish_state(new_state.value());
42 }
43}
44
45void ModbusSelect::control(size_t index) {
46 optional<int64_t> mapval = this->mapping_[index];
47 const char *option = this->option_at(index);
48 ESP_LOGD(TAG, "Found value %lld for option '%s'", *mapval, option);
49
50 std::vector<uint16_t> data;
51
52 if (this->write_transform_func_.has_value()) {
53 // Transform func requires string parameter for backward compatibility
54 auto val = (*this->write_transform_func_)(this, std::string(option), *mapval, data);
55 if (val.has_value()) {
56 mapval = val;
57 ESP_LOGV(TAG, "write_lambda returned mapping value %lld", *mapval);
58 } else {
59 ESP_LOGD(TAG, "Communication handled by write_lambda - exiting control");
60 return;
61 }
62 }
63
64 if (data.empty()) {
66 } else {
67 ESP_LOGV(TAG, "Using payload from write lambda");
68 }
69
70 if (data.empty()) {
71 ESP_LOGW(TAG, "No payload was created for updating select");
72 return;
73 }
74
75 const uint16_t write_address = this->start_address + this->offset / 2;
76 ModbusCommandItem write_cmd;
77 if ((this->register_count == 1) && (!this->use_write_multiple_)) {
78 write_cmd = ModbusCommandItem::create_write_single_command(this->parent_, write_address, data[0]);
79 } else {
80 write_cmd =
82 }
83
84 this->parent_->queue_command(write_cmd);
85
86 if (this->optimistic_)
87 this->publish_state(index);
88}
89
90} // namespace esphome::modbus_controller
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 queue_command(const ModbusCommandItem &command)
queues a modbus command in the send queue
optional< write_transform_func_t > write_transform_func_
void parse_and_publish(const std::vector< uint8_t > &data) override
void control(size_t index) override
optional< transform_func_t > transform_func_
const char * option_at(size_t index) const
Return the option value at the provided index offset (as const char* from flash).
Definition select.cpp:77
void publish_state(const std::string &state)
Definition select.cpp:11
mopeka_std_values val[3]
void number_to_payload(Container &data, int64_t value, SensorValueType value_type)
Append the Modbus register words for value to data.
std::optional< int64_t > payload_to_number(const uint8_t *data, size_t size, SensorValueType sensor_value_type, uint8_t offset, uint32_t bitmask)
Convert a raw response payload to a number.
const std::vector< uint8_t > & data