mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00: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:
		
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							103ba4c696
						
					
				
				
					commit
					de33cbd7e7
				
			| @@ -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})") | ||||
|  | ||||
|     if text_sensors: | ||||
|         cg.add_define( | ||||
|         "DSMR_TEXT_SENSOR_LIST(F, sep)", cg.RawExpression(" sep ".join(text_sensors)) | ||||
|             "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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user