DSMR 组件
DSMR 组件连接到符合 DSMR(荷兰智能电表 要求)的荷兰智能电表,也称为“Slimme meter”或“P1 端口”。
本组件支持明文非加密报文,也支持卢森堡使用的加密报文。 如果您的设备使用加密,必须从能源公司获取一个 32 字符长的加密密钥。
本组件是被动的,不会向您的设备传输任何数据,设备始终发送 数据,本组件对其进行解码,并以数据接收的速度更新配置的传感器。
# 示例配置条目uart: rx_pin: GPIO16 # 大多数 DSMR 电表使用 115200 波特率,但有些旧电表使用 9600 波特率。 baud_rate: 115200 # 建议将 rx_buffer_size 设置为至少 1500 字节,以避免数据包丢失。 rx_buffer_size: 1700
dsmr: # 可选。DSMR 的 ID。如果您有多个 DSMR 组件,请指定此项。 id: dsmr_id
# 可选。UART 中心的 ID。 # 如果您配置了多个 UART,则为必需项。 uart_id: uart_dsmr
# 可选。32 字符长的加密密钥。 # 仅在您的智能电表使用加密时才指定此项(例如您拥有“Luxembourg Smarty”) decryption_key: "00112233445566778899AABBCCDDEEFF"
# 可选。燃气表 ID。默认值=1。 gas_mbus_id: 1
# 可选。水表 ID。默认值=2。 water_mbus_id: 2
# 可选。热量表 ID。默认值=3。 thermal_mbus_id: 3
# 可选。指定是否必须执行 CRC 检查。默认值=true。 # 以下情况必须将其设为 false: # * 您使用的是不提供 CRC 的旧版 DSMR。 # * 您的智能电表使用错误的算法来计算 CRC。例如:EON Hungary。 crc_check: true
# 可选。用于读取 DSMR 报文的缓冲区大小。 # 仅在您的智能电表发送大型报文时才指定此参数。 max_telegram_length: 1500
# 可选。P1 端口的数据请求引脚。 # DSMR 模块使用此引脚告知智能电表何时发送数据。 # 默认情况下,智能电表持续发送数据。 # 仅当您需要使用自定义 `request_interval` 时指定此引脚才有用。 request_pin: GPIO5
# 可选。两次报文读取之间的最短时间。默认值=0ms。 # 智能电表发送数据的速度决定了更新频率。 # 与 `request_pin` 配合使用效果最佳,但没有它也能工作。 request_interval: 0ms
# 可选。仅用于接收加密报文。检测帧间间隔的延迟。默认值=200ms。 # 除非有非常特殊的用例,否则无需指定此参数。 receive_timeout: 200ms
## 可用传感器和文本传感器列表。# 并非所有传感器在所有设备上均可用。#旧版 DSMR 电表支持
Section titled “旧版 DSMR 电表支持”版本 2.2 支持以下配置:
# DSMR v2.2 的自定义 uart 设置uart: baud_rate: 9600 data_bits: 7 parity: NONE stop_bits: 1
dsmr: crc_check: false
sensor: - platform: dsmr energy_delivered_tariff1: name: dsmr_energy_delivered_tariff1 energy_delivered_lux: name: dsmr_energy_delivered_tarifflux
text_sensor: - platform: dsmr identification: name: "dsmr_identification" p1_version: name: "dsmr_p1_version" gas_delivered_text: name: "gas delivered raw"P1 数据请求引脚
Section titled “P1 数据请求引脚”摘自 P1 伴随指南:P1 端口通过将“Data Request”线拉高 (至 +5V)来激活(开始发送数据)。在接收数据期间,请求的 OSM 必须保持“Data Request”线激活(设为 +5V)。 要停止接收数据,OSM 需要将“Data Request”线置低(设为“高阻抗”模式)。在这种情况下数据传送 会立即停止。
使用请求引脚的优势
Section titled “使用请求引脚的优势”-
读取报文后,dsmr 组件将停止数据传输,直到报文已 完全处理。这将数据检索和处理分离开来,因此可视为一种 硬件流控制形式。
-
可以干净地控制传感器读数必须更新的时间间隔,仅在需要时启动数据 传输。此配置选项
request_interval可用于定义该时间间隔。
所需的硬件支持
Section titled “所需的硬件支持”许多 DSMR 读取器电路将 P1 端口的 +5V 引脚直接连接至其 Data Request 引脚。这样会使
智能电表以智能电表固件定义的速度发送报文。例如许多
DSMR v5 电表每秒发送一个报文。
使用此类布线的电路无法使用 request_pin 选项。
但是,当使用允许通过 GPIO 在 +5V 和高阻抗
模式之间切换 Data Request 引脚的电路时,可以将该 GPIO 配置为 request_pin。
使用光耦电路来处理开关取得了最佳效果。直接 GPIO 输出 或基于晶体管的电路不可行。以下是一个示例电路设计:
当使用在 GPIO 输出上提供 5V 而非 3.3V 的 MCU 时,请使用 330 欧姆 电阻代替 200 欧姆电阻。
提高读取器效果
Section titled “提高读取器效果”当报文有时丢失或出现大量 CRC 错误时,可能需要做一些 更改以获得更好的读取器效果。
建议将 UART 总线的 rx_buffer_size 选项设置为至少最大报文大小,
默认值为 1500 字节。默认 UART 读取缓冲区较小,很容易溢出,导致
数据字节丢失。
# 示例配置uart: pin: D7 baud_rate: 115200 rx_buffer_size: 1700
dsmr: max_telegram_length: 1700使用硬件 UART 读取 P1 数据时效果最佳。是否在 API 日志记录器连接时 获取的配置转储中检查是否使用了硬件 UART。示例日志输出:
[02:38:37][C][uart.arduino_esp8266:095]: UART 总线:[02:38:37][C][uart.arduino_esp8266:097]: RX 引脚: GPIO13[02:38:37][C][uart.arduino_esp8266:099]: RX 缓冲区大小: 1500[02:38:37][C][uart.arduino_esp8266:101]: 波特率: 115200 baud[02:38:37][C][uart.arduino_esp8266:102]: 数据位: 8[02:38:37][C][uart.arduino_esp8266:103]: 奇偶校验: NONE[02:38:37][C][uart.arduino_esp8266:104]: 停止位: 1[02:38:37][C][uart.arduino_esp8266:106]: 使用硬件串行接口。 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^当使用 ESP8266 时,GPIO13(例如 D1 Mini 上的 D7 引脚)可用于硬件 RX。然而,要 使其真正工作,必须禁用串行日志记录,以保持硬件 UART 可供 D7 使用。
# ESP8266 的示例配置logger: baud_rate: 0 level: DEBUG
uart: pin: GPIO13 baud_rate: 115200桥接支持 / 原始报文日志记录
Section titled “桥接支持 / 原始报文日志记录”您可以使用另一个 uart 为另一个 P1 接收器提供相同报文。请参见桥接用的配置示例。
# 定义多个 uartuart: - id: p1_uart rx_pin: number: 4 inverted: true baud_rate: 115200 rx_buffer_size: 1700 - id: p1_bridge_uart tx_pin: number: 10 baud_rate: 115200
# 将输入 uart 链接到 dsmrdsmr: uart_id: p1_uart max_telegram_length: 1700
# 记录报文并将报文传递给 p1_bridge_uarttext_sensor: - platform: dsmr telegram: name: "telegram" on_value: then: - lambda: |- ESP_LOGV("dsmr", "telegram: %s", x.c_str()); p1_bridge_uart->write_str(x.c_str());记录原始输入数据并启用非常详细的日志记录。
如果您在接收数据时遇到问题,请将这些配置选项添加到 logger 和 uart 组件中:
logger: level: VERY_VERBOSE
uart: debug: sequence: - lambda: UARTDebug::log_string(direction, bytes);