mirror of
https://github.com/esphome/esphome.git
synced 2024-11-25 08:28:12 +01:00
Dsmr updates (#2157)
* add option to use check_crc * ignore newline before ( in parsing * add gas delivered text for raw sensor * fix compile issue when not listing any sensor * make gas_mbus_id configurable * update dsmr lib for clang
This commit is contained in:
parent
103ba4c696
commit
de33cbd7e7
6 changed files with 33 additions and 10 deletions
|
@ -13,6 +13,8 @@ AUTO_LOAD = ["sensor", "text_sensor"]
|
|||
|
||||
CONF_DSMR_ID = "dsmr_id"
|
||||
CONF_DECRYPTION_KEY = "decryption_key"
|
||||
CONF_CRC_CHECK = "crc_check"
|
||||
CONF_GAS_MBUS_ID = "gas_mbus_id"
|
||||
|
||||
# Hack to prevent compile error due to ambiguity with lib namespace
|
||||
dsmr_ns = cg.esphome_ns.namespace("esphome::dsmr")
|
||||
|
@ -41,19 +43,23 @@ CONFIG_SCHEMA = cv.Schema(
|
|||
{
|
||||
cv.GenerateID(): cv.declare_id(Dsmr),
|
||||
cv.Optional(CONF_DECRYPTION_KEY): _validate_key,
|
||||
cv.Optional(CONF_CRC_CHECK, default=True): cv.boolean,
|
||||
cv.Optional(CONF_GAS_MBUS_ID, default=1): cv.int_,
|
||||
}
|
||||
).extend(uart.UART_DEVICE_SCHEMA)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
uart_component = await cg.get_variable(config[CONF_UART_ID])
|
||||
var = cg.new_Pvariable(config[CONF_ID], uart_component)
|
||||
var = cg.new_Pvariable(config[CONF_ID], uart_component, config[CONF_CRC_CHECK])
|
||||
if CONF_DECRYPTION_KEY in config:
|
||||
cg.add(var.set_decryption_key(config[CONF_DECRYPTION_KEY]))
|
||||
await cg.register_component(var, config)
|
||||
|
||||
cg.add_define("DSMR_GAS_MBUS_ID", config[CONF_GAS_MBUS_ID])
|
||||
|
||||
# DSMR Parser
|
||||
cg.add_library("glmnet/Dsmr", "0.3")
|
||||
cg.add_library("glmnet/Dsmr", "0.5")
|
||||
|
||||
# Crypto
|
||||
cg.add_library("rweather/Crypto", "0.2.0")
|
||||
|
|
|
@ -37,6 +37,12 @@ void Dsmr::receive_telegram_() {
|
|||
return;
|
||||
}
|
||||
|
||||
// Some v2.2 or v3 meters will send a new value which starts with '('
|
||||
// in a new line while the value belongs to the previous ObisId. For
|
||||
// proper parsing remove these new line characters
|
||||
while (c == '(' && (telegram_[telegram_len_ - 1] == '\n' || telegram_[telegram_len_ - 1] == '\r'))
|
||||
telegram_len_--;
|
||||
|
||||
telegram_[telegram_len_] = c;
|
||||
telegram_len_++;
|
||||
if (c == '!') { // footer: exclamation mark
|
||||
|
@ -130,8 +136,8 @@ bool Dsmr::parse_telegram() {
|
|||
MyData data;
|
||||
ESP_LOGV(TAG, "Trying to parse");
|
||||
::dsmr::ParseResult<void> res =
|
||||
::dsmr::P1Parser::parse(&data, telegram_, telegram_len_,
|
||||
false); // Parse telegram according to data definition. Ignore unknown values.
|
||||
::dsmr::P1Parser::parse(&data, telegram_, telegram_len_, false,
|
||||
this->crc_check_); // Parse telegram according to data definition. Ignore unknown values.
|
||||
if (res.err) {
|
||||
// Parsing error, show it
|
||||
auto err_str = res.fullError(telegram_, telegram_ + telegram_len_);
|
||||
|
|
|
@ -48,7 +48,7 @@ using MyData = ::dsmr::ParsedData<DSMR_TEXT_SENSOR_LIST(DSMR_DATA_SENSOR, DSMR_C
|
|||
|
||||
class Dsmr : public Component, public uart::UARTDevice {
|
||||
public:
|
||||
Dsmr(uart::UARTComponent *uart) : uart::UARTDevice(uart) {}
|
||||
Dsmr(uart::UARTComponent *uart, bool crc_check) : uart::UARTDevice(uart), crc_check_(crc_check) {}
|
||||
|
||||
void loop() override;
|
||||
|
||||
|
@ -99,6 +99,7 @@ class Dsmr : public Component, public uart::UARTDevice {
|
|||
DSMR_TEXT_SENSOR_LIST(DSMR_DECLARE_TEXT_SENSOR, )
|
||||
|
||||
std::vector<uint8_t> decryption_key_{};
|
||||
bool crc_check_;
|
||||
};
|
||||
} // namespace dsmr
|
||||
} // namespace esphome
|
||||
|
|
|
@ -244,4 +244,7 @@ async def to_code(config):
|
|||
cg.add(getattr(hub, f"set_{key}")(s))
|
||||
sensors.append(f"F({key})")
|
||||
|
||||
cg.add_define("DSMR_SENSOR_LIST(F, sep)", cg.RawExpression(" sep ".join(sensors)))
|
||||
if sensors:
|
||||
cg.add_define(
|
||||
"DSMR_SENSOR_LIST(F, sep)", cg.RawExpression(" sep ".join(sensors))
|
||||
)
|
||||
|
|
|
@ -71,6 +71,11 @@ CONFIG_SCHEMA = cv.Schema(
|
|||
cv.GenerateID(): cv.declare_id(text_sensor.TextSensor),
|
||||
}
|
||||
),
|
||||
cv.Optional("gas_delivered_text"): text_sensor.TEXT_SENSOR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(text_sensor.TextSensor),
|
||||
}
|
||||
),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
@ -89,6 +94,8 @@ async def to_code(config):
|
|||
cg.add(getattr(hub, f"set_{key}")(var))
|
||||
text_sensors.append(f"F({key})")
|
||||
|
||||
cg.add_define(
|
||||
"DSMR_TEXT_SENSOR_LIST(F, sep)", cg.RawExpression(" sep ".join(text_sensors))
|
||||
)
|
||||
if text_sensors:
|
||||
cg.add_define(
|
||||
"DSMR_TEXT_SENSOR_LIST(F, sep)",
|
||||
cg.RawExpression(" sep ".join(text_sensors)),
|
||||
)
|
||||
|
|
|
@ -34,7 +34,7 @@ lib_deps =
|
|||
1655@1.0.2 ; TinyGPSPlus (has name conflict)
|
||||
6865@1.0.0 ; TM1651 Battery Display
|
||||
6306@1.0.3 ; HM3301
|
||||
glmnet/Dsmr@0.3 ; used by dsmr
|
||||
glmnet/Dsmr@0.5 ; used by dsmr
|
||||
rweather/Crypto@0.2.0 ; used by dsmr
|
||||
esphome/noise-c@0.1.1 ; used by api
|
||||
dudanov/MideaUART@1.1.0 ; used by midea
|
||||
|
|
Loading…
Reference in a new issue