Skip to content

1. 简介

模型清单

可使用下列名称或 ID 在 ThinkLink 中搜索对应模型。

模型类型名称id_name平台模型 ID
RPC[DLT64507-3P GET] paradlt64507_3p_get_23107101053879206023173
RPC[DLT64507-3P SET] paradlt64507_3p_set_2310798887635589664773
TemplateDLT64507-3P101054643093639173
Thing Model[DLT64507-3P]dlt64507_3p_23107101022486501527557
Thing Model[MT-23107-DLT64507-3P资产] 区域聚合dlt64507_3p_asset_23107119677189950959621
Parameter Thing Model[DLT64507-3P-PARA]dlt64507_3p_para_2310798889760482791429

DLT645-2007 三相电能表是一类符合 DL/T 645-2007 通信协议的三相电力计量设备,可用于采集三相电压、三相电流、有功电能、反向电能、有功功率、无功功率、功率因数、电网频率等电力参数。

本方案以 DLT645-2007 三相电能表 为接入对象,通过 KC11 LoRaWAN 采集设备 连接电能表的 RS-485 接口,并利用 KC11 内置的 EdgeBus 脚本完成 DL/T 645-2007 协议采集、数据封装与 LoRaWAN 上报。


2. 产品特点

  • 支持 DLT645-2007 三相电能表 数据采集
  • 支持 RS-485 接口接入
  • 通过 KC11 实现电表数据 LoRaWAN 无线化接入
  • 支持 上传周期采集周期 分开设置
  • 支持配置 645 表地址
  • 支持三相电力参数统一采集
  • 支持 ThinkLink 物模型解析
  • 支持 RPC 下发配置参数
  • 支持子设备地址识别,适合多表或多设备管理场景

3. 适用范围

本方案适用于需要将传统 DL/T 645-2007 三相电能表接入 ThinkLink / LoRaWAN 系统的场景,例如:

  • 工业园区电力监测
  • 楼宇配电监测
  • 配电柜远程抄表
  • 能耗管理系统
  • 工厂设备用电监测
  • 存量电表无线化改造
  • 第三方平台 MQTT 数据订阅
  • PLC / SCADA / 能源管理系统数据对接

4. 采集器信息

4.1 硬件信息

项目内容
采集设备型号KC11
通信接口RS-485
供电方式220V 供电
通信方式LoRaWAN
EdgeBus 支持支持
适配协议DLT645-2007
业务代码23107
模板DLT645-2007-3P

4.2 接线信息

电源与通讯接口

接口说明
电源输入KC11 采用 220V 供电
RS-485 A/B接入 DLT645-2007 三相电能表 RS-485 通讯接口
LoRaWANKC11 通过 LoRaWAN 将采集数据上报至网关 / ThinkLink

传感器接口

本方案中,三相电能表通过 RS-485 接入 KC11。
KC11 作为 LoRaWAN 采集终端,负责完成 DLT645 数据读取与 LoRaWAN 上报。


5. 数据采集

本方案中,通过 DLT645-2007 协议 读取以下数据项:

序号数据项英文字段单位
1正向有功总电能energy_import_totalkWh
2反向有功总电能energy_export_totalkWh
3A 相电压voltage_aV
4B 相电压voltage_bV
5C 相电压voltage_cV
6A 相电流current_aA
7B 相电流current_bA
8C 相电流current_cA
9总有功功率active_power_totalkW
10A 相有功功率active_power_akW
11B 相有功功率active_power_bkW
12C 相有功功率active_power_ckW
13总无功功率reactive_power_totalkvar
14A 相无功功率reactive_power_akvar
15B 相无功功率reactive_power_bkvar
16C 相无功功率reactive_power_ckvar
17总功率因数power_factor_total-
18A 相功率因数power_factor_a-
19B 相功率因数power_factor_b-
20C 相功率因数power_factor_c-
21电网频率frequencyHz

5.1 寄存器定义

DLT645-2007 不采用 Modbus 寄存器方式,而是通过 数据标识 DI 进行数据读取。本方案中 EdgeBus 通过 DLT645-2007 抄读命令读取各数据项,并将返回数据打包至 LoRaWAN 上行帧。

