Merge pull request #3302 from esphome/bump-2022.3.0b2

2022.3.0b2
This commit is contained in:
Jesse Hills 2022-03-16 15:38:32 +13:00 committed by GitHub
commit 59e6e798dd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 41 additions and 5 deletions

View file

@ -11,6 +11,7 @@ from esphome.const import (
) )
from .. import ( from .. import (
MODBUS_WRITE_REGISTER_TYPE,
add_modbus_base_properties, add_modbus_base_properties,
modbus_controller_ns, modbus_controller_ns,
modbus_calc_properties, modbus_calc_properties,
@ -24,6 +25,7 @@ from ..const import (
CONF_CUSTOM_COMMAND, CONF_CUSTOM_COMMAND,
CONF_FORCE_NEW_RANGE, CONF_FORCE_NEW_RANGE,
CONF_MODBUS_CONTROLLER_ID, CONF_MODBUS_CONTROLLER_ID,
CONF_REGISTER_TYPE,
CONF_SKIP_UPDATES, CONF_SKIP_UPDATES,
CONF_USE_WRITE_MULTIPLE, CONF_USE_WRITE_MULTIPLE,
CONF_VALUE_TYPE, CONF_VALUE_TYPE,
@ -61,6 +63,9 @@ CONFIG_SCHEMA = cv.All(
number.NUMBER_SCHEMA.extend(ModbusItemBaseSchema).extend( number.NUMBER_SCHEMA.extend(ModbusItemBaseSchema).extend(
{ {
cv.GenerateID(): cv.declare_id(ModbusNumber), cv.GenerateID(): cv.declare_id(ModbusNumber),
cv.Optional(CONF_REGISTER_TYPE, default="holding"): cv.enum(
MODBUS_WRITE_REGISTER_TYPE
),
cv.Optional(CONF_VALUE_TYPE, default="U_WORD"): cv.enum(SENSOR_VALUE_TYPE), cv.Optional(CONF_VALUE_TYPE, default="U_WORD"): cv.enum(SENSOR_VALUE_TYPE),
cv.Optional(CONF_WRITE_LAMBDA): cv.returning_lambda, cv.Optional(CONF_WRITE_LAMBDA): cv.returning_lambda,
# 24 bits are the maximum value for fp32 before precison is lost # 24 bits are the maximum value for fp32 before precison is lost
@ -81,6 +86,7 @@ async def to_code(config):
byte_offset, reg_count = modbus_calc_properties(config) byte_offset, reg_count = modbus_calc_properties(config)
var = cg.new_Pvariable( var = cg.new_Pvariable(
config[CONF_ID], config[CONF_ID],
config[CONF_REGISTER_TYPE],
config[CONF_ADDRESS], config[CONF_ADDRESS],
byte_offset, byte_offset,
config[CONF_BITMASK], config[CONF_BITMASK],

View file

@ -11,9 +11,9 @@ using value_to_data_t = std::function<float>(float);
class ModbusNumber : public number::Number, public Component, public SensorItem { class ModbusNumber : public number::Number, public Component, public SensorItem {
public: public:
ModbusNumber(uint16_t start_address, uint8_t offset, uint32_t bitmask, SensorValueType value_type, int register_count, ModbusNumber(ModbusRegisterType register_type, uint16_t start_address, uint8_t offset, uint32_t bitmask,
uint8_t skip_updates, bool force_new_range) { SensorValueType value_type, int register_count, uint8_t skip_updates, bool force_new_range) {
this->register_type = ModbusRegisterType::HOLDING; this->register_type = register_type;
this->start_address = start_address; this->start_address = start_address;
this->offset = offset; this->offset = offset;
this->bitmask = bitmask; this->bitmask = bitmask;

View file

@ -1,7 +1,7 @@
import esphome.codegen as cg import esphome.codegen as cg
import esphome.config_validation as cv import esphome.config_validation as cv
from esphome.components import select from esphome.components import select
from esphome.const import CONF_ADDRESS, CONF_ID, CONF_LAMBDA from esphome.const import CONF_ADDRESS, CONF_ID, CONF_LAMBDA, CONF_OPTIMISTIC
from esphome.jsonschema import jschema_composite from esphome.jsonschema import jschema_composite
from .. import ( from .. import (
@ -79,6 +79,7 @@ CONFIG_SCHEMA = cv.All(
cv.Optional(CONF_FORCE_NEW_RANGE, default=False): cv.boolean, cv.Optional(CONF_FORCE_NEW_RANGE, default=False): cv.boolean,
cv.Required(CONF_OPTIONSMAP): ensure_option_map(), cv.Required(CONF_OPTIONSMAP): ensure_option_map(),
cv.Optional(CONF_USE_WRITE_MULTIPLE, default=False): cv.boolean, cv.Optional(CONF_USE_WRITE_MULTIPLE, default=False): cv.boolean,
cv.Optional(CONF_OPTIMISTIC, default=False): cv.boolean,
cv.Optional(CONF_LAMBDA): cv.returning_lambda, cv.Optional(CONF_LAMBDA): cv.returning_lambda,
cv.Optional(CONF_WRITE_LAMBDA): cv.returning_lambda, cv.Optional(CONF_WRITE_LAMBDA): cv.returning_lambda,
}, },
@ -112,6 +113,7 @@ async def to_code(config):
cg.add(parent.add_sensor_item(var)) cg.add(parent.add_sensor_item(var))
cg.add(var.set_parent(parent)) cg.add(var.set_parent(parent))
cg.add(var.set_use_write_mutiple(config[CONF_USE_WRITE_MULTIPLE])) cg.add(var.set_use_write_mutiple(config[CONF_USE_WRITE_MULTIPLE]))
cg.add(var.set_optimistic(config[CONF_OPTIMISTIC]))
if CONF_LAMBDA in config: if CONF_LAMBDA in config:
template_ = await cg.process_lambda( template_ = await cg.process_lambda(

View file

@ -80,6 +80,9 @@ void ModbusSelect::control(const std::string &value) {
} }
parent_->queue_command(write_cmd); parent_->queue_command(write_cmd);
if (this->optimistic_)
this->publish_state(value);
} }
} // namespace modbus_controller } // namespace modbus_controller

View file

@ -32,6 +32,7 @@ class ModbusSelect : public Component, public select::Select, public SensorItem
void set_parent(ModbusController *const parent) { this->parent_ = parent; } void set_parent(ModbusController *const parent) { this->parent_ = parent; }
void set_use_write_mutiple(bool use_write_multiple) { this->use_write_multiple_ = use_write_multiple; } void set_use_write_mutiple(bool use_write_multiple) { this->use_write_multiple_ = use_write_multiple; }
void set_optimistic(bool optimistic) { this->optimistic_ = optimistic; }
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; }
@ -43,6 +44,7 @@ class ModbusSelect : public Component, public select::Select, public SensorItem
std::vector<int64_t> mapping_; std::vector<int64_t> mapping_;
ModbusController *parent_; ModbusController *parent_;
bool use_write_multiple_{false}; bool use_write_multiple_{false};
bool optimistic_{false};
optional<transform_func_t> transform_func_; optional<transform_func_t> transform_func_;
optional<write_transform_func_t> write_transform_func_; optional<write_transform_func_t> write_transform_func_;
}; };

View file

@ -1,6 +1,6 @@
"""Constants used by esphome.""" """Constants used by esphome."""
__version__ = "2022.3.0b1" __version__ = "2022.3.0b2"
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"

View file

@ -213,6 +213,25 @@ std::string format_hex_pretty(const uint8_t *data, size_t length) {
} }
std::string format_hex_pretty(const std::vector<uint8_t> &data) { return format_hex_pretty(data.data(), data.size()); } std::string format_hex_pretty(const std::vector<uint8_t> &data) { return format_hex_pretty(data.data(), data.size()); }
std::string format_hex_pretty(const uint16_t *data, size_t length) {
if (length == 0)
return "";
std::string ret;
ret.resize(5 * length - 1);
for (size_t i = 0; i < length; i++) {
ret[5 * i] = format_hex_pretty_char((data[i] & 0xF000) >> 12);
ret[5 * i + 1] = format_hex_pretty_char((data[i] & 0x0F00) >> 8);
ret[5 * i + 2] = format_hex_pretty_char((data[i] & 0x00F0) >> 4);
ret[5 * i + 3] = format_hex_pretty_char(data[i] & 0x000F);
if (i != length - 1)
ret[5 * i + 2] = '.';
}
if (length > 4)
return ret + " (" + to_string(length) + ")";
return ret;
}
std::string format_hex_pretty(const std::vector<uint16_t> &data) { return format_hex_pretty(data.data(), data.size()); }
ParseOnOffState parse_on_off(const char *str, const char *on, const char *off) { ParseOnOffState parse_on_off(const char *str, const char *on, const char *off) {
if (on == nullptr && strcasecmp(str, "on") == 0) if (on == nullptr && strcasecmp(str, "on") == 0)
return PARSE_ON; return PARSE_ON;

View file

@ -386,8 +386,12 @@ template<typename T, enable_if_t<std::is_unsigned<T>::value, int> = 0> std::stri
/// Format the byte array \p data of length \p len in pretty-printed, human-readable hex. /// Format the byte array \p data of length \p len in pretty-printed, human-readable hex.
std::string format_hex_pretty(const uint8_t *data, size_t length); std::string format_hex_pretty(const uint8_t *data, size_t length);
/// Format the word array \p data of length \p len in pretty-printed, human-readable hex.
std::string format_hex_pretty(const uint16_t *data, size_t length);
/// Format the vector \p data in pretty-printed, human-readable hex. /// Format the vector \p data in pretty-printed, human-readable hex.
std::string format_hex_pretty(const std::vector<uint8_t> &data); std::string format_hex_pretty(const std::vector<uint8_t> &data);
/// Format the vector \p data in pretty-printed, human-readable hex.
std::string format_hex_pretty(const std::vector<uint16_t> &data);
/// Format an unsigned integer in pretty-printed, human-readable hex, starting with the most significant byte. /// Format an unsigned integer in pretty-printed, human-readable hex, starting with the most significant byte.
template<typename T, enable_if_t<std::is_unsigned<T>::value, int> = 0> std::string format_hex_pretty(T val) { template<typename T, enable_if_t<std::is_unsigned<T>::value, int> = 0> std::string format_hex_pretty(T val) {
val = convert_big_endian(val); val = convert_big_endian(val);