📄 commu.pas
字号:
* 函数名称:Disconnect
* 函数功能:中断与OPC服务的连接
* 入口参数:无
* 出口参数:无
* 返回值:无
*}
procedure TOPCComm.Disconnect;
begin
if Assigned(FOPCServer) then
FOPCServer := nil;
FStatus := Const_STATUS_DISCONNECT;
end;
{*
* 函数名称:HaveItemState
* 函数功能:判断采集点的状态是否存在
* 入口参数:1、CurrState: Byte
* 2、ItemState: Byte
* 出口参数:无
* 返回值:Boolean
*}
function TOPCComm.HaveItemState(const CurrState, ItemState: Byte): Boolean;
begin
Result := False;
if (CurrState = Const_ITEMSTATE_ERROR) then
Exit;
if (CurrState and ItemState) <> 0 then
Result := True;
end;
{*
* 函数名称:SetItemState
* 函数功能:设置采集点的状态
* 入口参数:1、CurrState: Byte
* 2、ItemState: Byte
* 出口参数:无
* 返回值:Byte
*}
function TOPCComm.SetItemState(const CurrState, ItemState: Byte): Byte;
begin
if CurrState = Const_ITEMSTATE_ERROR then
Result := Const_ITEMSTATE_NORMAL
else
Result := CurrState;
Result := Result or ItemState;
end;
{*
* 函数名称:ClrItemState
* 函数功能:清除采集点的状态
* 入口参数:1、CurrState: Byte
* 2、ItemState: Byte
* 出口参数:无
* 返回值:Byte
*}
function TOPCComm.ClrItemState(const CurrState, ItemState: Byte): Byte;
begin
if CurrState = Const_ITEMSTATE_ERROR then
begin
Result := Const_ITEMSTATE_NORMAL;
Exit;
end;
Result := CurrState and (not ItemState);
end;
{*
* 函数名称:Create
* 函数功能:构造函数
* 入口参数:无
* 出口参数:无
* 返回值:无
*}
constructor TOPCComm.Create;
begin
inherited;
ComObj.CoInitializeEx(nil, 0);
InitializeCriticalSection(FLock);
FReadEvent := CreateEvent(nil, True, False, '');
FOPCServer := nil;
FOPCItemMgt := nil;
FOPCSyncIO := nil;
FOPCDataCallback := nil;
FConnectionPoint := nil;
FCookie := 0;
FStatus := Const_STATUS_DISCONNECT;
FGroupName := 'GROUP' + IntToStr(GetTickCount);
end;
{*
* 函数名称:Destroy
* 函数功能:析构函数
* 入口参数:无
* 出口参数:无
* 返回值:无
*}
destructor TOPCComm.Destroy;
begin
DeleteCriticalSection(FLock);
CloseHandle(FReadEvent);
inherited;
end;
{*
* 函数名称:ReadData
* 函数功能:读取数据
* 入口参数:无
* 出口参数:1、Index: DWord
* 2、Value: Variant
* 3、ReadTime: TDateTime
* 返回值:Boolean
*}
function TOPCComm.ReadData(var ItemName: string; var Value: Variant; var ReadTime: TDateTime): Boolean;
var
I: Integer;
begin
if FStatus = Const_STATUS_DISCONNECT then
begin
Result := False;
Exit;
end;
EnterCriticalSection(FLock);
try
for I := 0 to FItemNum - 1 do
begin
if HaveItemState(FOPCItemInfos[I].wStatus, Const_ITEMSTATE_READ) then
begin
ItemName := string(FOPCItemInfos[I].szOPCID);
Value := FOPCItemInfos[I].vrRValue;
ReadTime := FOPCItemInfos[I].dtRTime;
FOPCItemInfos[I].wStatus := ClrItemState(FOPCItemInfos[I].wStatus, Const_ITEMSTATE_READ);
Result := True;
Exit;
end;
end;
Result := False;
ResetEvent(FReadEvent);
finally
LeaveCriticalSection(FLock);
end;
end;
{*
* 函数名称:QueryData
* 函数功能:查询数据
* 入口参数:1、Indexs: array of Word
* 出口参数:无
* 返回值:无
*}
procedure TOPCComm.QueryData(const ItemNames: array of string);
var
HRes: HRESULT;
Errors: PResultList;
ItemName, FindName: string;
I, J, ItemLen: Integer;
TransId, CancelId: Cardinal;
ItemHandles: array of OPCHANDLE;
begin
if FStatus = Const_STATUS_DISCONNECT then
Exit;
if Length(ItemNames) <= 0 then
Exit;
SetLength(ItemHandles, 0);
for I := 0 to High(ItemNames) do
begin
ItemName := ItemNames[I];
for J := 0 to High(FOPCItemInfos) do
begin
FindName := OleStrToString(FOPCItemInfos[J].szOPCID);
if AnsiCompareText(ItemName, FindName) = 0 then
begin
SetLength(ItemHandles, Length(ItemHandles) + 1);
ItemHandles[High(ItemHandles)] := FOPCItemInfos[J].hOPCItem;
Break;
end;
end;
end;
ItemLen := Length(ItemHandles);
if ItemLen <= 0 then
Exit;
ComObj.CoInitializeEx(nil, 0);
try
TransId := Random(High(Word));
HRes := FOPCAsyncIO.Read(ItemLen, @ItemHandles[0], TransId, CancelId, Errors);
if Failed(HRes) then
begin
FStatus := Const_STATUS_DISCONNECT;
WriteDebugLog(Format('查询采集点数据失败. 接口错误代码(%d)', [HRes]));
Exit;
end;
CoTaskMemFree(Errors);
finally
CoUnInitialize;
end;
end;
{*
* 函数名称:RefershData
* 函数功能:刷新数据
* 入口参数:无
* 出口参数:无
* 返回值:无
*}
procedure TOPCComm.RefershData;
var
I: Integer;
ItemNames: array of String;
begin
SetLength(ItemNames, Length(FOPCItemInfos));
for I := 0 to High(FOPCItemInfos) do
ItemNames[I] := OleStrToString(FOPCItemInfos[I].szOPCID);
QueryData(ItemNames);
end;
{*
* 函数名称:SendData
* 函数功能:发送数据
* 入口参数:1、Index: DWord
* 2、Value: Variant
* 出口参数:无
* 返回值:Boolean
*}
function TOPCComm.SendData(const ItemName: string; const Value: Variant): Boolean;
var
I, Idx: Integer;
HRes: HRESULT;
Errors: PResultList;
ItemValues: array of OleVariant;
ItemHandles: array of OPCHANDLE;
begin
SetLength(ItemValues, 0);
SetLength(ItemHandles, 0);
Result := False;
if FStatus = Const_STATUS_DISCONNECT then
Exit;
Idx := -1;
for I := 0 to High(FOPCItemInfos) do
begin
if AnsiCompareText(FOPCItemInfos[I].szOPCID, ItemName) = 0 then
begin
Idx := I;
Break;
end;
end;
if Idx = -1 then
Exit;
SetLength(ItemValues, 1);
SetLength(ItemHandles, 1);
ItemValues[0] := Value;
ItemHandles[0] := FOPCItemInfos[Idx].hOPCItem;
ComObj.CoInitializeEx(nil, 0);
try
HRes := FOPCSyncIO.Write(1, @ItemHandles[0], @ItemValues[0], Errors);
if Failed(HRes) then
begin
FStatus := Const_STATUS_DISCONNECT;
WriteDebugLog(Format('向采集点(%s)下发数据失败. 接口错误代码(%d)', [FOPCItemInfos[Idx].szOPCID, HRes]));
Exit;
end;
CoTaskMemFree(Errors);
VariantClear(ItemValues[0]);
Result := True;
finally
CoUnInitialize;
end;
end;
{*
* 函数名称:SetItems
* 函数功能:初始化采集点信息
* 入口参数:1、ItemNames: array of string
* 出口参数:无
* 返回值:Boolean
*}
function TOPCComm.SetItems(const ItemNames: array of string): Boolean;
var
I, Cnt: Integer;
begin
Result := False;
if FStatus <> Const_STATUS_DISCONNECT then
Exit;
Cnt := Length(ItemNames);
FItemNum := Cnt;
SetLength(FOPCItemInfos, FItemNum);
for I := 0 to FItemNum - 1 do
FOPCItemInfos[I].szOPCID := StringToOleStr(ItemNames[I]);
Result := True;
end;
{*
* 函数名称:StartComm
* 函数功能:启动通讯接口
* 入口参数:无
* 出口参数:无
* 返回值:Boolean
*}
function TOPCComm.StartComm: Boolean;
begin
Result := False;
if FStatus = Const_STATUS_CONNECTED then
StopComm;
if not Connect then
Exit;
if not AddGroup then
begin
Disconnect;
Exit;
end;
if not AddItems then
begin
RemoveGroup;
Disconnect;
Exit;
end;
if not AdviseCallback then
begin
RemoveItems;
RemoveGroup;
Disconnect;
Exit;
end;
FStatus := Const_STATUS_CONNECTED;
Result := True;
end;
{*
* 函数名称:StopComm
* 函数功能:停止通讯接口
* 入口参数:无
* 出口参数:无
* 返回值:无
*}
procedure TOPCComm.StopComm;
begin
if FStatus = Const_STATUS_DISCONNECT then
Exit;
//Unadvise Callback for OPC Items
UnadviseCallback;
//Call procedure Remove OPC Items
RemoveItems;
//Call procedure Remove OPC Group
RemoveGroup;
//Call procedure Remove OPC Group
Disconnect;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -