comp.lang.ada
 help / color / mirror / Atom feed
From: slos <new.stephane.los@gmail.com>
Subject: Re: Simple Components 4.12 with MQTT implementation released
Date: Thu, 14 Apr 2016 14:20:51 -0700 (PDT)
Date: 2016-04-14T14:20:51-07:00	[thread overview]
Message-ID: <b5b9f139-3349-4f8e-988f-c7e86fe35c2e@googlegroups.com> (raw)
In-Reply-To: <neofov$u38$1@dont-email.me>

Le jeudi 14 avril 2016 18:19:54 UTC+2, björn lundin a écrit :
> On 2016-04-14 15:01, slos wrote:
> > Anyone for OPC ? ;-)
> > http://open62541.org/
> 
> 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
> ...
> 
> 
> 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
> 
> 
> 
> 
> * connect to a server :
>       Server                 : aliased IOPCAutoServer_Type;
>         Create (This => Server, From => OPCDA.CLSID_OPCServer);
>         Connect(This => Server,
>                 ProgID => Gnatcom.Bstr.
>                    To_Bstr("some registered name for a server"));
> 
> You then need a group collection
>       Group_Collection       : IOPCGroups_Type;
>       P_Group_Collection     : Pointer_To_IOPCGroups;
> 
> 
>       --group collection
>         P_Group_Collection := Get_OPCGroups(This => Server);
>         Attach(This => Group_Collection, Pointer => P_Group_Collection);
>         Put_DefaultGroupIsActive(This    => Group_Collection,
>                                  DefaultGroupIsActive =>
>               GNATCOM.Types.VARIANT_BOOL_TRUE);
> 
>         Put_DefaultGroupDeadband(This  => Group_Collection,
>                                  DefaultGroupDeadband => 0.0);
> 
> then you need a group:
>       Group                  : IOPCGroup_Type;
>       P_Group                : Pointer_To_IOPCGroup;
> 
> 
>         P_Group := Add(This => Group_Collection,
>                        Name => Gnatcom.Variant.
>                   To_Variant("A predefined group"));
>         Attach(This => Group, Pointer => P_Group);
>         Put_IsSubscribed(This         => Group,
>                          IsSubscribed =>
>                 GNATCOM.Types.VARIANT_BOOL_TRUE);
>         Put_UpdateRate(This       => Group,
>                        UpdateRate => 0);
>         Put_DeadBand(This     => Group,
>                      DeadBand => 0.0);
> 
> 
> and the group has an item collection
> 
>    Item_Collection : OPCItems_Type;
>    P_Item_Collection : Pointer_To_OPCItems;
> 
> 
>         P_Item_Collection := Get_OPCItems(This => Group);
>         Attach(This => Item_Collection, Pointer => P_Item_Collection);
>         Put_DefaultIsActive(This            => Item_Collection,
>                             DefaultIsActive =>
>                     GNATCOM.Types.VARIANT_BOOL_TRUE);
> 
> 
> You also need to setup a handler for incoming updates
> in a group event
> 
>   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;
> 
> 
>         Group_Event :=
> OPCDA.DIOPCGroupEvent_Events.Create(Group_Event_Object'Unchecked_Access);
> 
>         OPCDA.DIOPCGroupEvent_Events.
>               Set_Events(This            =>
>                               Group_Events_Connection_Point,
>                          For_Object      => Group,
>                          Event_Interface => Group_Event);
>         Put_ClientName(This       => Server,
>                        ClientName =>
>            GNATCOM.BSTR.To_BSTR("A client name")));
> 
> 
> Now, you need to subscribe to som signals:
> 
> 
>       P_Item := AddItem(This         => Item_Collection,
>                         ItemId       =>
>                   Gnatcom.Bstr.To_Bstr("a signal name"),
>                         ClientHandle => C.Long(C_H));
>       Attach(This => Item, Pointer => P_Item);
>       Put_RequestedDataType(This => Item,
>                       RequestedDataType => The_Type);
> 
> 
> 
> 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
> 
> take care of the C_H, the client handle.
> Update eventes will refer to this value
> 
> 
> 
> To write a value:
> 
> 
>  declare
>    Local_Item : OPCItem_Type;
>  begin
>    Local_P_Item := GetOPCItem(This         => Item_Collection,
>                      ServerHandle => Server_Handle);
>        --  Returns an OPCItem specified by server handle
>    Attach(This => An_Item, Pointer => Local_P_Item);
>    Write(This => Local_Item, Value => Value);
>    Free(Local_Item);
> end;
> 
> 
> 
> to explicitly read a value:
> 
> 
> 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;
> 
>     begin
>       Gnatcom.Variant.Initialize(Value);
>       Gnatcom.Variant.Initialize(Quality);
>       Gnatcom.Variant.Initialize(TimeStamp);
>  	
>       declare
>         Local_Item : OPCItem_Type;
>       begin
>         Local_Item := GetOPCItem(This => Item_Collection,
>                                  ServerHandle => Server_Handle);
>         Read(This => Local_Item,
>            Source => OPCDA.OPCDevice,
>            Value => Value'Unchecked_Access,
>            Quality => Quality'Unchecked_Access,
>            TimeStamp => Timestamp'Unchecked_Access);
>         Free(Local_Item);
>       end;
> 
>       Gnatcom.Variant.Clear(Quality);
>       Gnatcom.Variant.Clear(TimeStamp);
>       Gnatcom.Variant.Clear(Value);
> 
> 
> 
> Disconnect:
>      RemoveAll(This => Group_Collection);
>      Disconnect(This => Server);
>      Finalize(This => Server);
>      P_Item := null;
>      P_Item_Collection := null;
>      P_Group := null;
>      P_Group_Collection := null;
> 
> 
> 
> for events, you inherit like this
> 
> 
> with OPCDA.DIOPCGroupEvent_Events;
> with GNATCOM.Types;
> 
> package Opc.Events.Group is
> 
>    type Group_Event_Type is
>      new OPCDA.DIOPCGroupEvent_Events.DIOPCGroupEvent_Event
>      with null record;
> 
>    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);
> 
> end Opc.Events.Group;
> 
> 
> and the body
> 
>    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
> 
>      use GNATCOM.Types;
>      function  Get_Variant is new
>             Gnatcom.Safearray.Get_Element(VARIANT);
>      function  Get_Integer is new
>            Gnatcom.Safearray.Get_Element(Integer);
> 
>      Client_Handle,Quality : Integer := Integer'First;
>      Value : VARIANT;
>      I_Num_Items : Integer  := To_Ada(From => NumItems);
>      Handles   : GNATCOM.Types.Pointer_To_SAFEARRAY :=
>                To_Pointer_To_SAFEARRAY(ClientHandles);
>      Values    : GNATCOM.Types.Pointer_To_SAFEARRAY :=
>                    To_Pointer_To_SAFEARRAY(ItemValues);
>      The_Qualities : GNATCOM.Types.Pointer_To_SAFEARRAY :=
>             To_Pointer_To_SAFEARRAY(Qualities);
> 
> 
> -----------------------------------------------------------------------------------
> 
> 
>    begin
>      --It's important that the words in what is sent back are separated by
>      -- 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 := Get_Integer(Of_Array => The_Qualities, Index => i);
>        Client_Handle := Get_Integer(Of_Array => Handles, Index => i);
>        Value := Get_Variant(Of_Array => Values,  Index => i);
> 
>         -- do something with value here
>        case Value.vt is
>          when VT_I2  =>  --Integer_2
>          when VT_I4  => --Integer_4
>          when VT_BSTR => --Strings
>          when VT_ARRAY + VT_I2   |  -- Array of I2
>               VT_ARRAY + VT_UI2  |  -- Array of UI2
>               VT_ARRAY + VT_I4   =>  -- Array of I4
>          when others =>
> 
>        end case
> 
> 
> 
>      end loop;
>      Clear(Value);
>    end DataChange;
> 
> 
> 
> 
> -- 
> --
> Björn

Hello Björn,

Thank you very much for the code example.

This could be a solution but only for the MS world.

BR;
Stéphane

  parent reply	other threads:[~2016-04-14 21:20 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-12 18:48 Simple Components 4.12 with MQTT implementation released Dmitry A. Kazakov
2016-04-14  8:54 ` slos
2016-04-14 10:07   ` Dmitry A. Kazakov
2016-04-14 13:01     ` slos
2016-04-14 16:19       ` Björn Lundin
2016-04-14 16:49         ` Dmitry A. Kazakov
2016-04-14 20:57           ` Björn Lundin
2016-04-14 21:29           ` slos
2016-04-14 21:20         ` slos [this message]
2016-04-15 11:29           ` Björn Lundin
2016-04-15 12:13             ` slos
2016-04-14 16:47       ` Dmitry A. Kazakov
2016-04-14 21:03         ` Björn Lundin
2016-04-14 21:30           ` slos
2016-04-15  8:01             ` Dmitry A. Kazakov
2016-04-15 10:06               ` slos
2016-04-15 11:12                 ` Björn Lundin
2016-04-15 15:05                 ` Dmitry A. Kazakov
2016-04-15 15:17                   ` slos
2016-04-15 15:34                     ` Dmitry A. Kazakov
2016-04-15 16:00                       ` slos
2016-04-15 16:39                         ` Dmitry A. Kazakov
2016-04-15 22:39                           ` slos
2016-04-15 15:47                   ` slos
2016-04-15 16:30                     ` Dmitry A. Kazakov
2016-04-15 22:18                       ` slos
2016-04-16  8:12                         ` Dmitry A. Kazakov
2016-04-16 17:48                           ` slos
2016-04-18 16:33                             ` Dmitry A. Kazakov
2016-04-19 11:51                       ` hanslad
2016-04-19 12:43                         ` Dmitry A. Kazakov
2016-04-19 12:59                           ` high frequency time stamping (Was: Simple Components 4.12 with MQTT implementation released) G.B.
2016-04-19 13:35                             ` Dmitry A. Kazakov
2016-04-20  7:55                               ` Georg Bauhaus
2016-04-20  8:48                                 ` Dmitry A. Kazakov
2016-04-19 13:43                           ` Simple Components 4.12 with MQTT implementation released hanslad
2016-04-19 16:39                             ` Dmitry A. Kazakov
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox