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

View file

@ -1,3 +1,4 @@
CONF_ALLOW_DUPLICATE_COMMANDS = "allow_duplicate_commands"
CONF_BITMASK = "bitmask" CONF_BITMASK = "bitmask"
CONF_BYTE_OFFSET = "byte_offset" CONF_BYTE_OFFSET = "byte_offset"
CONF_COMMAND_THROTTLE = "command_throttle" 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) { void ModbusController::queue_command(const ModbusCommandItem &command) {
// check if this command is already qeued. if (!this->allow_duplicate_commands_) {
// not very effective but the queue is never really large // check if this command is already qeued.
for (auto &item : command_queue_) { // not very effective but the queue is never really large
if (item->is_equal(command)) { for (auto &item : command_queue_) {
ESP_LOGW(TAG, "Duplicate modbus command found: type=0x%x address=%u count=%u", if (item->is_equal(command)) {
static_cast<uint8_t>(command.register_type), command.register_address, command.register_count); ESP_LOGW(TAG, "Duplicate modbus command found: type=0x%x address=%u count=%u",
// update the payload of the queued command static_cast<uint8_t>(command.register_type), command.register_address, command.register_count);
// replaces a previous command // update the payload of the queued command
item->payload = command.payload; // replaces a previous command
return; item->payload = command.payload;
return;
}
} }
} }
command_queue_.push_back(make_unique<ModbusCommandItem>(command)); command_queue_.push_back(make_unique<ModbusCommandItem>(command));

View file

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

View file

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

View file

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