[Modbus Controller] Added on_online and on_offline automation (#7417)

This commit is contained in:
TFGF 2024-11-12 17:48:40 -03:00 committed by GitHub
parent b367c01b4b
commit 7d75c9157b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 78 additions and 3 deletions

View File

@ -25,6 +25,8 @@ from .const import (
CONF_MODBUS_CONTROLLER_ID,
CONF_OFFLINE_SKIP_UPDATES,
CONF_ON_COMMAND_SENT,
CONF_ON_ONLINE,
CONF_ON_OFFLINE,
CONF_REGISTER_COUNT,
CONF_REGISTER_TYPE,
CONF_RESPONSE_SIZE,
@ -114,6 +116,14 @@ ModbusCommandSentTrigger = modbus_controller_ns.class_(
"ModbusCommandSentTrigger", automation.Trigger.template(cg.int_, cg.int_)
)
ModbusOnlineTrigger = modbus_controller_ns.class_(
"ModbusOnlineTrigger", automation.Trigger.template(cg.int_, cg.int_)
)
ModbusOfflineTrigger = modbus_controller_ns.class_(
"ModbusOfflineTrigger", automation.Trigger.template(cg.int_, cg.int_)
)
_LOGGER = logging.getLogger(__name__)
ModbusServerRegisterSchema = cv.Schema(
@ -146,6 +156,16 @@ CONFIG_SCHEMA = cv.All(
),
}
),
cv.Optional(CONF_ON_ONLINE): automation.validate_automation(
{
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(ModbusOnlineTrigger),
}
),
cv.Optional(CONF_ON_OFFLINE): automation.validate_automation(
{
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(ModbusOnlineTrigger),
}
),
}
)
.extend(cv.polling_component_schema("60s"))
@ -284,7 +304,17 @@ async def to_code(config):
for conf in config.get(CONF_ON_COMMAND_SENT, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(
trigger, [(int, "function_code"), (int, "address")], conf
trigger, [(cg.int_, "function_code"), (cg.int_, "address")], conf
)
for conf in config.get(CONF_ON_ONLINE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(
trigger, [(cg.int_, "function_code"), (cg.int_, "address")], conf
)
for conf in config.get(CONF_ON_OFFLINE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(
trigger, [(cg.int_, "function_code"), (cg.int_, "address")], conf
)

View File

@ -15,5 +15,21 @@ class ModbusCommandSentTrigger : public Trigger<int, int> {
}
};
class ModbusOnlineTrigger : public Trigger<int, int> {
public:
ModbusOnlineTrigger(ModbusController *a_modbuscontroller) {
a_modbuscontroller->add_on_online_callback(
[this](int function_code, int address) { this->trigger(function_code, address); });
}
};
class ModbusOfflineTrigger : public Trigger<int, int> {
public:
ModbusOfflineTrigger(ModbusController *a_modbuscontroller) {
a_modbuscontroller->add_on_offline_callback(
[this](int function_code, int address) { this->trigger(function_code, address); });
}
};
} // namespace modbus_controller
} // namespace esphome

View File

@ -9,6 +9,8 @@ CONF_MAX_CMD_RETRIES = "max_cmd_retries"
CONF_MODBUS_CONTROLLER_ID = "modbus_controller_id"
CONF_MODBUS_FUNCTIONCODE = "modbus_functioncode"
CONF_ON_COMMAND_SENT = "on_command_sent"
CONF_ON_ONLINE = "on_online"
CONF_ON_OFFLINE = "on_offline"
CONF_RAW_ENCODE = "raw_encode"
CONF_REGISTER_COUNT = "register_count"
CONF_REGISTER_TYPE = "register_type"

View File

@ -32,8 +32,10 @@ bool ModbusController::send_next_command_() {
r.skip_updates_counter = this->offline_skip_updates_;
}
}
this->module_offline_ = true;
this->offline_callback_.call((int) command->function_code, command->register_address);
}
this->module_offline_ = true;
ESP_LOGD(TAG, "Modbus command to device=%d register=0x%02X no response received - removed from send queue",
this->address_, command->register_address);
this->command_queue_.pop_front();
@ -68,8 +70,10 @@ void ModbusController::on_modbus_data(const std::vector<uint8_t> &data) {
r.skip_updates_counter = 0;
}
}
// Restore module online state
this->module_offline_ = false;
this->online_callback_.call((int) current_command->function_code, current_command->register_address);
}
this->module_offline_ = false;
// Move the commandItem to the response queue
current_command->payload = data;
@ -670,5 +674,13 @@ void ModbusController::add_on_command_sent_callback(std::function<void(int, int)
this->command_sent_callback_.add(std::move(callback));
}
void ModbusController::add_on_online_callback(std::function<void(int, int)> &&callback) {
this->online_callback_.add(std::move(callback));
}
void ModbusController::add_on_offline_callback(std::function<void(int, int)> &&callback) {
this->offline_callback_.add(std::move(callback));
}
} // namespace modbus_controller
} // namespace esphome

View File

@ -468,6 +468,10 @@ class ModbusController : public PollingComponent, public modbus::ModbusDevice {
bool get_module_offline() { return module_offline_; }
/// Set callback for commands
void add_on_command_sent_callback(std::function<void(int, int)> &&callback);
/// Set callback for online changes
void add_on_online_callback(std::function<void(int, int)> &&callback);
/// Set callback for offline changes
void add_on_offline_callback(std::function<void(int, int)> &&callback);
/// called by esphome generated code to set the max_cmd_retries.
void set_max_cmd_retries(uint8_t max_cmd_retries) { this->max_cmd_retries_ = max_cmd_retries; }
/// get how many times a command will be (re)sent if no response is received
@ -508,7 +512,12 @@ class ModbusController : public PollingComponent, public modbus::ModbusDevice {
uint16_t offline_skip_updates_;
/// How many times we will retry a command if we get no response
uint8_t max_cmd_retries_{4};
/// Command sent callback
CallbackManager<void(int, int)> command_sent_callback_{};
/// Server online callback
CallbackManager<void(int, int)> online_callback_{};
/// Server offline callback
CallbackManager<void(int, int)> offline_callback_{};
};
/** Convert vector<uint8_t> response payload to float.

View File

@ -21,6 +21,9 @@ modbus_controller:
address: 0x2
modbus_id: mod_bus1
allow_duplicate_commands: false
on_online:
then:
logger.log: "Module Online"
- id: modbus_controller2
address: 0x2
modbus_id: mod_bus2

View File

@ -13,4 +13,7 @@ modbus_controller:
address: 0x2
modbus_id: mod_bus1
allow_duplicate_commands: true
on_offline:
then:
logger.log: "Module Offline"
max_cmd_retries: 10