数据项DIlistVal说明
正向有功总电能00010000listVal[0] = EPI_T读取正向有功总电能
反向有功总电能00020000listVal[0] = EPO_T读取反向有功总电能
三相电压0201FF00listVal[0] = UA,listVal[1] = UB,listVal[2] = UC读取 A/B/C 三相电压
三相电流0202FF00listVal[0] = IA,listVal[1] = IB,listVal[2] = IC读取 A/B/C 三相电流
有功功率0203FF00listVal[0] = PT,listVal[1] = PA,listVal[2] = PB,listVal[3] = PC读取总/A/B/C 相有功功率
无功功率0204FF00listVal[0] = QT,listVal[1] = QA,listVal[2] = QB,listVal[3] = QC读取总/A/B/C 相无功功率
功率因数0206FF00listVal[0] = PFT,listVal[1] = PFA,listVal[2] = PFB,listVal[3] = PFC读取总/A/B/C 相功率因数
电网频率02800000listVal[0] = FREQ读取电网频率

5.2 状态位定义

本方案中物模型解析逻辑中包含状态判断:

javascript
if ((tdata?.status & 0x02) === 0x02) {
    // time out, just update the status.
}
状态位含义
status & 0x02采集超时

当出现采集超时时,物模型脚本会保留设备上一帧遥测数据,仅更新 status 状态字段,避免因为单次采集失败导致业务数据被异常清空。


6. EdgeBus 模型

本设备本身不是 LoRaWAN 设备,需要通过 KC11 + EdgeBus 完成 RS-485 / DLT645 协议采集,并通过 LoRaWAN 上报到 ThinkLink。


6.1 EB 配置参数

参数说明
BaudRate9600RS-485 波特率
StopBits1停止位
DataBits8数据位
CheckbitEVEN偶校验
Batteryfalse非电池供电
Class 模式Class C非电池供电,适合 Class C
ConfirmDuty60确认周期配置
BzType23107业务代码
BzVersion11业务版本

周期与参数地址:

参数APP 地址说明
period_up70上传周期
period_read74采集周期
addr_645150645 表地址,长度 6 字节

注意:采集周期应小于上传周期。


6.2 EB 代码

typescript
import { Buffer } from "buffer";
import { buildOtaFile } from "@EBSDK/run";
import {
    ActionAfertExpr, CalcData,
    CrcMode,
    CvtRule,
    EBBuffer,
    EBModel,
    ExprCondition,
    LoraUpEvent,
    QueryEvent, SetUpCovDataType,UserConfUPItem,EventInfoItem
} from "@EBSDK/EBCompiler/all_variable";
import { CheckbitEnum, getOtaConfig, HwTypeEnum, UpgrdTypeEnum } from "@EBSDK/otaConfig";
////////////////////////////////////////////////////////////////////////////////////////
const eventInfo: UserConfUPItem[] = [
    {
        name: "DLT64507_3P", port: 22, version: "0x87", dataType: "0x07", upPeriodIndex: 70,
        indexAddr: 5, addrSize: 6,
        quInfo: [
            // 正向有功总电能 ,listVal[0] = EPI_T,DI: 00010000
            {
                protocol: "DLT64507", periodIndex: 74,
                indexAPP: 150, indexCMD: 1, copySize: 6, preamble: 4,
                cmd: "0x68 22 01 13 07 11 25 68 11 04 33 33 34 33 25 16",
                ack: "0x68 22 01 13 07 11 25 68 91 08 33 33 34 33 33 33 33 33 75 16",
                listVal: [  { start: "14", end: "17" }]
            },
            // 反向有功总电能,listVal[0] = EPO_T, DI: 00020000
            {
                protocol: "DLT64507", periodIndex: 74,
                indexAPP: 150, indexCMD: 1, copySize: 6, preamble: 4,
                cmd: "0x68 22 01 13 07 11 25 68 11 04 33 33 35 33 26 16",
                ack: "0x68 22 01 13 07 11 25 68 91 08 33 33 35 33 33 33 33 33 76 16",
                listVal: [  { start: "14", end: "17" }]
            },
            // 三相电压,listVal[0] = UA,listVal[1] = UB,listVal[2] = UC,DI: 0201FF00
            {
                protocol: "DLT64507", periodIndex: 74,
                indexAPP: 150, indexCMD: 1, copySize: 6, preamble: 4,
                cmd: "0x68 22 01 13 07 11 25 68 11 04 33 32 34 35 26 16",
                ack: "0x68 22 01 13 07 11 25 68 91 0A 33 32 34 35 33 33 33 33 33 33 DE 16",
                listVal: [
                    { start: "14", end: "15" },
                    { start: "16", end: "17" },
                    { start: "18", end: "19" }
                ]
            },
            // 三相电流,listVal[0] = IA,listVal[1] = IB,listVal[2] = IC,DI: 0202FF00
            {
                protocol: "DLT64507", periodIndex: 74,
                indexAPP: 150, indexCMD: 1, copySize: 6, preamble: 4,
                cmd: "0x68 22 01 13 07 11 25 68 11 04 33 32 35 35 27 16",
                ack: "0x68 22 01 13 07 11 25 68 91 0D 33 32 35 35 33 33 33 33 33 33 33 33 33 7B 16",
                listVal: [
                    { start: "14", end: "16" },
                    { start: "17", end: "19" },
                    { start: "20", end: "22" }
                ]
            },
            // 有功功率,listVal[0] = PT,listVal[1] = PA,listVal[2] = PB,listVal[3] = PC,DI: 0203FF00
            {
                protocol: "DLT64507", periodIndex: 74,
                indexAPP: 150, indexCMD: 1, copySize: 6, preamble: 4,
                cmd: "0x68 22 01 13 07 11 25 68 11 04 33 32 36 35 28 16",
                ack: "0x68 22 01 13 07 11 25 68 91 10 33 32 36 35 33 33 33 33 33 33 33 33 33 33 33 33 18 16",
                listVal: [
                    { start: "14", end: "16" },
                    { start: "17", end: "19" },
                    { start: "20", end: "22" },
                    { start: "23", end: "25" }
                ]
            },
            // 无功功率,listVal[0] = QT,listVal[1] = QA,listVal[2] = QB,listVal[3] = QC, DI: 0204FF00
            {
                protocol: "DLT64507", periodIndex: 74,
                indexAPP: 150, indexCMD: 1, copySize: 6, preamble: 4,
                cmd: "0x68 22 01 13 07 11 25 68 11 04 33 32 37 35 29 16",
                ack: "0x68 22 01 13 07 11 25 68 91 10 33 32 37 35 33 33 33 33 33 33 33 33 33 33 33 33 19 16",
                listVal: [
                    { start: "14", end: "16" },
                    { start: "17", end: "19" },
                    { start: "20", end: "22" },
                    { start: "23", end: "25" }
                ]
            },
            // 功率因数,listVal[0] = PFT,listVal[1] = PFA,listVal[2] = PFB,listVal[3] = PFC,DI: 0206FF00
            {
                protocol: "DLT64507", periodIndex: 74,
                indexAPP: 150, indexCMD: 1, copySize: 6, preamble: 4,
                cmd: "0x68 22 01 13 07 11 25 68 11 04 33 32 39 35 2B 16",
                ack: "0x68 22 01 13 07 11 25 68 91 0C 33 32 39 35 33 33 33 33 33 33 33 33 4B 16",
                listVal: [
                    { start: "14", end: "15" },
                    { start: "16", end: "17" },
                    { start: "18", end: "19" },
                    { start: "20", end: "21" }
                ]
            },
            // 电网频率,listVal[0] = FREQ,DI: 02800000
            {
                protocol: "DLT64507", periodIndex: 74,
                indexAPP: 150, indexCMD: 1, copySize: 6, preamble: 4,
                cmd: "0x68 22 01 13 07 11 25 68 11 04 33 33 B3 35 A6 16",
                ack: "0x68 22 01 13 07 11 25 68 91 06 33 33 B3 35 33 33 8E 16",
                listVal: [
                    { start: "14", end: "15" }
                ]
            }
        ]
    }
]
let otaConfig = getOtaConfig({
    BaudRate: 9600,
    StopBits: 1,
    DataBits: 8,
    Checkbit: CheckbitEnum.EVEN,
    Battery: false, // 非电池供电,Class C模式
    ConfirmDuty: 60,
    BzType: 23107,
    BzVersion: 11
})
const MODBUS_TT = (ebModel: EBModel) => {
    for (let i=0; i<eventInfo.length; i++){
        let event=new EventInfoItem(eventInfo[i]);
        event.upEventSetup()
        event.eventInstall()
    }
    return JSON.stringify(ebModel, null, 2)
}
buildOtaFile(import.meta.url, otaConfig, MODBUS_TT)

6.3 说明

当前 EB 逻辑说明:

  1. KC11 通过 RS-485 接口连接 DLT645-2007 三相电能表。
  2. EB 脚本按照 periodIndex: 74 对电表进行周期采集。
  3. 上传周期参数存放在 APP 参数地址 70
  4. 采集周期参数存放在 APP 参数地址 74
  5. 645 表地址存放在 APP 参数地址 150,长度为 6 字节。
  6. 每条 DLT645 抄读命令在下发前,会从 APP 参数地址 150 复制 6 字节 645 表地址到命令中。
  7. DLT645 前导码 FE 数量为 4。
  8. EB 采集到电表返回数据后,将各 listVal 指定的数据段组合到 LoRaWAN 上行帧中。
  9. ThinkLink 物模型负责对上行帧进行余三码还原、BCD 解码、单位换算和字段映射。
  10. 由于 KC11 为 220V 供电,配置中 Battery: false,适合使用 Class C 模式。

7. 物模型

7.1 物模型基本信息

数据物模型

项目内容
名称DLT64507-3P
id Namedlt64507_3p_23107
LoRaWAN Port22
数据长度68
是否包含 RSSI
子设备地址index: 5,type: hexBE6
Tag 1index: 0,tag: 0x87
Tag 2index: 1,tag: 0x07

参数物模型

项目内容
名称DLT64507-3P-PARA
id Namedlt64507_3p_para_23107
参数上报 Port214
参数内容上传周期、采集周期、645 地址

7.2 上行帧结构

字段位置 / 类型说明
port22数据上行端口
dataLen68数据长度
rssitrue包含 RSSI
subDeviceindex: 5, type: hexBE6645 表地址 / 子设备地址
tagList[0]index: 0, tag: 0x87业务版本标识
tagList[1]index: 1, tag: 0x07数据类型标识
appDataindex 11-67DLT645 采集数据区

DLT645 采用余三码,EB 上行中的 appData 保存的是电表原始返回数据,即每个数据字节仍然为 +0x33 后的数据。因此在物模型解析前,需要对应用数据区进行余三码还原。

处理规则:

javascript
for (let i = 11; i < payload.length; i++) {
    payload[i] = (payload[i] - 0x33 + 0x100) & 0xff;
}

7.3 物模型脚本

javascript
import { Buffer } from "buffer";
import { BufferTKL, PayParser } from "../../tklHelper.js";

function payload_parser({ device, msg, thingModelId, noticeAttrs }) {
    let frameInfo = {
        port: 22,
        dataLen: 68,
        rssi: true,
        subDevice: { index: 5, type: "hexBE6" },
        tagList: [
            { index: 0, tag: 0x87 },
            { index: 1, tag: 0x07 }
        ]
    };

    if (msg?.userdata?.payload == undefined) return null;
    if (msg?.userdata?.payload == "") return null;

    /**
     * DLT645 采用余三码:
     * EB 上行中 appData 保存的是表计原始回复数据,
     * 即每个数据字节仍然是 +0x33 后的值。
     *
     * 因此在进入 PayParser 前,需要把应用数据区逐字节 -0x33。
     *
     * 注意:
     * 0-10 字节为 EB 上行头 + 表地址,不处理。
     * 11-67 字节为 DLT645 数据区,需要处理余三码。
     */
    let payload = Buffer.from(msg.userdata.payload, "base64");

    for (let i = 11; i < payload.length; i++) {
        payload[i] = (payload[i] - 0x33 + 0x100) & 0xff;
    }

    msg = JSON.parse(JSON.stringify(msg));
    msg.userdata.payload = payload.toString("base64");

    let appInfo = [
        { name: "正向有功总电能", unit: "kWh", field_name: "energy_import_total", index: 11, dataType: "bcdle4", coefficient: 0.01, decimal: 2 },
        { name: "反向有功总电能", unit: "kWh", field_name: "energy_export_total", index: 15, dataType: "bcdle4", coefficient: 0.01, decimal: 2 },

        { name: "A相电压", unit: "V", field_name: "voltage_a", index: 19, dataType: "bcdle2", coefficient: 0.1, decimal: 1 },
        { name: "B相电压", unit: "V", field_name: "voltage_b", index: 21, dataType: "bcdle2", coefficient: 0.1, decimal: 1 },
        { name: "C相电压", unit: "V", field_name: "voltage_c", index: 23, dataType: "bcdle2", coefficient: 0.1, decimal: 1 },

        { name: "A相电流", unit: "A", field_name: "current_a", index: 25, dataType: "bcdle3", coefficient: 0.001, decimal: 3 },
        { name: "B相电流", unit: "A", field_name: "current_b", index: 28, dataType: "bcdle3", coefficient: 0.001, decimal: 3 },
        { name: "C相电流", unit: "A", field_name: "current_c", index: 31, dataType: "bcdle3", coefficient: 0.001, decimal: 3 },

        { name: "总有功功率", unit: "kW", field_name: "active_power_total", index: 34, dataType: "bcdle3", coefficient: 0.0001, decimal: 4 },
        { name: "A相有功功率", unit: "kW", field_name: "active_power_a", index: 37, dataType: "bcdle3", coefficient: 0.0001, decimal: 4 },
        { name: "B相有功功率", unit: "kW", field_name: "active_power_b", index: 40, dataType: "bcdle3", coefficient: 0.0001, decimal: 4 },
        { name: "C相有功功率", unit: "kW", field_name: "active_power_c", index: 43, dataType: "bcdle3", coefficient: 0.0001, decimal: 4 },

        { name: "总无功功率", unit: "kvar", field_name: "reactive_power_total", index: 46, dataType: "bcdle3", coefficient: 0.0001, decimal: 4 },
        { name: "A相无功功率", unit: "kvar", field_name: "reactive_power_a", index: 49, dataType: "bcdle3", coefficient: 0.0001, decimal: 4 },
        { name: "B相无功功率", unit: "kvar", field_name: "reactive_power_b", index: 52, dataType: "bcdle3", coefficient: 0.0001, decimal: 4 },
        { name: "C相无功功率", unit: "kvar", field_name: "reactive_power_c", index: 55, dataType: "bcdle3", coefficient: 0.0001, decimal: 4 },

        { name: "总功率因数", unit: "", field_name: "power_factor_total", index: 58, dataType: "bcdle2", coefficient: 0.001, decimal: 3 },
        { name: "A相功率因数", unit: "", field_name: "power_factor_a", index: 60, dataType: "bcdle2", coefficient: 0.001, decimal: 3 },
        { name: "B相功率因数", unit: "", field_name: "power_factor_b", index: 62, dataType: "bcdle2", coefficient: 0.001, decimal: 3 },
        { name: "C相功率因数", unit: "", field_name: "power_factor_c", index: 64, dataType: "bcdle2", coefficient: 0.001, decimal: 3 },

        { name: "电网频率", unit: "Hz", field_name: "frequency", index: 66, dataType: "bcdle2", coefficient: 0.01, decimal: 2 }
    ];

    let payParser = new PayParser({
        device: device,
        msg: msg,
        frameInfo: frameInfo,
        appInfo: appInfo
    });

    let tdata = payParser.telemetry();

    if ((tdata?.status & 0x02) === 0x02) {
        const status = tdata.status;
        tdata = { ...(device.telemetry_data?.[thingModelId] ?? {}) };
        tdata.status = status;
    }

    return {
        sub_device: tdata?.addr === undefined ? null : tdata.addr,
        telemetry_data: tdata,
        server_attrs: null,
        shared_attrs: {
            class_mode: msg?.userdata?.class
        }
    };
}

8. 第三方平台数据订阅

8.1 MQTT Topic

latex
/v32/{Organization Account}/tkl/up/telemetry/{eui}

8.2 上报示例数据

json
{
    "eui": "6353012af10a9331",
    "active_time": "2026-02-05T08:35:48.000Z",
    "thingModelId": "dlt64507_3p_23107",
    "thingModelIdName": "DLT64507-3P",
    "sub_device": "221113071125",
    "telemetry_data": {
        "snr": 13.5,
        "rssi": -51,
        "status": 0,
        "addr": "221113071125",
        "energy_import_total": 12345.67,
        "energy_export_total": 12.34,
        "voltage_a": 220.1,
        "voltage_b": 219.8,
        "voltage_c": 220.5,
        "current_a": 5.123,
        "current_b": 4.987,
        "current_c": 5.001,
        "active_power_total": 3.4567,
        "active_power_a": 1.1234,
        "active_power_b": 1.1567,
        "active_power_c": 1.1766,
        "reactive_power_total": 0.2345,
        "reactive_power_a": 0.0781,
        "reactive_power_b": 0.0764,
        "reactive_power_c": 0.0800,
        "power_factor_total": 0.986,
        "power_factor_a": 0.981,
        "power_factor_b": 0.987,
        "power_factor_c": 0.990,
        "frequency": 50.01
    }
}

9. RPC

9.1 RPC 名称

配置参数

项目内容
名称DLT64507-3P SET
类型para
id Namedlt64507_3p_set_23107

读取参数

项目内容
名称DLT64507-3P GET
类型para
id Namedlt64507_3p_get_23107

9.2 参数定义

参数名字段名APP 地址类型单位说明
period_upperiod_upapp_70uint32LEs上传周期
period_readperiod_readapp_74uint32LEs采集周期
addr_645addr_645app_150hexBE6-DLT645 表地址

参数定义代码:

javascript
let paraDef = {
    app_70: {
        name: "period_up",
        field_name: "period_up",
        unit: "s",
        type: "uint32LE"
    },
    app_74: {
        name: "period_read",
        field_name: "period_read",
        unit: "s",
        type: "uint32LE"
    },
    app_150: {
        name: "addr_645",
        field_name: "addr_645",
        unit: "",
        type: "hexBE6"
    }
};

9.3 RPC 代码

配置参数 RPC

javascript
let classMode = (device && device.shared_attrs && device.shared_attrs.class_mode) || "ClassA";
const rpcName = "dlt64507_3p_para_23107";

let paraDef = {
    app_70: { name: "period_up", field_name: "period_up", unit: "s", type: "uint32LE" },
    app_74: { name: "period_read", field_name: "period_read", unit: "s", type: "uint32LE" },
    app_150: { name: "addr_645", field_name: "addr_645", unit: "", type: "hexBE6" }
};

logger.info("set paras");

let frames = RPCHelper.buildFrame({
    paraDef: paraDef,
    params: params
});

let redoBuffer = RPCHelper.redo();

let dnBuffer = Buffer.alloc(frames.writeBuffer.length + frames.readBuffer.length);
frames.writeBuffer.copy(dnBuffer, 0);
frames.readBuffer.copy(dnBuffer, frames.writeBuffer.length);

let msgQue = Utils.makeParaSetMSG({
    device: device,
    classMode: classMode,
    rpcName: rpcName,
    params: params,
    paraDownBuffer: dnBuffer,
    extraAppBuffer: redoBuffer
});

if (msgQue.length == 0) return null;

return msgQue;

读取参数 RPC

javascript
let paraDef = {
    app_70: { name: "period_up", field_name: "period_up", unit: "s", type: "uint32LE" },
    app_74: { name: "period_read", field_name: "period_read", unit: "s", type: "uint32LE" },
    app_150: { name: "addr_645", field_name: "addr_645", unit: "", type: "hexBE6" }
};

let frames = RPCHelper.buildFrame({
    paraDef: paraDef,
    params: params
});

let msg = RPCHelper.makeMSG({
    msgType: Utils.msgType.paras,
    device: device,
    dnBuffer: frames.readBuffer,
    sleepTime: 0
});

return [msg];

10. 模板选择

在 ThinkLink 平台中搜索模板:

latex
DLT645-2007-3P

或按业务类型查找:

latex
DLT645-2007 三相电能表

推荐选择:

模板类型名称 / id Name
数据物模型DLT64507-3P / dlt64507_3p_23107
参数物模型DLT64507-3P-PARA / dlt64507_3p_para_23107
设置参数 RPCDLT64507-3P SET / dlt64507_3p_set_23107
读取参数 RPCDLT64507-3P GET / dlt64507_3p_get_23107