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

📄 dl645lib.~pas

📁 符合DL645规约的电能表数据解析. 可直接实现远程RTU.
💻 ~PAS
📖 第 1 页 / 共 4 页
字号:
    '4','5': result:=  YUE1  ;
    '8','9': result:=  YUE2  ;
  end;
end;

Function GetBK( ID:string):TBK; //数据标识到 数据块定义
 var s2,s3:char;
begin
   s2:=ID[2]; s3:=ID[3];    result:=BK_NO;
   case s2 of
     '0','4','8': case s3 of
                     '1': result:=ZP; //+A
                     '2': result:=FP; //-A
                   end;

     else begin
                   case s3 of
                     '1': result:=ZQ; // +RL+Rc
                     '2': result:=FQ; // -RL-Rc
                     '3': result:=ZQL1;   //+RL (1)
                     '4': result:=FQC4;   //-Rc (4)
                     '5': result:=ZQC2;   //+Rc (2)
                     '6': result:=FQL3;   //-RL (3)
                   end;
     end;
   end;

end;

Function GetJH( ID:string):TJH; //数据标识到 数据集合
 var IDW:Dword;
begin
    result:=JH_NO;
    IDW:=StrToInt('$'+ID);
    case IDW of
        $90FF,$94FF,$98FF,
        $A0FF,$A4FF,$A8FF,  
        $B0FF,$B4FF,$B8FF:result:=JH_P2;
        
        $91FF,$95FF,$99FF ,  
        $A1FF,$A5FF,$A9FF, 
        $B1FF,$B5FF,$B9FF :result:=JH_Q6;

        $B3FF:           result:=JH_DX;
        $B6FF:           result:=JH_X;
    end;
end;


Function GetFL( ID:string):TFL;
 var s4:char;
begin
   s4:=ID[4];  result:=FL_NO;
   case s4 of
    '0':   result:= FL_Z  ;
    '1':   result:= FL_P  ;
    '2':   result:= FL_A  ;
    '3':   result:= FL_B  ;
    '4':   result:= FL_C  ;
    'F':   result:= FL_Block  ;
   end;
end;

Function GetBL( ID:string):TBL; //数据标识到 变量类型
 var s2,s3:char;
begin
   s2:=ID[2]; s3:=ID[3];
   result:=BL_No;
   case S2 of
    '3':  begin
             case s3 of
               '1': result:= DX_CNT;
               '2': result:= DX_T;
               '3': result:= DX_T1;
               '4': result:= DX_T2;
             end;
          end;
    '6':  begin
             case s3 of
               '1': result:= X_V;
               '2': result:= X_I;
               '3': result:= X_P;
               '4': result:= X_Q;
               '5': result:= X_COS;
             end;
          end;
   end;

end;

Function GetBLX( ID:string):TBLX; //数据标识到 变量的相属性
 var s4:char;
begin
   s4:=ID[4];  result:=X_NO;
   case s4 of
    '0':result:= X_Z;
    '1':result:= X_A;
    '2':result:= X_B;
    '3':result:= X_C;
    'F':result:= X_Block;
   end;
end;


Function ID1ToStr(ID1:TID1):string;
begin
   case ID1 of
    ID1_kWh:     result:='电能量:';
    ID1_Pm:      result:='最大需量:';
    ID1_PmTime:  result:='最大需量发生时间:';
    ID1_BL:      result:='变量:';
    ID1_FH:      result:='负荷曲线:';

    ID1_CS:      result:='电表参数设置:';
   end;
end;

Function ID2ToStr(ID2:TID2):string;
begin
  case ID2 of
    ID2_CurP:  result:='(当前)有功' ;
    ID2_CurQ:  result:='(当前)无功' ;
    ID2_Lst1P: result:='(上月)有功' ;
    ID2_Lst1Q: result:='(上月)无功' ;
    ID2_Lst2P: result:='(上上月)有功' ;
    ID2_Lst2Q: result:='(上上月)无功' ;
   end;
end;


Function ID3ToStr( ID3:TID3):string;
begin  
   case ID3 of
      ID3_ZX: result:='正向电能(+A)';
      ID3_FX: result:='反向电能(-A)';
      ID3_RL1: result:='一象限无功(+RL)';
      ID3_RC4: result:='四象限无功(-Rc)' ;
      ID3_RC2: result:='二象限无功(+Rc)';
      ID3_RL3: result:='三象限无功(-RL)';
   end;
end;


Function YUEToStr(Y:TYUE):string;
begin
  case Y of
    YUE0:  result:='(当前)' ;
    YUE1:  result:='(上月)' ;
    YUE2: result:='(上上月)' ;
   end;
end;

Function BKToStr(BK:TBK):string;
begin
  case BK of
    ZP:  result:='正向有功(+A)' ;
    FP:  result:='反向有功(-A)' ;
    ZQ:  result:='正向无功(+RL+Rc)' ;
    FQ:  result:='反向无功(-RL-Rc)' ;
    ZQL1:result:='一象限无功(+RL)' ;
    FQC4:result:='四象限无功(-Rc)' ;
    ZQC2:result:='二象限无功(+Rc)' ;
    FQL3:result:='三象限无功(-RL)' ;
   end;
end;

Function JHToStr(JH:TJH):string;
begin
  case JH of
    JH_P2: result:='有功集合' ;
    JH_Q6: result:='无功集合' ;
    JH_DX: result:='断相集合' ;
    JH_X : result:='瞬时值集合' ;
  end;
end;
Function FLtoStr( aFL:TFL):string;
begin
   case aFL of
    FL_Z:   result:= '总(P+A+B+C)'  ;
    FL_P :   result:= '费率1(P)'  ;
    FL_A :   result:= '费率2(A)'   ;
    FL_B :   result:= '费率3(B)'   ;
    FL_C:   result:= '费率4(C)'   ;
    FL_Block: result:= '块'   ;
   end;
end;


Function BLtoStr(blX:TBLX;blT:TBL):string;
  const blXStr:array[X_NO.. X_C] of string =( ' ',' 块' ,'总'  ,'A相'   ,'B相'   ,'C相' );
  const bltStr:array[BL_NO.. X_COS] of string =(' ','断相次数','断相时间','断相起始时间','断相结束时间', '电压','电流','有功','无功','功率因数');
begin
  result:=  bltStr[blt]+'_'  + blXStr[BlX];
end;

Function IDtoStr( ID:string):string;
 var JH:TJH;
 var ID1:TID1; Y:TYUE;BK:TBK;F:TFL;
begin
   JH:=GetJH(ID);
   ID1:=GetID1(ID);
   if ID1= ID1_BL then begin
      if JH=JH_NO then result:= BLtoStr ( GetBLX(ID),GetBL(ID) )
                   else result:= JHtoStr(JH);
   end else begin
        Y:=GetYUE(ID);
        BK:=GetBK(ID);
        F:=GetFL(ID);
        if JH=JH_NO then result:=ID1tostr(ID1)+YUEtostr(Y)+BKtostr(BK)+FLtostr(F) 
                    else result:=ID1tostr(ID1)+YUEtostr(Y)+JHtoStr(JH) ;
    end;
end;


///////////////////////////////////////////////////
            //命令的合成及数据检验//
//////////////////////////////////////////////////
Function GetReadCMD(ID,ADR:string;var STX:string;var CS0:Byte):TReadCMD;
 var CS,i:byte;
begin
   STX:=GetSTX(ADR,CS0);
   CopyMemory(@Result[0],@STX[1],8);  //0__7
   Result[8]:=01; //控制码C
   Result[9]:=02; // 数据长度L
   Result[10]:=StrToInt('$'+ ID[3]+ID[4])+$33;  //ID0
   Result[11]:=StrToInt('$'+ ID[1]+ID[2])+$33; //ID1
   CS:=CS0;
   for i:=8 to 11 do CS:=CS+ Result[i];
   Result[12]:=CS;   //  校sum for DL meter;
   Result[13]:=$16;   //  sto for DL
   CopyMemory(@STX[1],@Result[0],8);
end;
{
 Function GetReadCMD(ID,ADR:string;var STX:string;var CS0:Byte):TReadCMD;
 var i:byte;  adds:string[12];
begin
   setlength(STX,8);
   Result[0]:=$68;
     adds:=rightstr('00000000000000'+ADR,12);
   Result[1]:=StrToInt('$'+ adds[11]+adds[12]);   //A0
   Result[2]:=StrToInt('$'+ adds[9]+adds[10]);   //A1
   Result[3]:=StrToInt('$'+ adds[7]+adds[8]);   //A2
   Result[4]:=StrToInt('$'+ adds[5]+adds[6]);   //A3
   Result[5]:=StrToInt('$'+ adds[3]+adds[4]);   //A4
   Result[6]:=StrToInt('$'+ adds[1]+adds[2]);   //A5
   Result[7]:=$68; //stx for  DL meter read
   Result[8]:=01; //控制码C
   Result[9]:=02; // 数据长度L
   Result[10]:=StrToInt('$'+ ID[3]+ID[4])+$33;  //ID0
   Result[11]:=StrToInt('$'+ ID[1]+ID[2])+$33; //ID1
   
   CS0:=0;
   for i:=0 to 7 do CS0:=CS0+ Result[i];
   Result[12]:=CS0;   //  校sum for DL meter;
   for i:=8 to 11 do Result[12]:=Result[12]+ Result[i];

   Result[13]:=$16;   //  sto for DL
   CopyMemory(@STX[1],@Result[0],8);
end;

}
           //(ckLenErr,ckCSErr,ckOtherErr,ckC,ckOKErr,ckOK);
Function CheckData( data:string;CS0:Byte;Var B4:Byte):TCheckErr;
  var dataLen,L,i:Integer;  cs:Byte;
begin
   dataLen:=Length(Data); B4:=0;
   if dataLen<4 then begin
      result:=ckLenErr ;   exit;
   end else if dataLen=4 then begin
          //[C,L,ERR,CS]
      if Data[1]<>char($C1) then begin
         result:=ckC ;   exit;
      end;

      if Data[2]<>#1 then begin
         result:=ckLenErr ;   exit;
      end;

      cs:=CS0+$C1 +1+ ord( data[3]) ;
      if ord(data[4])<>cs then begin
         result:=ckCSErr ;   exit;
      end;
      B4:=  ord( data[3]) - $33;
      result:=ckOKErr;
   end else if dataLen<6  then begin
      result:=ckLenErr;
   end else  begin
       //[C,L,DI0,DI1,N1,...Nm,CS]
      if Data[1]<>char($81) then begin
         result:=ckC ;   exit;
      end;

      L:= ord(Data[2]);
      if  dataLen<>(L+3) then begin
          result:=ckLenErr ;   exit;
      end;

      cs:=CS0;
      for i:=1 to dataLen -1 do cs:=cs+ ord(Data[i]);
      if ord(data[dataLen])<>cs then begin
         result:=ckCSErr ;   exit;
      end;

      result:=ckOK;
   end;


end;


Function CheckErr2Str(Err:TCheckErr):string;
begin
 case Err of
  ckLenErr: Result:='长度错';
  ckCSErr: Result:='校验和错';
  ckOtherErr: Result:='未知错';
  ckC:  Result:='控制码错';
  ckOKErr: Result:='返回异常';
  ckOK: Result:='首次校验通过';
 end;
end;



//////////////////////////////////////////////////////
           //  数据包的解析  //
/////////////////////////////////////////////////////
      /////解析电表运行状态字
Function PaserB1(B1:byte):string;
begin
 result:='';
 result := result +'电池电压:'+      IIF(Bit1(B1,2), '欠压','正常')+#13#10;
 result := result +'有功电能方向:'+  IIF(Bit1(B1,4), '反向','正向')+#13#10;
 result := result +'无功电能方向 :'+ IIF(Bit1(B1,5), '反向','正向')+#13#10;
end;

      /////解析电网运行状态字
Function PaserB2(B2:byte):string;
begin
 result:='';
 result := result +'A相:'+ IIF(Bit1(B2,0), '断电','未断电')+#13#10;
 result := result +'B相:'+ IIF(Bit1(B2,1), '断电','未断电')+#13#10;
 result := result +'C相:'+ IIF(Bit1(B2,2), '断电','未断电')+#13#10;

 result := result +'A相:'+ IIF(Bit1(B2,4), '过压','未过压')+#13#10;
 result := result +'B相:'+ IIF(Bit1(B2,5), '过压','未过压')+#13#10;
 result := result +'C相:'+ IIF(Bit1(B2,6), '过压','未过压')+#13#10;
end;

      /////解析周休状态字
Function PaserB3(B3:byte):string;
begin
 result:='';
 result := result +'周日: '+ IIF(Bit1(B3,0), '工作','休息')+#13#10;
 result := result +'周一: '+ IIF(Bit1(B3,1), '工作','休息')+#13#10;
 result := result +'周二: '+ IIF(Bit1(B3,2), '工作','休息')+#13#10;
 result := result +'周三: '+ IIF(Bit1(B3,3), '工作','休息')+#13#10;
 result := result +'周四: '+ IIF(Bit1(B3,4), '工作','休息')+#13#10;
 result := result +'周五: '+ IIF(Bit1(B3,5), '工作','休息')+#13#10;
 result := result +'周六: '+ IIF(Bit1(B3,6), '工作','休息')+#13#10;
end;


      /////解析错误字
Function PaserB4(B4:byte):string;
begin
 result:='';
 if  Bit1(B4,0) then result := result +'非法数据'+#13#10;
 if  Bit1(B4,1) then result := result +'数据标识错'+#13#10;
 if  Bit1(B4,2) then result := result +'密码错'+#13#10;
 if  Bit1(B4,4) then result := result +'年时区超限'+#13#10;
 if  Bit1(B4,5) then result := result +'日段超限'+#13#10;
 if  Bit1(B4,6) then result := result +'费率数超限'+#13#10;
end;

/////////////////解析电能量//////////////////

Function PaserkWh_Block(aFL:TFL;Data:String; Idx:Integer):TBlock_kWh;
  var buf:Tbuf4;  tmp:double;
begin
 result.kWh_Z:=0;  result.kWh_P:=0;   result.kWh_A:=0;
 result.kWh_B:=0;  result.kWh_C:=0;

 if aFL=FL_Block then begin  //块
    if Length(Data) < (Idx -1+4* 5) then begin
         raise  Exception.Create('长度错');
         exit;
    end;
                                        
    CopyMemory(@buf[0],@Data[Idx], 4);   //Ind=5
    result.kWh_Z:= buf4toDword(buf)/100; Idx:=idx+4; //Ind=9
    CopyMemory(@buf[0],@Data[Idx], 4);   
    result.kWh_P:= buf4toDword(buf)/100;  Idx:=idx+4; //Ind=13
    CopyMemory(@buf[0],@Data[Idx], 4);  
    result.kWh_A:= buf4toDword(buf)/100;  Idx:=idx+4; //Ind=17
    CopyMemory(@buf[0],@Data[Idx], 4);  
    result.kWh_B:= buf4toDword(buf)/100;  Idx:=idx+4;  //Ind=21
    CopyMemory(@buf[0],@Data[Idx], 4);  
    result.kWh_C:= buf4toDword(buf)/100; 
 end else begin //块  //相
  //[C  L  DI0  DI1  XX0  XX1  XX2  XX3   CS]
      if Length(Data) < (Idx -1+4) then begin
         raise  Exception.Create('长度错');
         exit;
      end;
    CopyMemory(@buf[0],@Data[5], 4);
    tmp:=buf4toDword(buf)/100;
    case aFL of
       FL_Z:    result.kWh_Z:=tmp;
       FL_P:    result.kWh_P:=tmp;
       FL_A:    result.kWh_A:=tmp;
       FL_B:    result.kWh_B:=tmp;
       FL_C:    result.kWh_C:=tmp;
    end;
 end; //相

end;

/////////////解析最大需量//////////////

Function PaserPm_Block(aFL:TFL;Data:String; Idx:Integer):TBlock_Pm;
 var  buf:Tbuf3; tmp:double;
begin
                   
 result.Pm_Z:=0.0;  result.Pm_P:=0.0; result.Pm_A:=0.0;
 result.Pm_B:=0.0;  result.Pm_C:=0.0;

 if aFL=FL_Block then begin  //块
    if Length(Data) < (Idx -1+3* 5) then begin
         raise  Exception.Create('长度错');
         exit;
    end;
   CopyMemory(@buf[0],@Data[Idx], 3); //idx=5;
   result.Pm_Z:= buf3toDword(buf)/10000; idx:=idx+3;
   CopyMemory(@buf[0],@Data[Idx], 3);  //idx=8;
   result.Pm_P:= buf3toDword(buf)/10000; idx:=idx+3;
   CopyMemory(@buf[0],@Data[Idx], 3);  //idx=11;
   result.Pm_A:= buf3toDword(buf)/10000; idx:=idx+3;
   CopyMemory(@buf[0],@Data[Idx], 3);  //idx=14;
   result.Pm_B:= buf3toDword(buf)/10000; idx:=idx+3;
   CopyMemory(@buf[0],@Data[Idx], 3);  //idx=17;
   result.Pm_C:= buf3toDword(buf)/10000;
 end else begin //块  //相
  //[C  L  DI0  DI1  XX0  XX1  XX2    CS]

⌨️ 快捷键说明

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