diff --git a/.clang-tidy.hash b/.clang-tidy.hash index a14b44ef96..59caddf59b 100644 --- a/.clang-tidy.hash +++ b/.clang-tidy.hash @@ -1 +1 @@ -94557f94be073390342833aff12ef8676a8b597db5fa770a5a1232e9425cb48f +97fb425f1d681a5994ed1cc6187910f5d2c37ee577b6dc07eb3f4d8862a011de diff --git a/CODEOWNERS b/CODEOWNERS index 00db5a3c79..a2267621e7 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -135,7 +135,7 @@ esphome/components/display_menu_base/* @numo68 esphome/components/dps310/* @kbx81 esphome/components/ds1307/* @badbadc0ffee esphome/components/ds2484/* @mrk-its -esphome/components/dsmr/* @glmnet @zuidwijk +esphome/components/dsmr/* @glmnet @PolarGoose @zuidwijk esphome/components/duty_time/* @dudanov esphome/components/ee895/* @Stock-M esphome/components/ektf2232/touchscreen/* @jesserockz diff --git a/esphome/components/dsmr/__init__.py b/esphome/components/dsmr/__init__.py index 017a11673f..0ba68daf5d 100644 --- a/esphome/components/dsmr/__init__.py +++ b/esphome/components/dsmr/__init__.py @@ -4,7 +4,7 @@ from esphome.components import uart import esphome.config_validation as cv from esphome.const import CONF_ID, CONF_RECEIVE_TIMEOUT, CONF_UART_ID -CODEOWNERS = ["@glmnet", "@zuidwijk"] +CODEOWNERS = ["@glmnet", "@zuidwijk", "@PolarGoose"] MULTI_CONF = True @@ -61,7 +61,6 @@ CONFIG_SCHEMA = cv.All( ): cv.positive_time_period_milliseconds, } ).extend(uart.UART_DEVICE_SCHEMA), - cv.only_with_arduino, ) @@ -83,7 +82,7 @@ async def to_code(config): cg.add_build_flag("-DDSMR_WATER_MBUS_ID=" + str(config[CONF_WATER_MBUS_ID])) # DSMR Parser - cg.add_library("glmnet/Dsmr", "0.8") + cg.add_library("esphome/dsmr_parser", "1.0.0") # Crypto - cg.add_library("rweather/Crypto", "0.4.0") + cg.add_library("polargoose/Crypto-no-arduino", "0.4.0") diff --git a/esphome/components/dsmr/dsmr.cpp b/esphome/components/dsmr/dsmr.cpp index d99cf5e7a9..41fc2f0d85 100644 --- a/esphome/components/dsmr/dsmr.cpp +++ b/esphome/components/dsmr/dsmr.cpp @@ -1,5 +1,3 @@ -#ifdef USE_ARDUINO - #include "dsmr.h" #include "esphome/core/log.h" @@ -7,8 +5,7 @@ #include #include -namespace esphome { -namespace dsmr { +namespace esphome::dsmr { static const char *const TAG = "dsmr"; @@ -257,9 +254,9 @@ bool Dsmr::parse_telegram() { ESP_LOGV(TAG, "Trying to parse telegram"); this->stop_requesting_data_(); - ::dsmr::ParseResult res = - ::dsmr::P1Parser::parse(&data, this->telegram_, this->bytes_read_, false, - this->crc_check_); // Parse telegram according to data definition. Ignore unknown values. + const auto &res = dsmr_parser::P1Parser::parse( + data, this->telegram_, this->bytes_read_, 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(this->telegram_, this->telegram_ + this->bytes_read_); @@ -329,7 +326,4 @@ void Dsmr::set_decryption_key(const std::string &decryption_key) { } } -} // namespace dsmr -} // namespace esphome - -#endif // USE_ARDUINO +} // namespace esphome::dsmr diff --git a/esphome/components/dsmr/dsmr.h b/esphome/components/dsmr/dsmr.h index 7304737b50..56ba75b5fa 100644 --- a/esphome/components/dsmr/dsmr.h +++ b/esphome/components/dsmr/dsmr.h @@ -1,24 +1,17 @@ #pragma once -#ifdef USE_ARDUINO - #include "esphome/core/component.h" #include "esphome/components/sensor/sensor.h" #include "esphome/components/text_sensor/text_sensor.h" #include "esphome/components/uart/uart.h" #include "esphome/core/log.h" -#include "esphome/core/defines.h" - -// don't include because it puts everything in global namespace -#include -#include - +#include +#include #include -namespace esphome { -namespace dsmr { +namespace esphome::dsmr { -using namespace ::dsmr::fields; +using namespace dsmr_parser::fields; // DSMR_**_LIST generated by ESPHome and written in esphome/core/defines @@ -44,8 +37,8 @@ using namespace ::dsmr::fields; #define DSMR_DATA_SENSOR(s) s #define DSMR_COMMA , -using MyData = ::dsmr::ParsedData; +using MyData = dsmr_parser::ParsedData; class Dsmr : public Component, public uart::UARTDevice { public: @@ -140,7 +133,4 @@ class Dsmr : public Component, public uart::UARTDevice { std::vector decryption_key_{}; bool crc_check_; }; -} // namespace dsmr -} // namespace esphome - -#endif // USE_ARDUINO +} // namespace esphome::dsmr diff --git a/esphome/components/dsmr/sensor.py b/esphome/components/dsmr/sensor.py index 0696fccdf7..7d69f79530 100644 --- a/esphome/components/dsmr/sensor.py +++ b/esphome/components/dsmr/sensor.py @@ -3,27 +3,34 @@ from esphome.components import sensor import esphome.config_validation as cv from esphome.const import ( CONF_ID, + DEVICE_CLASS_APPARENT_POWER, DEVICE_CLASS_CURRENT, + DEVICE_CLASS_DURATION, DEVICE_CLASS_ENERGY, + DEVICE_CLASS_FREQUENCY, DEVICE_CLASS_GAS, DEVICE_CLASS_POWER, + DEVICE_CLASS_REACTIVE_POWER, DEVICE_CLASS_VOLTAGE, DEVICE_CLASS_WATER, STATE_CLASS_MEASUREMENT, STATE_CLASS_TOTAL_INCREASING, UNIT_AMPERE, UNIT_CUBIC_METER, + UNIT_HERTZ, + UNIT_KILOVOLT_AMPS, UNIT_KILOVOLT_AMPS_REACTIVE, UNIT_KILOVOLT_AMPS_REACTIVE_HOURS, UNIT_KILOWATT, UNIT_KILOWATT_HOURS, + UNIT_SECOND, UNIT_VOLT, ) from . import CONF_DSMR_ID, Dsmr AUTO_LOAD = ["dsmr"] - +UNIT_GIGA_JOULE = "GJ" CONFIG_SCHEMA = cv.Schema( { @@ -46,6 +53,18 @@ CONFIG_SCHEMA = cv.Schema( device_class=DEVICE_CLASS_ENERGY, state_class=STATE_CLASS_TOTAL_INCREASING, ), + cv.Optional("energy_delivered_tariff3"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOWATT_HOURS, + accuracy_decimals=3, + device_class=DEVICE_CLASS_ENERGY, + state_class=STATE_CLASS_TOTAL_INCREASING, + ), + cv.Optional("energy_delivered_tariff4"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOWATT_HOURS, + accuracy_decimals=3, + device_class=DEVICE_CLASS_ENERGY, + state_class=STATE_CLASS_TOTAL_INCREASING, + ), cv.Optional("energy_returned_lux"): sensor.sensor_schema( unit_of_measurement=UNIT_KILOWATT_HOURS, accuracy_decimals=3, @@ -64,14 +83,82 @@ CONFIG_SCHEMA = cv.Schema( device_class=DEVICE_CLASS_ENERGY, state_class=STATE_CLASS_TOTAL_INCREASING, ), + cv.Optional("energy_returned_tariff3"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOWATT_HOURS, + accuracy_decimals=3, + device_class=DEVICE_CLASS_ENERGY, + state_class=STATE_CLASS_TOTAL_INCREASING, + ), + cv.Optional("energy_returned_tariff4"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOWATT_HOURS, + accuracy_decimals=3, + device_class=DEVICE_CLASS_ENERGY, + state_class=STATE_CLASS_TOTAL_INCREASING, + ), + cv.Optional("energy_delivered_tariff1_ch"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOWATT_HOURS, + accuracy_decimals=3, + device_class=DEVICE_CLASS_ENERGY, + state_class=STATE_CLASS_TOTAL_INCREASING, + ), + cv.Optional("energy_delivered_tariff2_ch"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOWATT_HOURS, + accuracy_decimals=3, + device_class=DEVICE_CLASS_ENERGY, + state_class=STATE_CLASS_TOTAL_INCREASING, + ), + cv.Optional("energy_returned_tariff1_ch"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOWATT_HOURS, + accuracy_decimals=3, + device_class=DEVICE_CLASS_ENERGY, + state_class=STATE_CLASS_TOTAL_INCREASING, + ), + cv.Optional("energy_returned_tariff2_ch"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOWATT_HOURS, + accuracy_decimals=3, + device_class=DEVICE_CLASS_ENERGY, + state_class=STATE_CLASS_TOTAL_INCREASING, + ), cv.Optional("total_imported_energy"): sensor.sensor_schema( unit_of_measurement=UNIT_KILOVOLT_AMPS_REACTIVE_HOURS, accuracy_decimals=3, ), + cv.Optional("reactive_energy_delivered_tariff1"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOVOLT_AMPS_REACTIVE_HOURS, + accuracy_decimals=3, + ), + cv.Optional("reactive_energy_delivered_tariff2"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOVOLT_AMPS_REACTIVE_HOURS, + accuracy_decimals=3, + ), + cv.Optional("reactive_energy_delivered_tariff3"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOVOLT_AMPS_REACTIVE_HOURS, + accuracy_decimals=3, + ), + cv.Optional("reactive_energy_delivered_tariff4"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOVOLT_AMPS_REACTIVE_HOURS, + accuracy_decimals=3, + ), cv.Optional("total_exported_energy"): sensor.sensor_schema( unit_of_measurement=UNIT_KILOVOLT_AMPS_REACTIVE_HOURS, accuracy_decimals=3, ), + cv.Optional("reactive_energy_returned_tariff1"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOVOLT_AMPS_REACTIVE_HOURS, + accuracy_decimals=3, + ), + cv.Optional("reactive_energy_returned_tariff2"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOVOLT_AMPS_REACTIVE_HOURS, + accuracy_decimals=3, + ), + cv.Optional("reactive_energy_returned_tariff3"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOVOLT_AMPS_REACTIVE_HOURS, + accuracy_decimals=3, + ), + cv.Optional("reactive_energy_returned_tariff4"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOVOLT_AMPS_REACTIVE_HOURS, + accuracy_decimals=3, + ), cv.Optional("power_delivered"): sensor.sensor_schema( unit_of_measurement=UNIT_KILOWATT, accuracy_decimals=3, @@ -84,61 +171,195 @@ CONFIG_SCHEMA = cv.Schema( device_class=DEVICE_CLASS_POWER, state_class=STATE_CLASS_MEASUREMENT, ), + cv.Optional("power_delivered_ch"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOWATT, + accuracy_decimals=3, + device_class=DEVICE_CLASS_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("power_returned_ch"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOWATT, + accuracy_decimals=3, + device_class=DEVICE_CLASS_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), cv.Optional("reactive_power_delivered"): sensor.sensor_schema( unit_of_measurement=UNIT_KILOVOLT_AMPS_REACTIVE, accuracy_decimals=3, + device_class=DEVICE_CLASS_REACTIVE_POWER, state_class=STATE_CLASS_MEASUREMENT, ), cv.Optional("reactive_power_returned"): sensor.sensor_schema( unit_of_measurement=UNIT_KILOVOLT_AMPS_REACTIVE, accuracy_decimals=3, + device_class=DEVICE_CLASS_REACTIVE_POWER, state_class=STATE_CLASS_MEASUREMENT, ), cv.Optional("electricity_threshold"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOWATT, accuracy_decimals=3, + device_class=DEVICE_CLASS_POWER, + state_class=STATE_CLASS_MEASUREMENT, ), cv.Optional("electricity_switch_position"): sensor.sensor_schema( accuracy_decimals=3, + state_class=STATE_CLASS_MEASUREMENT, ), cv.Optional("electricity_failures"): sensor.sensor_schema( accuracy_decimals=0, + state_class=STATE_CLASS_MEASUREMENT, ), cv.Optional("electricity_long_failures"): sensor.sensor_schema( accuracy_decimals=0, + state_class=STATE_CLASS_MEASUREMENT, ), cv.Optional("electricity_sags_l1"): sensor.sensor_schema( accuracy_decimals=0, + state_class=STATE_CLASS_MEASUREMENT, ), cv.Optional("electricity_sags_l2"): sensor.sensor_schema( accuracy_decimals=0, + state_class=STATE_CLASS_MEASUREMENT, ), cv.Optional("electricity_sags_l3"): sensor.sensor_schema( accuracy_decimals=0, + state_class=STATE_CLASS_MEASUREMENT, ), cv.Optional("electricity_swells_l1"): sensor.sensor_schema( accuracy_decimals=0, + state_class=STATE_CLASS_MEASUREMENT, ), cv.Optional("electricity_swells_l2"): sensor.sensor_schema( accuracy_decimals=0, + state_class=STATE_CLASS_MEASUREMENT, ), cv.Optional("electricity_swells_l3"): sensor.sensor_schema( accuracy_decimals=0, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("voltage_sag_time_l1"): sensor.sensor_schema( + unit_of_measurement=UNIT_SECOND, + accuracy_decimals=0, + device_class=DEVICE_CLASS_DURATION, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("voltage_sag_time_l2"): sensor.sensor_schema( + unit_of_measurement=UNIT_SECOND, + accuracy_decimals=0, + device_class=DEVICE_CLASS_DURATION, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("voltage_sag_time_l3"): sensor.sensor_schema( + unit_of_measurement=UNIT_SECOND, + accuracy_decimals=0, + device_class=DEVICE_CLASS_DURATION, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("voltage_sag_l1"): sensor.sensor_schema( + unit_of_measurement=UNIT_VOLT, + accuracy_decimals=0, + device_class=DEVICE_CLASS_VOLTAGE, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("voltage_sag_l2"): sensor.sensor_schema( + unit_of_measurement=UNIT_VOLT, + accuracy_decimals=0, + device_class=DEVICE_CLASS_VOLTAGE, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("voltage_sag_l3"): sensor.sensor_schema( + unit_of_measurement=UNIT_VOLT, + accuracy_decimals=0, + device_class=DEVICE_CLASS_VOLTAGE, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("voltage_swell_time_l1"): sensor.sensor_schema( + unit_of_measurement=UNIT_SECOND, + accuracy_decimals=0, + device_class=DEVICE_CLASS_DURATION, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("voltage_swell_time_l2"): sensor.sensor_schema( + unit_of_measurement=UNIT_SECOND, + accuracy_decimals=0, + device_class=DEVICE_CLASS_DURATION, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("voltage_swell_time_l3"): sensor.sensor_schema( + unit_of_measurement=UNIT_SECOND, + accuracy_decimals=0, + device_class=DEVICE_CLASS_DURATION, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("voltage_swell_l1"): sensor.sensor_schema( + unit_of_measurement=UNIT_VOLT, + accuracy_decimals=0, + device_class=DEVICE_CLASS_VOLTAGE, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("voltage_swell_l2"): sensor.sensor_schema( + unit_of_measurement=UNIT_VOLT, + accuracy_decimals=0, + device_class=DEVICE_CLASS_VOLTAGE, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("voltage_swell_l3"): sensor.sensor_schema( + unit_of_measurement=UNIT_VOLT, + accuracy_decimals=0, + device_class=DEVICE_CLASS_VOLTAGE, + state_class=STATE_CLASS_MEASUREMENT, ), cv.Optional("current_l1"): sensor.sensor_schema( unit_of_measurement=UNIT_AMPERE, - accuracy_decimals=1, + accuracy_decimals=3, device_class=DEVICE_CLASS_CURRENT, state_class=STATE_CLASS_MEASUREMENT, ), cv.Optional("current_l2"): sensor.sensor_schema( unit_of_measurement=UNIT_AMPERE, - accuracy_decimals=1, + accuracy_decimals=3, device_class=DEVICE_CLASS_CURRENT, state_class=STATE_CLASS_MEASUREMENT, ), cv.Optional("current_l3"): sensor.sensor_schema( unit_of_measurement=UNIT_AMPERE, - accuracy_decimals=1, + accuracy_decimals=3, + device_class=DEVICE_CLASS_CURRENT, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("current"): sensor.sensor_schema( + unit_of_measurement=UNIT_AMPERE, + accuracy_decimals=3, + device_class=DEVICE_CLASS_CURRENT, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("current_n"): sensor.sensor_schema( + unit_of_measurement=UNIT_AMPERE, + accuracy_decimals=3, + device_class=DEVICE_CLASS_CURRENT, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("current_sum"): sensor.sensor_schema( + unit_of_measurement=UNIT_AMPERE, + accuracy_decimals=3, + device_class=DEVICE_CLASS_CURRENT, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("current_fuse_l1"): sensor.sensor_schema( + unit_of_measurement=UNIT_AMPERE, + accuracy_decimals=3, + device_class=DEVICE_CLASS_CURRENT, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("current_fuse_l2"): sensor.sensor_schema( + unit_of_measurement=UNIT_AMPERE, + accuracy_decimals=3, + device_class=DEVICE_CLASS_CURRENT, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("current_fuse_l3"): sensor.sensor_schema( + unit_of_measurement=UNIT_AMPERE, + accuracy_decimals=3, device_class=DEVICE_CLASS_CURRENT, state_class=STATE_CLASS_MEASUREMENT, ), @@ -181,51 +402,93 @@ CONFIG_SCHEMA = cv.Schema( cv.Optional("reactive_power_delivered_l1"): sensor.sensor_schema( unit_of_measurement=UNIT_KILOVOLT_AMPS_REACTIVE, accuracy_decimals=3, + device_class=DEVICE_CLASS_REACTIVE_POWER, state_class=STATE_CLASS_MEASUREMENT, ), cv.Optional("reactive_power_delivered_l2"): sensor.sensor_schema( unit_of_measurement=UNIT_KILOVOLT_AMPS_REACTIVE, accuracy_decimals=3, + device_class=DEVICE_CLASS_REACTIVE_POWER, state_class=STATE_CLASS_MEASUREMENT, ), cv.Optional("reactive_power_delivered_l3"): sensor.sensor_schema( unit_of_measurement=UNIT_KILOVOLT_AMPS_REACTIVE, accuracy_decimals=3, + device_class=DEVICE_CLASS_REACTIVE_POWER, state_class=STATE_CLASS_MEASUREMENT, ), cv.Optional("reactive_power_returned_l1"): sensor.sensor_schema( unit_of_measurement=UNIT_KILOVOLT_AMPS_REACTIVE, accuracy_decimals=3, + device_class=DEVICE_CLASS_REACTIVE_POWER, state_class=STATE_CLASS_MEASUREMENT, ), cv.Optional("reactive_power_returned_l2"): sensor.sensor_schema( unit_of_measurement=UNIT_KILOVOLT_AMPS_REACTIVE, accuracy_decimals=3, + device_class=DEVICE_CLASS_REACTIVE_POWER, state_class=STATE_CLASS_MEASUREMENT, ), cv.Optional("reactive_power_returned_l3"): sensor.sensor_schema( unit_of_measurement=UNIT_KILOVOLT_AMPS_REACTIVE, accuracy_decimals=3, + device_class=DEVICE_CLASS_REACTIVE_POWER, state_class=STATE_CLASS_MEASUREMENT, ), cv.Optional("voltage_l1"): sensor.sensor_schema( unit_of_measurement=UNIT_VOLT, - accuracy_decimals=1, + accuracy_decimals=3, device_class=DEVICE_CLASS_VOLTAGE, state_class=STATE_CLASS_MEASUREMENT, ), cv.Optional("voltage_l2"): sensor.sensor_schema( unit_of_measurement=UNIT_VOLT, - accuracy_decimals=1, + accuracy_decimals=3, device_class=DEVICE_CLASS_VOLTAGE, state_class=STATE_CLASS_MEASUREMENT, ), cv.Optional("voltage_l3"): sensor.sensor_schema( unit_of_measurement=UNIT_VOLT, - accuracy_decimals=1, + accuracy_decimals=3, device_class=DEVICE_CLASS_VOLTAGE, state_class=STATE_CLASS_MEASUREMENT, ), + cv.Optional("voltage_avg_l1"): sensor.sensor_schema( + unit_of_measurement=UNIT_VOLT, + accuracy_decimals=3, + device_class=DEVICE_CLASS_VOLTAGE, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("voltage_avg_l2"): sensor.sensor_schema( + unit_of_measurement=UNIT_VOLT, + accuracy_decimals=3, + device_class=DEVICE_CLASS_VOLTAGE, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("voltage_avg_l3"): sensor.sensor_schema( + unit_of_measurement=UNIT_VOLT, + accuracy_decimals=3, + device_class=DEVICE_CLASS_VOLTAGE, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("voltage"): sensor.sensor_schema( + unit_of_measurement=UNIT_VOLT, + accuracy_decimals=3, + device_class=DEVICE_CLASS_VOLTAGE, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("frequency"): sensor.sensor_schema( + unit_of_measurement=UNIT_HERTZ, + accuracy_decimals=3, + device_class=DEVICE_CLASS_FREQUENCY, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("abs_power"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOWATT, + accuracy_decimals=3, + device_class=DEVICE_CLASS_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), cv.Optional("gas_delivered"): sensor.sensor_schema( unit_of_measurement=UNIT_CUBIC_METER, accuracy_decimals=3, @@ -244,6 +507,109 @@ CONFIG_SCHEMA = cv.Schema( device_class=DEVICE_CLASS_WATER, state_class=STATE_CLASS_TOTAL_INCREASING, ), + cv.Optional("thermal_delivered"): sensor.sensor_schema( + unit_of_measurement=UNIT_GIGA_JOULE, + accuracy_decimals=3, + device_class=DEVICE_CLASS_ENERGY, + state_class=STATE_CLASS_TOTAL_INCREASING, + ), + cv.Optional("sub_delivered"): sensor.sensor_schema( + unit_of_measurement=UNIT_CUBIC_METER, + accuracy_decimals=3, + state_class=STATE_CLASS_TOTAL_INCREASING, + ), + cv.Optional("gas_device_type"): sensor.sensor_schema( + accuracy_decimals=0, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("gas_valve_position"): sensor.sensor_schema( + accuracy_decimals=0, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("thermal_device_type"): sensor.sensor_schema( + accuracy_decimals=0, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("thermal_valve_position"): sensor.sensor_schema( + accuracy_decimals=0, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("water_device_type"): sensor.sensor_schema( + accuracy_decimals=0, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("water_valve_position"): sensor.sensor_schema( + accuracy_decimals=0, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("sub_device_type"): sensor.sensor_schema( + accuracy_decimals=0, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("sub_valve_position"): sensor.sensor_schema( + accuracy_decimals=0, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("apparent_delivery_power"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOVOLT_AMPS, + accuracy_decimals=3, + device_class=DEVICE_CLASS_APPARENT_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("apparent_delivery_power_l1"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOVOLT_AMPS, + accuracy_decimals=3, + device_class=DEVICE_CLASS_APPARENT_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("apparent_delivery_power_l2"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOVOLT_AMPS, + accuracy_decimals=3, + device_class=DEVICE_CLASS_APPARENT_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("apparent_delivery_power_l3"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOVOLT_AMPS, + accuracy_decimals=3, + device_class=DEVICE_CLASS_APPARENT_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("apparent_return_power"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOVOLT_AMPS, + accuracy_decimals=3, + device_class=DEVICE_CLASS_APPARENT_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("apparent_return_power_l1"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOVOLT_AMPS, + accuracy_decimals=3, + device_class=DEVICE_CLASS_APPARENT_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("apparent_return_power_l2"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOVOLT_AMPS, + accuracy_decimals=3, + device_class=DEVICE_CLASS_APPARENT_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("apparent_return_power_l3"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOVOLT_AMPS, + accuracy_decimals=3, + device_class=DEVICE_CLASS_APPARENT_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("active_demand_power"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOWATT, + accuracy_decimals=3, + device_class=DEVICE_CLASS_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("active_demand_abs"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOWATT, + accuracy_decimals=3, + device_class=DEVICE_CLASS_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), cv.Optional( "active_energy_import_current_average_demand" ): sensor.sensor_schema( @@ -252,6 +618,90 @@ CONFIG_SCHEMA = cv.Schema( device_class=DEVICE_CLASS_POWER, state_class=STATE_CLASS_MEASUREMENT, ), + cv.Optional( + "active_energy_export_current_average_demand" + ): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOWATT, + accuracy_decimals=3, + device_class=DEVICE_CLASS_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional( + "reactive_energy_import_current_average_demand" + ): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOVOLT_AMPS_REACTIVE, + accuracy_decimals=3, + device_class=DEVICE_CLASS_REACTIVE_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional( + "reactive_energy_export_current_average_demand" + ): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOVOLT_AMPS_REACTIVE, + accuracy_decimals=3, + device_class=DEVICE_CLASS_REACTIVE_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional( + "apparent_energy_import_current_average_demand" + ): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOVOLT_AMPS, + accuracy_decimals=3, + device_class=DEVICE_CLASS_APPARENT_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional( + "apparent_energy_export_current_average_demand" + ): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOVOLT_AMPS, + accuracy_decimals=3, + device_class=DEVICE_CLASS_APPARENT_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("active_energy_import_last_completed_demand"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOWATT, + accuracy_decimals=3, + device_class=DEVICE_CLASS_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("active_energy_export_last_completed_demand"): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOWATT, + accuracy_decimals=3, + device_class=DEVICE_CLASS_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional( + "reactive_energy_import_last_completed_demand" + ): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOVOLT_AMPS_REACTIVE, + accuracy_decimals=3, + device_class=DEVICE_CLASS_REACTIVE_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional( + "reactive_energy_export_last_completed_demand" + ): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOVOLT_AMPS_REACTIVE, + accuracy_decimals=3, + device_class=DEVICE_CLASS_REACTIVE_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional( + "apparent_energy_import_last_completed_demand" + ): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOVOLT_AMPS, + accuracy_decimals=3, + device_class=DEVICE_CLASS_APPARENT_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional( + "apparent_energy_export_last_completed_demand" + ): sensor.sensor_schema( + unit_of_measurement=UNIT_KILOVOLT_AMPS, + accuracy_decimals=3, + device_class=DEVICE_CLASS_APPARENT_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), cv.Optional( "active_energy_import_maximum_demand_running_month" ): sensor.sensor_schema( @@ -268,6 +718,14 @@ CONFIG_SCHEMA = cv.Schema( device_class=DEVICE_CLASS_POWER, state_class=STATE_CLASS_MEASUREMENT, ), + cv.Optional("fw_core_version"): sensor.sensor_schema( + accuracy_decimals=3, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional("fw_module_version"): sensor.sensor_schema( + accuracy_decimals=3, + state_class=STATE_CLASS_MEASUREMENT, + ), } ).extend(cv.COMPONENT_SCHEMA) diff --git a/esphome/components/dsmr/text_sensor.py b/esphome/components/dsmr/text_sensor.py index 3223d943be..4c7455a38f 100644 --- a/esphome/components/dsmr/text_sensor.py +++ b/esphome/components/dsmr/text_sensor.py @@ -18,11 +18,15 @@ CONFIG_SCHEMA = cv.Schema( cv.Optional("electricity_failure_log"): text_sensor.text_sensor_schema(), cv.Optional("message_short"): text_sensor.text_sensor_schema(), cv.Optional("message_long"): text_sensor.text_sensor_schema(), + cv.Optional("equipment_id"): text_sensor.text_sensor_schema(), cv.Optional("gas_equipment_id"): text_sensor.text_sensor_schema(), + cv.Optional("gas_equipment_id_be"): text_sensor.text_sensor_schema(), cv.Optional("thermal_equipment_id"): text_sensor.text_sensor_schema(), cv.Optional("water_equipment_id"): text_sensor.text_sensor_schema(), cv.Optional("sub_equipment_id"): text_sensor.text_sensor_schema(), cv.Optional("gas_delivered_text"): text_sensor.text_sensor_schema(), + cv.Optional("fw_core_checksum"): text_sensor.text_sensor_schema(), + cv.Optional("fw_module_checksum"): text_sensor.text_sensor_schema(), cv.Optional("telegram"): text_sensor.text_sensor_schema().extend( {cv.Optional(CONF_INTERNAL, default=True): cv.boolean} ), diff --git a/platformio.ini b/platformio.ini index e58989c566..dd9eb566c5 100644 --- a/platformio.ini +++ b/platformio.ini @@ -38,6 +38,8 @@ lib_deps_base = wjtje/qr-code-generator-library@1.7.0 ; qr_code functionpointer/arduino-MLX90393@1.0.2 ; mlx90393 pavlodn/HaierProtocol@0.9.31 ; haier + esphome/dsmr_parser@1.0.0 ; dsmr + polargoose/Crypto-no-arduino@0.4.0 ; dsmr https://github.com/esphome/TinyGPSPlus.git#v1.1.0 ; gps ; This is using the repository until a new release is published to PlatformIO https://github.com/Sensirion/arduino-gas-index-algorithm.git#3.2.1 ; Sensirion Gas Index Algorithm Arduino Library @@ -82,8 +84,6 @@ lib_deps = heman/AsyncMqttClient-esphome@1.0.0 ; mqtt fastled/FastLED@3.9.16 ; fastled_base freekode/TM1651@1.0.1 ; tm1651 - glmnet/Dsmr@0.7 ; dsmr - rweather/Crypto@0.4.0 ; dsmr dudanov/MideaUART@1.1.9 ; midea tonia/HeatpumpIR@1.0.37 ; heatpumpir build_flags = diff --git a/tests/components/dsmr/test.esp32-idf.yaml b/tests/components/dsmr/test.esp32-idf.yaml new file mode 100644 index 0000000000..522f60db49 --- /dev/null +++ b/tests/components/dsmr/test.esp32-idf.yaml @@ -0,0 +1,7 @@ +substitutions: + request_pin: GPIO15 + +packages: + uart: !include ../../test_build_components/common/uart/esp32-idf.yaml + +<<: !include common.yaml