Hi Milan,

thanks for the quick reply.

Of course I can show you my example code - I basically just modified Julian's 
code from https://github.com/pragmaticindustries/webinar-plc4x to try the 
read/write functionality of all data types present in the Eclipse Milo Server.
I hope the formatting of the mail doesn't look as awful again, my apologies if 
it does.

Best regards
Gregor Minuge


public class OpcDemo
{

   private static final Logger logger = LoggerFactory.getLogger( OpcDemo.class 
);

   public static void main( String[] args )
   {
      PlcDriverManager driverManager = new PlcDriverManager();

      try (PlcConnection connection = driverManager.getConnection( 
"opcua:tcp://127.0.0.1:12686/milo" ))
      {

         logger.info( "Verbindung ist aufgebaut..." );
         if( !connection.getMetadata().canWrite() )
         {
            logger.error( "This connection doesn't support writing." );
            return;
         }
                 
                 
         Boolean[] booleanArray = {true, true, true, true, true};

         CompletableFuture<? extends PlcWriteResponse> requestWriteFuture = 
connection.writeRequestBuilder()
                  .addItem( "Boolean", "ns=2;s=HelloWorld/ScalarTypes/Boolean", 
true ) // WORKS
                  .addItem( "Double", "ns=2;s=HelloWorld/ScalarTypes/Double", 
3.15 ) // WORKS
                  .addItem( "Float", "ns=2;s=HelloWorld/ScalarTypes/Float", 
(float) 2.3 ) // WORKS               
                  .addItem( "Int16", "ns=2;s=HelloWorld/ScalarTypes/Int16", 
(short) 15  ) // WORKS
                  .addItem( "Int32", "ns=2;s=HelloWorld/ScalarTypes/Int32", 
64363 ) // WORKS
                  .addItem( "Int64", "ns=2;s=HelloWorld/ScalarTypes/Int64", 
(long) 513 ) // WORKS
                  .addItem( "Integer", "ns=2;s=HelloWorld/ScalarTypes/Integer", 
432 ) // WORKS
                  .addItem( "SByte", "ns=2;s=HelloWorld/ScalarTypes/SByte", 
(byte) 2 ) // WORKS
                  .addItem( "String", "ns=2;s=HelloWorld/ScalarTypes/String", 
"helloWorld" ) // WORKS
                  .addItem( "StringWrite", 
"ns=2;s=HelloWorld/WriteOnly/String", "write" ) // WORKS

                  //.addItem( "BooleanArray", 
"ns=2;s=HelloWorld/ArrayTypes/BooleanArray", true ) //ClassCastException
                                  //.addItem( "BooleanArray", 
"ns=2;s=HelloWorld/ArrayTypes/BooleanArray[0]", true ) 
//PlcInvalidFieldException
                  //.addItem( "BooleanArray", 
"ns=2;s=HelloWorld/ArrayTypes/BooleanArray", booleanArray ) //ACCES DENIED

                  //.addItem( "Bar", "ns=2;s=HelloWorld/MyObject/2:Bar", object 
) //no field handler for class java.lang.Object found (but maybe my approach 
was too simple)
                  //.addItem( "DateTime", 
"ns=2;s=HelloWorld/ScalarTypes/DateTime", Instant.now()) //no field handler 
found (I also tried it with localdatetime and milliseconds)
                                  //.addItem( "Duration", 
"ns=2;s=HelloWorld/ScalarTypes/Duration", (long) 1 ) //ACCESS DENIED (was 
playing around with that, "real" duration leads to PlcInvalidFieldException 
iirc)
                  //.addItem( "Guid", "ns=2;s=HelloWorld/ScalarTypes/Guid", 
UUID.randomUUID() ) //NO FIELD HANDLER FOUND
                  //.addItem( "LocalizedText", 
"ns=2;s=HelloWorld/ScalarTypes/LocalizedText", "localized" ) //ACCESS DENIED 
(probably needs some other format, but maybe not implemented?)
                  //.addItem( "NodeId", "ns=2;s=HelloWorld/ScalarTypes/NodeId", 
"{ns=1234, id=abcde}" ) //ACCESS DENIED
                  //.addItem( "QualifiedName", 
"ns=2;s=HelloWorld/ScalarTypes/QualifiedName", "{name=defg, 
namespaceIndex=1234}" ) //ACCESS DENIED (with or without braces)

                  //.addItem( "UtcTime", 
"ns=2;s=HelloWorld/ScalarTypes/UtcTime", Instant.now() ) //NO FIELD HANDLER 
FOUND
                  //.addItem( "Variant", 
"ns=2;s=HelloWorld/ScalarTypes/Variant", new Variant(32) ) //NO FIELD HANDLER 
FOUND
                  //.addItem( "XmlElement", 
