[modbus_controller] Allow duplicate command config (#7311)

This commit is contained in:
Tercio Filho 2024-09-02 20:56:19 -03:00 committed by GitHub
parent 3b14b0efce
commit d6eeac0619
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 26 additions and 10 deletions

View file

@ -13,6 +13,7 @@ from esphome.const import (
)
from esphome.cpp_helpers import logging
from .const import (
CONF_ALLOW_DUPLICATE_COMMANDS,
CONF_BITMASK,
CONF_BYTE_OFFSET,
CONF_COMMAND_THROTTLE,
@ -126,6 +127,7 @@ CONFIG_SCHEMA = cv.All(
cv.Schema(
{
cv.GenerateID(): cv.declare_id(ModbusController),
cv.Optional(CONF_ALLOW_DUPLICATE_COMMANDS, default=False): cv.boolean,
cv.Optional(
CONF_COMMAND_THROTTLE, default="0ms"
): cv.positive_time_period_milliseconds,
@ -253,6 +255,7 @@ async def add_modbus_base_properties(
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
cg.add(var.set_allow_duplicate_commands(config[CONF_ALLOW_DUPLICATE_COMMANDS]))
cg.add(var.set_command_throttle(config[CONF_COMMAND_THROTTLE]))
cg.add(var.set_offline_skip_updates(config[CONF_OFFLINE_SKIP_UPDATES]))
if CONF_SERVER_REGISTERS in config:

View file

@ -1,3 +1,4 @@
CONF_ALLOW_DUPLICATE_COMMANDS = "allow_duplicate_commands"
CONF_BITMASK = "bitmask"
CONF_BYTE_OFFSET = "byte_offset"
CONF_COMMAND_THROTTLE = "command_throttle"

View file

@ -175,16 +175,18 @@ void ModbusController::on_register_data(ModbusRegisterType register_type, uint16
}
void ModbusController::queue_command(const ModbusCommandItem &command) {
// check if this command is already qeued.
// not very effective but the queue is never really large
for (auto &item : command_queue_) {
if (item->is_equal(command)) {
ESP_LOGW(TAG, "Duplicate modbus command found: type=0x%x address=%u count=%u",
static_cast<uint8_t>(command.register_type), command.register_address, command.register_count);
// update the payload of the queued command
// replaces a previous command
item->payload = command.payload;
return;
if (!this->allow_duplicate_commands_) {
// check if this command is already qeued.
// not very effective but the queue is never really large
for (auto &item : command_queue_) {
if (item->is_equal(command)) {
ESP_LOGW(TAG, "Duplicate modbus command found: type=0x%x address=%u count=%u",
static_cast<uint8_t>(command.register_type), command.register_address, command.register_count);
// update the payload of the queued command
// replaces a previous command
item->payload = command.payload;
return;
}
}
}
command_queue_.push_back(make_unique<ModbusCommandItem>(command));

View file

@ -448,6 +448,12 @@ class ModbusController : public PollingComponent, public modbus::ModbusDevice {
/// incoming queue
void on_write_register_response(ModbusRegisterType register_type, uint16_t start_address,
const std::vector<uint8_t> &data);
/// Allow a duplicate command to be sent
void set_allow_duplicate_commands(bool allow_duplicate_commands) {
this->allow_duplicate_commands_ = allow_duplicate_commands;
}
/// get if a duplicate command can be sent
bool get_allow_duplicate_commands() { return this->allow_duplicate_commands_; }
/// called by esphome generated code to set the command_throttle period
void set_command_throttle(uint16_t command_throttle) { this->command_throttle_ = command_throttle; }
/// called by esphome generated code to set the offline_skip_updates
@ -482,6 +488,8 @@ class ModbusController : public PollingComponent, public modbus::ModbusDevice {
std::list<std::unique_ptr<ModbusCommandItem>> command_queue_;
/// modbus response data waiting to get processed
std::queue<std::unique_ptr<ModbusCommandItem>> incoming_queue_;
/// if duplicate commands can be sent
bool allow_duplicate_commands_;
/// when was the last send operation
uint32_t last_command_timestamp_;
/// min time in ms between sending modbus commands

View file

@ -20,6 +20,7 @@ modbus_controller:
- id: modbus_controller1
address: 0x2
modbus_id: mod_bus1
allow_duplicate_commands: false
- id: modbus_controller2
address: 0x2
modbus_id: mod_bus2

View file

@ -12,3 +12,4 @@ modbus_controller:
- id: modbus_controller1
address: 0x2
modbus_id: mod_bus1
allow_duplicate_commands: true