亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? driveru.pas

?? omroln OPC 用delphi描述了同OMROLnOPC通訊的過程
?? PAS
?? 第 1 頁 / 共 5 頁
字號:
        Continue;

      //獲得需要主動查詢的信息
      ReadInfo.szItemName := FNormalInfos[I].rcdAddress.dwReadItem;
      ReadInfo.dwReadSample := FNormalInfos[I].rcdAddress.dwSampleTime * 1000; //采集周期為毫秒
      ReadInfo.dwPriorRead := GetTickCount; //上一讀取周期的時間
      SetLength(ReadInfo.arrVarList, 1); //與該OPCITEM關聯的設備變量的索引信息
      ReadInfo.arrVarList[0] := FNormalInfos[I].dwLocalIndex;

      //查找變量所在的RTU編號
      Idx := -1;
      FindIt := False;
      for J := 0 to High(FReadListInfos) do
      begin
        if FReadListInfos[J].dwRTUNo = FNormalInfos[I].rcdAddress.dwRTUNo then
        begin
          FindIt := True;
          Idx := J;
          Break;
        end;
      end;

      //不存在則添加一個RTU編號
      if not FindIt then
      begin
        SetLength(FReadListInfos, Length(FReadListInfos) + 1);
        FReadListInfos[High(FReadListInfos)].dwRTUNo := FNormalInfos[I].rcdAddress.dwRTUNo;
        FReadListInfos[High(FReadListInfos)].bCommState := True;
        SetLength(FReadListInfos[High(FReadListInfos)].rcdReadInfo, 0);
        Idx := High(FReadListInfos);
      end;

      //過濾掉FReadListInfos中存在的變量描述
      FindIt := False;
      for J := 0 to High(FReadListInfos) do //查找的第一層(RTU層)
      begin
        for K := 0 to High(FReadListInfos[J].rcdReadInfo) do //查找的第二層(變量信息)
        begin
          if AnsiCompareText(FReadListInfos[J].rcdReadInfo[K].szItemName, ReadInfo.szItemName) = 0 then
          begin
            //更新關聯設備變量的索引信息
            FindIt := True;
            SetLength(FReadListInfos[J].rcdReadInfo[K].arrVarList, Length(FReadListInfos[J].rcdReadInfo[K].arrVarList) + 1);
            FReadListInfos[J].rcdReadInfo[K].arrVarList[High(FReadListInfos[J].rcdReadInfo[K].arrVarList)] := FNormalInfos[I].dwLocalIndex;
            Break;
          end;
        end;
        if FindIt then
          Break;
      end;

      //如果沒有找到
      if not FindIt then
      begin
        //將ReadInfo信息加入到FReadInfo中
        SetLength(FReadListInfos[Idx].rcdReadInfo, Length(FReadListInfos[Idx].rcdReadInfo) + 1);
        FReadListInfos[Idx].rcdReadInfo[High(FReadListInfos[Idx].rcdReadInfo)] := ReadInfo;
        SetLength(FReadListInfos[Idx].rcdReadInfo[High(FReadListInfos[Idx].rcdReadInfo)].arrVarList, 1);
        FReadListInfos[Idx].rcdReadInfo[High(FReadListInfos[Idx].rcdReadInfo)].arrVarList[0] := ReadInfo.arrVarList[0];
      end;
    end;
  finally
    LeaveCriticalSection(FLock);
  end;
end;

{*
 *                函數名稱:SetCommState
 *                函數功能:通知該通信端口的所有通信狀態類型的設備變量
 *                          并改變這些設備變量的數據
 *                入口參數:1、State: Boolean。通信狀態
 *                          True -- 通信正常;False -- 通信中斷
 *                出口參數:無
 *                  返回值:無
 *}

procedure TAddressParse.SetCommState(State: Boolean);
var
  I: Integer;
  Data: Integer;
  Infos: TIntegerArray;
  DeviceVar: TDeviceVar;
begin
  EnterCriticalSection(FLock);
  try
    //根據通信狀態判斷要設置的數值
    if State then
      Data := Const_Value_CommNormal
    else
      Data := Const_Value_CommError;

    Infos := FindCommErrorItems;
    for I := Low(Infos) to High(Infos) do
    begin
      DeviceVar := TDeviceVarList.GetDeviceVarList.GetItem(Infos[I]);
      if Assigned(DeviceVar) then
        DeviceVar.RecvData(Data, Now);
    end;
  finally
    LeaveCriticalSection(FLock);
  end;
end;

{*
 *                函數名稱:SetRecvData
 *                函數功能:根據接收到的數據報文設置相關設備變量的數據
 *                          1、將接收的地址信息轉換為設備變量的索引信息
 *                          2、根據設備變量的類型從接收數據中取出有用的數據
 *                入口參數:1、AppDatas: TAppDataInfoArray。從報文中分析出的DT塊信息
 *                出口參數:無
 *                  返回值:無
 *}

procedure TAddressParse.SetRecvData(AppDataInfo: TAppDataInfo);
var
  I: Integer;
  DeviceVar: TDeviceVar;
  ReadValue: Variant;
  VarList: TIntegerArray;
begin
  EnterCriticalSection(FLock);
  try
    VarList := FindItems(AppDataInfo.rcdAddress);
    for I := Low(VarList) to High(VarList) do
    begin
      DeviceVar := TDeviceVarList.GetDeviceVarList.GetItem(VarList[I]);
      if Assigned(DeviceVar) then
      begin
        if SplitValue(DeviceVar, AppDataInfo.AppData, ReadValue) then
        begin
          DeviceVar.RecvData(ReadValue, AppDataInfo.dtDateTime);
          try
            if (DeviceVar.AddressInfo.dwFuncGroup = Const_FG_SYSTEM) and
              (DeviceVar.AddressInfo.dwDataType = Const_Type_RTUCommState) then
              SetRTUFault(DeviceVar.AddressInfo.dwRTUNo, (ReadValue = Const_RTUCOMM_NORMAL));
          except
          end;
        end;
      end;
    end;
  finally
    LeaveCriticalSection(FLock);
  end;
end;

{*
 *                函數名稱:SetRTUFault
 *                函數功能:設置RTU故障信息
 *                入口參數:1、RTUNo: DWord。RTU編號
 *                          2、CommState: Boolean。通訊狀態。TRUE-正常
 *                出口參數:無
 *                  返回值:無
 *}

procedure TAddressParse.SetRTUFault(RTUNo: DWord; CommState: Boolean);
var
  I: Integer;
  Value: Variant;
  ValueDate: TDateTime;
  DeviceVar: TDeviceVar;
  VarIndexs: TIntegerArray;
  FindIt, OpFlag: Boolean;
begin
  EnterCriticalSection(FLock);
  try
    //初始化變量
    FindIt := False;
    OpFlag := False;
    SetLength(VarIndexs, 0);
    
    //首先維護RTU故障列表
    for I := 0 to FRTUFaultList.Count - 1 do
    begin
      if DWord(FRTUFaultList.Items[I]) = RTUNo then
      begin
        FindIt := True;
        Break;
      end;
    end;
    if FindIt and CommState then
    begin
      FRTUFaultList.Remove(Pointer(RTUNo));
      OpFlag := True;
    end;
    if (Not FindIt) and (not CommState) then
    begin
      FRTUFaultList.Add(Pointer(RTUNo));
      OpFlag := True;
    end;
    if not OpFlag then
      Exit;

    //設置查詢列表中的RTU故障,這樣就不再輪循該地址的數據
    for I := 0 to High(FReadListInfos) do
    begin
      if FReadListInfos[I].dwRTUNo = RTUNo then
      begin
        FReadListInfos[I].bCommState := CommState;
        Break;
      end;
    end;

    //查詢該RTU下的所有通訊故障變量,通知系統設備故障
    ValueDate := Now;
    VarIndexs := FindRTUCommErrorItems(RTUNo);
    for I := Low(VarIndexs) to High(VarIndexs) do
    begin
      DeviceVar := TDeviceVarList.GetDeviceVarList.GetItem(VarIndexs[I]);
      if Assigned(DeviceVar) then
      begin
        if CommState then //通訊正常后,應結合設備的實際狀態綜合判斷
        begin
          Value := Integer(Const_Value_CommNormal);
          if not ItemIsNull(DeviceVar.AddressInfo.dwReadItem) then //能夠獲得通訊故障的采集點
          begin
            if not VarIsEmpty(DeviceVar.FLastRecvData) then
              Value := Value or DeviceVar.FLastRecvData;
          end;
        end
        else begin
          Value := Integer(Const_Value_CommError);
        end;
        DeviceVar.RecvData(Value, ValueDate);
      end;
    end;
  finally
    LeaveCriticalSection(FLock);
  end;
end;
{*
 *                函數名稱:GetQueryData
 *                函數功能:獲得需要讀取數據的設備變量信息
 *                          1、系統根據各個設備變量的
 *                入口參數:無
 *                出口參數:1、AddrInfos: TAddressInfoArray。
 *                  返回值:無
 *}

procedure TAddressParse.GetQueryData(var ReadInfos: TReadInfoArray);
var
  I, J: Integer;
  ReadInfo: TReadInfo;
begin
  EnterCriticalSection(FLock);
  try
    SetLength(ReadInfos, 0);
    for I := 0 to High(FReadListInfos) do
    begin
      if not FReadListInfos[I].bCommState then
        Continue;
      for J := 0 to High(FReadListInfos[I].rcdReadInfo) do
      begin
        ReadInfo := FReadListInfos[I].rcdReadInfo[J];
        if ReadInfo.dwReadSample = 0 then
          Continue;
        if (ReadInfo.dwPriorRead = 0) or (GetTimeInterval(ReadInfo.dwPriorRead) >= ReadInfo.dwReadSample) then //達到采集周期
        begin
          FReadListInfos[I].rcdReadInfo[J].dwPriorRead := GetTickCount;
          SetLength(ReadInfos, Length(ReadInfos) + 1);
          ReadInfos[High(ReadInfos)] := ReadInfo;
        end;
      end;
    end;
  finally
    LeaveCriticalSection(FLock);
  end;
end;

{*
 *                函數名稱:GetWriteData
 *                函數功能:獲得需要下發數據的設備變量信息
 *                          1、系統根據各個設備變量的
 *                入口參數:無
 *                出口參數:1、WriteInfos: TWriteInfoArray。下發數據列表
 *                  返回值:無
 *}

procedure TAddressParse.GetWriteData(var WriteInfos: TWriteInfoArray);
var
  I: Integer;
  WriteInfo: TWriteInfo;
begin
  EnterCriticalSection(FLock);
  try
    SetLength(WriteInfos, 0);
    for I := 0 to High(FAutoWriteInfos) do
    begin
      WriteInfo := FAutoWriteInfos[I];
      if (WriteInfo.dwPriorWrite = 0) or (GetTimeInterval(WriteInfo.dwPriorWrite) >= WriteInfo.dwWriteSample) then //達到采集周期
      begin
        WriteInfo.dwPriorWrite := GetTickCount;
        if (WriteInfo.dwWriteValue + 1) > High(WriteInfo.dwWriteValue) then
          WriteInfo.dwWriteValue := 0
        else
          WriteInfo.dwWriteValue := WriteInfo.dwWriteValue + 1;
        FAutoWriteInfos[I] := WriteInfo;
        SetLength(WriteInfos, Length(WriteInfos) + 1);
        WriteInfos[High(WriteInfos)] := WriteInfo;
      end;
    end;
  finally
    LeaveCriticalSection(FLock);
  end;
end;

//**************************************************************************
//                  類名:TDriver
//                  功能:通信設備對象
//**************************************************************************

{*
 *                函數名稱:GetPortId
 *                函數功能:查詢通信端口的編號
 *                入口參數:無
 *                出口參數:無
 *                  返回值:DWord。通信端口編號
 *}

function TDriver.GetPortId: DWord;
begin
  Result := FPortInfo.dwCommPortId;
end;

{*
 *                函數名稱:SendPktToComm
 *                函數功能:向通訊端口發送數據
 *                入口參數:1、WriteData: Variant。數據包
 *                          3、Address: DWord。發送地址
 *                出口參數:無
 *                  返回值:Boolean。True -- 發送成功
 *}

function TDriver.SendPktToComm(WriteData: Variant; Address: string): Boolean;
begin
  try
    {$IFDEF DEBUG}
    FrmOPC.AddPacket(Format('<--: 地址(%s). 數據(%s).', [Address, String(WriteData)]));
    WriteDebugLog(Format('<--: 服務(%s). 地址(%s). 數據(%s).', [FOPCComm.MachineName, Address, String(WriteData)]));
    {$ENDIF}
    Result := FOPCComm.SendData(Address, WriteData);
    if not Result then
      SetDriveStatus(COMM_STATUS_DISCONNECT);
  except
    Result := False;
  end;
end;

{*
 *                函數名稱:SetDriveStatus
 *                函數功能:設置通信端口狀態
 *                          通知與該通信端口關聯的所有通信狀態類型的設備變量
 *                入口參數:1、Value: Integer。通信端口狀態
 *                出口參數:無
 *                  返回值:無
 *}

procedure TDriver.SetDriveStatus(Value: Integer);
begin
  if FDriveStatus <> Value then
  begin
    FDriveStatus := Value;

    //設置通信狀態類型的設備變量
    FAddressParse.SetCommState((FDriveStatus = COMM_STATUS_Connected));

    //根據更新的狀態進行相應的處理
    if FDriveStatus <> COMM_STATUS_Connected then
      FWindow.Reset; //刪除FWindow中所有未發送報文

    //Add 2003/11/16
    TDriverList.GetDriverList.SetTrgEvent;
    //End Add
  end;
end;

{*
 *                函數名稱:SendApplicationFrm
 *                函數功能:發送應用數據報文
 *                入口參數:Frm: TFrame
 *                出口參數:無
 *                  返回值:True -- 發送成功
 *}

function TDriver.SendApplicationFrm(Frm: TFrame): Boolean;
begin
  EnterCriticalSection(FSyncObj);
  try
    FWindow.AddFrame(Frm);
    NotifyToSendPkt;
    Result := True;
  finally
    LeaveCriticalSection(FSyncObj);
  end;
end;