"ns=2;s=HelloWorld/ScalarTypes/XmlElement",new Variant(new 
XmlElement("<a>hello</a>")) ) //NO FIELD HANDLER FOUND


                  .build().execute();
         logger.info( "Schreibanfrage gesendet..." );

         PlcWriteResponse writeResponse = requestWriteFuture.get();
         logger.info( "Antwort auf Schreibanfrage erhalten..." );

         //          Inspect response
         logger.info( "Antwort der Steuerung:" );
         for( String fieldName : writeResponse.getFieldNames() )
         {
            logger.info( "{} - {}", fieldName, writeResponse.getResponseCode( 
fieldName ) );
            if( writeResponse.getResponseCode( fieldName ) == 
PlcResponseCode.OK )
            {
               logger.info( "{} - {}", fieldName, writeResponse.getField( 
fieldName ) );
            }
         }

         // Send Read Request
         //
         // Everything except for arrays works fine
                 
         CompletableFuture<? extends PlcReadResponse> requestFuture = 
connection.readRequestBuilder()
                                  //.addItem( "BooleanArray", 
"ns=2;s=HelloWorld/ArrayTypes/BooleanArray[0]" ) // PLCInvalidFieldException
                  //.addItem( "BooleanArray", 
"ns=2;s=HelloWorld/ArrayTypes/BooleanArray" ) // ClassCastException
                  //
                  .build()
                  .execute();
         //
         logger.info( "Anfrage gesendet..." );
         PlcReadResponse readResponse = requestFuture.get();
         logger.info( "Antwort erhalten..." );
         // Inspect response
         logger.info( "Antwort der Steuerung:" );
         for( String fieldName : readResponse.getFieldNames() )
         {
            logger.info( "{} - {}", fieldName, readResponse.getResponseCode( 
fieldName ) );
            if( readResponse.getResponseCode( fieldName ) == PlcResponseCode.OK 
)
            {
               logger.info( "{} - {}", fieldName, readResponse.getObject( 
fieldName ) );
            }
         }
      }

      catch(

               Exception e )
      {
         logger.error( "Konnte keine Verbindung aufbauen", e );
      }
   }
}




-----Ursprüngliche Nachricht-----
Von: Strljic, Matthias Milan <matthias-milan.strl...@isw.uni-stuttgart.de> 
Gesendet: Mittwoch, 16. September 2020 15:20
An: dev@plc4x.apache.org
Betreff: AW: Problems with Read/Write using PLC4J OPC UA driver

Hi Gregor,

i will look for your issue to write/read the basic types and arrays. At the 
moment the support for custom/dynamic types is not included into the OPC UA 
integration. If you could provide me there some example code, we could try to 
find there a solution for or at least the information if it is intentionally 
not included 😊

Greetings Matthias
Matthias Strljic, M.Sc.

Universität Stuttgart
Institut für Steuerungstechnik der Werkzeugmaschinen und 
Fertigungseinrichtungen (ISW)

Seidenstraße 36
70174 Stuttgart
GERMANY

Tel: +49 711 685-84530
Fax: +49 711 685-74530

E-Mail: matthias.strl...@isw.uni-stuttgart.de
Web: http://www.isw.uni-stuttgart.de

-----Ursprüngliche Nachricht-----
Von: Gregor Minuge <gregor.min...@sql-ag.de> 
Gesendet: Tuesday, September 15, 2020 2:20 PM
An: dev@plc4x.apache.org
Betreff: Problems with Read/Write using PLC4J OPC UA driver

Hi everyone,
I have two questions regarding the PLC4J OPC UA driver. I am connecting to the 
Eclipse Milo Server using the standard syntax as described 
here<https://plc4x.apache.org/users/protocols/opc-ua.html>.

  1.  I'm not able to read arrays (or their elements). All other data types 
work fine, but I don't understand how to add array fields as items to the 
readRequestBuilder. I'm either (obviously) getting a ClassCastException when 
I'm trying .additem(.../BooleanArray) or an PlcInvalidFieldException when 
trying to access a field of the array like addItem(...BooleanArray[0]).

The response.getObject(fieldName) call mentioned under the "Getting 
Started<https://plc4x.apache.org/users/plc4j/gettingstarted.html>" section on 
the website is not helping, because compilation already fails before getting 
the response.

If the reading of arrays is already implemented, could you please point me in 
the right direction here?



  1.  Likewise, I'm not able to write all data types. Apart from unsigned 
types, I'm having problems with Array, CustomStructTypeVariable, 
CustomUnionTypeVariable, AnalogValue, Object, Byte, ByteString, DateTime, Guid, 
QualifiedName, SByte, UtcTime, Variant and XmlElement.

I'm either getting an AccessDenied-error, probably because I'm trying to write 
the wrong data type to a field (which is especially strange for Byte), or a 
"java.lang.IllegalArgumentException: no field handler for class ... found" 
exception.

I could provide my code if needed, but as I'm generally following the suggested 
path for writing a writeRequest/Response, and it is working fine for simpler 
file types, I'd like to know whether these other types are already supported by 
the PLC4J library or not.
Lastly, if these features are not implemented in PLC4J, are there any plans to 
do so in the future, or would you recommend using Eclipse Milo to a wider 
extent, even if that meant neglecting the PLC4X-API in part? If it is the 
former and it would be appreciated, we could imagine helping you in your 
efforts.
Thanks for your time!
Best regards
Gregor Minuge

Reply via email to