Skip to content

1. Introduction

Model catalog

Search for these models in ThinkLink by name or ID.

Model typeNameid_namePlatform model 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

The DL/T 645-2007 three-phase energy meter is a three-phase power metering device compliant with the DL/T 645-2007 communication protocol. It can be used to collect electrical parameters such as three-phase voltage, three-phase current, active energy, reverse energy, active power, reactive power, power factor, and grid frequency.

This solution uses the DL/T 645-2007 three-phase energy meter as the access target. The meter is connected through the RS-485 interface of the KC11 LoRaWAN data acquisition device. The built-in EdgeBus script of KC11 is used to complete DL/T 645-2007 protocol acquisition, data encapsulation, and LoRaWAN uplink reporting.


2. Product Features

  • Supports data acquisition from DL/T 645-2007 three-phase energy meters
  • Supports RS-485 interface access
  • Enables wireless LoRaWAN access for meter data through KC11
  • Supports separate configuration of upload period and acquisition period
  • Supports configuration of the DL/T 645 meter address
  • Supports unified acquisition of three-phase electrical parameters
  • Supports ThinkLink thing model parsing
  • Supports RPC-based parameter configuration
  • Supports sub-device address identification, suitable for multi-meter or multi-device management scenarios

3. Application Scope

This solution is suitable for scenarios where traditional DL/T 645-2007 three-phase energy meters need to be connected to ThinkLink / LoRaWAN systems, such as:

  • Power monitoring in industrial parks
  • Building power distribution monitoring
  • Remote meter reading for distribution cabinets
  • Energy consumption management systems
  • Power consumption monitoring for factory equipment
  • Wireless retrofit of existing energy meters
  • MQTT data subscription by third-party platforms
  • Data integration with PLC / SCADA / energy management systems

4. Data Acquisition Device Information

4.1 Hardware Information

ItemDescription
Data acquisition device modelKC11
Communication interfaceRS-485
Power supply220V power supply
Communication methodLoRaWAN
EdgeBus supportSupported
Adapted protocolDL/T 645-2007
Business code23107
TemplateDLT645-2007-3P

4.2 Wiring Information

Power and Communication Interfaces

InterfaceDescription
Power inputKC11 uses 220V power supply
RS-485 A/BConnected to the RS-485 communication interface of the DL/T 645-2007 three-phase energy meter
LoRaWANKC11 reports collected data to the gateway / ThinkLink through LoRaWAN

Sensor Interface

In this solution, the three-phase energy meter is connected to KC11 through RS-485.

KC11 acts as a LoRaWAN acquisition terminal and is responsible for DL/T 645 data reading and LoRaWAN uplink reporting.


5. Data Acquisition

In this solution, the following data items are read through the DL/T 645-2007 protocol:

No.Data ItemField NameUnit
1Forward active total energyenergy_import_totalkWh
2Reverse active total energyenergy_export_totalkWh
3Phase A voltagevoltage_aV
4Phase B voltagevoltage_bV
5Phase C voltagevoltage_cV
6Phase A currentcurrent_aA
7Phase B currentcurrent_bA
8Phase C currentcurrent_cA
9Total active poweractive_power_totalkW
10Phase A active poweractive_power_akW
11Phase B active poweractive_power_bkW
12Phase C active poweractive_power_ckW
13Total reactive powerreactive_power_totalkvar
14Phase A reactive powerreactive_power_akvar
15Phase B reactive powerreactive_power_bkvar
16Phase C reactive powerreactive_power_ckvar
17Total power factorpower_factor_total-
18Phase A power factorpower_factor_a-
19Phase B power factorpower_factor_b-
20Phase C power factorpower_factor_c-
21Grid frequencyfrequencyHz

5.1 Register Definition

DL/T 645-2007 does not use the Modbus register method. Instead, data is read through the data identifier, DI.

In this solution, EdgeBus reads each data item through DL/T 645-2007 meter-reading commands and packages the returned data into the LoRaWAN uplink frame.

Data ItemDIlistValDescription
Forward active total energy00010000listVal[0] = EPI_TRead forward active total energy
Reverse active total energy00020000listVal[0] = EPO_TRead reverse active total energy
Three-phase voltage0201FF00listVal[0] = UA, listVal[1] = UB, listVal[2] = UCRead A/B/C phase voltage
Three-phase current0202FF00listVal[0] = IA, listVal[1] = IB, listVal[2] = ICRead A/B/C phase current
Active power0203FF00listVal[0] = PT, listVal[1] = PA, listVal[2] = PB, listVal[3] = PCRead total / A / B / C phase active power
Reactive power0204FF00listVal[0] = QT, listVal[1] = QA, listVal[2] = QB, listVal[3] = QCRead total / A / B / C phase reactive power
Power factor0206FF00listVal[0] = PFT, listVal[1] = PFA, listVal[2] = PFB, listVal[3] = PFCRead total / A / B / C phase power factor
Grid frequency02800000listVal[0] = FREQRead grid frequency

5.2 Status Bit Definition

The thing model parsing logic in this solution includes status judgment:

javascript
if ((tdata?.status & 0x02) === 0x02) {
    // time out, just update the status.
}
Status BitMeaning
status & 0x02Acquisition timeout

When an acquisition timeout occurs, the thing model script keeps the telemetry data from the previous frame and only updates the status field. This avoids abnormal clearing of business data caused by a single acquisition failure.


6. EdgeBus Model

The meter itself is not a LoRaWAN device. It needs to use KC11 + EdgeBus to complete RS-485 / DL/T 645 protocol acquisition and report data to ThinkLink through LoRaWAN.


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.1 EB Configuration Parameters

ParameterValueDescription
BaudRate9600RS-485 baud rate
StopBits1Stop bit
DataBits8Data bit
CheckbitEVENEven parity
BatteryfalseNon-battery powered
Class modeClass CNon-battery powered, suitable for Class C
ConfirmDuty60Confirmation period configuration
BzType23107Business code
BzVersion11Business version

Period and Parameter Addresses

ParameterAPP AddressDescription
period_up70Upload period
period_read74Acquisition period
addr_645150DL/T 645 meter address, 6 bytes

Note: The acquisition period should be shorter than the upload period.


6.2 EB Code

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: [
      {
        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" }]
      },
      {
        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" }]
      },
      {
        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" }
        ]
      },
      {
        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" }
        ]
      },
      {
        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" }
        ]
      },
      {
        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" }
        ]
      },
      {
        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" }
        ]
      },
      {
        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,
  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);
};

6.3 Description

Description of the current EB logic:

  1. KC11 connects to the DL/T 645-2007 three-phase energy meter through the RS-485 interface.
  2. The EB script periodically collects data from the meter according to periodIndex: 74.
  3. The upload period parameter is stored at APP parameter address 70.
  4. The acquisition period parameter is stored at APP parameter address 74.
  5. The DL/T 645 meter address is stored at APP parameter address 150, with a length of 6 bytes.
  6. Before each DL/T 645 meter-reading command is sent, the 6-byte DL/T 645 meter address is copied from APP parameter address 150 into the command.
  7. The number of DL/T 645 preamble bytes FE is 4.
  8. After EB collects the returned data from the meter, it combines the data segments specified by listVal into the LoRaWAN uplink frame.
  9. The ThinkLink thing model is responsible for restoring the DL/T 645 offset code, BCD decoding, unit conversion, and field mapping.
  10. Since KC11 is powered by 220V, Battery: false is configured, making it suitable for Class C mode.

7. Thing Model

7.1 Basic Thing Model Information

Data Thing Model

ItemDescription
NameDLT64507-3P
id Namedlt64507_3p_23107
LoRaWAN Port22
Data length68
RSSI includedYes
Sub-device addressindex: 5, type: hexBE6
Tag 1index: 0, tag: 0x87
Tag 2index: 1, tag: 0x07

Parameter Thing Model

ItemDescription
NameDLT64507-3P-PARA
id Namedlt64507_3p_para_23107
Parameter report Port214
Parameter contentUpload period, acquisition period, DL/T 645 address

FieldPosition / TypeDescription
port22Data uplink port
dataLen68Data length
rssitrueIncludes RSSI
subDeviceindex: 5, type: hexBE6DL/T 645 meter address / sub-device address
tagList[0]index: 0, tag: 0x87Business version identifier
tagList[1]index: 1, tag: 0x07Data type identifier
appDataindex 11-67DL/T 645 acquisition data area

DL/T 645 uses offset code encoding. In the EB uplink, appData stores the original response data from the meter. That means each data byte is still in the +0x33 format.

Therefore, before parsing the thing model, the application data area must be restored from the DL/T 645 offset code.

Processing rule:

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

7.3 Thing Model Script

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;

    /**
     * DL/T 645 uses offset code encoding:
     * The appData in the EB uplink stores the original response data from the meter,
     * which means each data byte is still in the +0x33 format.
     *
     * Therefore, before entering PayParser,
     * each byte in the application data area needs to be subtracted by 0x33.
     *
     * Note:
     * Bytes 0-10 are the EB uplink header + meter address and should not be processed.
     * Bytes 11-67 are the DL/T 645 data area and need offset code restoration.
     */
    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: "Forward active total energy", unit: "kWh", field_name: "energy_import_total", index: 11, dataType: "bcdle4", coefficient: 0.01, decimal: 2 },
        { name: "Reverse active total energy", unit: "kWh", field_name: "energy_export_total", index: 15, dataType: "bcdle4", coefficient: 0.01, decimal: 2 },

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

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

        { name: "Total active power", unit: "kW", field_name: "active_power_total", index: 34, dataType: "bcdle3", coefficient: 0.0001, decimal: 4 },
        { name: "Phase A active power", unit: "kW", field_name: "active_power_a", index: 37, dataType: "bcdle3", coefficient: 0.0001, decimal: 4 },
        { name: "Phase B active power", unit: "kW", field_name: "active_power_b", index: 40, dataType: "bcdle3", coefficient: 0.0001, decimal: 4 },
        { name: "Phase C active power", unit: "kW", field_name: "active_power_c", index: 43, dataType: "bcdle3", coefficient: 0.0001, decimal: 4 },

        { name: "Total reactive power", unit: "kvar", field_name: "reactive_power_total", index: 46, dataType: "bcdle3", coefficient: 0.0001, decimal: 4 },
        { name: "Phase A reactive power", unit: "kvar", field_name: "reactive_power_a", index: 49, dataType: "bcdle3", coefficient: 0.0001, decimal: 4 },
        { name: "Phase B reactive power", unit: "kvar", field_name: "reactive_power_b", index: 52, dataType: "bcdle3", coefficient: 0.0001, decimal: 4 },
        { name: "Phase C reactive power", unit: "kvar", field_name: "reactive_power_c", index: 55, dataType: "bcdle3", coefficient: 0.0001, decimal: 4 },

        { name: "Total power factor", unit: "", field_name: "power_factor_total", index: 58, dataType: "bcdle2", coefficient: 0.001, decimal: 3 },
        { name: "Phase A power factor", unit: "", field_name: "power_factor_a", index: 60, dataType: "bcdle2", coefficient: 0.001, decimal: 3 },
        { name: "Phase B power factor", unit: "", field_name: "power_factor_b", index: 62, dataType: "bcdle2", coefficient: 0.001, decimal: 3 },
        { name: "Phase C power factor", unit: "", field_name: "power_factor_c", index: 64, dataType: "bcdle2", coefficient: 0.001, decimal: 3 },

        { name: "Grid frequency", 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. Third-Party Platform Data Subscription

8.1 MQTT Topic

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

8.2 Example Reported Data

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 Names

Parameter Configuration

ItemDescription
NameDLT64507-3P SET
Typepara
id Namedlt64507_3p_set_23107

Parameter Reading

ItemDescription
NameDLT64507-3P GET
Typepara
id Namedlt64507_3p_get_23107

9.2 Parameter Definition

Parameter NameField NameAPP AddressTypeUnitDescription
period_upperiod_upapp_70uint32LEsUpload period
period_readperiod_readapp_74uint32LEsAcquisition period
addr_645addr_645app_150hexBE6-DL/T 645 meter address

Parameter definition code:

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 Code

Parameter Configuration 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;

Parameter Reading 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. Template Selection

Search for the following template in the ThinkLink platform:

latex
DLT645-2007-3P

Or search by business type:

latex
DLT645-2007 Three-Phase Energy Meter

Recommended selection:

Template TypeName / id Name
Data thing modelDLT64507-3P / dlt64507_3p_23107
Parameter thing modelDLT64507-3P-PARA / dlt64507_3p_para_23107
Set parameter RPCDLT64507-3P SET / dlt64507_3p_set_23107
Read parameter RPCDLT64507-3P GET / dlt64507_3p_get_23107