Tasmota 通用 Modbus 电能表 JSON 配置完全指南:寄存器映射、数据类型与三相扩展
2026/9/13 19:54:04 网站建设 项目流程

Tasmota 通用 Modbus 电能表 JSON 配置完全指南:寄存器映射、数据类型与三相扩展

【免费下载链接】TasmotaAlternative firmware for ESP8266 and ESP32 based devices with easy configuration using webUI, OTA updates, automation using timers or rules, expandability and entirely local control over MQTT, HTTP, Serial or KNX. Full documentation at项目地址: https://gitcode.com/GitHub_Trending/ta/Tasmota

导读

本文基于 Tasmota 仓库中 energy_modbus_configs/configurations.md 与 value_pairs_description.md 两篇官方文档,系统讲解通用 Modbus 电能表驱动(xnrg_29_modbus,源码见 xnrg_29_modbus.ino)的 JSON 配置体系。读完本文,你将掌握:通过规则、脚本或文件系统三种方式加载 Modbus 配置、理解全部顶层参数与寄存器值对的含义、为 SDM230 / DDSU666 / PZEM014 / WE517 等常见电表套用开箱即用的官方配置,并能为任意自定义 Modbus 电能设备编写寄存器映射实现本地化电能监测。

一、通用 Modbus 电能驱动与配置数据的定位

Tasmota 的通用 Modbus 电能驱动(Generic Modbus energy meter)支持:

  • 单台三相设备,或总线上三台同型号单相设备(以三个相位呈现);
  • 除浮点寄存器外,还支持 Modbus 单/双整型寄存器;
  • 通过一份 JSON 描述文件完成全部寄存器映射,无需改动固件。

驱动编译需要USE_ENERGY_SENSORUSE_MODBUS_ENERGY两个宏,参考 tasmota_configurations_ESP32.h(ESP32 默认启用)与 tasmota_configurations.h(其他平台可选,约增加 5k 代码)。这份 JSON 配置数据的官方参考即位于energy_modbus_configs/目录下的两个文档:

  • configurations.md:现成设备配置清单(默认配置 + 扩展配置);
  • value_pairs_description.md:JSON 键值对字段的完整语义说明。

二、三种加载 Modbus JSON 的方式

驱动在初始化时按固定优先级读取配置(详见 xnrg_29_modbus.ino 的EnergyModbusReadRegisters()):

  1. 文件系统驱动(优先级最高)——若存在文件系统(每个 ESP32 都有),创建名为modbus.json的文件,将所需 JSON 内容写入其中。源码中对应ENERGY_MODBUS_FILE宏定义:"/modbus.json"(xnrg_29_modbus.ino)。
  2. 规则驱动——将所需 JSON 内容复制到任意规则缓冲区,前缀为rule3 on file#modbus do,后缀为endon
  3. 脚本驱动——将 JSON 内容复制到脚本中,前缀为>y,后缀为#

从源码的读取顺序看,驱动依次尝试文件系统(TfsLoadString(ENERGY_MODBUS_FILE))→ 规则(RuleLoadFile("MODBUS"))→ 脚本(ScriptLoadSection(">y")),取第一个非空来源;若 JSON 内容长度小于 7 个字符或解析失败,则视为无效并放弃加载(if (modbus.length() < 7) { return false; })。

注意事项

  • 长规则与串口缓冲:通过串口控制台输入长规则时,可能遇到Serial buffer overrun错误,需要用命令serialbuffer 800增大串口输入缓冲区。
  • 配置生效时机:配置的改动只有在执行restart命令重启后才会被激活。

三、顶层配置参数

顶层 JSON 键描述设备与通信层,参数表如下(来自 value_pairs_description.md):

参数说明默认值
Name电能监测设备的名称
Baud设备 Modbus 接口的波特率(可选)9600
Config串口配置,如8N1(8 数据位、无校验、1 停止位)由驱动内部宏决定
Poll两次 Modbus 请求之间的间隔时间(可选)200毫秒
AddressModbus 设备地址,十进制(1)或十六进制(0x01),最多三个地址([1,2,3])(可选)1
Function访问寄存器用的 Modbus 功能码(可选)4

对应源码中的默认宏(xnrg_29_modbus.ino):默认波特率ENERGY_MODBUS_SPEED = 9600、默认串口配置TS_SERIAL_8N1、默认地址ENERGY_MODBUS_ADDR = 1、默认功能码ENERGY_MODBUS_FUNC = 0x04、默认轮询间隔ENERGY_MODBUS_TICKER_POLL = 200

几点实现细节值得注意:

  • Config在解析时会经过ParseSerialConfig()/ConvertSerialConfig()转换(xnrg_29_modbus.ino);
  • Poll低于 100 ms 会被强制还原为默认值,因为 9600 bps 下通信通常不可能更快(xnrg_29_modbus.ino);
  • Address传数组时,驱动按数组元素数量设置设备数devices,最多ENERGY_MODBUS_MAX_DEVICES(即 3)台设备(xnrg_29_modbus.ino)。

四、Tasmota 内置寄存器名称

内置寄存器即 Tasmota 电能框架中的标准字段,每个寄存器可配置为以下三种形式之一:

  • 单相单值:十进制或十六进制寄存器地址,如"Voltage":0"Voltage":0x0000
  • 三相数组:最多三个地址,如"Voltage":[0,2,4]
  • 值对对象:带类型与因子的详细描述,如"Voltage":{"R":0,"T":0,"F":0}

内置寄存器清单(名称须与 Tasmota 默认嵌入名称一致,不可被用户自定义名称占用):

键名含义典型地址示例
Voltage电压(单相或三相)0x0000/[0x0000,0x0002,0x0004]
Current电流0x0006/[0x0006,0x0008,0x000A]
Power有功功率0x000C/[0x000C,0x000E,0x0010]
ApparentPower视在功率0x000C起(同 Power 布局)
ReactivePower无功功率0x0018
Factor功率因数0x001E
Frequency电网频率0x0046
Total总正向有功电能0x0156
ExportActive反向(输出)有功电能0x0160

源码中这些字段定义在kEnergyModbusValues字符串表与EnergyModbusRegisters枚举中(xnrg_29_modbus.ino),读取到的原始值经类型解析与因子换算后,分别写入Energy->voltage[]Energy->current[]Energy->active_power[]等标准电能结构体(xnrg_29_modbus.ino)。

寄存器值对(Value Pair)描述

{"R":0,"T":0,"F":0}三个字段:

  • R(Modbus register):寄存器地址,十进制或十六进制;单相一个值(0x0160),三相最多三个值([0x0160,0x0162,0x0164])。
  • T(Datatype,数据类型):可选,默认0(float,4 字节浮点):
数据类型
0float(4 字节浮点)
12 字节有符号整型
24 字节有符号整型
32 字节无符号整型
44 字节无符号整型
5未使用
64 字节有符号整型(字序交换)
7未使用
84 字节无符号整型(字序交换)

源码中对应枚举EnergyModbusDataType(xnrg_29_modbus.ino),并在EnergyModbusLoop()的 switch 中逐类型解码字节流。值得注意的是:偶数为单寄存器类型(2 字节),奇数为双寄存器类型(4 字节),源码用2 - (datatype & 1)计算需读取的寄存器个数(xnrg_29_modbus.ino)。字序交换类型(6/8)用于 Solax 等高低字颠倒的协议(源码注释示例:01 04 04 EB EC 00 0E 8E 51 = 977.9000)。

  • F(Register factor,寄存器系数):可选,默认0表示不处理。正数表示乘,负数表示除
运算
-4除以 10000
-3除以 1000
-2除以 100
-1除以 10
0不处理
1乘以 10
2乘以 100
3乘以 1000
4乘以 10000

源码实现为按绝对值累乘 10 得到缩放因子,再根据符号决定乘除(xnrg_29_modbus.ino)。

五、用户自定义寄存器(User

当内置字段不够用时,可用User数组补充任意数量的用户自定义寄存器。单个值对格式:

{"R":0x0024,"T":0,"F":0,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2}

字段说明:

  • R/T/F:与内置寄存器值对完全相同的寄存器地址、数据类型与系数(见上节表格)。
  • J(JSON register name):JSON 输出中使用的名称,建议无空格(如"PhaseAngle"),必填;且必须与 Tasmota 默认内置寄存器名称不同,否则该条用户寄存器会被驱动丢弃(源码 xnrg_29_modbus.ino 用GetCommandCode(..., kEnergyModbusValues)检测重名后return false)。
  • G(GUI register name):Web 界面显示名称,可选;未定义则该寄存器不会显示在 GUI 中
  • U(GUI unit name):Web 界面显示的单位,可选,默认为空。
  • D(Decimals,小数位):浮点显示的位数(0 到 20),或对应 Tasmota 分辨率命令(VoltRes/AmpRes/WattRes等)设置代码:
D含义
020固定小数位数
21VoltRes(V)
22AmpRes(A)
23WattRes(W、VA、var)
24EnergyRes(kWh、kVAh、kvarh)
25FreqRes(Hz)
26TempRes(°C、°F)
27HumRes(%)
28PressRes(hPa、mmHg)
29WeightRes(Kg)

源码中分辨率映射位于EnergyModbusResolution()(xnrg_29_modbus.ino),枚举定义见EnergyModbusResolutions(xnrg_29_modbus.ino)。User可传对象(单条)或数组(多条);每条用户寄存器在 JSON 输出中以其J名称出现,并在 Web 界面以G+U呈现。

六、默认配置清单(开箱即用)

以下为官方文档提供的默认配置,覆盖 DDSU666、PZEM014、SDM230、Solax X3MIC、WE517 五类常见设备:

DDSU6666 {"Name":"DDSU666","Baud":9600,"Config":"8N1","Address":1,"Function":4,"Voltage":0x2000,"Current":0x2002,"Power":0x2004,"ReactivePower":0x2006,"Factor":0x200A,"Frequency":0x200E,"Total":0x4000,"ExportActive":0x400A} PZEM014 {"Name":"PZEM014","Baud":9600,"Config":"8N1","Address":1,"Function":4,"Voltage":{"R":0,"T":3,"F":-1},"Current":{"R":1,"T":8,"F":-3},"Power":{"R":3,"T":8,"F":-1},"Factor":{"R":8,"T":3,"F":-2},"Frequency":{"R":7,"T":3,"F":-1},"Total":{"R":5,"T":8,"F":-3}} 3 x PZEM014 {"Name":"3 x PZEM014","Baud":9600,"Config":"8N1","Address":[1,2,3],"Function":4,"Voltage":{"R":0,"T":3,"F":-1},"Current":{"R":1,"T":8,"F":-3},"Power":{"R":3,"T":8,"F":-1},"Factor":{"R":8,"T":3,"F":-2},"Frequency":{"R":7,"T":3,"F":-1},"Total":{"R":5,"T":8,"F":-3}} SDM230 {"Name":"SDM230","Baud":2400,"Config":"8N1","Address":1,"Function":4,"Voltage":0,"Current":6,"Power":12,"ApparentPower":18,"ReactivePower":24,"Factor":30,"Frequency":70,"Total":342,"ExportActive":0x004A} Solax X3MIC {"Name":"Solax X3MIC","Baud":9600,"Config":"8N1","Address":1,"Function":4,"Voltage":{"R":0x0404,"T":3,"F":-1},"Power":{"R":0x040e,"T":3,"F":0},"Total":{"R":0x0423,"T":8,"F":-3}} WE517 {"Name":"WE517","Baud":9600,"Config":"8E1","Address":1,"Function":3,"Voltage":[0xE,0x10,0x12],"Current":[0x16,0x18,0x1A],"Power":[0x1E,0x20,0x22],"ReactivePower":[0x26,0x28,0x2A],"Factor":[0x36,0x38,0x3A],"Frequency":0x14,"Total":0x100}

要点解读:

  • DDSU666:单相直读型电表,全部使用十六进制地址,注意其Baud为 9600;
  • PZEM014:寄存器内容为裸整型,因此大量使用T(2 字节无符号3/ 4 字节无符号交换字序8)与F(除以 10/100/1000)组合还原真实物理量;
  • 3 x PZEM014:与单个 PZEM014 完全相同的寄存器映射,仅把Address改为[1,2,3],即可将三台单相设备当作三相读取;
  • SDM230:寄存器地址全部为十进制浮点型,只有ExportActive用十六进制0x004A(十进制 74 的对应值);
  • Solax X3MIC:逆变器协议,电压用 2 字节无符号除以 10,总量用 4 字节无符号交换字序除以 1000;
  • WE517:使用8E1(偶校验)与功能码3(保持寄存器),三相字段全部为数组。

七、扩展配置清单(含用户自定义寄存器示例)

扩展配置在默认配置基础上增加了User用户自定义寄存器,官方提供如下示例:

SDM72 {"Name":"SDM72","Baud":9600,"Config":"8N1","Address":0x01,"Function":0x04,"Power":0x0034,"Total":0x0156,"ExportActive":0x004A,"User":[{"R":0x0502,"J":"ImportActive","G":"Import Active","U":"kWh","D":24},{"R":0x0502,"J":"ExportPower","G":"Export Power","U":"W","D":23},{"R":0x0500,"J":"ImportPower","G":"Import Power","U":"W","D":23}]} SDM72D_M {"Name":"SDM72D-M","Baud":9600,"Config":"8N1","Address":1,"Function":4,"Voltage":[0,2,4],"Current":[6,8,10],"Power":[12,14,16],"ApparentPower":[18,20,22],"ReactivePower":[24,26,28],"Factor":[30,32,34],"Frequency":70,"ExportActive":74,"Total":342,"User":[{"R":42,"J":"AverageVoltage","G":"Average Voltage","U":"V","D":21},{"R":46,"J":"AverageCurrent","G":"Average Current","U":"A","D":22},{"R":48,"J":"TotalCurrents","G":"Total Currents","U":"A","D":22},{"R":52,"J":"TotalPower","G":"Total Power","U":"W","D":23},{"R":56,"J":"TotalApparentPower","G":"Total Apparent Power","U":"W","D":23},{"R":60,"J":"TotalReactivePower","G":"Total Reactive Power","U":"W","D":23},{"R":62,"J":"TotalPowerFactor","G":"Total Power Factor","U":"W","D":2},{"R":72,"J":"ImportActive","G":"Import Active","U":"kWh","D":24},{"R":396,"J":"DiffPower","G":"Diff Power","U":"kWh","D":24},{"R":1280,"J":"TotalImportActive","G":"Total Import Active","U":"W","D":23},{"R":1282,"J":"TotalExportActive","G":"Total Export Active","U":"W","D":23}]} SDM120 {"Name":"SDM120","Baud":2400,"Config":"8N1","Address":1,"Function":4,"Voltage":0,"Current":6,"Power":12,"ApparentPower":18,"ReactivePower":24,"Factor":30,"Frequency":70,"Total":342,"ExportActive":0x004A,"User":[{"R":0x0048,"J":"ImportActive","G":"Import Active","U":"kWh","D":24},{"R":0x004E,"J":"ExportReactive","G":"Export Reactive","U":"kVArh","D":24},{"R":0x004C,"J":"ImportReactive","G":"Import Reactive","U":"kVArh","D":24},{"R":0x0024,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2}]} SDM230 {"Name":"SDM230 with two user registers","Baud":2400,"Config":"8N1","Address":1,"Function":4,"Voltage":0,"Current":6,"Power":12,"ApparentPower":18,"ReactivePower":24,"Factor":30,"Frequency":70,"Total":342,"ExportActive":0x004A,"User":[{"R":0x004E,"J":"ExportReactive","G":"Export Reactive","U":"kVArh","D":3},{"R":0x0024,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2}]} SDM630 {"Name":"SDM630","Baud":9600,"Config":"8N1","Address":1,"Function":4,"Voltage":[0,2,4],"Current":[6,8,10],"Power":[12,14,16],"ApparentPower":[18,20,22],"ReactivePower":[24,26,28],"Factor":[30,32,34],"Frequency":70,"Total":342,"ExportActive":[352,354,356],"User":{"R":[346,348,350],"J":"ImportActive","G":"Import Active","U":"kWh","D":24}} WE517 {"Name":"WE517","Baud":9600,"Config":"8E1","Address":1,"Function":3,"Voltage":[0xE,0x10,0x12],"Current":[0x16,0x18,0x1A],"Power":[0x1E,0x20,0x22],"ReactivePower":[0x26,0x28,0x2A],"Factor":[0x36,0x38,0x3A],"Frequency":0x14,"Total":0x100,"ExportActive":0x110,"User":[{"J":"ImportActive","G":"Import Active","R":0x108,"U":"kWh","D":24},{"J":"TotalPower","G":"Active Power Total","R":0x1C,"U":"W","D":23}]} Growatt 12KTL-3S (v3.x) {"Name":"Growatt","Baud":"9600","Config":"8N1","Function":4,"Address":1,"Poll":1000,"Voltage":{"R":[3,7],"T":3,"F":-1}, "Power":{"R":11,"T":4,"F":-1},"Total":{"R":28,"T":4,"F":-1}, "User": [{"J":"IntTemp","R":32,"T":3,"F":-1, "G":"Internal temperature", "U": "C", "D":26}]}

这些示例展示了User的多种写法:

  • 纯对象写法(SDM630):"User":{"R":[346,348,350],...}表示三相同一类型的用户寄存器;
  • 多条数组写法(SDM120 / SDM72D_M):依次列出多条用户寄存器;
  • 三相值对写法(Growatt):"Voltage":{"R":[3,7],"T":3,"F":-1}R传两个地址(两路输入电压),并以Poll:1000放慢轮询间隔适配逆变器;
  • SDM72D-M的三相总量寄存器(Total)传十进制342,并借助D:21/D:22等分辨率代码复用 Tasmota 的电压/电流/功率精度设置。

八、接线与启用前提

驱动由EnergyModbusDrvInit()FUNC_PRE_INIT阶段注册(xnrg_29_modbus.ino),要求模板中同时配置GPIO_NRG_MBS_RXGPIO_NRG_MBS_TX两个引脚,可选配置GPIO_NRG_MBS_TX_ENA(发送使能,常用于 RS485 方向控制)与GPIO_MBS_RX_ENA。引脚定义见 tasmota_template.h(GPIO_NRG_MBS_TX, GPIO_NRG_MBS_RX),并可通过 Berry 的gpio模块按名称NRG_MBS_RX访问(be_gpio_defines.h)。

初始化成功后,驱动通过TickerPoll(默认 200 ms)为周期调度EnergyModbusLoop()逐寄存器轮询;当所有寄存器读取完成后调用EnergyUpdateTotal()更新总量(xnrg_29_modbus.ino)。此外:

  • 配置了Total时,驱动会自动启用SetOption72(硬件电能总量作为参考,见 xnrg_29_modbus.ino);
  • 多设备(Address数组)情况下自动启用SetOption129(显示相位信息),并关闭共电压/共频率假设(xnrg_29_modbus.ino)。

九、实操步骤:接入一台自定义 Modbus 电表

  1. 接线:将电表 RS485 A/B 通过转换模块接到 ESP 的NRG_MBS_RX/NRG_MBS_TX引脚(半双工设备可加NRG_MBS_TX_ENA方向控制),在模板或配置中指定引脚。
  2. 查阅电表寄存器表:从设备手册取得电压、电流、功率等量的寄存器地址、数据类型(float / int16 / uint32 等)与缩放系数(如 ×0.1、÷1000)。
  3. 编写 JSON:按上文字段规则组织顶层参数 + 内置寄存器 +User自定义寄存器。不确定数据类型时,可用T:0(float)配合F系数调整,并利用串口日志(ENERGY_MODBUS_DEBUG宏,见 xnrg_29_modbus.ino)验证解析结果。
  4. 加载配置:三选一——写入modbus.json到文件系统、用rule3 on file#modbus do {...} endon、或用脚本段>y {...} #。串口输入长规则时先执行serialbuffer 800
  5. 重启生效:执行restart,随后在 Web 界面 Energy 页面或 MQTTSTATUS/SENSOR中核对各量值是否与电表本地读数一致,微调F系数与D小数位直至匹配。

十、扩展阅读

  • 完整的 Modbus 电能 JSON 值对语义:value_pairs_description.md
  • 官方配置与示例清单:configurations.md
  • 驱动核心实现:xnrg_29_modbus.ino
  • 编译开关与代码量说明:tasmota_configurations.h、tasmota_configurations_ESP32.h
  • 引脚定义与模块支持:tasmota_template.h
  • 其他 Modbus 电能驱动的配置方式可参考同目录下各xnrg_*驱动源码(如 xnrg_08_sdm120.ino、xnrg_10_sdm630.ino)

【免费下载链接】TasmotaAlternative firmware for ESP8266 and ESP32 based devices with easy configuration using webUI, OTA updates, automation using timers or rules, expandability and entirely local control over MQTT, HTTP, Serial or KNX. Full documentation at项目地址: https://gitcode.com/GitHub_Trending/ta/Tasmota

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询