⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dl645lib.~pas

📁 符合DL645规约的电能表数据解析. 可直接实现远程RTU.
💻 ~PAS
📖 第 1 页 / 共 4 页
字号:
unit DL645lib;

interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Dialogs,
  myconlib,DateUtils;

////////////////原始数据缓冲区/////////////////////////
type TBuf200=array[0..199] of byte;
     Tbuf6=array[0..5] of byte;
     Tbuf4=array[0..3] of byte;
     Tbuf3=array[0..2] of byte;
     Tbuf2=array[0..1] of byte;


/////////////////数据命令缓冲区///////////////////////
     TReadCMD=array[0..13] of byte;
        // 68H,A0,A1,A2,A3,A4,A5,68H,01,02,ID0+33H,ID1+33H,CS,16H
     TCheckErr=(ckLenErr,ckCSErr,ckC,ckOtherErr,ckOKErr,ckOK);
           //长度错,校验和错, 控制码错, 未知错, 返回异常, 无错

////////////////控制码定义/////////////////////////
  Const CtlRead=1; // 读电表数据
        CtlWriteCS=4;//  写电表参数
        CtlBrdTime=8;  // 广播校时
        CtlWriteADR=10;//写设备地址
        CtlUpdateBPS=12; //写通信速率
        CtlUpdatePass=15;//写密码
        CtlClearPm=16;//最大需量清零
 //////////////////通信速率/////////
 Type TBPS=(Bps300,Bps600,Bps2400,Bps4800,Bps9600);

////////////////数据标识定义/////////////////////////
type TID1=(ID1_NO,ID1_kWh,ID1_Pm,ID1_PmTime,ID1_BL,ID1_FH,ID1_CS);//数据属性
     TID2=(ID2_NO,ID2_CurP,ID2_CurQ,ID2_Lst1P,ID2_Lst1Q,ID2_Lst2P,ID2_Lst2Q); //数据时间1
     TID3=(ID3_NO,ID3_ZX,ID3_FX,ID3_RL1,ID3_RC2,ID3_RL3,ID3_RC4); //数据子属性

     TYUE=(YUE_NO,YUE0,YUE1,YUE2);
     TBK=(BK_NO,ZP,FP,ZQ,FQ,ZQL1,FQC4,ZQC2,FQL3);
     TBKSet= set of TBK;

     TJH=(JH_NO,JH_P2,JH_Q6,JH_DX,JH_X);

     TFL=(FL_NO,FL_Block,FL_Z,FL_P,FL_A,FL_B,FL_C);
        ////数据块,数据时间2,费率Z,  费率P,  费率A, 费率B,  费率C,

        
     TBL=(BL_NO,DX_CNT,DX_T,DX_T1,DX_T2,X_V,X_I,X_P,X_Q,X_COS); // 变量类型
     TBLSet= set of TBL;
             //断相次数,时间,起始时间,结束时间,
             //相电压,电流,有功,无功,功率因数
     TBLX=(X_NO,X_Block,X_Z,X_A, X_B ,X_C); // 变量类型

///////////////数据结构定义/////////////////

type TBlock_kWh = Record   //电能量数据结构
        kWh_Z:double; //XXXXXX.XX
        kWh_P:double;
        kWh_A:double;
        kWh_B:double;
        kWh_C:double;
     end;

     TBlock_Pm = Record  //最大需量数据结构
        Pm_Z:double; //XXXX.XX
        Pm_P:double;
        Pm_A:double;
        Pm_B:double;
        Pm_C:double;
     end;

    TBlock_PmTime = Record    //最大需量发生时间数据结构
        PmTime_Z:TDateTime;  //MMDD HHmm
        PmTime_P:TDateTime;
        PmTime_A:TDateTime;
        PmTime_B:TDateTime;
        PmTime_C:TDateTime;
     end;

  
type TBlock_DXCNT = Record   //断相发生次数数据结构
        DXCNT_Z:Word;
        DXCNT_A:Word;
        DXCNT_B:Word;
        DXCNT_C:Word;
     end;

    TBlock_DXT = Record  //断相发生总时间数据结构
        DXT_Z:DWord;
        DXT_A:DWord;
        DXT_B:DWord;
        DXT_C:DWord;
     end;

    TBlock_DXT1 = Record   //断相发生时间1数据结构
        DXT_Z:TDateTime;  //MMDD HHmm
        DXT_A:TDateTime;
        DXT_B:TDateTime;
        DXT_C:TDateTime;
     end;
    TBlock_DXT2  =   TBlock_DXT1 ;  //断相发生时间2数据结构


