OPCClient dotnet

自动控可能大都是用wincc来完成的,由于当时我对wincc 不熟悉,所以想用自己的熟悉的编成工具来完成计算机到西门子plc的控制,于是我翻遍了互联网,在外国一个网站http://www.viscomvisual.com/dotnet/上找到了一个 OPCClient 并且包含代码,自己分析了他们提供的代码,然后自己写了一个简单的opcclient, 把plc内部的控制过程通过pc来实现,并且很快完成了目标程序,但是甲方要求必须使用wincc,我只好放弃了自己编写的opcclient ,最后通过自己的努力用wincc完成了所有的项目,但是对于自己来说这是一个锻炼的机会。今天我把我查找的网址和部分代码贴出来,大家共同学习,同时感谢http://www.viscomvisual.com。如果下面的代码侵害了你们的利益,请和我联系,我会及时这个删除这个帖子,我只是通过学习和分析了下面的源码,并没有照抄和用于商业应用。谢谢大家和我共同讨论。

public bool DoInit()
  {
  try
   {
   SelServer frmSelSrv = new SelServer( );  // create form and let user select a name
   frmSelSrv.ShowDialog( this );
   if( frmSelSrv.selectedOpcSrv == null )
    this.Close();

   selectedOpcSrv = frmSelSrv.selectedOpcSrv;   // OPC server ProgID
   txtServer.Text = selectedOpcSrv;


   // ---------------
   theSrv = new OpcServer();
   if( ! DoConnect( selectedOpcSrv ) )
    return false;

   // add event handler for server shutdown
   theSrv.ShutdownRequested += new ShutdownRequestEventHandler( this.theSrv_ServerShutDown );

   // precreate the only OPC group in this example
   if( ! CreateGroup() )
    return false;

   // browse the namespace of the OPC-server
   if( ! DoBrowse() )
    return false;
   }
  catch( Exception e )  // exceptions MUST be handled
   {
   MessageBox.Show( this, "init error! " + e.ToString(), "Exception", MessageBoxButtons.OK, MessageBoxIcon.Warning );
   return false;
   }
  return true;
  }

 // connect to OPC server via ProgID
 public bool DoConnect( string progid )
  {
  try
   {
   theSrv.Connect( progid );
   Thread.Sleep( 100 );
   theSrv.SetClientName( "DirectOPC " + thisprocess.Id ); // set my client name (exe+process no)

  // MessageBox.Show("DirectOPC " + thisprocess.Id);
   SERVERSTATUS sts;
   theSrv.GetStatus( out sts );

   // get infos about OPC server
   StringBuilder sb = new StringBuilder( sts.szVendorInfo, 200 );
   sb.AppendFormat( " ver:{0}.{1}.{2}", sts.wMajorVersion, sts.wMinorVersion, sts.wBuildNumber );
   txtServerInfo.Text = sb.ToString();
   

   // set status bar text to show server state
   sbpTimeStart.Text = DateTime.FromFileTime( sts.ftStartTime ).ToString();
   sbpStatus.Text = sts.eServerState.ToString();
   }
  catch( COMException )
   {
   MessageBox.Show( this, "connect error!", "Exception", MessageBoxButtons.OK, MessageBoxIcon.Warning );
   return false;
   }
  return true;
  }


 public bool CreateGroup()
  {
  try
   {
   // add our only working group
   theGrp = theSrv.AddGroup( "OPCdotNET-Group", true, 500 );

   // add event handler for data changes
   theGrp.DataChanged += new DataChangeEventHandler( this.theGrp_DataChange );
   theGrp.WriteCompleted += new WriteCompleteEventHandler( this.theGrp_WriteComplete );
   }
  catch( COMException )
   {
   MessageBox.Show( this, "create group error!", "Exception", MessageBoxButtons.OK, MessageBoxIcon.Warning );
   return false;
   }
  return true;
  }

 // event handler: called if any item in group has changed values
 protected void theGrp_DataChange( object sender, DataChangeEventArgs e )
  {
  Trace.WriteLine( "theGrp_DataChange  id=" + e.transactionID.ToString() + " me=0x" + e.masterError.ToString( "X" ) );

  foreach( OPCItemState s in e.sts )
   {
   if( s.HandleClient != itmHandleClient )  // only one client handle
    continue;

   Trace.WriteLine( "  item error=0x" + s.Error.ToString( "X" ) );

   if( HRESULTS.Succeeded( s.Error ) )
    {
    Trace.WriteLine( "  val=" + s.DataValue.ToString() );


    txtItemValue.Text = s.DataValue.ToString();  // update screen
    txtItemQual.Text = OpcGroup.QualityToString( s.Quality );
    txtItemTimeSt.Text = DateTime.FromFileTime( s.TimeStamp ).ToString();
    }
   else
    {
    txtItemValue.Text = "ERROR 0x" + s.Error.ToString( "X" );
    txtItemQual.Text = "error";
    txtItemTimeSt.Text = "error";
    }
   }
  }

 // event handler: called if asynch write finished
 protected void theGrp_WriteComplete( object sender, WriteCompleteEventArgs e )
  {
  foreach( OPCWriteResult w in e.res )
   {
   if( w.HandleClient != itmHandleClient )  // only one client handle
    continue;

   if( HRESULTS.Failed( w.Error ) )
    txtItemWriteRes.Text = "ERROR 0x" + w.Error.ToString( "X" );
   else
    txtItemWriteRes.Text = "ok";
   }
  }


 public bool DoBrowse()
  {
  try
   {
   OPCNAMESPACETYPE opcorgi = theSrv.QueryOrganization();

   // fill TreeView with all
   treeOpcItems.Nodes.Clear();
   TreeNode tnRoot = new TreeNode( rootname, 0, 1 );
   if( opcorgi == OPCNAMESPACETYPE.OPC_NS_HIERARCHIAL )
    {
    theSrv.ChangeBrowsePosition( OPCBROWSEDIRECTION.OPC_BROWSE_TO, "" ); // to root
    RecurBrowse( tnRoot, 1 );
    }
   treeOpcItems.Nodes.Add( tnRoot );

   tnRoot.ExpandAll();   // expand all nodes ([+] -> [-])
   tnRoot.EnsureVisible();  // make the root visible

   // preselect root (dummy)
   treeOpcItems.SelectedNode = tnRoot;  // force treeOpcItems_AfterSelect
   }
  catch( COMException /* eX */ )
   {
   MessageBox.Show( this, "browse error!", "DoBrowse", MessageBoxButtons.OK, MessageBoxIcon.Warning );
   return false;
   }
  return true;
  }

 // recursively call the OPC namespace tree
 public bool RecurBrowse( TreeNode tnParent, int depth )
  {
  try
   {
   ArrayList lst;
   theSrv.Browse( OPCBROWSETYPE.OPC_BRANCH, out lst );
   if( lst == null )
    return true;
   if( lst.Count < 1 )
    return true;
  
   foreach( string s in lst )
    {
    TreeNode tnNext = new TreeNode( s, 0, 1 );
    
    theSrv.ChangeBrowsePosition( OPCBROWSEDIRECTION.OPC_BROWSE_DOWN, s );
    RecurBrowse( tnNext, depth + 1 );
    theSrv.ChangeBrowsePosition( OPCBROWSEDIRECTION.OPC_BROWSE_UP, "" );
   
    tnParent.Nodes.Add( tnNext );
    }
   }
  catch( COMException /* eX */ )
   {
   MessageBox.Show( this, "browse error!", "RecurBrowse", MessageBoxButtons.OK, MessageBoxIcon.Warning );
   return false;
   }
  return true;
  }


 public bool ViewItem( string opcid )
  {
  try
   {
   RemoveItem();  // first remove previous item if any

   itmHandleClient = 1234;
   OPCItemDef[] aD = new OPCItemDef[1];
   aD[0] = new OPCItemDef( opcid, true, itmHandleClient, VarEnum.VT_EMPTY );
  
   OPCItemResult[]  arrRes;
   theGrp.AddItems( aD, out arrRes );
   if( arrRes == null )
    return false;
   if( arrRes[0].Error != HRESULTS.S_OK )
    return false;

   btnItemMore.Enabled = true;
   itmHandleServer  = arrRes[0].HandleServer;
   itmAccessRights  = arrRes[0].AccessRights;
  
   itmTypeCode   = VT2TypeCode( arrRes[0].CanonicalDataType );

   txtItemID.Text   = opcid;
   txtItemDataType.Text = DUMMY_VARIANT.VarEnumToString( arrRes[0].CanonicalDataType );

   if( (itmAccessRights & OPCACCESSRIGHTS.OPC_READABLE) != 0 )
    {
    int  cancelID;
    theGrp.Refresh2( OPCDATASOURCE.OPC_DS_DEVICE, 7788, out cancelID );
    }
   else
    txtItemValue.Text = "no read access";

   if( itmTypeCode != TypeCode.Object )    // Object=failed!
    {
    // check if write is premitted
    if( (itmAccessRights & OPCACCESSRIGHTS.OPC_WRITEABLE) != 0 )
     btnItemWrite.Enabled = true;
    }
   }
  catch( COMException )
   {
   MessageBox.Show( this, "AddItem OPC error!", "ViewItem", MessageBoxButtons.OK, MessageBoxIcon.Warning );
   return false;
   }
  return true;
  }


 // remove previous OPC item if any
 public bool RemoveItem()
  {
  try
   {
   if( itmHandleClient != 0 )
    {
    itmHandleClient   = 0;
    txtItemID.Text   = "";  // clear screen texts
    txtItemValue.Text  = "";
    txtItemDataType.Text = "";
    txtItemQual.Text  = "";
    txtItemTimeSt.Text  = "";
    txtItemSendValue.Text = "";
    txtItemWriteRes.Text = "";
    btnItemWrite.Enabled = false;
    btnItemMore.Enabled  = false;

    int[] serverhandles = new int[1] { itmHandleServer };
    int[] remerrors;
    theGrp.RemoveItems( serverhandles, out remerrors );
    itmHandleServer = 0;
    }
   }
  catch( COMException )
   {
   MessageBox.Show( this, "RemoveItem OPC error!", "RemoveItem", MessageBoxButtons.OK, MessageBoxIcon.Warning );
   return false;
   }
  return true;
  } 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值