SML(智能消息语言)
SML 组件用于连接使用 智能消息语言(SML)协议的智能电表。
虽然 SML 协议定义明确,但它为制造商在如何存储和识别传输数据方面提供了很大的自由度。在电报中,物理值由 OBIS 代码(对象识别系统)标识。如果知道制造商将哪个代码分配给物理值,就可以提取相应的值。
此组件是被动的,它不会向您的设备传输任何数据。通常,智能电表会以固定间隔(2-4 秒)自动发送电报。 此组件按照接收数据的速度解码并更新配置的传感器。
大多数智能电表通过红外光学接口传输电报。作为传感器,可以将合适的光电晶体管(例如 BPW40)连接到 ESP 的 UART(发射极接 GND,集电极接 RX 引脚)。更成熟的解决方案可以在 Volkszaehler Wiki(德语)上找到。网络上还有许多其他示例和现成的解决方案。
组件/集线器
Section titled “组件/集线器”由于与传感器的通信是通过 UART 进行的,您需要在配置中设置 UART 总线。接口参数应根据您的智能电表设置为 9600/8N1 或 9600/7E1。如果您在日志中看到校验和错误,请尝试更改接口参数。
# 配置示例sml: id: mysml uart_id: uart_bus on_data: - lambda: !lambda |- char hex[512]; // 根据您的数据适当调整大小 if (valid) { id(mqttclient).publish("gridmeter/sensor/sml/state", format_hex_to(hex, bytes)); } else { id(mqttclient).publish("gridmeter/sensor/sml/error", format_hex_to(hex, bytes)); }sensor: - platform: sml name: "总能量" sml_id: mysml server_id: "0123456789abcdef" obis_code: "1-0:1.8.0" unit_of_measurement: kWh accuracy_decimals: 1 device_class: energy state_class: total_increasing filters: - multiply: 0.0001-
obis_code (必填, 字符串): 指定要从设备检索数据的 OBIS 代码。 格式必须为 (A-B:C.D.E,例如 1-0:1.8.0)
-
server_id (可选, 字符串): 指定设备的 server_id 以从中检索 OBIS 代码。如果同一硬件传感器组件连接了多个设备,则应指定此项。
-
所有其他选项来自 传感器。
text_sensor: - platform: sml name: "制造商" sml_id: mysml server_id: "0123456789abcdef" obis_code: "129-129:199.130.3" format: text-
obis_code (必填, 字符串): 指定要从设备检索数据的 OBIS 代码。 格式必须为 (A-B:C.D.E,例如 1-0:1.8.0)
-
server_id (可选, 字符串): 指定设备的 server_id 以从中检索 OBIS 代码。如果同一硬件传感器组件连接了多个设备,则应指定此项。
-
format (可选, 字符串): 覆盖传输二进制数据值的自动解释。可能的值有 (
int、uint、bool、hex、text)。 -
所有其他选项来自 文本传感器。
- on_data (可选, 自动化): 当接收到 SML 消息时执行的操作。请参阅
on_data触发器。
on_data 触发器
Section titled “on_data 触发器”当接收到有效的 SML 消息时,将触发此自动化。变量 bytes(类型为 std::vector<uint8_t>)包含原始 sml 数据,包括起始/结束序列。变量 valid(类型为 bool)包含校验和验证的结果。
获取 OBIS 代码和传感器 ID
Section titled “获取 OBIS 代码和传感器 ID”传输的 SML 电报中的物理值由 server id 和 OBIS 代码 标识。server id 标识您的智能电表。如果您只有一个硬件组件连接到光学传感器,通常不需要关心 server id,可以在配置中省略它。
为了获取智能电表提供的 server id 和可用的 OBIS 代码,只需设置 SML 平台 并观察日志输出(日志级别必须至少设置为 debug!)。
您的日志输出将显示如下内容:
每行代表 server id(在括号中)、OBIS 代码和传输的十六进制值(在方括号中)的组合。
许多智能电表对某些 OBIS 代码发出非常大的数字(如累计总有功电能)。这可能导致传感器组件向 ESPHome 报告的值出现精度误差。这表现为向 HomeAssistant 报告的数字可能略有错误。这是 ESPHome 内部限制的结果,与 SML 组件无关。
如果您无法接受这种情况,可以使用带有适当格式的 TextSensor 将值作为字符串传输到 HomeAssistant。在 HomeAssistant 端,您可以定义一个 模板传感器 将值转换为适当的格式并进行一些缩放。
对于 ESPHome,我们有:
# ESPHome 配置文件text_sensor: - platform: sml name: "总能量文本" obis_code: "1-0:1.8.0" format: uintformat 参数是可选的。如果省略,SML 组件将尝试从接收到的 SML 消息中猜测正确的数据类型。
在 HomeAssistant 中:
# Home Assistant configuration.yamltemplate: - sensor: - name: "总能耗" unit_of_measurement: "kWh" state: > {% if states('sensor.total_energy_text') == 'unavailable' %} {{ states('sensor.total_energy_consumption') }} {% else %} {{ ((states('sensor.total_energy_text') | float) * 0.0001) | round(2) }} {% endif %}通常,如果 ESP 设备不可用,模板传感器的值会变为 0。 这会导致在将传感器与 公用事业仪表 集成结合使用时出现问题。 上面提供的状态模板会检查传感器的可用性,并在不可用时保持当前状态。
Holley DTZ541 智能电表
Section titled “Holley DTZ541 智能电表”Holley DTZ541 系列电能表的 SML 协议实现存在问题。
这些电表发送多个与 OBIS 代码 1-0:1.8.0 冲突的值,该代码是电表能量读数的代码。
由于每个数据包的第一个值是正确的值,为了丢弃错误的值,可以应用 0.5s 的节流过滤器。
sensor: - platform: sml name: "总能耗" sml_id: mysml obis_code: "1-0:1.8.0" unit_of_measurement: kWh accuracy_decimals: 5 device_class: energy state_class: total_increasing filters: - throttle: 0.5s - multiply: 0.0001这些电表还可以测量瞬时功率使用情况。
sensor: - platform: sml name: "瞬时功率" sml_id: mysml obis_code: "1-0:16.7.0" unit_of_measurement: W accuracy_decimals: 0 device_class: power state_class: measurement