Modbus number/output use write single (#2896)

Co-authored-by: Martin <25747549+martgras@users.noreply.github.com>
This commit is contained in:
Guillermo Ruffino 2021-12-09 17:44:43 -03:00 committed by Jesse Hills
parent 649366ff44
commit 708b928c73
No known key found for this signature in database
GPG key ID: BEAAE804EFD8E83A
8 changed files with 27 additions and 6 deletions

View file

@ -10,5 +10,6 @@ CONF_REGISTER_COUNT = "register_count"
CONF_REGISTER_TYPE = "register_type" CONF_REGISTER_TYPE = "register_type"
CONF_RESPONSE_SIZE = "response_size" CONF_RESPONSE_SIZE = "response_size"
CONF_SKIP_UPDATES = "skip_updates" CONF_SKIP_UPDATES = "skip_updates"
CONF_USE_WRITE_MULTIPLE = "use_write_multiple"
CONF_VALUE_TYPE = "value_type" CONF_VALUE_TYPE = "value_type"
CONF_WRITE_LAMBDA = "write_lambda" CONF_WRITE_LAMBDA = "write_lambda"

View file

@ -25,6 +25,7 @@ from ..const import (
CONF_FORCE_NEW_RANGE, CONF_FORCE_NEW_RANGE,
CONF_MODBUS_CONTROLLER_ID, CONF_MODBUS_CONTROLLER_ID,
CONF_SKIP_UPDATES, CONF_SKIP_UPDATES,
CONF_USE_WRITE_MULTIPLE,
CONF_VALUE_TYPE, CONF_VALUE_TYPE,
CONF_WRITE_LAMBDA, CONF_WRITE_LAMBDA,
) )
@ -69,6 +70,7 @@ CONFIG_SCHEMA = cv.All(
cv.Optional(CONF_MIN_VALUE, default=-16777215.0): cv.float_, cv.Optional(CONF_MIN_VALUE, default=-16777215.0): cv.float_,
cv.Optional(CONF_STEP, default=1): cv.positive_float, cv.Optional(CONF_STEP, default=1): cv.positive_float,
cv.Optional(CONF_MULTIPLY, default=1.0): cv.float_, cv.Optional(CONF_MULTIPLY, default=1.0): cv.float_,
cv.Optional(CONF_USE_WRITE_MULTIPLE, default=False): cv.boolean,
} }
) )
.extend(cv.polling_component_schema("60s")), .extend(cv.polling_component_schema("60s")),
@ -105,6 +107,7 @@ async def to_code(config):
cg.add(var.set_parent(parent)) cg.add(var.set_parent(parent))
cg.add(parent.add_sensor_item(var)) cg.add(parent.add_sensor_item(var))
await add_modbus_base_properties(var, config, ModbusNumber) await add_modbus_base_properties(var, config, ModbusNumber)
cg.add(var.set_use_write_mutiple(config[CONF_USE_WRITE_MULTIPLE]))
if CONF_WRITE_LAMBDA in config: if CONF_WRITE_LAMBDA in config:
template_ = await cg.process_lambda( template_ = await cg.process_lambda(
config[CONF_WRITE_LAMBDA], config[CONF_WRITE_LAMBDA],

View file

@ -55,9 +55,13 @@ void ModbusNumber::control(float value) {
this->get_name().c_str(), this->start_address, this->register_count, write_value, write_value); this->get_name().c_str(), this->start_address, this->register_count, write_value, write_value);
// Create and send the write command // Create and send the write command
auto write_cmd = ModbusCommandItem::create_write_multiple_command(parent_, this->start_address + this->offset, ModbusCommandItem write_cmd;
if (this->register_count == 1 && !this->use_write_multiple_) {
write_cmd = ModbusCommandItem::create_write_single_command(parent_, this->start_address + this->offset, data[0]);
} else {
write_cmd = ModbusCommandItem::create_write_multiple_command(parent_, this->start_address + this->offset,
this->register_count, data); this->register_count, data);
}
// publish new value // publish new value
write_cmd.on_data_func = [this, write_cmd, value](ModbusRegisterType register_type, uint16_t start_address, write_cmd.on_data_func = [this, write_cmd, value](ModbusRegisterType register_type, uint16_t start_address,
const std::vector<uint8_t> &data) { const std::vector<uint8_t> &data) {

View file

@ -35,6 +35,7 @@ class ModbusNumber : public number::Number, public Component, public SensorItem
using write_transform_func_t = std::function<optional<float>(ModbusNumber *, float, std::vector<uint16_t> &)>; using write_transform_func_t = std::function<optional<float>(ModbusNumber *, float, std::vector<uint16_t> &)>;
void set_template(transform_func_t &&f) { this->transform_func_ = f; } void set_template(transform_func_t &&f) { this->transform_func_ = f; }
void set_write_template(write_transform_func_t &&f) { this->write_transform_func_ = f; } void set_write_template(write_transform_func_t &&f) { this->write_transform_func_ = f; }
void set_use_write_mutiple(bool use_write_multiple) { this->use_write_multiple_ = use_write_multiple; }
protected: protected:
void control(float value) override; void control(float value) override;
@ -42,6 +43,7 @@ class ModbusNumber : public number::Number, public Component, public SensorItem
optional<write_transform_func_t> write_transform_func_; optional<write_transform_func_t> write_transform_func_;
ModbusController *parent_; ModbusController *parent_;
float multiply_by_{1.0}; float multiply_by_{1.0};
bool use_write_multiple_{false};
}; };
} // namespace modbus_controller } // namespace modbus_controller

View file

@ -18,6 +18,7 @@ from .. import (
from ..const import ( from ..const import (
CONF_MODBUS_CONTROLLER_ID, CONF_MODBUS_CONTROLLER_ID,
CONF_USE_WRITE_MULTIPLE,
CONF_VALUE_TYPE, CONF_VALUE_TYPE,
CONF_WRITE_LAMBDA, CONF_WRITE_LAMBDA,
) )
@ -36,6 +37,7 @@ CONFIG_SCHEMA = cv.All(
cv.GenerateID(): cv.declare_id(ModbusOutput), cv.GenerateID(): cv.declare_id(ModbusOutput),
cv.Optional(CONF_WRITE_LAMBDA): cv.returning_lambda, cv.Optional(CONF_WRITE_LAMBDA): cv.returning_lambda,
cv.Optional(CONF_MULTIPLY, default=1.0): cv.float_, cv.Optional(CONF_MULTIPLY, default=1.0): cv.float_,
cv.Optional(CONF_USE_WRITE_MULTIPLE, default=False): cv.boolean,
} }
), ),
validate_modbus_register, validate_modbus_register,
@ -54,6 +56,7 @@ async def to_code(config):
await output.register_output(var, config) await output.register_output(var, config)
cg.add(var.set_write_multiply(config[CONF_MULTIPLY])) cg.add(var.set_write_multiply(config[CONF_MULTIPLY]))
parent = await cg.get_variable(config[CONF_MODBUS_CONTROLLER_ID]) parent = await cg.get_variable(config[CONF_MODBUS_CONTROLLER_ID])
cg.add(var.set_use_write_mutiple(config[CONF_USE_WRITE_MULTIPLE]))
cg.add(var.set_parent(parent)) cg.add(var.set_parent(parent))
if CONF_WRITE_LAMBDA in config: if CONF_WRITE_LAMBDA in config:
template_ = await cg.process_lambda( template_ = await cg.process_lambda(

View file

@ -40,8 +40,14 @@ void ModbusOutput::write_state(float value) {
this->start_address, this->register_count, value, original_value); this->start_address, this->register_count, value, original_value);
// Create and send the write command // Create and send the write command
auto write_cmd = // Create and send the write command
ModbusCommandItem::create_write_multiple_command(parent_, this->start_address, this->register_count, data); ModbusCommandItem write_cmd;
if (this->register_count == 1 && !this->use_write_multiple_) {
write_cmd = ModbusCommandItem::create_write_single_command(parent_, this->start_address + this->offset, data[0]);
} else {
write_cmd = ModbusCommandItem::create_write_multiple_command(parent_, this->start_address + this->offset,
this->register_count, data);
}
parent_->queue_command(write_cmd); parent_->queue_command(write_cmd);
} }

View file

@ -33,6 +33,7 @@ class ModbusOutput : public output::FloatOutput, public Component, public Sensor
using write_transform_func_t = std::function<optional<float>(ModbusOutput *, float, std::vector<uint16_t> &)>; using write_transform_func_t = std::function<optional<float>(ModbusOutput *, float, std::vector<uint16_t> &)>;
void set_write_template(write_transform_func_t &&f) { this->write_transform_func_ = f; } void set_write_template(write_transform_func_t &&f) { this->write_transform_func_ = f; }
void set_use_write_mutiple(bool use_write_multiple) { this->use_write_multiple_ = use_write_multiple; }
protected: protected:
void write_state(float value) override; void write_state(float value) override;
@ -40,6 +41,7 @@ class ModbusOutput : public output::FloatOutput, public Component, public Sensor
ModbusController *parent_; ModbusController *parent_;
float multiply_by_{1.0}; float multiply_by_{1.0};
bool use_write_multiple_;
}; };
} // namespace modbus_controller } // namespace modbus_controller

View file

@ -18,10 +18,10 @@ from ..const import (
CONF_FORCE_NEW_RANGE, CONF_FORCE_NEW_RANGE,
CONF_MODBUS_CONTROLLER_ID, CONF_MODBUS_CONTROLLER_ID,
CONF_REGISTER_TYPE, CONF_REGISTER_TYPE,
CONF_USE_WRITE_MULTIPLE,
CONF_WRITE_LAMBDA, CONF_WRITE_LAMBDA,
) )
CONF_USE_WRITE_MULTIPLE = "use_write_multiple"
DEPENDENCIES = ["modbus_controller"] DEPENDENCIES = ["modbus_controller"]
CODEOWNERS = ["@martgras"] CODEOWNERS = ["@martgras"]