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

📄 dlmeter.pas

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

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls,  Dialogs,
  VaSystem, myconlib,DL645lib;

const RepeatCount=1;
  
type

   TOnWriteLog = Procedure(sender:Tobject;var msg:string) of object;
   TOnPaserkWh = Procedure(sender:Tobject;aJH:TJH;
                                          aYUE :TYUE;
                                          aBKSet :TBKSet;
                                          aFL  :TFL;
                                          aTime:TDateTime;
                                          aV: TkWh_BKS) of object;


   TOnPaserPm = Procedure(sender:Tobject; aJH:TJH;
                                          aYUE :TYUE;
                                          aBKSet :TBKSet;
                                          aFL  :TFL;
                                          aTime:TDateTime;
                                          aV:TPm_BKS ) of object;


   TOnPaserPmTime = Procedure(sender:Tobject; aJH:TJH;
                                          aYUE :TYUE;
                                          aBKSet :TBKSet;
                                          aFL  :TFL;
                                          aTime:TDateTime;
                                          aV:TPmTime_BKS ) of object;

   TOnPaserBL = Procedure(sender:Tobject; aJH:TJH;
                                          aBLSet:TBLSet;
                                          aBLX :TBLX;
                                          aTime:TDateTime ;
                                          aV:TBL_BKS ) of object;
  TDLMeter = class(TVaCapture)
  private
    FADR:string;
    FID: string;
    FCom:TReadCMD;
    FN:Byte;
    FonStop: TnotifyEvent;
    FOnWriteLog: TOnWriteLog;
    FOnDebug: TOnWriteLog;
    FGoing: Boolean;
    FOnPaserkWh: TOnPaserkWh;
    FOnPaserPm: TOnPaserPm;
    FOnPaserPmTime: TOnPaserPmTime;
    FOnPaserBL: TOnPaserBL;

    procedure onDL_ExpTime(sender:Tobject);
    procedure onDL_Message(Sender: TObject; const Data: string);
  protected
   //  STX:string;
   //  CS0:Byte;
     procedure DologEvent(aMsg:string);
     procedure DoDebugEvent(aMsg:string);
     procedure DoStopEvent;

     procedure Execute;
  public
     STX:string;
     CS0:Byte;
     constructor Create(Owner: TComponent); override;
     destructor Destroy; override;

     procedure Go;

     procedure stop;
     property Going:Boolean read  FGoing;
  published
    property ID:string read  FID write FID;
    property ADR:string read  FADR write FADR;
    property OnWriteLog: TOnWriteLog read   FOnWriteLog   write FOnWriteLog;
    property OnDebug: TOnWriteLog read   FOnDebug   write FOnDebug;
    property onStop:TnotifyEvent read FonStop write  FonStop;

    property OnPaserkWh:TOnPaserkWh read FOnPaserkWh write  FOnPaserkWh;
    property OnPaserPm:TOnPaserPm read FOnPaserPm write  FOnPaserPm;
    property OnPaserPmTime:TOnPaserPmTime read FOnPaserPmTime write  FOnPaserPmTime;
    property OnPaserBL:TOnPaserBL read FOnPaserBL write  FOnPaserBL;

  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('TMS Async32', [TDLMeter]);
end;

{ TDLMeter }

constructor TDLMeter.Create(Owner: TComponent);
begin
  inherited;
  Active:=false;
  DataFinish:=#22;
  OnExpTime :=  OnDL_ExpTime ;
  OnMessage :=  onDL_Message ;
end;

destructor TDLMeter.Destroy;
begin
  inherited;
end;


procedure  TDLMeter.DoLogEvent(aMsg:string);
begin
  if assigned(Fonwritelog) then  Fonwritelog(self, Amsg  );
end;

procedure  TDLMeter.DoStopEvent;
begin
  if assigned(FOnStop) then  FOnStop(self);
end;

procedure TDLMeter.DoDebugEvent(aMsg: string);
begin
   if assigned(FOnDebug) then  FOnDebug(self, Amsg  );
end;

/////////////////////////////////////////////////////////////////////////

procedure TDLMeter.Execute;
begin
  if not FGoing then begin
     DoStopEvent;  exit;
  end;

  if  FN > RepeatCount  then begin
     DoLogEvent('* 执行'+ID+':第'+inttostr(FN)+'次;放弃!');
     DoStopEvent;
  end else begin
     DoLogEvent('* 执行'+ID+':第'+inttostr(FN)+'次;....');
     Active:=True;
     self.
     WriteBuf(FCom,sizeof(FCom) );
  end;
end;



procedure TDLMeter.onDL_ExpTime(sender: Tobject);
begin
  DoLogEvent('* 执行'+ID+':超时' );
  inc(FN);
  execute;
end;

procedure TDLMeter.onDL_Message(Sender: TObject; const Data: string);
 var Err:TCheckErr; B4:Byte;
     i:Integer; S,tmp:string;   ID1_3:Dword; s4:char;
 
     aJH:TJH; aTime:TDateTime;
     aYUE:TYUE; aBK:TBK;  aBKSet:TBKSet; aFL:TFL;
          aV1:TkWh_BKS; aV2:TPm_BKS; aV3: TPmTime_BKS;
     aBL:TBL; aBLSet:TBLSet; aX:TBLX;
          aV4:TBL_BKS;

     aC01:TC01_;  aC02:TC02_;  aC03:TC03_;
     aC11:TC11_;  aC21:TC21_;  aC31:TC31_;
     aC32:TC32_;  aC33:TC33_;  aC41:TC41_;
begin

   Active:=False;
   DoDebugEvent(data ) ;

////////////////////////////////////////////////
//////       检验的处理                //////////
///////////////////////////////////////////////
  Err:=CheckData(data,CS0,B4);
  DoLogEvent(CheckErr2Str(err));
  if Err<>ckOK then begin
      case Err of
       ckOKErr: begin
                 DoLogEvent(PaserB4(B4));
                 DoStopEvent; exit;
       end;
       else     begin
                inc(FN); execute; exit;
       end;
      end;
  end;


aBLSet:=[];
aBKSet:=[];
case  GetID1(ID) of

////////////////////////////////////////////////
//////       电能量的处理                //////////
///////////////////////////////////////////////


    ID1_kWh:
    begin //电能量
      aBKSet:=[];
      aJH:=GetJH(ID);
      aYUE:=GetYUE(ID);
      aBK:=GetBK(ID);
      aFL:=GetFL(ID);

//////////////有功电能量集合//////////////////////////////////
      if   aJH=JH_P2 then begin  // 有功集合,
            S:=data;
            tmp:=StrToken(S);
            if  length(tmp) = (4+20)  then begin
               try
               aV1[ZP]:= PaserkWh_Block(aFL,tmp,5); //正向有功,
               aBKSet:=aBKSet+[ZP];
               except
                  DoLogEvent('正向有功数据格式错!');
               end;
            end;
            tmp:=StrToken(S);
            if  length(tmp) = (20)  then begin
               try
               aV1[FP]:= PaserkWh_Block(aFL,tmp,1); //反向有功,
               aBKSet:=aBKSet+[FP];
               except
                  DoLogEvent('反向有功数据格式错!');
               end;
            end;

          if assigned(FOnPaserkWh) then
               FOnPaserkWh(self,aJH, aYUE,aBKSet,aFL,aTime,aV1);

          DoStopEvent;
          exit;
      end;  //有功集合,

//////////////无功电能量集合//////////////////////////////////

      if   aJH=JH_Q6 then begin  // 无功集合,
            S:=data;
            tmp:=StrToken(S);
            if  length(tmp) = (4+20)  then begin
               try
               aV1[ZQ]:= PaserkWh_Block(aFL,tmp,5); //正向无功,
               aBKSet:=aBKSet+[ZQ];
               except
                  DoLogEvent('正向无功数据格式错!');
               end;
            end;

            tmp:=StrToken(S);
            if  length(tmp) = (20)  then begin
               try
               aV1[FQ]:= PaserkWh_Block(aFL,tmp,1); //反向无功,
               aBKSet:=aBKSet+[FQ];
               except
                  DoLogEvent('反向无功数据格式错!');
               end;
            end;
            
            tmp:=StrToken(S);
            if  length(tmp) = (20)  then begin
               try
               aV1[ZQL1]:= PaserkWh_Block(aFL,tmp,1); //一象限无功(+RL),
               aBKSet:=aBKSet+[ZQL1];
               except
                  DoLogEvent('一象限无功(+RL)数据格式错!');
               end;
            end;

            tmp:=StrToken(S);
            if  length(tmp) = (20)  then begin
               try
               aV1[FQC4]:= PaserkWh_Block(aFL,tmp,1); //四象限无功(-RC)
               aBKSet:=aBKSet+[FQC4];
               except
                  DoLogEvent('四象限无功(-RC)数据格式错!');
               end;
            end;

            tmp:=StrToken(S);
            if  length(tmp) = (20)  then begin
               try
               aV1[ZQC2]:= PaserkWh_Block(aFL,tmp,1); //二象限无功(+RC),
               aBKSet:=aBKSet+[ZQC2];
               except
                  DoLogEvent('二象限无功(+RC)数据格式错!');
               end;
            end;
            
            tmp:=StrToken(S);
            if  length(tmp) = (20)  then begin
               try
               aV1[FQL3]:= PaserkWh_Block(aFL,tmp,1); //三象限无功(-RL)
               aBKSet:=aBKSet+[FQL3];
               except
                  DoLogEvent('三象限无功(-RL)数据格式错!');
               end;
            end;

          if assigned(FOnPaserkWh) then
               FOnPaserkWh(self,aJH, aYUE,aBKSet,aFL,aTime,aV1);

          DoStopEvent;
          exit;
      end;  //无功集合


//////////////电能量块 或 项//////////////////////////////////

      try
        aV1[aBK]:=PaserkWh_Block(aFL,Data,5);
      except
        DoLogEvent('数据格式错!');
        inc(FN); execute; exit;
      end;
      aBKSet:=[aBK];
      if assigned(FOnPaserkWh) then
         FOnPaserkWh(self,aJH, aYUE,aBKSet,aFL,aTime,aV1);

   end;  //电能量

//////////////////////////////
//电能量结束
//////////////////////////////////////
//  /////////最大需量开始////
///////////////////////////////////////


    ID1_Pm:
    begin   //最大需量


      aBKSet:=[];
      aJH:=GetJH(ID);
      aYUE:=GetYUE(ID);
      aBK:=GetBK(ID);
      aFL:=GetFL(ID);

//////////////有功最大需量集合//////////////////////////////////
      if   aJH=JH_P2 then begin  // 有功最大需量集合,
            S:=data;
            tmp:=StrToken(S);
            if  length(tmp) = (4+15)  then begin
               try
               aV2[ZP]:= PaserPm_Block(aFL,tmp,5); //正向有功最大需量,
               aBKSet:=aBKSet+[ZP];
               except
                  DoLogEvent('正向有功最大需量数据格式错!');
               end;
            end;
            tmp:=StrToken(S);
            if  length(tmp) = (15)  then begin
               try
               aV2[FP]:= PaserPm_Block(aFL,tmp,1); //反向有功,
               aBKSet:=aBKSet+[FP];
               except
                  DoLogEvent('反向有功最大需量数据格式错!');
               end;
            end;

          if assigned(FOnPaserPm) then
               FOnPaserPm(self,aJH, aYUE,aBKSet,aFL,aTime,aV2);

          DoStopEvent;
          exit;
      end;  //有功最大需量集合,

//////////////无功最大需量集合//////////////////////////////////

      if   aJH=JH_Q6 then begin  // 无功最大需量集合,
            S:=data;
            tmp:=StrToken(S);
            if  length(tmp) = (4+15)  then begin
               try
               aV2[ZQ]:= PaserPm_Block(aFL,tmp,5); //正向无功最大需量,
               aBKSet:=aBKSet+[ZQ];
               except
                  DoLogEvent('正向无功最大需量数据格式错!');
               end;
            end;

            tmp:=StrToken(S);
            if  length(tmp) = (15)  then begin
               try
               aV2[FQ]:= PaserPm_Block(aFL,tmp,1); //反向最大需量无功,
               aBKSet:=aBKSet+[FQ];
               except
                  DoLogEvent('反向无功最大需量数据格式错!');
               end;
            end;

            tmp:=StrToken(S);
            if  length(tmp) = (15)  then begin
               try
               aV2[ZQL1]:= PaserPm_Block(aFL,tmp,1); //一象限无功最大需量(+RL),
               aBKSet:=aBKSet+[ZQL1];
               except
                  DoLogEvent('一象限无功最大需量(+RL)数据格式错!');
               end;
            end;

            tmp:=StrToken(S);
            if  length(tmp) = (15)  then begin
               try
               aV2[FQC4]:= PaserPm_Block(aFL,tmp,1); //四象限无功最大需量(-RC)
               aBKSet:=aBKSet+[FQC4];
               except
                  DoLogEvent('四象限无功最大需量(-RC)数据格式错!');
               end;
            end;

            tmp:=StrToken(S);
            if  length(tmp) = (15)  then begin
               try
               aV2[ZQC2]:= PaserPm_Block(aFL,tmp,1); //二象限无功最大需量(+RC),
               aBKSet:=aBKSet+[ZQC2];
               except
                  DoLogEvent('二象限无功最大需量(+RC)数据格式错!');
               end;
            end;

            tmp:=StrToken(S);
            if  length(tmp) = (15)  then begin
               try
               aV2[FQL3]:= PaserPm_Block(aFL,tmp,1); //三象限无功最大需量(-RL)
               aBKSet:=aBKSet+[FQL3];
               except
                  DoLogEvent('三象限无功最大需量(-RL)数据格式错!');
               end;
            end;

          if assigned(FOnPaserPm) then
               FOnPaserPm(self,aJH, aYUE,aBKSet,aFL,aTime,aV2);

          DoStopEvent;
          exit;
      end;  //无功集合


//////////////最大需量块 或 项//////////////////////////////////
      aJH:=JH_NO;
      aYUE:=GetYUE(ID);
      aBK:=GetBK(ID);
      aBKSet:=[aBK];
      aFL:=GetFL(ID);
      try
         aV2[aBK]:=PaserPm_Block(aFL,Data,5);
      except
         DoLogEvent('数据格式错!');
         inc(FN); execute; exit;
      end;

      if assigned(FOnPaserPm) then
         FOnPaserPm(self,aJH, aYUE,aBKSet,aFL,aTime,aV2);

    end;  //最大需量

//////////////////////////////
//最大需量结束
//////////////////////////////////////
//  /////////最大需量发生时间开始////
///////////////////////////////////////

⌨️ 快捷键说明

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