跳转到内容

OpenEnergyMonitor EmonTx 传感器

emontx 组件允许您使用 ESPHome 通过受支持的设备(推荐使用 ESP32)与 OpenEnergyMonitor emonTX 建立连接。 该组件是一个全局中心,通过 UART 总线 与 EmonTx 建立连接并翻译接收到的数据。 使用 emontx 传感器,您可以创建用于 Home Assistant 的传感器,以跟踪电压、电流、功率(由最多 12 个 CT 测量)、脉冲数据和温度(取决于 emonTX 的配置)。

该组件可以将数据发送到 MQTT Broker,既可作为 JSON 发送,也可作为单独的主题供任何系统消费。

该组件还可用于通过 HTTP 将数据发送到远程 emoncms 实例(如 emoncms),或通过 HTTP 或 MQTT 发送到本地托管的系统。与 emoncms 无缝直接配合工作是本组件的核心优势,允许您将能源监控数据与强大的可视化和分析工具集成。

OpenEnergyMonitor EmonTx5
OpenEnergyMonitor EmonTx。

EmonTx 可通过串行 UART 接口连接到您的 ESP 设备。

根据您的 emontx 版本,商店中可能有扩展板可简化接线。您也可以不使用扩展板直接使用标准 EmonTx,但需要手动连接 UART/Vcc/Gnd 引脚。

确保 EmonTx 已配置为以 JSON 格式输出数据。通信的默认波特率为 115200。

由于与 EmonTx 的通信使用 UART 完成,因此配置中需要有一个 UART 总线,将 rx_pin 连接到 EmonTx 的数据引脚,并将波特率设置为 115200。

# 示例配置条目
uart:
id: emontx_uart # 使用 UART2
rx_pin: GPIOXX # 使用 emonWifi 时为 GPIO20
tx_pin: GPIOXX # 使用 emonWifi 时为 GPIO21
baud_rate: 115200
rx_buffer_size: 2048
emontx:
id: myemontx
on_json:
- then:
# 接收 JSON 数据时要执行的操作,例如:
- logger.log:
format: "Received JSON: %s"
args: [raw_json.c_str()]

在 emontx 平台中:

  • id (可选, ID): 手动指定用于代码生成或多个中心的 ID。
  • uart_id (可选, ID): 如果您想使用多个 UART 总线,请手动指定 UART 组件 的 ID。
  • on_json (可选): 每当从 EmonTx 接收到新的 JSON 数据时触发的自动化。在此触发器中,raw_json 变量(字符串类型)包含接收到的 JSON 数据。json 变量(JsonObject 类型)也提供了解析后的 JSON 对象,可用于访问和操作 JSON 数据中的特定字段。
  • on_data (可选): 每当从 EmonTx 接收每一行串行数据时(包括纯文本和 JSON)触发的自动化。在此触发器中,data 变量(字符串类型)包含接收到的行。这对于调试、记录所有串行输出或处理来自 EmonTx 的配置响应非常有用。

通过 UART 向 EmonTx 设备发送命令字符串。自动附加换行符。

button:
- platform: template
name: "请求 EmonTx 版本"
on_press:
- emontx.send_command:
id: myemontx
command: "v"
  • id (必选, ID): EmonTx 中心的 ID。
  • command (必选, string, templatable): 要发送的命令字符串。

以下是一个最小工作配置,用于从 EmonTx 开始基本的传感器读数:

uart:
id: emontx_uart
rx_pin: GPIOXX # 使用 emonWifi 时为 GPIO20
tx_pin: GPIOXX # 使用 emonWifi 时为 GPIO21
baud_rate: 115200
rx_buffer_size: 2048
emontx:
sensor:
- platform: emontx
tag_name: "V1" # 多相使用 "V1"-"V3";单相 "Vrms" 请参见传感器索引
name: "电压"
- platform: emontx
tag_name: "P1"
name: "CT1 功率"
- platform: emontx
tag_name: "E1"
name: "CT1 能量"

这将在 Home Assistant 中创建三个传感器,分别跟踪来自第一个 CT 通道的电压、功率和能量。请参见下方的 传感器 部分以了解所有可用的传感器类型及其标签名称。

EmonTx 组件提供几个可用于监控各种参数的传感器:

  • 功率:根据电压和电流读数计算功率消耗。
  • 能量:随时间累计能量消耗。
  • 电压:测量 mains 电压。
  • 电流:测量通过连接的 CT 钳的电流。
  • 功率因子:根据电压和电流读数计算功率因子。
  • 脉冲:测量来自连接的脉冲传感器(例如 S0 接口)的脉冲数。
  • 温度:报告连接的 Dallas DS18B20 传感器的温度。
  • platform (必选): 设为 emontx。
  • tag_name (必选, string): EmonTx 数据中映射到此传感器的 JSON 键名称。请参见 传感器索引 以了解所有可用的标签名称。
  • 所有其他标准 传感器 配置变量也适用。

EmonTx 组件中每种类型的传感器都具有预定义的配置参数:

功率传感器具有以下默认配置:

  • 单位:W(瓦特)
  • 设备类型:power
  • 状态类型:measurement
  • 精度:0 位小数

能量传感器具有以下默认配置:

  • 单位:Wh(瓦时)
  • 设备类型:energy
  • 状态类型:total_increasing
  • 精度:0 位小数

电压传感器具有以下默认配置:

  • 单位:V(伏特)
  • 设备类型:voltage
  • 状态类型:measurement
  • 精度:2 位小数

电流传感器具有以下默认配置:

  • 单位:A(安培)
  • 设备类型:current
  • 状态类型:measurement
  • 精度:2 位小数

功率因子传感器具有以下默认配置:

  • 单位:(无量纲)
  • 设备类型:power_factor
  • 状态类型:measurement
  • 精度:2 位小数

温度传感器具有以下默认配置:

  • 单位:°C(摄氏度)
  • 设备类型:temperature
  • 状态类型:measurement
  • 精度:2 位小数

脉冲传感器具有以下默认配置:

  • 单位:pulses
  • 精度:0 位小数(整数)

如有需要,可在 YAML 配置中覆盖这些预定义配置。

EmonTx 传感器使用特定的索引方案,取决于您的 EmonTx 设备的物理配置:

电压传感器的索引基于您的电源系统配置:

  • Vrms:单相系统的电压读数。此标签不适用自动默认值——必须手动指定 unit_of_measurement、device_class 和 state_class。
  • V1:多相系统中第 1 相的电压读数
  • V2:多相系统中第 2 相的电压读数
  • V3:三相系统中第 3 相的电压读数

功率传感器的索引基于 CT 钳连接:

  • P1-P6:标准 EmonTx 上 CT1-CT6 的功率读数
  • P7-P12:存在扩展板时 CT7-CT12 的功率读数

能量传感器遵循与功率传感器相同的索引方案:

  • E1-E6:标准 EmonTx 上 CT1-CT6 的能量累计
  • E7-E12:存在扩展板时 CT7-CT12 的能量累计

电流传感器的索引根据 CT 输入而定:

  • I1-I6:标准 EmonTx 上 CT1-CT6 的电流读数
  • I7-I12:存在扩展板时 CT7-CT12 的电流读数

功率因子传感器的索引与 CT 输入相同:

  • PF1-PF6:标准 EmonTx 上 CT1-CT6 的功率因子
  • PF7-PF12:存在扩展板时 CT7-CT12 的功率因子

温度传感器的索引根据连接的温度探头而定:

  • T1-T3:最多 3 个温度传感器(通常为 DS18B20)的读数

pulse 传感器是单一计数器输入,不使用索引。

传感器的实际可用性取决于您的特定 EmonTx 配置和固件。 并非所有传感器索引在您的设置中均激活或报告值。

例如,在单相系统中,仅 Vrms/V1 提供读数,而 V2 和 V3 不可用。

要查看 EmonTx 中有哪些传感器可用,可以参考 EmonTx 文档或固件配置。 您还可以使用 ESPHome 日志查看哪些传感器正在报告数据。

例如:

[14:43:36][I][emontx:099]: Received data: {"MSG":54378,"V1":234.16,"V2":234.13,"V3":234.22,"P1":0,"P2":0,"P3":0, "P4":0,"P5":0,"P6":0,"E1":74,"E2":-9,"E3":-12,"E4":7,"E5":-4,"E6":-6,"pulse":0}

以下是在 ESPHome YAML 配置中配置 EmonTx 传感器的示例:

sensor:
- platform: emontx
tag_name: "V1"
name: "电压 L1"
- platform: emontx
tag_name: "V2"
name: "电压 L2"
- platform: emontx
tag_name: "V3"
name: "电压 L3"
- platform: emontx
tag_name: "P1"
name: "CT1 功率"
- platform: emontx
tag_name: "E2"
name: "CT2 能量"
- platform: emontx
tag_name: "I3"
name: "CT3 电流"
- platform: emontx
tag_name: "PF1"
name: "CT1 功率因子"
- platform: emontx
tag_name: "T1"
name: "温度 1"
- platform: emontx
tag_name: "pulse"
name: "脉冲"

on_json 触发器提供了一种灵活处理从 EmonTx 接收的 JSON 数据的方式。可使用此触发器:

  1. 通过 HTTP 将数据转发到本地/远程 emoncms
  2. 通过 MQTT 将数据转发到本地 emoncms 实例
  3. 将数据发送到任何本地/远程 HTTP 端点
  4. 将数据发布到 MQTT 主题
  5. 在转发前处理或转换数据
  6. 基于接收的数据实现自定义逻辑

WARNING

如果您不使用 API 组件,即模块仅用于将数据转发到 Emoncms 且不连接到任何 Home Assistant 实例,则必须移除 api: 配置或设置 reboot_timeout: 0s,否则 ESP 会每 15 分钟重启一次,因为没有客户端连接到原生 API。

要通过 HTTP 将数据转发到 emoncms,可在 on_json 触发器中使用 http_request.post 操作:

substitutions:
emoncms_server: "https://emoncms.org"
emoncms_node: "emontx"
emoncms_apikey: !secret emoncms_rw_apikey
http_request:
useragent: esphome/emontx
timeout: 10s
emontx:
on_json:
- then:
- http_request.post:
url: !lambda 'return "${emoncms_server}/input/post";'
request_headers:
Content-Type: "application/x-www-form-urlencoded"
body: !lambda |-
return "node=${emoncms_node}&apikey=${emoncms_apikey}&fulljson=" + raw_json;

NOTE

严格来说,fulljson 值应在 application/x-www-form-urlencoded 主体中进行 URL 编码。实际上,emoncms PHP 后端接受未编码的原始 JSON 字符串。

emoncms API 密钥必须是读写 API 密钥。仅读 API 密钥无法用于发布数据。可在 emoncms Web 界面中 My Account > API Keys 下找到读写 API 密钥。

node 参数必须符合 emoncms 的预期。根据您的 emoncms 服务器配置,这可能是一个数字 ID(如“1”)或字符串标识符。请检查 emoncms 服务器文档以确保使用正确的 node 格式。

如果想将数据发送到非 EmonCMS 服务器,则需要调整 http_request.post 操作以匹配目标端点的要求。 例如,要以 JSON 形式将数据发送到通用 REST API,可使用:

- http_request.post:
url: "https://your-api-endpoint.example.com/data"
request_headers:
Content-Type: "application/json"
body: !lambda 'return raw_json;'

有关自定义请求的更多详细信息,请参阅 ESPHome HTTP 请求文档。

要通过 MQTT 将数据转发到本地 emoncms,可在 on_json 触发器中使用 mqtt.publish 操作:

mqtt:
broker: 192.168.1.10
port: 1883 # 可选
username: mqtt_user # 可选
password: mqtt_pass # 可选
id: mqtt_client # 可选
emontx:
on_json:
- then:
- mqtt.publish:
topic: emon/emontx
payload: !lambda 'return raw_json;'
qos: 0
retain: false

在此配置下,原始 JSON 数据将发布到主题 emon/emontx。

主题 emon/emontx 遵循 emoncms 默认格式:emon 前缀是 emoncms MQTT 服务订阅的用于接收数据的名称,emontx 是数据在 emoncms 中出现的 Node 名称。

可在单个配置中组合 HTTP 和 MQTT 转发:

substitutions:
emoncms_server: "https://emoncms.org"
emontx_node: "emontx"
emoncms_apikey: !secret emoncms_rw_apikey
http_request:
useragent: esphome/emontx
timeout: 10s
mqtt:
broker: 192.168.1.10
port: 1883 # 可选
username: mqtt_user # 可选
password: mqtt_pass # 可选
id: mqtt_client # 可选
emontx:
on_json:
- then:
- mqtt.publish:
topic: emon/emontx
payload: !lambda 'return raw_json;'
qos: 0
retain: false
- http_request.post:
url: !lambda 'return "${emoncms_server}/input/post";'
request_headers:
Content-Type: "application/x-www-form-urlencoded"
body: !lambda |-
return "node=${emoncms_node}&apikey=${emoncms_apikey}&fulljson=" + raw_json;

在此配置下,原始 JSON 数据将发布到本地 MQTT Broker 192.168.1.10 的主题 emon/emontx。同时也会通过 HTTP POST 请求发送到远程 emoncms 服务器。

使用 on_json 触发器的一个优势是可以在转发前处理 JSON 数据。当并非所有 CT 钳都连接到您的 EmonTx 时,这特别有用,会导致某些值始终为零。

可在 http_request.post 操作中直接过滤 JSON:

emontx:
on_json:
- then:
- http_request.post:
url: !lambda 'return "${emoncms_server}/input/post";'
request_headers:
Content-Type: "application/x-www-form-urlencoded"
body: !lambda |-
// json 变量已作为解析后的对象提供
// 移除未使用的 CT 值(假设 CT4、CT5、CT6 未连接)
json.remove("P4");
json.remove("P5");
json.remove("P6");
json.remove("E4");
json.remove("E5");
json.remove("E6");
// 转换回字符串以进行转发
std::string filtered_json;
serializeJson(json, filtered_json);
return "node=${emoncms_node}&apikey=${emoncms_apikey}&fulljson=" + filtered_json;

此示例在转发到 emoncms 前从 JSON 对象中移除了未使用的 CT 值(P4、P5、P6、E4、E5、E6)。serializeJson(json, filtered_json) 函数将修改后的 JSON 对象转换回字符串以用于 HTTP 请求。

同样的过滤也可以应用于 MQTT 有效载荷(如果也在发布到 MQTT):

emontx:
on_json:
- then:
- mqtt.publish:
topic: emon/emontx
payload: !lambda |-
// 从 JSON 对象中移除未使用的 CT 值
json.remove("P4");
json.remove("P5");
json.remove("P6");
json.remove("E4");
json.remove("E5");
json.remove("E6");
// 转换回字符串以作为 MQTT 有效载荷
std::string filtered_json;
serializeJson(json, filtered_json);
return filtered_json;

此集成通常用于将数据转发到非 Home Assistant 系统,如 Jeedom、Domoticz 或自定义 MQTT 消费者。

WARNING

如果启用 mqtt 转发且不使用 API 组件,即模块仅用于通过 MQTT 转发数据且不连接到任何 Home Assistant 实例,则必须移除 api: 配置或设置 reboot_timeout: 0s,否则 ESP 会每 15 分钟重启一次,因为没有客户端连接到原生 API。

如果在 ESPHome 设备中配置了 MQTT 组件,配置中定义的所有 emontx 传感器将自动发布到遵循 ESPHome 标准结构的 MQTT 主题:

<topic_prefix>/sensor/<sensor_name>/state

其中 <topic_prefix> 默认为设备名称,<sensor_name> 源自传感器的 name: 字段(小写,空格替换为下划线)。

例如,设备名称为 emontx_living_room 且定义以下传感器时,数据将发布到:

  • 名为“Voltage”的传感器发布到 emontx_living_room/sensor/voltage/state
  • 名为“Energy CT2”的传感器发布到 emontx_living_room/sensor/energy_ct2/state

仅配置中定义的传感器将发布(参见 传感器)。

示例:

mqtt:
broker: 192.168.1.10
port: 1883 # 可选
username: mqtt_user # 可选
password: mqtt_pass # 可选
id: mqtt_client # 可选
emontx:
sensor:
- platform: emontx
tag_name: "Vrms"
name: "电压"
unit_of_measurement: V
device_class: voltage
state_class: measurement
accuracy_decimals: 2
- platform: emontx
tag_name: "E2"
name: "CT2 能量"

可通过在 mqtt 配置中设置 topic_prefix 来自定义 MQTT 主题前缀。 有关如何配置 MQTT 主题的更多详细信息,请参阅 MQTT 文档。