电表解码库实战指南)
Tasmota 集成 LibTeleinfo基于 Arduino 的法国 TeleinfoTIC电表解码库实战指南【免费下载链接】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/TasmotaTeleinfo又称 TICTélé-Information Client是法国电网运营商 Enedis原 ERDF在其电表含 Linky 智能电表上提供的一种串行遥测数据协议通过电表端口周期性输出电流、电压、功率、累计用电量、费率档位等计量信息。本指南围绕当前仓库 lib/lib_div/LibTeleinfo 目录中的通用 Teleinfo 解码库展开它既是一套可在 Arduino、ParticleSpark Core、ESP8266、ESP32、树莓派等任何可运行 C 的环境里独立使用的库也是 Tasmota 固件中 Teleinfo 电能传感器驱动 xnrg_15_teleinfo.ino 的底层解析引擎。读完本文你将掌握 Teleinfo 的两种传输模式Historique 历史模式与 Standard 标准模式及其帧格式、校验和算法、库的安装方法与回调 API并能结合 Tasmota 的Teleinfo/EnergyConfig命令完成电表接入、原始数据上报与接收质量统计。库概述从通用 C 库到 Tasmota 能量驱动LibTeleinfo 由 Charles-Henri Hallard 编写仓库中的 library.properties 将其描述为 Decoder for Teleinfo (aka TIC) from French smart power meters版本为 1.1.7类别为 Communication支持任意架构architectures*并明确可在 Arduino、Particle、ESP8266、树莓派等平台运行library.json 中的 frameworks 为arduino平台覆盖espressif8266与espressif32这正是 Tasmota 所面向的两类芯片。从 LibTeleinfo.h 的版本历史可以看到它与 Tasmota 的深度绑定V1.002015-06-14首次发布V2.002020-06-11集成进 TasmotaV2.012020-08-11合并 LibTeleinfo 官方版与 Tasmota 版新增对 Linky 智能电表 Standard 模式的支持V2.022021-04-20为过载回调ADPS增加 label 字段。核心类为TInfo它对外暴露的 API 分成三类初始化与状态机init(_Mode_e mode)、process(char c)回调挂接attachADPS()、attachData()、attachNewFrame()、attachUpdatedFrame()数据访问valueGet()、valueGet_P()、getList()、valuesDump()、labelCount()、addCustomValue()、listDelete()统计getChecksumErrorCount()、getFrameSizeErrorCount()、getFrameFormatErrorCount()、getFrameInterruptedCount()、clearStats()。在 Tasmota 中该库被 xnrg_15_teleinfo.inoXNRG_15能量驱动直接使用驱动声明一个全局TInfo tinfo对象通过TasmotaSerial读取电表串口字节流再逐字节喂给tinfo.process(c)。因此理解 LibTeleinfo 的帧处理机制就是理解 Tasmota Teleinfo 功能的前提。安装把库放入 Arduino libraries 目录原文档给出的标准 Arduino 安装步骤下文已结合本仓库实际目录结构说明将 lib/lib_div/LibTeleinfo 目录整体下载Arduino 环境下通常下载 zip 解压把解压后的文件夹放入 Arduino 环境的libraries目录最终应形如your_sketchbook_folder/libraries/LibTeleinfo且该目录下必须包含.cpp与.h源文件以及examples子目录在 Arduino IDE 中通过File Preferences查看你的 sketchbook 文件夹路径。注意本仓库中的 LibTeleinfo 是作为 Tasmota 的依赖库放在lib/lib_div/下的因此它并不需要也不应手动复制到 Arduino libraries 目录——Tasmota 通过 PlatformIO 的 lib 目录机制自动编译它。手工安装方式适用于把该库单独用于你自己的 Arduino 工程例如文档中列出的各示例 sketch。仓库内的库结构为lib/lib_div/LibTeleinfo/ ├── README.md ├── library.json ├── library.properties └── src/ ├── LibTeleinfo.cpp └── LibTeleinfo.h可以看到本仓库保留了核心src/源码但未附带examples/子目录Tasmota 场景下示例被 xnrg_15_teleinfo.ino 所替代如果你需要示例请以原库发布包为准。支持的示例场景原文档列出的 sketch 清单原 README 列举了该库作者围绕不同硬件开发的示例 sketch虽然它们不在本仓库内仓库以 Tasmota 集成为准但这份清单可以帮助你判断库的能力边界与适配硬件示例平台功能Arduino_Softserial_EtiquetteArduino逐条étiquette/标签显示收到的遥信信息Arduino_Softserial_BlinkArduino逐帧显示遥信信息数据变化时 LED 短/长闪烁Arduino_Softserial_JSONArduino通过串口以 JSON 格式输出遥信信息Raspberry_JSON树莓派在 stdout 上以 JSON 格式输出遥信信息WifinfoESP8266 / ESP32Wi-Fi 遥信Web REST 附加功能ESP32ESP32WifInfo32后更名 Denky基础测试ESP32_PassthruESP32Denky D4 透传测试在串口控制台显示数据与统计ESP8266_DataChangedESP8266监视两帧之间变化的数据按变化情况闪烁 RGB LEDTeleinfo_DenkyD4ESP32基于 ESP32-Pico-V3-02 的 Denky D4 基础测试与统计Teleinfo_StatsESP32针对接收质量的测试与统计程序此外xnrg_15_teleinfo.ino 文件头部还保留了 Tasmota 场景下的硬件模板DenkyTeleinfoESP32 模板DenkyD4ESP32-Pico-V3-02模板DenkyWifInfoESP8266 模板多个版本。这些模板可直接作为 Tasmota 的模块配置使用从中也能看出该库在实际硬件方案中的典型应用形态。Teleinfo 协议基础两种传输模式与帧格式Historique历史模式 vs Standard标准模式_Mode_e枚举定义了库支持的两种模式见 LibTeleinfo.henum _Mode_e { TINFO_MODE_HISTORIQUE, // Legacy mode (1200) TINFO_MODE_STANDARD // Standard mode (9600) };Historique历史/传统模式串口波特率 1200帧中标签与值以空格 分隔适用于传统电表Standard标准模式Linky 智能电表的新格式波特率 9600标签、值、时间戳之间以制表符\tTINFO_HT0x09分隔支持可选的时间戳字段horodatage。TInfo::init()会根据模式设置分隔符见 LibTeleinfo.cppif ( _mode TINFO_MODE_STANDARD ) { _separator TINFO_HT; // \t 0x09 } else { _separator ; // 0x20 }帧与组Frame / Group的控制字符头文件中定义了完整的帧控制字符集#define TINFO_STX 0x02 // 帧起始 #define TINFO_ETX 0x03 // 帧结束 #define TINFO_EOT 0x04 // 帧中断End Of Transmission #define TINFO_HT 0x09 // 制表符Standard 模式分隔符 #define TINFO_SGR \n // 组起始Start of Group #define TINFO_EGR \r // 组结束End of Group一帧遥信数据由若干组group组成每一组是一行标签 值 校验和Historique或标签 [时间戳] 值 校验和Standard行与行之间以\n组起始和\r组结束包裹整帧以 STX0x02开始、以 ETX0x03结束。当电表需要打断当前帧时会发送 EOT0x04字符。组格式与校验和算法calcChecksum()的注释见 LibTeleinfo.cpp给出了两种模式的精确组格式Historique 模式校验和不包含末尾空格LF etiquette SP donnee SP Chk CR 0A 20 20 0D \____check________/Standard 模式带时间戳校验和包含最后一个 HTLF etiquette HT horodatage HT donnee HT Chk CR 0A 09 09 09 0D \____________checkum_______________/Standard 模式无时间戳校验和包含最后一个 HTLF etiquette HT donnee HT Chk CR 0A 09 09 0D \_____checkum________/校验和的计算方法见 LibTeleinfo.cppuint8_t sum (_mode TINFO_MODE_HISTORIQUE) ? _separator : (2 * _separator); // 对标签、值以及时间戳中每个 0x20~0x7E 范围内的字符累加其 ASCII 码 // 时间戳字段必须以 E/H/e/h 开头EÉté 夏季HHiver 冬季后跟数字 return ( (sum 0x3f) );即将所有参与校验的字符 ASCII 码相加Historique 模式初始为分隔符空格的值Standard 模式初始为两倍制表符值取sum 0x3F后再加上 0x20得到校验字符。校验和用于在checkLine()中逐行验证数据完整性验证失败会递增_checksumerror计数器见 LibTeleinfo.cpp。库状态机process() 的逐字符解析库以有限状态机方式逐字符消化串口字节流状态定义见 LibTeleinfo.henum _State_e { TINFO_INIT, // 初始化 TINFO_WAIT_STX, // 等待帧起始 STX TINFO_WAIT_ETX, // 已收到 STX等待帧结束 ETX TINFO_READY // 已收到 STX 和 ETX可正常接收数据 };TInfo::process(char c)的完整处理逻辑见 LibTeleinfo.cpp收到 STX0x02清空接收缓冲区重置_frame_updated标志若状态为TINFO_INIT或TINFO_WAIT_STX则转入TINFO_WAIT_ETX收到 EOT0x04丢弃未完成的帧清空缓冲区_frameinterrupted回到TINFO_WAIT_STX这就是原文档Addon一节所说的EOT 帧中断字符处理收到 ETX0x03若当前处于TINFO_READY则说明一帧接收完毕——若本帧内有数据更新_frame_updated则调用_fn_updated_frame回调否则调用_fn_new_frame回调随后清除TINFO_FLAGS_ALERT标志例如 ADPS 过载告警避免长期驻留链表同时根据当前状态推进到TINFO_READY或回到TINFO_WAIT_STX收到\n组起始忽略实际处理推迟到组结束收到\r组结束若状态为TINFO_READY把当前接收缓冲中的一行交给checkLine()校验并入库然后清空缓冲区。若缓冲区溢出_recv_idx TINFO_BUFSIZE缓冲区大小TINFO_BUFSIZE为 128 字节则递增_framesizeerror其他字符仅在TINFO_READY状态下存入接收缓冲区溢出时记录日志并清空。checkLine()见 LibTeleinfo.cpp是单行解析的核心要求一行至少 7 个字符通过统计分隔符数量判断 Standard 模式是否携带时间戳分离标签/值/校验和验证校验和后将值写入以ValueList为节点的单向链表同时通过标志位区分该值是新增TINFO_FLAGS_ADDED、已存在TINFO_FLAGS_EXIST、更新TINFO_FLAGS_UPDATED还是告警TINFO_FLAGS_ALERT。特别地DATE标签格式特殊格式错误不计入_frameformaterror。链表数据模型ValueList 与标志位所有收到的遥信值存放在以ValueList为节点的链表中见 LibTeleinfo.htypedef struct _ValueList ValueList; struct _ValueList { ValueList *next; // 下一个节点 time_t ts; // 时间戳如 Standard 模式的 horodatage uint8_t checksum;// 校验和 uint8_t flags; // 标志位 char * name; // 标签名LABEL char * value; // 值 };标志位定义见 LibTeleinfo.h#define TINFO_FLAGS_NONE 0x00 #define TINFO_FLAGS_NOTHING 0x01 #define TINFO_FLAGS_ADDED 0x02 // 新值 #define TINFO_FLAGS_EXIST 0x04 // 已存在值未变 #define TINFO_FLAGS_UPDATED 0x08 // 值已更新 #define TINFO_FLAGS_ALERT 0x80 // 告警如 ADPS 过载valueAdd()在写入链表时会计算并比对校验和校验和不符直接拒绝并维护节点内存节点连同名称、值字符串一次性malloc分配sizeof(ValueList) lgname 1 lgvalue 1名称和值字符串内联在节点之后见 LibTeleinfo.cpp。如果新值与旧值长度不同旧节点会被释放重建。customLabel()见 LibTeleinfo.cpp对特定标签做预处理单相电表的ADPS标签触发相位 0 告警三相电表的ADIR1/ADIR2/ADIR3分别触发相位 1/2/3 告警并调用_fn_ADPS回调。这类标签不会被永久保存。Tasmota 集成实践从 GPIO 到 MQTT 的完整链路硬件接线与模板Tasmota 通过两个 GPIO 功能接入电表见 tasmota_template.hGPIO_TELEINFO_RXTeleinfo 遥测数据接收引脚即Teleinfo接电表 TIC 输出的 RX 数据GPIO_TELEINFO_ENABLETeleinfo 使能引脚即Teleinfo Enable部分电表/光电头需要拉高此引脚才输出数据Tasmota 在初始化时将其置为 HIGH重启前置为 LOW见TInfoInit()与TInfoSaveBeforeRestart()。在 xnrg_15_teleinfo.ino 头部保留了官方硬件模板示例例如 DenkyD4 模板与 WifInfo 模板可作为配置参考。串口初始化TInfoInit()见 xnrg_15_teleinfo.ino根据模式选择波特率与串口缓冲区大小模式波特率串口接收缓冲区Historique1200512 字节TELEINFO_SERIAL_BUFFER_HISTORIQUEStandard96001536 字节TELEINFO_SERIAL_BUFFER_STANDARD串口配置为SERIAL_7E17 数据位 偶校验 1 停止位。ESP8266 上优先尝试硬件串口失败则回退软件串口ESP32 使用 UART 硬件串口。初始化完成后调用tinfo.init(tinfo_mode); tinfo.attachADPS(ADPSCallback); tinfo.attachData(DataCallback); tinfo.attachNewFrame(NewFrameCallback);把三个回调挂接到库上ADPS 过载告警、逐条数据更新、整帧接收完成。数据消费回调ADPSCallback(phase, label)见 xnrg_15_teleinfo.ino过载告警发生时发布 MQTT 消息{TIC:{ADPS:相位号}}并写日志DataCallback(me, flags)见 xnrg_15_teleinfo.ino把实时数据映射进 Tasmota 的Energy对象——电压TENSION/URMS1/URMS2/URMS3、电流IINST/IINST1…IRMS3、视在/有功功率PAPP/SINSTS/SINSTS1…SINSTS3并处理 Wh 累计值Historique 的BASE、HCHCHCHPStandard 的EAST、EASF01/EASF02等以及费率/合约PTEC、LTARF、OPTARIF、NGTFNewFrameCallback(me)见 xnrg_15_teleinfo.ino重置能量看门狗Energy-data_valid[0]并根据Settings-teleinfo.raw_send决定是否把整帧原始遥信以 JSON 发布到 MQTT。Tasmota 在FUNC_EVERY_250_MSECOND周期调用TInfoProcess()见 xnrg_15_teleinfo.ino将串口缓冲区的字节逐个送入tinfo.process(c)从而驱动整个解析状态机。常用控制命令Tasmota 控制台通过Teleinfo命令族配置遥信功能命令枚举见 xnrg_15_teleinfo.ino命令说明Teleinfo0设置为 Historique 模式1200 波特Teleinfo1设置为 Standard 模式9600 波特LinkyTeleinfo2关闭原始帧上报Teleinfo3开启全量原始帧上报Teleinfo4仅上报发生变化的原始帧Teleinfo5 n原始模式下每n1帧上报一次帧跳数Teleinfo6 n限制原始帧只包含快速变化的值如功率、电流Teleinfo7显示/清除/启用接收错误统计同时EnergyConfig命令也可以携带这些子参数如EnergyConfig Teleinfo Standard并可在不带参数时打印当前遥信配置模式、RX/EN 引脚、Raw 模式、Skip/Limit/Stats 值。统计开关Teleinfo7 1会启用统计此时 Web 界面 Energy 页面会额外显示四类错误计数Bad Checksum校验和错误、Wrong Size帧尺寸错误、Bad Format帧格式错误、Interruption帧中断分别对应库中的getChecksumErrorCount()、getFrameSizeErrorCount()、getFrameFormatErrorCount()、getFrameInterruptedCount()见 xnrg_15_teleinfo.ino。典型标签速查xnrg_15_teleinfo.ino 中通过kLabel表维护了驱动认识的全部标签以下为常见标签的用途说明Historique 与 Standard 的标签集略有差异Standard 模式多用SINSTS、URMS、IRMS、EAST、EASFxx、NGTF、LTARF等标签含义ADCO电表序列号12 位旧式ADSCLinky 电表序列号BASE/HCHC/HCHP累计 WhBase 合约 / 谷时 / 峰时EAST总累计 WhStandardEASF01~EASF06各费率累计 WhStandardIINST/IINST1~IINST3瞬时电流Historique单相/三相IRMS1~IRMS3电流有效值Standard三相PAPP视在功率 VAHistoriqueSINSTS/SINSTS1~SINSTS3视在功率 VAStandard三相TENSION/URMS1~URMS3电压 VOPTARIF/NGTF合约类型Historique 编码值 / Standard 明文PTEC/LTARF/NTARF当前费率档位ISOUSC订阅电流 AIMAX/IMAX1~IMAX3最大电流PMAX/SMAXSN最大功率ADPS/ADIR1~ADIR3过载告警触发回调后不长期保存DEMAIN明日颜色Tempo 合约MSG1/MSG2/STGE电表状态/消息部分标签被驱动列入黑名单不随遥测上报常见问题与调试建议接不上电表 / 无数据先确认模板中 RX 引脚与GPIO_TELEINFO_RX对应使能引脚如有已接并会被拉高再核对模式老电表用 Historique1200Linky 用 Standard9600。可通过Teleinfo0/Teleinfo1即时切换模式切换时驱动会自动重初始化库LibTeleinfo在init()时总会释放链表。数据时断时续 / 校验和错误飙升多为串口参数7E1或信号质量问题。开启统计Teleinfo7 1后观察四类错误计数Bad Checksum多为线路干扰或光电头不稳Interruption表示收到 EOT 帧中断Wrong Size表示组长度异常。可配合Teleinfo5降低上报频率。MQTT 原始帧过多默认遥测只携带 Energy 摘要数据原始帧需要显式开启Teleinfo3全量或Teleinfo4仅变化并用Teleinfo5 n做降频。若只想在 Web 上看统计而不要 MQTT 原始帧保持Teleinfo2即可。Raw 模式下偶发空报文驱动只在确有数据hasData时才发布 MQTT避免无用流量见 xnrg_15_teleinfo.ino。许可与致谢库头文件声明采用 Creative Commons Attribution Share-Alike LicenseCC-BY-SA 4.0见 LibTeleinfo.h原 README 中注明的许可为 Creative Commons Attribution - Pas dUtilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International非商业用途 相同方式共享使用时请遵守对应条款库作者欢迎硬件厂商在商业产品中使用时回赠样品。Tasmota 侧的能量驱动 xnrg_15_teleinfo.ino 则采用 GPL-3.0 许可两者叠加使用时请分别遵守各自的许可证要求。Teleinfo 协议的官方规范可参考 Enedis 发布的技术文档原 README 中引用了 ERDF/Enedis 的 NOI-CPT 02E 与 NOI-CPT 54E 数据手册。【免费下载链接】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),仅供参考