{*
 *                函數名稱:GeneralWriteData

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美一区二区精品在线| 一区二区三区四区视频精品免费| 欧美—级在线免费片| 亚洲一区欧美一区| a4yy欧美一区二区三区| 精品国产精品一区二区夜夜嗨| 最新国产精品久久精品| 国产精品一级二级三级| 在线综合视频播放| 亚洲一区二区在线播放相泽| 成人黄色免费短视频| 久久综合视频网| 免费观看在线色综合| 欧美日韩一区在线| 亚洲黄一区二区三区| 99久久久久久| 国产精品第四页| 波多野结衣中文字幕一区二区三区 | 久久免费电影网| 日本中文字幕一区二区视频 | 欧美aⅴ一区二区三区视频| 一本色道a无线码一区v| 中文字幕不卡在线观看| 国产精品香蕉一区二区三区| 精品国产成人在线影院| 久久黄色级2电影| 欧美一级久久久久久久大片| 午夜视频一区在线观看| 欧美三级欧美一级| 亚洲综合无码一区二区| 91传媒视频在线播放| 日韩理论片一区二区| 色88888久久久久久影院野外| 国产精品久久久久精k8| gogo大胆日本视频一区| 亚洲欧洲日产国产综合网| 丁香激情综合五月| 国产精品天美传媒| 99精品久久只有精品| 一区二区三区中文在线| 欧美日韩一区二区三区四区五区| 同产精品九九九| 欧美精品一级二级| 日韩电影在线一区| 精品成人一区二区三区四区| 国产91综合网| 国产精品国产三级国产普通话三级| 成人黄色777网| 亚洲精品视频在线观看免费| 制服.丝袜.亚洲.另类.中文| 国内外成人在线视频| 日韩一区欧美一区| 欧美肥大bbwbbw高潮| 国内精品伊人久久久久av影院| 国产欧美日韩另类视频免费观看| 97精品电影院| 日韩—二三区免费观看av| 国产喂奶挤奶一区二区三区| 色诱亚洲精品久久久久久| 天堂av在线一区| 国产日本亚洲高清| 欧洲激情一区二区| 麻豆成人在线观看| 欧美国产欧美综合| 欧美群妇大交群的观看方式| 精品一区二区三区视频| 亚洲欧洲精品一区二区三区 | 国产视频一区二区在线| 91国偷自产一区二区三区成为亚洲经典 | 成人免费观看视频| 日韩成人免费电影| 欧美国产激情二区三区| 欧美日韩一区视频| 99亚偷拍自图区亚洲| 日韩国产欧美三级| 亚洲欧美日韩在线不卡| 日韩精品一区二区三区视频播放| 色哟哟一区二区| 国产伦精品一区二区三区免费| 一区二区三区自拍| 国产精品久99| 欧美精品一区二| 91精品国产综合久久久蜜臀粉嫩| 成人高清伦理免费影院在线观看| 蜜桃av一区二区三区| 亚洲二区视频在线| 综合激情成人伊人| 久久久国产精品午夜一区ai换脸| 在线成人午夜影院| 欧美无乱码久久久免费午夜一区| av不卡免费电影| 国产麻豆精品久久一二三| 免费观看久久久4p| 日本亚洲免费观看| 亚洲不卡在线观看| 亚洲在线视频网站| 亚洲精品综合在线| 亚洲欧美精品午睡沙发| 亚洲国产激情av| 国产色产综合产在线视频| 精品欧美一区二区三区精品久久| 欧美午夜精品理论片a级按摩| 91亚洲精华国产精华精华液| 成人午夜短视频| 成人福利视频网站| 成人午夜av电影| 99久久免费精品| 97aⅴ精品视频一二三区| 成人午夜激情片| av激情亚洲男人天堂| www.99精品| 日本精品一区二区三区高清| 91美女视频网站| 在线观看精品一区| 欧美精品一级二级| 欧美一区二区三区成人| 欧美电视剧在线看免费| 欧美精品一区二区久久婷婷| 久久久亚洲精品一区二区三区 | 亚洲一区二区三区影院| 亚洲制服丝袜一区| 三级影片在线观看欧美日韩一区二区 | 欧美一级高清片| 久久综合狠狠综合久久激情| 久久久99免费| 中文字幕一区二区三区蜜月| 亚洲欧美另类图片小说| 亚洲mv在线观看| 老司机免费视频一区二区三区| 国产一区在线看| 91美女片黄在线观看91美女| 欧美日韩一区 二区 三区 久久精品| 欧美一区二区性放荡片| 久久众筹精品私拍模特| 亚洲欧洲日韩一区二区三区| 亚洲一卡二卡三卡四卡无卡久久| 视频一区国产视频| 国产乱一区二区| 色天天综合色天天久久| 欧美一区三区四区| 欧美国产欧美综合| 亚洲成人在线网站| 国产美女娇喘av呻吟久久| 99国产麻豆精品| 5858s免费视频成人| 久久久久久一级片| 亚洲一区二区三区四区不卡| 精品一区二区免费| 色域天天综合网| 久久亚洲一级片| 亚洲国产成人av好男人在线观看| 经典三级视频一区| 91搞黄在线观看| 久久精品一区蜜桃臀影院| 一区二区激情视频| 国产成人午夜精品影院观看视频| 色先锋久久av资源部| 久久网站热最新地址| 亚洲午夜免费福利视频| 成人综合在线观看| 欧美一级理论片| 亚洲一区二区三区小说| 成人永久aaa| 日韩免费观看2025年上映的电影| 亚洲精品久久7777| 国产成人av自拍| 日韩欧美综合一区| 亚洲一区二区三区四区在线观看 | 亚洲成av人片一区二区| 成人黄色在线网站| 久久综合色综合88| 日本va欧美va瓶| 欧美性猛交xxxx黑人交| ...xxx性欧美| 成人app在线观看| 精品国产91九色蝌蚪| 日本在线不卡视频| 欧美日韩亚洲综合一区二区三区| 欧美激情一区二区三区在线| 美女诱惑一区二区| 欧美一区二区三区思思人| 亚洲自拍偷拍欧美| 日本高清免费不卡视频| 成人免费在线视频| 成人av午夜影院| 国产精品素人一区二区| 国产精品1024| 久久精品一区蜜桃臀影院| 国产精一区二区三区| 久久久久国产精品麻豆ai换脸 | 久久天天做天天爱综合色| 日本不卡免费在线视频| 欧美福利电影网| 视频一区中文字幕国产| 在线观看视频一区| 亚洲国产一区二区在线播放| 欧美亚洲综合另类| 亚洲成在线观看| 欧美一区二区免费视频| 日本麻豆一区二区三区视频|