mirror of
https://github.com/esphome/esphome.git
synced 2024-11-26 17:05:21 +01:00
Modbus Controller added some features (#5318)
This commit is contained in:
parent
bff74af882
commit
bf5352b44e
4 changed files with 38 additions and 4 deletions
|
@ -8,6 +8,7 @@ from .const import (
|
||||||
CONF_BITMASK,
|
CONF_BITMASK,
|
||||||
CONF_BYTE_OFFSET,
|
CONF_BYTE_OFFSET,
|
||||||
CONF_COMMAND_THROTTLE,
|
CONF_COMMAND_THROTTLE,
|
||||||
|
CONF_OFFLINE_SKIP_UPDATES,
|
||||||
CONF_CUSTOM_COMMAND,
|
CONF_CUSTOM_COMMAND,
|
||||||
CONF_FORCE_NEW_RANGE,
|
CONF_FORCE_NEW_RANGE,
|
||||||
CONF_MODBUS_CONTROLLER_ID,
|
CONF_MODBUS_CONTROLLER_ID,
|
||||||
|
@ -104,6 +105,7 @@ CONFIG_SCHEMA = cv.All(
|
||||||
cv.Optional(
|
cv.Optional(
|
||||||
CONF_COMMAND_THROTTLE, default="0ms"
|
CONF_COMMAND_THROTTLE, default="0ms"
|
||||||
): cv.positive_time_period_milliseconds,
|
): cv.positive_time_period_milliseconds,
|
||||||
|
cv.Optional(CONF_OFFLINE_SKIP_UPDATES, default=0): cv.positive_int,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.extend(cv.polling_component_schema("60s"))
|
.extend(cv.polling_component_schema("60s"))
|
||||||
|
@ -206,8 +208,9 @@ async def add_modbus_base_properties(
|
||||||
|
|
||||||
|
|
||||||
async def to_code(config):
|
async def to_code(config):
|
||||||
var = cg.new_Pvariable(config[CONF_ID], config[CONF_COMMAND_THROTTLE])
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
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]))
|
||||||
await register_modbus_device(var, config)
|
await register_modbus_device(var, config)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
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"
|
||||||
|
CONF_OFFLINE_SKIP_UPDATES = "offline_skip_updates"
|
||||||
CONF_CUSTOM_COMMAND = "custom_command"
|
CONF_CUSTOM_COMMAND = "custom_command"
|
||||||
CONF_FORCE_NEW_RANGE = "force_new_range"
|
CONF_FORCE_NEW_RANGE = "force_new_range"
|
||||||
CONF_MODBUS_CONTROLLER_ID = "modbus_controller_id"
|
CONF_MODBUS_CONTROLLER_ID = "modbus_controller_id"
|
||||||
|
|
|
@ -26,6 +26,17 @@ bool ModbusController::send_next_command_() {
|
||||||
|
|
||||||
// remove from queue if command was sent too often
|
// remove from queue if command was sent too often
|
||||||
if (command->send_countdown < 1) {
|
if (command->send_countdown < 1) {
|
||||||
|
if (!this->module_offline_) {
|
||||||
|
ESP_LOGW(TAG, "Modbus device=%d set offline", this->address_);
|
||||||
|
|
||||||
|
if (this->offline_skip_updates_ > 0) {
|
||||||
|
// Update skip_updates_counter to stop flooding channel with timeouts
|
||||||
|
for (auto &r : this->register_ranges_) {
|
||||||
|
r.skip_updates_counter = this->offline_skip_updates_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->module_offline_ = true;
|
||||||
ESP_LOGD(
|
ESP_LOGD(
|
||||||
TAG,
|
TAG,
|
||||||
"Modbus command to device=%d register=0x%02X countdown=%d no response received - removed from send queue",
|
"Modbus command to device=%d register=0x%02X countdown=%d no response received - removed from send queue",
|
||||||
|
@ -49,6 +60,18 @@ bool ModbusController::send_next_command_() {
|
||||||
void ModbusController::on_modbus_data(const std::vector<uint8_t> &data) {
|
void ModbusController::on_modbus_data(const std::vector<uint8_t> &data) {
|
||||||
auto ¤t_command = this->command_queue_.front();
|
auto ¤t_command = this->command_queue_.front();
|
||||||
if (current_command != nullptr) {
|
if (current_command != nullptr) {
|
||||||
|
if (this->module_offline_) {
|
||||||
|
ESP_LOGW(TAG, "Modbus device=%d back online", this->address_);
|
||||||
|
|
||||||
|
if (this->offline_skip_updates_ > 0) {
|
||||||
|
// Restore skip_updates_counter to restore commands updates
|
||||||
|
for (auto &r : this->register_ranges_) {
|
||||||
|
r.skip_updates_counter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->module_offline_ = false;
|
||||||
|
|
||||||
// Move the commandItem to the response queue
|
// Move the commandItem to the response queue
|
||||||
current_command->payload = data;
|
current_command->payload = data;
|
||||||
this->incoming_queue_.push(std::move(current_command));
|
this->incoming_queue_.push(std::move(current_command));
|
||||||
|
|
|
@ -409,7 +409,6 @@ class ModbusCommandItem {
|
||||||
|
|
||||||
class ModbusController : public PollingComponent, public modbus::ModbusDevice {
|
class ModbusController : public PollingComponent, public modbus::ModbusDevice {
|
||||||
public:
|
public:
|
||||||
ModbusController(uint16_t throttle = 0) : command_throttle_(throttle){};
|
|
||||||
void dump_config() override;
|
void dump_config() override;
|
||||||
void loop() override;
|
void loop() override;
|
||||||
void setup() override;
|
void setup() override;
|
||||||
|
@ -431,6 +430,12 @@ class ModbusController : public PollingComponent, public modbus::ModbusDevice {
|
||||||
const std::vector<uint8_t> &data);
|
const std::vector<uint8_t> &data);
|
||||||
/// 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
|
||||||
|
void set_offline_skip_updates(uint16_t offline_skip_updates) { this->offline_skip_updates_ = offline_skip_updates; }
|
||||||
|
/// get the number of queued modbus commands (should be mostly empty)
|
||||||
|
size_t get_command_queue_length() { return command_queue_.size(); }
|
||||||
|
/// get if the module is offline, didn't respond the last command
|
||||||
|
bool get_module_offline() { return module_offline_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// parse sensormap_ and create range of sequential addresses
|
/// parse sensormap_ and create range of sequential addresses
|
||||||
|
@ -443,8 +448,6 @@ class ModbusController : public PollingComponent, public modbus::ModbusDevice {
|
||||||
void process_modbus_data_(const ModbusCommandItem *response);
|
void process_modbus_data_(const ModbusCommandItem *response);
|
||||||
/// send the next modbus command from the send queue
|
/// send the next modbus command from the send queue
|
||||||
bool send_next_command_();
|
bool send_next_command_();
|
||||||
/// get the number of queued modbus commands (should be mostly empty)
|
|
||||||
size_t get_command_queue_length_() { return command_queue_.size(); }
|
|
||||||
/// dump the parsed sensormap for diagnostics
|
/// dump the parsed sensormap for diagnostics
|
||||||
void dump_sensors_();
|
void dump_sensors_();
|
||||||
/// Collection of all sensors for this component
|
/// Collection of all sensors for this component
|
||||||
|
@ -459,6 +462,10 @@ class ModbusController : public PollingComponent, public modbus::ModbusDevice {
|
||||||
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
|
||||||
uint16_t command_throttle_;
|
uint16_t command_throttle_;
|
||||||
|
/// if module didn't respond the last command
|
||||||
|
bool module_offline_;
|
||||||
|
/// how many updates to skip if module is offline
|
||||||
|
uint16_t offline_skip_updates_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Convert vector<uint8_t> response payload to float.
|
/** Convert vector<uint8_t> response payload to float.
|
||||||
|
|
Loading…
Reference in a new issue