type TBlock_XV = Record   //瞬时电压 数据结构
        X_A:double;
        X_B:double;
        X_C:double;
     end;
     TBlock_XI  =   TBlock_XV ; //瞬时电流 数据结构

    TBlock_XP = Record    //瞬时有功功率 数据结构
        X_Z:double;
        X_A:double;
        X_B:double;
        X_C:double;
     end;
     TBlock_XQ =  TBlock_XP  ;     //瞬时无功功率 数据结构
     TBlock_XCos =  TBlock_XP  ;     //瞬时功率因数 数据结构
type TBL_BKS = Record
       aDXCNT_BK:TBlock_DXCNT;
       aDXT_BK:TBlock_DXT;
       aDXT1_BK:TBlock_DXT1;
       aDXT2_BK:TBlock_DXT2;
       aXV_BK:TBlock_XV;
       aXI_BK:TBlock_XI;
       aXP_BK:TBlock_XP;
       aXQ_BK:TBlock_XQ;
       aXCos_BK:TBlock_XCos ;
    end;

type TkWh_BKS   =  array[ZP..FQL3] of  TBlock_kWh;
     TPm_BKS    =  array[ZP..FQL3] of  TBlock_Pm;
     TPmTime_BKS = array[ZP..FQL3] of  TBlock_PmTime;
////////////////////////////////////////////////////
 //电表参数数据结构
type  TC01_=record
        D:TDate;
        W:Byte;
        T:TTime;
      end;
      TC02_ =record
         B1,B2,B3:Byte;
      end;
      TC03_ =record
          Pkwh,Qkwh:Dword;
          BH,UseID,DEVID:string[12];
      end;
      TC11_ =record
         PmT,DelayT,LoopT,DisT:Byte;
         DLDot,PmDot:Byte;
         ReadDDHH:string[8];
         FHDay:Byte;
         P_kWh0:double;
         Q_kWh0:double;
      end;
      TC21_ =record
         PWms:Word;
         PA,P1,P2,P3:Byte;
      end;
      TC31_ =record
        P,q,m,k,n :Byte;
      end;
      TC32_ = array[1..14] of string;
      TC33_ = array[1..10] of string;
      TC41_ =   array[1..14] of string;



////////////////////////////////////////////////////////////////////////
function StrToken(var S: String): String;
Function HexToBCD(b:Byte):Byte;
Function STR2Hex(A:String):string;
Function Array2Str(A:array of byte):string;


Function GetReadCMD( ID,ADR:string;var STX:string;var CS0:Byte):TReadCMD;
Function CheckData( data:string;CS0:Byte;Var B4:Byte):TCheckErr;
Function CheckErr2Str(Err:TCheckErr):string;



                      //总 ,尖,峰 ,平,谷
Function GetID1( ID:string):TID1; //数据标识到 数据属性
Function GetID2( ID:string):TID2;  //数据标识到 数据时间1
Function GetID3( ID:string):TID3; //数据标识到 数据子属性
Function GetYUE( ID:string):TYUE; //数据标识到 数据月份
Function GetBK( ID:string):TBK; //数据标识到 数据块定义
Function GetJH( ID:string):TJH; //数据标识到 数据集合

Function GetFL( ID:string):TFL; //数据标识到 数据时间2,费率
Function GetBL( ID:string):TBL; //数据标识到 变量类型
Function GetBLX( ID:string):TBLX; //数据标识到 变量的相属性

Function ID1ToStr(ID1:TID1):string;
Function ID2ToStr(ID2:TID2):string;
Function ID3ToStr( ID3:TID3):string;
Function YUEToStr(Y:TYUE):string;
Function BKToStr(BK:TBK):string;
Function JHToStr(JH:TJH):string;
Function FLtoStr( aFL:TFL):string;
Function BLtoStr(blX:TBLX;blT:TBL):string;
Function IDtoStr( ID:string):string;



Function PaserB1(B1:byte):string;
Function PaserB2(B2:byte):string;
Function PaserB3(B3:byte):string;
Function PaserB4(B4:byte):string;

Function PaserkWh_Block(aFL:TFL;Data:String; Idx:Integer):TBlock_kWh;   //电能
Function PaserPm_Block( aFL:TFL;Data:String; Idx:Integer):TBlock_Pm;       //最大需量
Function PaserPmTime_Block(aFL:TFL; Data:String; Idx:Integer):TBlock_PmTime; //最大需量发生时间

Function PaserDXCNT_Block(X:TBLX;Data:String; Idx:Integer):TBlock_DXCNT;
Function PaserDXT_Block(X:TBLX;Data:String; Idx:Integer):TBlock_DXT;
Function PaserDXT1_Block(X:TBLX;Data:String; Idx:Integer):TBlock_DXT1;
Function PaserDXT2_Block(X:TBLX;Data:String; Idx:Integer):TBlock_DXT2;
Function PaserXV_Block(X:TBLX;Data:String; Idx:Integer):TBlock_XV;
Function PaserXI_Block(X:TBLX;Data:String; Idx:Integer):TBlock_XI;
Function PaserXP_Block(X:TBLX;Data:String; Idx:Integer):TBlock_XP;
Function PaserXQ_Block(X:TBLX;Data:String; Idx:Integer):TBlock_XQ;
Function PaserXCos_Block(X:TBLX;Data:String; Idx:Integer):TBlock_XCos;

Function PaserC01_(DI0L:char;Data:String):TC01_;
Function PaserC02_(DI0L:char;Data:String):TC02_;
Function PaserC03_(DI0L:char;Data:String):TC03_;
Function PaserC11_(DI0L:char;Data:String):TC11_;
Function PaserC21_(DI0L:char;Data:String):TC21_;
Function PaserC31_(DI0L:char;Data:String):TC31_;
Function PaserC32_(DI0L:char;Data:String):TC32_;
Function PaserC33_(ID:string;DI0L:char;Data:String):TC33_;
Function PaserC41_(DI0L:char;Data:String):TC41_;


Function GetSTX(ADR:string;var CS0:Byte):string;
Function GetCmdC01( ADR:string;aC01:TC01_; PA,P1,P2,P3:Byte;
                   var STX:string;var CS0:Byte; var Size:Integer):TBuf200;
Function GetCmdBrdTime(t:TdateTime; var Size:Integer):TBuf200;
Function GetCmdWriteADR(NewADR:string; var STX:string;var CS0:Byte; var Size:Integer):TBuf200;
Function BpsToZ(bps:TBps;var BpsInt:Integer):Byte;
Function GetCmdUpdateBPS(ADR:string; Bps:TBps;
                         var STX:string;  var CS0:Byte;var Size:Integer):TBuf200;

Function GetCmdUpdatePass(ADR:string;PA0,P10,P20,P30,PAN,P1N,P2N,P3N:Byte;
                         var STX:string;  var CS0:Byte;var Size:Integer):TBuf200;

Function GetCmdBrdFrz(var Size:Integer):TBuf200;

implementation

////////////////////////////////////////
             // 数据格式转换 //
////////////////////////////////////////
function IIF(B: Boolean; const ATrue: string; AFalse: string = ''): string;
begin
  if B then Result := ATrue
       else Result := AFalse;
end;

function StrToken(var S: String): String;
  var I: Integer;
begin
  I := Pos( char($DD)  ,S );
  if I <> 0 then  begin
    Result := Copy(S, 1, I - 1);
    Delete(S, 1, I);
  end else begin
    Result := S;
    S := '';
  end;
end;





Function STR2Hex(A:String):string;
 var i:Integer;
begin
    result:='';
    for i:=1 to Length(A) do
     result:=result+inttohex( ord(  A[i] ) ,2)+' ';
end;

Function Array2Str(A:array of byte):string;
 var i:Integer;
begin
    result:='';
    for i:=Low(A) to High(A) do
     result:=result+inttohex(A[i],2)+' ';
end;



Function Bit1(B:byte;bit:byte):boolean;
begin
    result:=(B and ($01 shl bit)) <>0;
end;

Function HexToBCD(b:Byte):Byte;
var BH,BL:Byte;
  //var s:String;
begin
 //  s:=inttohex(b,2);
  // result:=strtoInt(s);
   BH:=b div 16; BL:=b mod 16;
   result:=BH*10+BL;
end;


Function BCDToHex(b:Byte):Byte; 
var BH,BL:Byte;
  //var s:String;
begin
 //  s:=inttohex(b,2);
  // result:=strtoInt(s);
   BH:=b div 10; BL:=b mod 10;
   result:=BH*16+BL;
end;


Function Buf4ToDword(buf4:Tbuf4):Dword;
  var i:integer; s:string;
begin
 For i:=0 to 3 do  Buf4[i]:=Buf4[i]-$33;
    s :=inttohex(buf4[3],2) + inttohex(buf4[2],2)
    + inttohex(buf4[1],2) +inttohex(buf4[0],2);
    result:=strtoInt(s);
     // result:=HexToBCD(buf4[3])*1000000 + HexToBCD(buf4[2])*10000 + HexToBCD(buf4[1])*100 + HexToBCD(buf4[0]);
end;

Function Buf3ToDword(buf3:Tbuf3):Dword;
  var i:integer; s:string;
begin
 For i:=0 to 2 do  Buf3[i]:=Buf3[i]-$33;
   s :=inttohex(buf3[2],2) + inttohex(buf3[1],2) + inttohex(buf3[0],2) ;
   result:=strtoInt(s);
end;

Function Buf2ToWord(buf2:Tbuf2):Word;
  var i:integer; s:string;
begin
 For i:=0 to 1 do  Buf2[i]:=Buf2[i]-$33;
   s := inttohex(buf2[1],2) + inttohex(buf2[0],2) ;
   result:=strtoInt(s);
end;

Function buf1ToByte(buf1:Char):Byte;
  var  s:string;
begin
 //  result:=HexToBCD( ord(buf1)- $33);
   s:= InttoHex( ord(buf1)- $33 ,2) ;
   result:=strtoInt(s);
end;


      //buf:  mm HH DD MM  >>> DateTime
Function Buf4ToDT(buf4:Tbuf4):TDateTime;
  var i:integer;
     Y,M,D,H,F :Word;
begin
   For i:=0 to 3 do  Buf4[i]:=Buf4[i]-$33;
       
   DecodeDate(Date,Y,M,D);
   M:= HexToBCD(buf4[3]) ;
   D:= HexToBCD(buf4[2]) ;
   H:= HexToBCD(buf4[1]) ;
   F:= HexToBCD(buf4[0]) ;
   result:=EncodeDateTime(Y,M,D,H,F,0,0);
   if  result > now then result:=IncYear(result,-1);
end;

Function Buf6ToStr(buf6:Tbuf6):string;
  var   i:Integer;
begin
  result:='';
  for i:=5 downto  0   do
      result:=result +  IntToHex (buf6[i]-$33 ,2);
end;

////////////////////////////////////////////////////////////
             //  数据标识分析   //
///////////////////////////////////////////////////////////


Function GetID1( ID:string):TID1;
 var s1,s2:char;
begin
  s1:=ID[1]; result:=ID1_NO;   //,,DL_PmTime,DL_BL
  case S1 of
    '9':result:=ID1_kWh ;  //电能量
    'A':result:=ID1_Pm ;  //最大量
    'B':begin
         s2:=ID[2];
         case s2 of
           '2','3','6': result:=ID1_BL ;  //变量
           '0','1','4','5','8','9': result:=ID1_PmTime ; //最大量发生时间
         end;
        end;
     'C': result:=ID1_CS;   
  end;
end;


Function GetID2( ID:string):TID2;
  var s2:char;
begin
  s2:=ID[2]; result:=ID2_NO;
  case s2 of
    '0': result:=  ID2_curP;//当前有功
    '1': result:=  ID2_CurQ;//当前无功
    '4': result:=  ID2_Lst1P;    //上月有功
    '5': result:=  ID2_Lst1Q;    //上月无功
    '8': result:=  ID2_Lst2P;          //上上月有功
    '9': result:=  ID2_Lst2Q;         //上上月无功
  end;
  
end;



Function GetID3( ID:string):TID3;
 var s3:char;
begin   //ID3_NO,ID3_ZX,ID3_FX,ID3_RL1,ID3_RC2,ID3_RL3,ID3_RC4
    s3:=ID[3];  result:=ID3_NO;
    case s3 of
       '1': result:=ID3_ZX; //+A
       '2': result:=ID3_FX; //-A
       '3': result:=ID3_RL1;   //+RL (1)
       '4': result:=ID3_RC4;   //-Rc (4)
       '5': result:=ID3_RC2;   //+Rc (2)
       '6': result:=ID3_RL3;   //-RL (3)
   end;

end;

Function GetYUE( ID:string):TYUE; //数据标识到 数据月份
   var s2:char;
begin
  result:=YUE_NO;
  s2:=ID[2];
  case s2 of
    '0','1': result:=  YUE0 ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -