From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM autolearn=unavailable autolearn_force=no version=3.4.4 X-Received: by 10.66.63.68 with SMTP id e4mr10948382pas.40.1460668852154; Thu, 14 Apr 2016 14:20:52 -0700 (PDT) X-Received: by 10.157.11.1 with SMTP id a1mr206374ota.6.1460668852008; Thu, 14 Apr 2016 14:20:52 -0700 (PDT) Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!mx02.eternal-september.org!feeder.eternal-september.org!news.glorb.com!g8no1120381igr.0!news-out.google.com!j7ni296igm.0!nntp.google.com!gy3no4067419igb.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Thu, 14 Apr 2016 14:20:51 -0700 (PDT) In-Reply-To: Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=80.119.168.149; posting-account=O3LyFwoAAACc1uh60ZcOUmAGdDmGsEcV NNTP-Posting-Host: 80.119.168.149 References: <6d3b7ac5-8fc6-406c-8aac-947d25a78249@googlegroups.com> User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: Subject: Re: Simple Components 4.12 with MQTT implementation released From: slos Injection-Date: Thu, 14 Apr 2016 21:20:52 +0000 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Xref: news.eternal-september.org comp.lang.ada:30112 Date: 2016-04-14T14:20:51-07:00 List-Id: Le jeudi 14 avril 2016 18:19:54 UTC+2, bj=F6rn lundin a =E9crit=A0: > On 2016-04-14 15:01, slos wrote: > > Anyone for OPC ? ;-) > > http://open62541.org/ >=20 > Via David's gnatcom, you have most of it. > Use it on opcda.dll, and it will create lots of files. > if the prefix id opcda, you'll get > .... > opcda-opcitems_interface.adb > opcda-opcitems_interface.ads > opcda-opcitems_object.adb > opcda-opcitems_object.ads > opcda-opcitem_interface.adb > opcda-opcitem_interface.ads > opcda-opcitem_object.adb > opcda-opcitem_object.ads > opcda.ads > ... >=20 >=20 > you then need an application to use the files. > com is no fun to use, but it looks like this > first > - connect > - definitions > - subscribe > - write > - read > - catch events. > there are more events, but group is the most important one >=20 >=20 >=20 >=20 > * connect to a server : > Server : aliased IOPCAutoServer_Type; > Create (This =3D> Server, From =3D> OPCDA.CLSID_OPCServer); > Connect(This =3D> Server, > ProgID =3D> Gnatcom.Bstr. > To_Bstr("some registered name for a server")); >=20 > You then need a group collection > Group_Collection : IOPCGroups_Type; > P_Group_Collection : Pointer_To_IOPCGroups; >=20 >=20 > --group collection > P_Group_Collection :=3D Get_OPCGroups(This =3D> Server); > Attach(This =3D> Group_Collection, Pointer =3D> P_Group_Collectio= n); > Put_DefaultGroupIsActive(This =3D> Group_Collection, > DefaultGroupIsActive =3D> > GNATCOM.Types.VARIANT_BOOL_TRUE); >=20 > Put_DefaultGroupDeadband(This =3D> Group_Collection, > DefaultGroupDeadband =3D> 0.0); >=20 > then you need a group: > Group : IOPCGroup_Type; > P_Group : Pointer_To_IOPCGroup; >=20 >=20 > P_Group :=3D Add(This =3D> Group_Collection, > Name =3D> Gnatcom.Variant. > To_Variant("A predefined group")); > Attach(This =3D> Group, Pointer =3D> P_Group); > Put_IsSubscribed(This =3D> Group, > IsSubscribed =3D> > GNATCOM.Types.VARIANT_BOOL_TRUE); > Put_UpdateRate(This =3D> Group, > UpdateRate =3D> 0); > Put_DeadBand(This =3D> Group, > DeadBand =3D> 0.0); >=20 >=20 > and the group has an item collection >=20 > Item_Collection : OPCItems_Type; > P_Item_Collection : Pointer_To_OPCItems; >=20 >=20 > P_Item_Collection :=3D Get_OPCItems(This =3D> Group); > Attach(This =3D> Item_Collection, Pointer =3D> P_Item_Collection)= ; > Put_DefaultIsActive(This =3D> Item_Collection, > DefaultIsActive =3D> > GNATCOM.Types.VARIANT_BOOL_TRUE); >=20 >=20 > You also need to setup a handler for incoming updates > in a group event >=20 > Group_Event_Object : aliased Opc.Events.Group.Group_Event_Type; > Group_Event : GNATCOM.Create.COM_Interface. > Pointer_To_COM_Interface_Type ; > Group_Events_Connection_Point : GNATCOM.Events.IConnectionPoint_Type; >=20 >=20 > Group_Event :=3D > OPCDA.DIOPCGroupEvent_Events.Create(Group_Event_Object'Unchecked_Access); >=20 > OPCDA.DIOPCGroupEvent_Events. > Set_Events(This =3D> > Group_Events_Connection_Point, > For_Object =3D> Group, > Event_Interface =3D> Group_Event); > Put_ClientName(This =3D> Server, > ClientName =3D> > GNATCOM.BSTR.To_BSTR("A client name"))); >=20 >=20 > Now, you need to subscribe to som signals: >=20 >=20 > P_Item :=3D AddItem(This =3D> Item_Collection, > ItemId =3D> > Gnatcom.Bstr.To_Bstr("a signal name"), > ClientHandle =3D> C.Long(C_H)); > Attach(This =3D> Item, Pointer =3D> P_Item); > Put_RequestedDataType(This =3D> Item, > RequestedDataType =3D> The_Type); >=20 >=20 >=20 > where the type is one of allowed type, eg > VT_BOOL,VT_UI2,VT_I4. for arrys add VT_ARRAY like > VT_UI2 + VT_ARRAY >=20 > take care of the C_H, the client handle. > Update eventes will refer to this value >=20 >=20 >=20 > To write a value: >=20 >=20 > declare > Local_Item : OPCItem_Type; > begin > Local_P_Item :=3D GetOPCItem(This =3D> Item_Collection, > ServerHandle =3D> Server_Handle); > -- Returns an OPCItem specified by server handle > Attach(This =3D> An_Item, Pointer =3D> Local_P_Item); > Write(This =3D> Local_Item, Value =3D> Value); > Free(Local_Item); > end; >=20 >=20 >=20 > to explicitly read a value: >=20 >=20 > procedure Read(Server_Handle : Interfaces.C.Long) is > use GNATCOM.Types; > Quality : aliased GNATCOM.Types.Variant; > Value : aliased GNATCOM.Types.Variant; > TimeStamp : aliased GNATCOM.Types.Variant; >=20 > begin > Gnatcom.Variant.Initialize(Value); > Gnatcom.Variant.Initialize(Quality); > Gnatcom.Variant.Initialize(TimeStamp); > =09 > declare > Local_Item : OPCItem_Type; > begin > Local_Item :=3D GetOPCItem(This =3D> Item_Collection, > ServerHandle =3D> Server_Handle); > Read(This =3D> Local_Item, > Source =3D> OPCDA.OPCDevice, > Value =3D> Value'Unchecked_Access, > Quality =3D> Quality'Unchecked_Access, > TimeStamp =3D> Timestamp'Unchecked_Access); > Free(Local_Item); > end; >=20 > Gnatcom.Variant.Clear(Quality); > Gnatcom.Variant.Clear(TimeStamp); > Gnatcom.Variant.Clear(Value); >=20 >=20 >=20 > Disconnect: > RemoveAll(This =3D> Group_Collection); > Disconnect(This =3D> Server); > Finalize(This =3D> Server); > P_Item :=3D null; > P_Item_Collection :=3D null; > P_Group :=3D null; > P_Group_Collection :=3D null; >=20 >=20 >=20 > for events, you inherit like this >=20 >=20 > with OPCDA.DIOPCGroupEvent_Events; > with GNATCOM.Types; >=20 > package Opc.Events.Group is >=20 > type Group_Event_Type is > new OPCDA.DIOPCGroupEvent_Events.DIOPCGroupEvent_Event > with null record; >=20 > procedure DataChange(This : Group_Event_Type; > TransactionID : GNATCOM.Types.VARIANT; > NumItems : GNATCOM.Types.VARIANT; > ClientHandles : GNATCOM.Types.VARIANT; > ItemValues : GNATCOM.Types.VARIANT; > Qualities : GNATCOM.Types.VARIANT; > TimeStamps : GNATCOM.Types.VARIANT); >=20 > end Opc.Events.Group; >=20 >=20 > and the body >=20 > procedure DataChange(This : Group_Event_Type; > TransactionID : GNATCOM.Types.VARIANT; > NumItems : GNATCOM.Types.VARIANT; > ClientHandles : GNATCOM.Types.VARIANT; > ItemValues : GNATCOM.Types.VARIANT; > Qualities : GNATCOM.Types.VARIANT; > TimeStamps : GNATCOM.Types.VARIANT) is >=20 > use GNATCOM.Types; > function Get_Variant is new > Gnatcom.Safearray.Get_Element(VARIANT); > function Get_Integer is new > Gnatcom.Safearray.Get_Element(Integer); >=20 > Client_Handle,Quality : Integer :=3D Integer'First; > Value : VARIANT; > I_Num_Items : Integer :=3D To_Ada(From =3D> NumItems); > Handles : GNATCOM.Types.Pointer_To_SAFEARRAY :=3D > To_Pointer_To_SAFEARRAY(ClientHandles); > Values : GNATCOM.Types.Pointer_To_SAFEARRAY :=3D > To_Pointer_To_SAFEARRAY(ItemValues); > The_Qualities : GNATCOM.Types.Pointer_To_SAFEARRAY :=3D > To_Pointer_To_SAFEARRAY(Qualities); >=20 >=20 > -------------------------------------------------------------------------= ---------- >=20 >=20 > begin > --It's important that the words in what is sent back are separated b= y > -- one (1) space (' ') and one ONLY! OPC_IO will misinterpret > otherwise! > -- 'HANDLE server_handle VALUE some_value TYPE some_type' > Initialize(Value); > for i in 1 .. I_Num_Items loop > Quality :=3D Get_Integer(Of_Array =3D> The_Qualities, Index =3D> i= ); > Client_Handle :=3D Get_Integer(Of_Array =3D> Handles, Index =3D> i= ); > Value :=3D Get_Variant(Of_Array =3D> Values, Index =3D> i); >=20 > -- do something with value here > case Value.vt is > when VT_I2 =3D> --Integer_2 > when VT_I4 =3D> --Integer_4 > when VT_BSTR =3D> --Strings > when VT_ARRAY + VT_I2 | -- Array of I2 > VT_ARRAY + VT_UI2 | -- Array of UI2 > VT_ARRAY + VT_I4 =3D> -- Array of I4 > when others =3D> >=20 > end case >=20 >=20 >=20 > end loop; > Clear(Value); > end DataChange; >=20 >=20 >=20 >=20 > --=20 > -- > Bj=F6rn Hello Bj=F6rn, Thank you very much for the code example. This could be a solution but only for the MS world. BR; St=E9phane