You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@plc4x.apache.org by Christofer Dutz <ch...@c-ware.de> on 2019/03/22 07:46:58 UTC

Please don't commit or push anything ... We're working on the syncing of pull requests

We're working with infra to get the sync work in the direction from GitHub ... So please don't do any commits and especially no pushing for now.

I'll inform you as soon as we can continue.

https://issues.apache.org/jira/plugins/servlet/mobile#issue/INFRA-18056


Chris

Outlook für Android<https://aka.ms/ghei36> herunterladen


Reconnect of driver

Posted by Gunther Gruber <gu...@IDA-Analytics.de>.
Hello,

i have the following technical question:

in our setup every night the network connection from our system 
collecting the data and the sps (s7) is disconnected.

I came up with the idear to reconnecting every 10 minutes in a different 
thread.

Is there a another maybe more elegant way to check if the connection is 
alive, and in case of a disconnect reconnect after a certain timeout?


Gunther Gruber


AW: Reconnect of driver 2

Posted by Julian Feinauer <j....@pragmaticminds.de>.
Yes, I agree.
One of the few use cases of Java 8s default methods in interfaces...

Julian


-------- Ursprüngliche Nachricht --------
Betreff: Re: Reconnect of driver 2
Von: Christofer Dutz
An: dev@plc4x.apache.org
Cc:

Hi All,

I would agree that a void type and exceptions would allow a more fine-grained reporting of what's going on.

Sort of:
- "Yeah ... I am a S7 400, but I don't support the S7-TIA protocol"
- "No connection under this number" (no connection possible)
- "You're not allowed to connect"
- "Invalid credentials"
- ...

Maybe we should do that ASAP, adding it to the API, but have it report "Not Implemented" for now and to create JIRA tickets for the individual drivers ping implementations.

Chris


Am 26.03.19, 14:44 schrieb "Julian Feinauer" <j....@pragmaticminds.de>:

    Hi Gunther,

    thats really great to hear : )
    When I remember correctly the idea was...

    1. Extend the PlcConnection interface with a "ping()" method (Boolean? Throw Exception if not possible?)
    2. Implement the Ping functionality for each plc with a sensible "operation" (not sure what this could be for S7... read the SLZ or something?)
    3. Use this feature as "keep alive" e.g. for the PooledDriverManager

    does that make sense?

    Julian

    Am 26.03.19, 13:55 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:

        Sure I like to contribute. I guess by that you mean checking out the
        code and create a pull request with something working.


        I like your idear with the ping check. I will focus on implementing a
        function for the ping check, which can be reused later.


        Gunther

        > Hi Gunther,
        >
        > good catch : )
        > In fact, the isConnected() implementation is currently not soo god.
        > In fact it checks if the underlying communication channel from netty is connected (which does not know that it is disconnected yet, in your case).
        > We already had discussions to introduce a real "request" based implementation like "ping()" which sends a request.
        >
        > Furthermore, for your use case there is the PooledDriverManager which does implicitly what you do... throws away a not working connection and issues a new one, if needed, but that’s a separate topic.
        >
        > I think we should spend some effort into this "ping" functionality.
        > Perhaps you can even assist with the implementation Gunther, what do you think?
        >
        > Julian
        >
        > Am 26.03.19, 11:19 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:
        >
        >      Put it another way, isConnected does not work as i expect it
        >
        >      plcConnection.isConnected() returns true even when i disconnect the vpn (maybe of some tcp/ip keepalive?)
        >
        >      this is the snippet of code which i expect to work (instead of the thread which reconnects ever 10 minutes)
        >      while (doCollect) {
        >
        >        try {
        >          if (plcConnection == null || plcConnection.isConnected() == false) {
        >            plcConnection = initPLC(config.get(CONNECTION_KEY));
        >          }
        >        } catch (PlcConnectionException e) {
        >          logger.log(Level.WARNING, "error connecting with driver", e);
        >          plcConnection = null;
        >          incrementalSleep();
        >          break;
        >        }
        >
        >        // Create a new read request:
        >        // - Give the single item requested the alias name "value"
        >        PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
        >
        >      Gunther Gruber
        >
        >
        >






Re: Reconnect of driver 2

Posted by Julian Feinauer <j....@pragmaticminds.de>.
Hey Gunter,

one more notice.
I just submitted the PR with your ping method, which seems to work pretty well for S7 and Modbus-tcp as we checked.

If you want to use the pool, which basically works like a JDBC Connection pool, you can use something like this snippet:

```
private static PooledPlcDriverManager createPooledDriverManager() {
        return new PooledPlcDriverManager(pooledPlcConnectionFactory -> {
            GenericKeyedObjectPoolConfig<PlcConnection> poolConfig = new GenericKeyedObjectPoolConfig<>();
            poolConfig.setMinIdlePerKey(1);  // This should avoid problems with long running connect attempts??
            poolConfig.setTestOnBorrow(true);
            poolConfig.setTestOnReturn(true);
            return new GenericKeyedObjectPool<>(pooledPlcConnectionFactory, poolConfig);
        });
    }
```
(Taken from org.apache.plc4x.java.scraper.ScraperImpl).

The pool keeps a set of connections and hands them over if someone needs them. Before handing over and after getting them back, the pool verifies that the connection is still alive (TestOnBorrw, TestOnReturn) and in case it is not, the Connection is removed from the pool (and a new one is created when requested).
This should be a more elegant solution to your loop.
Especially as the pool would create more concurrent connections, if multiple requests are made concurrently.

Best
Julian

Am 29.03.19, 09:59 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:

    Hi Julian,
    
    i am not sure about this. according to documentation this has to be 
    enabled explicitly. 
    https://support.industry.siemens.com/cs/document/87149213/how-do-you-define-the-true-constant-in-the-lad-fdb-editor-in-step-7-(tia-portal)-?dti=0&lc=en-AT.
    
    Gunther
    
    
    On 29.03.19 09:17, Julian Feinauer wrote:
    > Hi Gunter,
    >
    > I am currently looking through your code and wanted to prepare a commit, so just a question about the s7 implementation.
    > Is the M1.2 a generally available bit or is this something more specific to your use cases?
    > I know that the M are the Markers and generally all Boolean, but can there be a situation where this bit does not exist?
    >
    > Julian
    >
    > Am 28.03.19, 15:16 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:
    >
    >      Hi Julian,
    >      
    >      somhow my github account got flagged.
    >      
    >      I append the two functions below, i think it will take some time for github to respond on the mail i wrote.
    >      
    >      
    >      public boolean ping(String host, int port, int timeout) {
    >        Socket s = null;
    >        try {
    >          s = new Socket();
    >          s.connect(new InetSocketAddress(host, port), timeout);
    >          return true;
    >        } catch (Exception e) {
    >          return false;
    >        } finally {
    >          if (s != null) {
    >            try {
    >              s.close();
    >            } catch (Exception e) {
    >            }
    >          }
    >        }
    >      }
    >      
    >      private boolean channelPingCheck(int timeout) {
    >              String variable = "%M1.2:BOOL";
    >              return channelPingCheck(timeout, variable);
    >          }
    >      
    >          private boolean channelPingCheck(int timeout, String variable) {
    >      
    >      //      String variable = "%M1.2:BOOL";
    >      
    >      //      boolean expectedResult = true;
    >      
    >              try {
    >                  plcConnection = getPlcConnection();
    >              } catch (PlcConnectionException e) {
    >                  return false;
    >              }
    >      
    >              PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
    >      
    >              builder.addItem(variable, variable);
    >      
    >              PlcReadRequest readRequest = builder.build();
    >      
    >              PlcReadResponse result = null;
    >              try {
    >                  result = readRequest.execute().get(timeout, TimeUnit.MILLISECONDS);
    >              } catch (InterruptedException e) {
    >                  Thread.currentThread().interrupt();
    >              } catch (ExecutionException | TimeoutException e) {
    >                  return false;
    >              }
    >      
    >              if (result == null) {
    >                  return false;
    >              }
    >      
    >              Object content;
    >              content = result.getObject(variable);
    >              if (content == null) {
    >                  return false;
    >              }
    >              //we could compare against the real value of the object here, but then we need to be more specific about the variable type
    >              return true;
    >      
    >          }
    >   
    


Re: Reconnect of driver 2

Posted by Julian Feinauer <j....@pragmaticminds.de>.
Thanks for the fast reply.
So I suggest to keep the Ping also fort he S7 by default, until we find something which is really always there (like querying the SZL).
Do you agree?

Am 29.03.19, 09:59 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:

    Hi Julian,
    
    i am not sure about this. according to documentation this has to be 
    enabled explicitly. 
    https://support.industry.siemens.com/cs/document/87149213/how-do-you-define-the-true-constant-in-the-lad-fdb-editor-in-step-7-(tia-portal)-?dti=0&lc=en-AT.
    
    Gunther
    
    
    On 29.03.19 09:17, Julian Feinauer wrote:
    > Hi Gunter,
    >
    > I am currently looking through your code and wanted to prepare a commit, so just a question about the s7 implementation.
    > Is the M1.2 a generally available bit or is this something more specific to your use cases?
    > I know that the M are the Markers and generally all Boolean, but can there be a situation where this bit does not exist?
    >
    > Julian
    >
    > Am 28.03.19, 15:16 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:
    >
    >      Hi Julian,
    >      
    >      somhow my github account got flagged.
    >      
    >      I append the two functions below, i think it will take some time for github to respond on the mail i wrote.
    >      
    >      
    >      public boolean ping(String host, int port, int timeout) {
    >        Socket s = null;
    >        try {
    >          s = new Socket();
    >          s.connect(new InetSocketAddress(host, port), timeout);
    >          return true;
    >        } catch (Exception e) {
    >          return false;
    >        } finally {
    >          if (s != null) {
    >            try {
    >              s.close();
    >            } catch (Exception e) {
    >            }
    >          }
    >        }
    >      }
    >      
    >      private boolean channelPingCheck(int timeout) {
    >              String variable = "%M1.2:BOOL";
    >              return channelPingCheck(timeout, variable);
    >          }
    >      
    >          private boolean channelPingCheck(int timeout, String variable) {
    >      
    >      //      String variable = "%M1.2:BOOL";
    >      
    >      //      boolean expectedResult = true;
    >      
    >              try {
    >                  plcConnection = getPlcConnection();
    >              } catch (PlcConnectionException e) {
    >                  return false;
    >              }
    >      
    >              PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
    >      
    >              builder.addItem(variable, variable);
    >      
    >              PlcReadRequest readRequest = builder.build();
    >      
    >              PlcReadResponse result = null;
    >              try {
    >                  result = readRequest.execute().get(timeout, TimeUnit.MILLISECONDS);
    >              } catch (InterruptedException e) {
    >                  Thread.currentThread().interrupt();
    >              } catch (ExecutionException | TimeoutException e) {
    >                  return false;
    >              }
    >      
    >              if (result == null) {
    >                  return false;
    >              }
    >      
    >              Object content;
    >              content = result.getObject(variable);
    >              if (content == null) {
    >                  return false;
    >              }
    >              //we could compare against the real value of the object here, but then we need to be more specific about the variable type
    >              return true;
    >      
    >          }
    >   
    


Re: Reconnect of driver 2

Posted by Gunther Gruber <gu...@IDA-Analytics.de>.
Hi Julian,

i am not sure about this. according to documentation this has to be 
enabled explicitly. 
https://support.industry.siemens.com/cs/document/87149213/how-do-you-define-the-true-constant-in-the-lad-fdb-editor-in-step-7-(tia-portal)-?dti=0&lc=en-AT.

Gunther


On 29.03.19 09:17, Julian Feinauer wrote:
> Hi Gunter,
>
> I am currently looking through your code and wanted to prepare a commit, so just a question about the s7 implementation.
> Is the M1.2 a generally available bit or is this something more specific to your use cases?
> I know that the M are the Markers and generally all Boolean, but can there be a situation where this bit does not exist?
>
> Julian
>
> Am 28.03.19, 15:16 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:
>
>      Hi Julian,
>      
>      somhow my github account got flagged.
>      
>      I append the two functions below, i think it will take some time for github to respond on the mail i wrote.
>      
>      
>      public boolean ping(String host, int port, int timeout) {
>        Socket s = null;
>        try {
>          s = new Socket();
>          s.connect(new InetSocketAddress(host, port), timeout);
>          return true;
>        } catch (Exception e) {
>          return false;
>        } finally {
>          if (s != null) {
>            try {
>              s.close();
>            } catch (Exception e) {
>            }
>          }
>        }
>      }
>      
>      private boolean channelPingCheck(int timeout) {
>              String variable = "%M1.2:BOOL";
>              return channelPingCheck(timeout, variable);
>          }
>      
>          private boolean channelPingCheck(int timeout, String variable) {
>      
>      //      String variable = "%M1.2:BOOL";
>      
>      //      boolean expectedResult = true;
>      
>              try {
>                  plcConnection = getPlcConnection();
>              } catch (PlcConnectionException e) {
>                  return false;
>              }
>      
>              PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
>      
>              builder.addItem(variable, variable);
>      
>              PlcReadRequest readRequest = builder.build();
>      
>              PlcReadResponse result = null;
>              try {
>                  result = readRequest.execute().get(timeout, TimeUnit.MILLISECONDS);
>              } catch (InterruptedException e) {
>                  Thread.currentThread().interrupt();
>              } catch (ExecutionException | TimeoutException e) {
>                  return false;
>              }
>      
>              if (result == null) {
>                  return false;
>              }
>      
>              Object content;
>              content = result.getObject(variable);
>              if (content == null) {
>                  return false;
>              }
>              //we could compare against the real value of the object here, but then we need to be more specific about the variable type
>              return true;
>      
>          }
>   

Re: Reconnect of driver 2

Posted by Julian Feinauer <j....@pragmaticminds.de>.
Hi,

first, I created a issue for this (https://issues.apache.org/jira/browse/PLC4X-108) and second, yes, I agree.
I want to prepare a Branch where I implement the snippets from Gunter with the things bespoken.

But, thinking again about it, I dislike the contract of the method as "either completes or throws".
This is okay for a "write" operation but not for a question.
If we would do scala, I would suggest to use a Either[Boolean, Exception] or so.
Personally, I would prefer to return a "PingResponse" which is either Successful (.isSuccessfull()) or contains some kind of exception or error message (.getException()).
Can we all agree on that?

Julian

PS.: The branch is https://github.com/apache/incubator-plc4x/tree/feature/PLC4X-108-ping-method

Am 29.03.19, 09:35 schrieb "Christofer Dutz" <ch...@c-ware.de>:

    Hi guys,
    
    Just a question, as I'm currently traveling and haven't had my computer open for the past few days.
    
    On the API side we were thinking of a no-args void method in the PlcConnection that fires exceptions ... Correct? The up, port and stuff like that should be provided by the connection itself. Cause not all protocols and drivers have to be TCP or UDP based.
    
    Chris
    
    Outlook für Android<https://aka.ms/ghei36> herunterladen
    
    ________________________________
    From: Julian Feinauer <j....@pragmaticminds.de>
    Sent: Friday, March 29, 2019 9:17:35 AM
    To: dev@plc4x.apache.org
    Subject: Re: Reconnect of driver 2
    
    Hi Gunter,
    
    I am currently looking through your code and wanted to prepare a commit, so just a question about the s7 implementation.
    Is the M1.2 a generally available bit or is this something more specific to your use cases?
    I know that the M are the Markers and generally all Boolean, but can there be a situation where this bit does not exist?
    
    Julian
    
    Am 28.03.19, 15:16 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:
    
        Hi Julian,
    
        somhow my github account got flagged.
    
        I append the two functions below, i think it will take some time for github to respond on the mail i wrote.
    
    
        public boolean ping(String host, int port, int timeout) {
          Socket s = null;
          try {
            s = new Socket();
            s.connect(new InetSocketAddress(host, port), timeout);
            return true;
          } catch (Exception e) {
            return false;
          } finally {
            if (s != null) {
              try {
                s.close();
              } catch (Exception e) {
              }
            }
          }
        }
    
        private boolean channelPingCheck(int timeout) {
                String variable = "%M1.2:BOOL";
                return channelPingCheck(timeout, variable);
            }
    
            private boolean channelPingCheck(int timeout, String variable) {
    
        //      String variable = "%M1.2:BOOL";
    
        //      boolean expectedResult = true;
    
                try {
                    plcConnection = getPlcConnection();
                } catch (PlcConnectionException e) {
                    return false;
                }
    
                PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
    
                builder.addItem(variable, variable);
    
                PlcReadRequest readRequest = builder.build();
    
                PlcReadResponse result = null;
                try {
                    result = readRequest.execute().get(timeout, TimeUnit.MILLISECONDS);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } catch (ExecutionException | TimeoutException e) {
                    return false;
                }
    
                if (result == null) {
                    return false;
                }
    
                Object content;
                content = result.getObject(variable);
                if (content == null) {
                    return false;
                }
                //we could compare against the real value of the object here, but then we need to be more specific about the variable type
                return true;
    
            }
    
    
        On 28.03.19 14:49, Julian Feinauer wrote:
    
        Hi Gunter,
    
        very cool to hear... and I like your idea with the port... this is so simple and robust…
        I wanted to check and review (and MERGE) your code but I did not find the PR.
        Are you sure you made the PR towards apache/incubator-plc4x?
    
        Best
        Julian
    
        Von: Gunther Gruber <gu...@IDA-Analytics.de>
        Antworten an: "dev@plc4x.apache.org"<ma...@plc4x.apache.org> <de...@plc4x.apache.org>
        Datum: Donnerstag, 28. März 2019 um 14:44
        An: "dev@plc4x.apache.org"<ma...@plc4x.apache.org> <de...@plc4x.apache.org>
        Betreff: Re: Reconnect of driver 2
    
    
        Hi All,
    
        i implemented two simple ping checks one specifically for s7 and one in generall to check reachability of a port. Which can simply be copied.
    
        I also wrote a connection-manager which checks the connection and recreates it if neccessary.
    
        Our szenario is that we want to read data in a loop and the higher the sampling frequency the better. I do not want to waste that on the "liveness" check of the connection. Best S7 could do is every 100ms i heared.
    
        Also i load the driver for the s7 directly because in osgi the classloader stuff does not work.
    
        I put my working code into examples/connection-manager and created a pull request. i did not grasp the code of PooledDriverManager in this short time to integrate. Feel free to adapt/change pieces of my code or give me feedback.
    
        Gunther Gruber
        On 26.03.19 15:24, Christofer Dutz wrote:
    
        Hi All,
    
    
    
        I would agree that a void type and exceptions would allow a more fine-grained reporting of what's going on.
    
    
    
        Sort of:
    
        - "Yeah ... I am a S7 400, but I don't support the S7-TIA protocol"
    
        - "No connection under this number" (no connection possible)
    
        - "You're not allowed to connect"
    
        - "Invalid credentials"
    
        - ...
    
    
    
        Maybe we should do that ASAP, adding it to the API, but have it report "Not Implemented" for now and to create JIRA tickets for the individual drivers ping implementations.
    
    
    
        Chris
    
    
    
    
    
        Am 26.03.19, 14:44 schrieb "Julian Feinauer" <j....@pragmaticminds.de>:
    
    
    
            Hi Gunther,
    
    
    
            thats really great to hear : )
    
            When I remember correctly the idea was...
    
    
    
            1. Extend the PlcConnection interface with a "ping()" method (Boolean? Throw Exception if not possible?)
    
            2. Implement the Ping functionality for each plc with a sensible "operation" (not sure what this could be for S7... read the SLZ or something?)
    
            3. Use this feature as "keep alive" e.g. for the PooledDriverManager
    
    
    
            does that make sense?
    
    
    
            Julian
    
    
    
            Am 26.03.19, 13:55 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:
    
    
    
                Sure I like to contribute. I guess by that you mean checking out the
    
                code and create a pull request with something working.
    
    
    
    
    
                I like your idear with the ping check. I will focus on implementing a
    
                function for the ping check, which can be reused later.
    
    
    
    
    
                Gunther
    
    
    
                > Hi Gunther,
    
                >
    
                > good catch : )
    
                > In fact, the isConnected() implementation is currently not soo god.
    
                > In fact it checks if the underlying communication channel from netty is connected (which does not know that it is disconnected yet, in your case).
    
                > We already had discussions to introduce a real "request" based implementation like "ping()" which sends a request.
    
                >
    
                > Furthermore, for your use case there is the PooledDriverManager which does implicitly what you do... throws away a not working connection and issues a new one, if needed, but that’s a separate topic.
    
                >
    
                > I think we should spend some effort into this "ping" functionality.
    
                > Perhaps you can even assist with the implementation Gunther, what do you think?
    
                >
    
                > Julian
    
                >
    
                > Am 26.03.19, 11:19 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:
    
                >
    
                >      Put it another way, isConnected does not work as i expect it
    
                >
    
                >      plcConnection.isConnected() returns true even when i disconnect the vpn (maybe of some tcp/ip keepalive?)
    
                >
    
                >      this is the snippet of code which i expect to work (instead of the thread which reconnects ever 10 minutes)
    
                >      while (doCollect) {
    
                >
    
                >        try {
    
                >          if (plcConnection == null || plcConnection.isConnected() == false) {
    
                >            plcConnection = initPLC(config.get(CONNECTION_KEY));
    
                >          }
    
                >        } catch (PlcConnectionException e) {
    
                >          logger.log(Level.WARNING, "error connecting with driver", e);
    
                >          plcConnection = null;
    
                >          incrementalSleep();
    
                >          break;
    
                >        }
    
                >
    
                >        // Create a new read request:
    
                >        // - Give the single item requested the alias name "value"
    
                >        PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
    
                >
    
                >      Gunther Gruber
    
                >
    
                >
    
                >
    
    
    
    


Re: Reconnect of driver 2

Posted by Julian Feinauer <j....@pragmaticminds.de>.
Oh and to your original question, yes, this Port thing should be given by the Driver itself as "default implementation" of this ping method which can be overridden, as in the S7 case.

Am 29.03.19, 09:35 schrieb "Christofer Dutz" <ch...@c-ware.de>:

    Hi guys,
    
    Just a question, as I'm currently traveling and haven't had my computer open for the past few days.
    
    On the API side we were thinking of a no-args void method in the PlcConnection that fires exceptions ... Correct? The up, port and stuff like that should be provided by the connection itself. Cause not all protocols and drivers have to be TCP or UDP based.
    
    Chris
    
    Outlook für Android<https://aka.ms/ghei36> herunterladen
    
    ________________________________
    From: Julian Feinauer <j....@pragmaticminds.de>
    Sent: Friday, March 29, 2019 9:17:35 AM
    To: dev@plc4x.apache.org
    Subject: Re: Reconnect of driver 2
    
    Hi Gunter,
    
    I am currently looking through your code and wanted to prepare a commit, so just a question about the s7 implementation.
    Is the M1.2 a generally available bit or is this something more specific to your use cases?
    I know that the M are the Markers and generally all Boolean, but can there be a situation where this bit does not exist?
    
    Julian
    
    Am 28.03.19, 15:16 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:
    
        Hi Julian,
    
        somhow my github account got flagged.
    
        I append the two functions below, i think it will take some time for github to respond on the mail i wrote.
    
    
        public boolean ping(String host, int port, int timeout) {
          Socket s = null;
          try {
            s = new Socket();
            s.connect(new InetSocketAddress(host, port), timeout);
            return true;
          } catch (Exception e) {
            return false;
          } finally {
            if (s != null) {
              try {
                s.close();
              } catch (Exception e) {
              }
            }
          }
        }
    
        private boolean channelPingCheck(int timeout) {
                String variable = "%M1.2:BOOL";
                return channelPingCheck(timeout, variable);
            }
    
            private boolean channelPingCheck(int timeout, String variable) {
    
        //      String variable = "%M1.2:BOOL";
    
        //      boolean expectedResult = true;
    
                try {
                    plcConnection = getPlcConnection();
                } catch (PlcConnectionException e) {
                    return false;
                }
    
                PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
    
                builder.addItem(variable, variable);
    
                PlcReadRequest readRequest = builder.build();
    
                PlcReadResponse result = null;
                try {
                    result = readRequest.execute().get(timeout, TimeUnit.MILLISECONDS);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } catch (ExecutionException | TimeoutException e) {
                    return false;
                }
    
                if (result == null) {
                    return false;
                }
    
                Object content;
                content = result.getObject(variable);
                if (content == null) {
                    return false;
                }
                //we could compare against the real value of the object here, but then we need to be more specific about the variable type
                return true;
    
            }
    
    
        On 28.03.19 14:49, Julian Feinauer wrote:
    
        Hi Gunter,
    
        very cool to hear... and I like your idea with the port... this is so simple and robust…
        I wanted to check and review (and MERGE) your code but I did not find the PR.
        Are you sure you made the PR towards apache/incubator-plc4x?
    
        Best
        Julian
    
        Von: Gunther Gruber <gu...@IDA-Analytics.de>
        Antworten an: "dev@plc4x.apache.org"<ma...@plc4x.apache.org> <de...@plc4x.apache.org>
        Datum: Donnerstag, 28. März 2019 um 14:44
        An: "dev@plc4x.apache.org"<ma...@plc4x.apache.org> <de...@plc4x.apache.org>
        Betreff: Re: Reconnect of driver 2
    
    
        Hi All,
    
        i implemented two simple ping checks one specifically for s7 and one in generall to check reachability of a port. Which can simply be copied.
    
        I also wrote a connection-manager which checks the connection and recreates it if neccessary.
    
        Our szenario is that we want to read data in a loop and the higher the sampling frequency the better. I do not want to waste that on the "liveness" check of the connection. Best S7 could do is every 100ms i heared.
    
        Also i load the driver for the s7 directly because in osgi the classloader stuff does not work.
    
        I put my working code into examples/connection-manager and created a pull request. i did not grasp the code of PooledDriverManager in this short time to integrate. Feel free to adapt/change pieces of my code or give me feedback.
    
        Gunther Gruber
        On 26.03.19 15:24, Christofer Dutz wrote:
    
        Hi All,
    
    
    
        I would agree that a void type and exceptions would allow a more fine-grained reporting of what's going on.
    
    
    
        Sort of:
    
        - "Yeah ... I am a S7 400, but I don't support the S7-TIA protocol"
    
        - "No connection under this number" (no connection possible)
    
        - "You're not allowed to connect"
    
        - "Invalid credentials"
    
        - ...
    
    
    
        Maybe we should do that ASAP, adding it to the API, but have it report "Not Implemented" for now and to create JIRA tickets for the individual drivers ping implementations.
    
    
    
        Chris
    
    
    
    
    
        Am 26.03.19, 14:44 schrieb "Julian Feinauer" <j....@pragmaticminds.de>:
    
    
    
            Hi Gunther,
    
    
    
            thats really great to hear : )
    
            When I remember correctly the idea was...
    
    
    
            1. Extend the PlcConnection interface with a "ping()" method (Boolean? Throw Exception if not possible?)
    
            2. Implement the Ping functionality for each plc with a sensible "operation" (not sure what this could be for S7... read the SLZ or something?)
    
            3. Use this feature as "keep alive" e.g. for the PooledDriverManager
    
    
    
            does that make sense?
    
    
    
            Julian
    
    
    
            Am 26.03.19, 13:55 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:
    
    
    
                Sure I like to contribute. I guess by that you mean checking out the
    
                code and create a pull request with something working.
    
    
    
    
    
                I like your idear with the ping check. I will focus on implementing a
    
                function for the ping check, which can be reused later.
    
    
    
    
    
                Gunther
    
    
    
                > Hi Gunther,
    
                >
    
                > good catch : )
    
                > In fact, the isConnected() implementation is currently not soo god.
    
                > In fact it checks if the underlying communication channel from netty is connected (which does not know that it is disconnected yet, in your case).
    
                > We already had discussions to introduce a real "request" based implementation like "ping()" which sends a request.
    
                >
    
                > Furthermore, for your use case there is the PooledDriverManager which does implicitly what you do... throws away a not working connection and issues a new one, if needed, but that’s a separate topic.
    
                >
    
                > I think we should spend some effort into this "ping" functionality.
    
                > Perhaps you can even assist with the implementation Gunther, what do you think?
    
                >
    
                > Julian
    
                >
    
                > Am 26.03.19, 11:19 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:
    
                >
    
                >      Put it another way, isConnected does not work as i expect it
    
                >
    
                >      plcConnection.isConnected() returns true even when i disconnect the vpn (maybe of some tcp/ip keepalive?)
    
                >
    
                >      this is the snippet of code which i expect to work (instead of the thread which reconnects ever 10 minutes)
    
                >      while (doCollect) {
    
                >
    
                >        try {
    
                >          if (plcConnection == null || plcConnection.isConnected() == false) {
    
                >            plcConnection = initPLC(config.get(CONNECTION_KEY));
    
                >          }
    
                >        } catch (PlcConnectionException e) {
    
                >          logger.log(Level.WARNING, "error connecting with driver", e);
    
                >          plcConnection = null;
    
                >          incrementalSleep();
    
                >          break;
    
                >        }
    
                >
    
                >        // Create a new read request:
    
                >        // - Give the single item requested the alias name "value"
    
                >        PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
    
                >
    
                >      Gunther Gruber
    
                >
    
                >
    
                >
    
    
    
    


Re: Reconnect of driver 2

Posted by Christofer Dutz <ch...@c-ware.de>.
Hi guys,

Just a question, as I'm currently traveling and haven't had my computer open for the past few days.

On the API side we were thinking of a no-args void method in the PlcConnection that fires exceptions ... Correct? The up, port and stuff like that should be provided by the connection itself. Cause not all protocols and drivers have to be TCP or UDP based.

Chris

Outlook für Android<https://aka.ms/ghei36> herunterladen

________________________________
From: Julian Feinauer <j....@pragmaticminds.de>
Sent: Friday, March 29, 2019 9:17:35 AM
To: dev@plc4x.apache.org
Subject: Re: Reconnect of driver 2

Hi Gunter,

I am currently looking through your code and wanted to prepare a commit, so just a question about the s7 implementation.
Is the M1.2 a generally available bit or is this something more specific to your use cases?
I know that the M are the Markers and generally all Boolean, but can there be a situation where this bit does not exist?

Julian

Am 28.03.19, 15:16 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:

    Hi Julian,

    somhow my github account got flagged.

    I append the two functions below, i think it will take some time for github to respond on the mail i wrote.


    public boolean ping(String host, int port, int timeout) {
      Socket s = null;
      try {
        s = new Socket();
        s.connect(new InetSocketAddress(host, port), timeout);
        return true;
      } catch (Exception e) {
        return false;
      } finally {
        if (s != null) {
          try {
            s.close();
          } catch (Exception e) {
          }
        }
      }
    }

    private boolean channelPingCheck(int timeout) {
            String variable = "%M1.2:BOOL";
            return channelPingCheck(timeout, variable);
        }

        private boolean channelPingCheck(int timeout, String variable) {

    //      String variable = "%M1.2:BOOL";

    //      boolean expectedResult = true;

            try {
                plcConnection = getPlcConnection();
            } catch (PlcConnectionException e) {
                return false;
            }

            PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();

            builder.addItem(variable, variable);

            PlcReadRequest readRequest = builder.build();

            PlcReadResponse result = null;
            try {
                result = readRequest.execute().get(timeout, TimeUnit.MILLISECONDS);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } catch (ExecutionException | TimeoutException e) {
                return false;
            }

            if (result == null) {
                return false;
            }

            Object content;
            content = result.getObject(variable);
            if (content == null) {
                return false;
            }
            //we could compare against the real value of the object here, but then we need to be more specific about the variable type
            return true;

        }


    On 28.03.19 14:49, Julian Feinauer wrote:

    Hi Gunter,

    very cool to hear... and I like your idea with the port... this is so simple and robust…
    I wanted to check and review (and MERGE) your code but I did not find the PR.
    Are you sure you made the PR towards apache/incubator-plc4x?

    Best
    Julian

    Von: Gunther Gruber <gu...@IDA-Analytics.de>
    Antworten an: "dev@plc4x.apache.org"<ma...@plc4x.apache.org> <de...@plc4x.apache.org>
    Datum: Donnerstag, 28. März 2019 um 14:44
    An: "dev@plc4x.apache.org"<ma...@plc4x.apache.org> <de...@plc4x.apache.org>
    Betreff: Re: Reconnect of driver 2


    Hi All,

    i implemented two simple ping checks one specifically for s7 and one in generall to check reachability of a port. Which can simply be copied.

    I also wrote a connection-manager which checks the connection and recreates it if neccessary.

    Our szenario is that we want to read data in a loop and the higher the sampling frequency the better. I do not want to waste that on the "liveness" check of the connection. Best S7 could do is every 100ms i heared.

    Also i load the driver for the s7 directly because in osgi the classloader stuff does not work.

    I put my working code into examples/connection-manager and created a pull request. i did not grasp the code of PooledDriverManager in this short time to integrate. Feel free to adapt/change pieces of my code or give me feedback.

    Gunther Gruber
    On 26.03.19 15:24, Christofer Dutz wrote:

    Hi All,



    I would agree that a void type and exceptions would allow a more fine-grained reporting of what's going on.



    Sort of:

    - "Yeah ... I am a S7 400, but I don't support the S7-TIA protocol"

    - "No connection under this number" (no connection possible)

    - "You're not allowed to connect"

    - "Invalid credentials"

    - ...



    Maybe we should do that ASAP, adding it to the API, but have it report "Not Implemented" for now and to create JIRA tickets for the individual drivers ping implementations.



    Chris





    Am 26.03.19, 14:44 schrieb "Julian Feinauer" <j....@pragmaticminds.de>:



        Hi Gunther,



        thats really great to hear : )

        When I remember correctly the idea was...



        1. Extend the PlcConnection interface with a "ping()" method (Boolean? Throw Exception if not possible?)

        2. Implement the Ping functionality for each plc with a sensible "operation" (not sure what this could be for S7... read the SLZ or something?)

        3. Use this feature as "keep alive" e.g. for the PooledDriverManager



        does that make sense?



        Julian



        Am 26.03.19, 13:55 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:



            Sure I like to contribute. I guess by that you mean checking out the

            code and create a pull request with something working.





            I like your idear with the ping check. I will focus on implementing a

            function for the ping check, which can be reused later.





            Gunther



            > Hi Gunther,

            >

            > good catch : )

            > In fact, the isConnected() implementation is currently not soo god.

            > In fact it checks if the underlying communication channel from netty is connected (which does not know that it is disconnected yet, in your case).

            > We already had discussions to introduce a real "request" based implementation like "ping()" which sends a request.

            >

            > Furthermore, for your use case there is the PooledDriverManager which does implicitly what you do... throws away a not working connection and issues a new one, if needed, but that’s a separate topic.

            >

            > I think we should spend some effort into this "ping" functionality.

            > Perhaps you can even assist with the implementation Gunther, what do you think?

            >

            > Julian

            >

            > Am 26.03.19, 11:19 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:

            >

            >      Put it another way, isConnected does not work as i expect it

            >

            >      plcConnection.isConnected() returns true even when i disconnect the vpn (maybe of some tcp/ip keepalive?)

            >

            >      this is the snippet of code which i expect to work (instead of the thread which reconnects ever 10 minutes)

            >      while (doCollect) {

            >

            >        try {

            >          if (plcConnection == null || plcConnection.isConnected() == false) {

            >            plcConnection = initPLC(config.get(CONNECTION_KEY));

            >          }

            >        } catch (PlcConnectionException e) {

            >          logger.log(Level.WARNING, "error connecting with driver", e);

            >          plcConnection = null;

            >          incrementalSleep();

            >          break;

            >        }

            >

            >        // Create a new read request:

            >        // - Give the single item requested the alias name "value"

            >        PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();

            >

            >      Gunther Gruber

            >

            >

            >




Re: Reconnect of driver 2

Posted by Julian Feinauer <j....@pragmaticminds.de>.
Hi Gunter,

I am currently looking through your code and wanted to prepare a commit, so just a question about the s7 implementation.
Is the M1.2 a generally available bit or is this something more specific to your use cases?
I know that the M are the Markers and generally all Boolean, but can there be a situation where this bit does not exist?

Julian

Am 28.03.19, 15:16 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:

    Hi Julian,
    
    somhow my github account got flagged.
    
    I append the two functions below, i think it will take some time for github to respond on the mail i wrote.
    
    
    public boolean ping(String host, int port, int timeout) {
      Socket s = null;
      try {
        s = new Socket();
        s.connect(new InetSocketAddress(host, port), timeout);
        return true;
      } catch (Exception e) {
        return false;
      } finally {
        if (s != null) {
          try {
            s.close();
          } catch (Exception e) {
          }
        }
      }
    }
    
    private boolean channelPingCheck(int timeout) {
            String variable = "%M1.2:BOOL";
            return channelPingCheck(timeout, variable);
        }
    
        private boolean channelPingCheck(int timeout, String variable) {
    
    //      String variable = "%M1.2:BOOL";
    
    //      boolean expectedResult = true;
    
            try {
                plcConnection = getPlcConnection();
            } catch (PlcConnectionException e) {
                return false;
            }
    
            PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
    
            builder.addItem(variable, variable);
    
            PlcReadRequest readRequest = builder.build();
    
            PlcReadResponse result = null;
            try {
                result = readRequest.execute().get(timeout, TimeUnit.MILLISECONDS);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } catch (ExecutionException | TimeoutException e) {
                return false;
            }
    
            if (result == null) {
                return false;
            }
    
            Object content;
            content = result.getObject(variable);
            if (content == null) {
                return false;
            }
            //we could compare against the real value of the object here, but then we need to be more specific about the variable type
            return true;
    
        }
    
    
    On 28.03.19 14:49, Julian Feinauer wrote:
    
    Hi Gunter,
    
    very cool to hear... and I like your idea with the port... this is so simple and robust…
    I wanted to check and review (and MERGE) your code but I did not find the PR.
    Are you sure you made the PR towards apache/incubator-plc4x?
    
    Best
    Julian
    
    Von: Gunther Gruber <gu...@IDA-Analytics.de>
    Antworten an: "dev@plc4x.apache.org"<ma...@plc4x.apache.org> <de...@plc4x.apache.org>
    Datum: Donnerstag, 28. März 2019 um 14:44
    An: "dev@plc4x.apache.org"<ma...@plc4x.apache.org> <de...@plc4x.apache.org>
    Betreff: Re: Reconnect of driver 2
    
    
    Hi All,
    
    i implemented two simple ping checks one specifically for s7 and one in generall to check reachability of a port. Which can simply be copied.
    
    I also wrote a connection-manager which checks the connection and recreates it if neccessary.
    
    Our szenario is that we want to read data in a loop and the higher the sampling frequency the better. I do not want to waste that on the "liveness" check of the connection. Best S7 could do is every 100ms i heared.
    
    Also i load the driver for the s7 directly because in osgi the classloader stuff does not work.
    
    I put my working code into examples/connection-manager and created a pull request. i did not grasp the code of PooledDriverManager in this short time to integrate. Feel free to adapt/change pieces of my code or give me feedback.
    
    Gunther Gruber
    On 26.03.19 15:24, Christofer Dutz wrote:
    
    Hi All,
    
    
    
    I would agree that a void type and exceptions would allow a more fine-grained reporting of what's going on.
    
    
    
    Sort of:
    
    - "Yeah ... I am a S7 400, but I don't support the S7-TIA protocol"
    
    - "No connection under this number" (no connection possible)
    
    - "You're not allowed to connect"
    
    - "Invalid credentials"
    
    - ...
    
    
    
    Maybe we should do that ASAP, adding it to the API, but have it report "Not Implemented" for now and to create JIRA tickets for the individual drivers ping implementations.
    
    
    
    Chris
    
    
    
    
    
    Am 26.03.19, 14:44 schrieb "Julian Feinauer" <j....@pragmaticminds.de>:
    
    
    
        Hi Gunther,
    
    
    
        thats really great to hear : )
    
        When I remember correctly the idea was...
    
    
    
        1. Extend the PlcConnection interface with a "ping()" method (Boolean? Throw Exception if not possible?)
    
        2. Implement the Ping functionality for each plc with a sensible "operation" (not sure what this could be for S7... read the SLZ or something?)
    
        3. Use this feature as "keep alive" e.g. for the PooledDriverManager
    
    
    
        does that make sense?
    
    
    
        Julian
    
    
    
        Am 26.03.19, 13:55 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:
    
    
    
            Sure I like to contribute. I guess by that you mean checking out the
    
            code and create a pull request with something working.
    
    
    
    
    
            I like your idear with the ping check. I will focus on implementing a
    
            function for the ping check, which can be reused later.
    
    
    
    
    
            Gunther
    
    
    
            > Hi Gunther,
    
            >
    
            > good catch : )
    
            > In fact, the isConnected() implementation is currently not soo god.
    
            > In fact it checks if the underlying communication channel from netty is connected (which does not know that it is disconnected yet, in your case).
    
            > We already had discussions to introduce a real "request" based implementation like "ping()" which sends a request.
    
            >
    
            > Furthermore, for your use case there is the PooledDriverManager which does implicitly what you do... throws away a not working connection and issues a new one, if needed, but that’s a separate topic.
    
            >
    
            > I think we should spend some effort into this "ping" functionality.
    
            > Perhaps you can even assist with the implementation Gunther, what do you think?
    
            >
    
            > Julian
    
            >
    
            > Am 26.03.19, 11:19 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:
    
            >
    
            >      Put it another way, isConnected does not work as i expect it
    
            >
    
            >      plcConnection.isConnected() returns true even when i disconnect the vpn (maybe of some tcp/ip keepalive?)
    
            >
    
            >      this is the snippet of code which i expect to work (instead of the thread which reconnects ever 10 minutes)
    
            >      while (doCollect) {
    
            >
    
            >        try {
    
            >          if (plcConnection == null || plcConnection.isConnected() == false) {
    
            >            plcConnection = initPLC(config.get(CONNECTION_KEY));
    
            >          }
    
            >        } catch (PlcConnectionException e) {
    
            >          logger.log(Level.WARNING, "error connecting with driver", e);
    
            >          plcConnection = null;
    
            >          incrementalSleep();
    
            >          break;
    
            >        }
    
            >
    
            >        // Create a new read request:
    
            >        // - Give the single item requested the alias name "value"
    
            >        PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
    
            >
    
            >      Gunther Gruber
    
            >
    
            >
    
            >
    
    


Re: Reconnect of driver 2

Posted by Gunther Gruber <gu...@IDA-Analytics.de>.
Hi Julian,

somhow my github account got flagged.

I append the two functions below, i think it will take some time for github to respond on the mail i wrote.


public boolean ping(String host, int port, int timeout) {
  Socket s = null;
  try {
    s = new Socket();
    s.connect(new InetSocketAddress(host, port), timeout);
    return true;
  } catch (Exception e) {
    return false;
  } finally {
    if (s != null) {
      try {
        s.close();
      } catch (Exception e) {
      }
    }
  }
}

private boolean channelPingCheck(int timeout) {
        String variable = "%M1.2:BOOL";
        return channelPingCheck(timeout, variable);
    }

    private boolean channelPingCheck(int timeout, String variable) {

//      String variable = "%M1.2:BOOL";

//      boolean expectedResult = true;

        try {
            plcConnection = getPlcConnection();
        } catch (PlcConnectionException e) {
            return false;
        }

        PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();

        builder.addItem(variable, variable);

        PlcReadRequest readRequest = builder.build();

        PlcReadResponse result = null;
        try {
            result = readRequest.execute().get(timeout, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } catch (ExecutionException | TimeoutException e) {
            return false;
        }

        if (result == null) {
            return false;
        }

        Object content;
        content = result.getObject(variable);
        if (content == null) {
            return false;
        }
        //we could compare against the real value of the object here, but then we need to be more specific about the variable type
        return true;

    }


On 28.03.19 14:49, Julian Feinauer wrote:

Hi Gunter,

very cool to hear... and I like your idea with the port... this is so simple and robust…
I wanted to check and review (and MERGE) your code but I did not find the PR.
Are you sure you made the PR towards apache/incubator-plc4x?

Best
Julian

Von: Gunther Gruber <gu...@IDA-Analytics.de>
Antworten an: "dev@plc4x.apache.org"<ma...@plc4x.apache.org> <de...@plc4x.apache.org>
Datum: Donnerstag, 28. März 2019 um 14:44
An: "dev@plc4x.apache.org"<ma...@plc4x.apache.org> <de...@plc4x.apache.org>
Betreff: Re: Reconnect of driver 2


Hi All,

i implemented two simple ping checks one specifically for s7 and one in generall to check reachability of a port. Which can simply be copied.

I also wrote a connection-manager which checks the connection and recreates it if neccessary.

Our szenario is that we want to read data in a loop and the higher the sampling frequency the better. I do not want to waste that on the "liveness" check of the connection. Best S7 could do is every 100ms i heared.

Also i load the driver for the s7 directly because in osgi the classloader stuff does not work.

I put my working code into examples/connection-manager and created a pull request. i did not grasp the code of PooledDriverManager in this short time to integrate. Feel free to adapt/change pieces of my code or give me feedback.

Gunther Gruber
On 26.03.19 15:24, Christofer Dutz wrote:

Hi All,



I would agree that a void type and exceptions would allow a more fine-grained reporting of what's going on.



Sort of:

- "Yeah ... I am a S7 400, but I don't support the S7-TIA protocol"

- "No connection under this number" (no connection possible)

- "You're not allowed to connect"

- "Invalid credentials"

- ...



Maybe we should do that ASAP, adding it to the API, but have it report "Not Implemented" for now and to create JIRA tickets for the individual drivers ping implementations.



Chris





Am 26.03.19, 14:44 schrieb "Julian Feinauer" <j....@pragmaticminds.de>:



    Hi Gunther,



    thats really great to hear : )

    When I remember correctly the idea was...



    1. Extend the PlcConnection interface with a "ping()" method (Boolean? Throw Exception if not possible?)

    2. Implement the Ping functionality for each plc with a sensible "operation" (not sure what this could be for S7... read the SLZ or something?)

    3. Use this feature as "keep alive" e.g. for the PooledDriverManager



    does that make sense?



    Julian



    Am 26.03.19, 13:55 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:



        Sure I like to contribute. I guess by that you mean checking out the

        code and create a pull request with something working.





        I like your idear with the ping check. I will focus on implementing a

        function for the ping check, which can be reused later.





        Gunther



        > Hi Gunther,

        >

        > good catch : )

        > In fact, the isConnected() implementation is currently not soo god.

        > In fact it checks if the underlying communication channel from netty is connected (which does not know that it is disconnected yet, in your case).

        > We already had discussions to introduce a real "request" based implementation like "ping()" which sends a request.

        >

        > Furthermore, for your use case there is the PooledDriverManager which does implicitly what you do... throws away a not working connection and issues a new one, if needed, but that’s a separate topic.

        >

        > I think we should spend some effort into this "ping" functionality.

        > Perhaps you can even assist with the implementation Gunther, what do you think?

        >

        > Julian

        >

        > Am 26.03.19, 11:19 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:

        >

        >      Put it another way, isConnected does not work as i expect it

        >

        >      plcConnection.isConnected() returns true even when i disconnect the vpn (maybe of some tcp/ip keepalive?)

        >

        >      this is the snippet of code which i expect to work (instead of the thread which reconnects ever 10 minutes)

        >      while (doCollect) {

        >

        >        try {

        >          if (plcConnection == null || plcConnection.isConnected() == false) {

        >            plcConnection = initPLC(config.get(CONNECTION_KEY));

        >          }

        >        } catch (PlcConnectionException e) {

        >          logger.log(Level.WARNING, "error connecting with driver", e);

        >          plcConnection = null;

        >          incrementalSleep();

        >          break;

        >        }

        >

        >        // Create a new read request:

        >        // - Give the single item requested the alias name "value"

        >        PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();

        >

        >      Gunther Gruber

        >

        >

        >


Re: Reconnect of driver 2

Posted by Julian Feinauer <j....@pragmaticminds.de>.
Hi Gunter,

very cool to hear... and I like your idea with the port... this is so simple and robust…
I wanted to check and review (and MERGE) your code but I did not find the PR.
Are you sure you made the PR towards apache/incubator-plc4x?

Best
Julian

Von: Gunther Gruber <gu...@IDA-Analytics.de>
Antworten an: "dev@plc4x.apache.org" <de...@plc4x.apache.org>
Datum: Donnerstag, 28. März 2019 um 14:44
An: "dev@plc4x.apache.org" <de...@plc4x.apache.org>
Betreff: Re: Reconnect of driver 2


Hi All,

i implemented two simple ping checks one specifically for s7 and one in generall to check reachability of a port. Which can simply be copied.

I also wrote a connection-manager which checks the connection and recreates it if neccessary.

Our szenario is that we want to read data in a loop and the higher the sampling frequency the better. I do not want to waste that on the "liveness" check of the connection. Best S7 could do is every 100ms i heared.

Also i load the driver for the s7 directly because in osgi the classloader stuff does not work.

I put my working code into examples/connection-manager and created a pull request. i did not grasp the code of PooledDriverManager in this short time to integrate. Feel free to adapt/change pieces of my code or give me feedback.

Gunther Gruber
On 26.03.19 15:24, Christofer Dutz wrote:

Hi All,



I would agree that a void type and exceptions would allow a more fine-grained reporting of what's going on.



Sort of:

- "Yeah ... I am a S7 400, but I don't support the S7-TIA protocol"

- "No connection under this number" (no connection possible)

- "You're not allowed to connect"

- "Invalid credentials"

- ...



Maybe we should do that ASAP, adding it to the API, but have it report "Not Implemented" for now and to create JIRA tickets for the individual drivers ping implementations.



Chris





Am 26.03.19, 14:44 schrieb "Julian Feinauer" <j....@pragmaticminds.de>:



    Hi Gunther,



    thats really great to hear : )

    When I remember correctly the idea was...



    1. Extend the PlcConnection interface with a "ping()" method (Boolean? Throw Exception if not possible?)

    2. Implement the Ping functionality for each plc with a sensible "operation" (not sure what this could be for S7... read the SLZ or something?)

    3. Use this feature as "keep alive" e.g. for the PooledDriverManager



    does that make sense?



    Julian



    Am 26.03.19, 13:55 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:



        Sure I like to contribute. I guess by that you mean checking out the

        code and create a pull request with something working.





        I like your idear with the ping check. I will focus on implementing a

        function for the ping check, which can be reused later.





        Gunther



        > Hi Gunther,

        >

        > good catch : )

        > In fact, the isConnected() implementation is currently not soo god.

        > In fact it checks if the underlying communication channel from netty is connected (which does not know that it is disconnected yet, in your case).

        > We already had discussions to introduce a real "request" based implementation like "ping()" which sends a request.

        >

        > Furthermore, for your use case there is the PooledDriverManager which does implicitly what you do... throws away a not working connection and issues a new one, if needed, but that’s a separate topic.

        >

        > I think we should spend some effort into this "ping" functionality.

        > Perhaps you can even assist with the implementation Gunther, what do you think?

        >

        > Julian

        >

        > Am 26.03.19, 11:19 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:

        >

        >      Put it another way, isConnected does not work as i expect it

        >

        >      plcConnection.isConnected() returns true even when i disconnect the vpn (maybe of some tcp/ip keepalive?)

        >

        >      this is the snippet of code which i expect to work (instead of the thread which reconnects ever 10 minutes)

        >      while (doCollect) {

        >

        >        try {

        >          if (plcConnection == null || plcConnection.isConnected() == false) {

        >            plcConnection = initPLC(config.get(CONNECTION_KEY));

        >          }

        >        } catch (PlcConnectionException e) {

        >          logger.log(Level.WARNING, "error connecting with driver", e);

        >          plcConnection = null;

        >          incrementalSleep();

        >          break;

        >        }

        >

        >        // Create a new read request:

        >        // - Give the single item requested the alias name "value"

        >        PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();

        >

        >      Gunther Gruber

        >

        >

        >










--


Gunther Gruber

Software Developer
[cid:part1.F5933BD1.9D08F9C5@ida-analytics.de]


Intelligent Data Analytics GmbH & Co. KG



c/o TechQuartier

Platz der Einheit 2

60327 Frankfurt

Telefon: +49 6421/4805274

Telefax: +49 6421/4805275

E-Mail: gunther.gruber@ida-analytics.de

Internet: www.ida-analytics.de<http://www.ida-analytics.de/>



Unternehmenssitz: Frankfurt am Main | Handelsregister beim Amtsgericht: Frankfurt am Main, Registernummer: HRA 49357 | USt. ID-Nr.: DE310205810 | Finanzamt: Frankfurt am Main

Persönlich haftende Gesellschafterin: IDA Intelligent Data Analytics GmbH | Sitz: Frankfurt am Main | Handelsregister beim Amtsgericht: Frankfurt am Main | Handelsregister-Nummer: HRB 106805 | Geschäftsführer: Mohamed Ayadi, Nils Björn Krugmann, Matthias Leinweber, Marc Seidemann

If you are not the addressee, please inform us immediately that you have received this e-mail by mistake, and delete it. We thank you for your support.

Re: Reconnect of driver 2

Posted by Gunther Gruber <gu...@IDA-Analytics.de>.
Hi All,

i implemented two simple ping checks one specifically for s7 and one in generall to check reachability of a port. Which can simply be copied.

I also wrote a connection-manager which checks the connection and recreates it if neccessary.

Our szenario is that we want to read data in a loop and the higher the sampling frequency the better. I do not want to waste that on the "liveness" check of the connection. Best S7 could do is every 100ms i heared.

Also i load the driver for the s7 directly because in osgi the classloader stuff does not work.

I put my working code into examples/connection-manager and created a pull request. i did not grasp the code of PooledDriverManager in this short time to integrate. Feel free to adapt/change pieces of my code or give me feedback.

Gunther Gruber

On 26.03.19 15:24, Christofer Dutz wrote:

Hi All,

I would agree that a void type and exceptions would allow a more fine-grained reporting of what's going on.

Sort of:
- "Yeah ... I am a S7 400, but I don't support the S7-TIA protocol"
- "No connection under this number" (no connection possible)
- "You're not allowed to connect"
- "Invalid credentials"
- ...

Maybe we should do that ASAP, adding it to the API, but have it report "Not Implemented" for now and to create JIRA tickets for the individual drivers ping implementations.

Chris


Am 26.03.19, 14:44 schrieb "Julian Feinauer" <j....@pragmaticminds.de>:

    Hi Gunther,

    thats really great to hear : )
    When I remember correctly the idea was...

    1. Extend the PlcConnection interface with a "ping()" method (Boolean? Throw Exception if not possible?)
    2. Implement the Ping functionality for each plc with a sensible "operation" (not sure what this could be for S7... read the SLZ or something?)
    3. Use this feature as "keep alive" e.g. for the PooledDriverManager

    does that make sense?

    Julian

    Am 26.03.19, 13:55 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:

        Sure I like to contribute. I guess by that you mean checking out the
        code and create a pull request with something working.


        I like your idear with the ping check. I will focus on implementing a
        function for the ping check, which can be reused later.


        Gunther

        > Hi Gunther,
        >
        > good catch : )
        > In fact, the isConnected() implementation is currently not soo god.
        > In fact it checks if the underlying communication channel from netty is connected (which does not know that it is disconnected yet, in your case).
        > We already had discussions to introduce a real "request" based implementation like "ping()" which sends a request.
        >
        > Furthermore, for your use case there is the PooledDriverManager which does implicitly what you do... throws away a not working connection and issues a new one, if needed, but that’s a separate topic.
        >
        > I think we should spend some effort into this "ping" functionality.
        > Perhaps you can even assist with the implementation Gunther, what do you think?
        >
        > Julian
        >
        > Am 26.03.19, 11:19 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:
        >
        >      Put it another way, isConnected does not work as i expect it
        >
        >      plcConnection.isConnected() returns true even when i disconnect the vpn (maybe of some tcp/ip keepalive?)
        >
        >      this is the snippet of code which i expect to work (instead of the thread which reconnects ever 10 minutes)
        >      while (doCollect) {
        >
        >        try {
        >          if (plcConnection == null || plcConnection.isConnected() == false) {
        >            plcConnection = initPLC(config.get(CONNECTION_KEY));
        >          }
        >        } catch (PlcConnectionException e) {
        >          logger.log(Level.WARNING, "error connecting with driver", e);
        >          plcConnection = null;
        >          incrementalSleep();
        >          break;
        >        }
        >
        >        // Create a new read request:
        >        // - Give the single item requested the alias name "value"
        >        PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
        >
        >      Gunther Gruber
        >
        >
        >







--

Gunther Gruber

Software Developer

[cid:part1.F5933BD1.9D08F9C5@ida-analytics.de]


Intelligent Data Analytics GmbH & Co. KG



c/o TechQuartier

Platz der Einheit 2

60327 Frankfurt

Telefon: +49 6421/4805274

Telefax: +49 6421/4805275

E-Mail: gunther.gruber@ida-analytics.de

Internet: www.ida-analytics.de<http://www.ida-analytics.de/>



Unternehmenssitz: Frankfurt am Main | Handelsregister beim Amtsgericht: Frankfurt am Main, Registernummer: HRA 49357 | USt. ID-Nr.: DE310205810 | Finanzamt: Frankfurt am Main

Persönlich haftende Gesellschafterin: IDA Intelligent Data Analytics GmbH | Sitz: Frankfurt am Main | Handelsregister beim Amtsgericht: Frankfurt am Main | Handelsregister-Nummer: HRB 106805 | Geschäftsführer: Mohamed Ayadi, Nils Björn Krugmann, Matthias Leinweber, Marc Seidemann

If you are not the addressee, please inform us immediately that you have received this e-mail by mistake, and delete it. We thank you for your support.

Re: Reconnect of driver 2

Posted by Christofer Dutz <ch...@c-ware.de>.
Hi All,

I would agree that a void type and exceptions would allow a more fine-grained reporting of what's going on.

Sort of:
- "Yeah ... I am a S7 400, but I don't support the S7-TIA protocol"
- "No connection under this number" (no connection possible)
- "You're not allowed to connect"
- "Invalid credentials"
- ...

Maybe we should do that ASAP, adding it to the API, but have it report "Not Implemented" for now and to create JIRA tickets for the individual drivers ping implementations.

Chris


Am 26.03.19, 14:44 schrieb "Julian Feinauer" <j....@pragmaticminds.de>:

    Hi Gunther,
    
    thats really great to hear : )
    When I remember correctly the idea was...
    
    1. Extend the PlcConnection interface with a "ping()" method (Boolean? Throw Exception if not possible?)
    2. Implement the Ping functionality for each plc with a sensible "operation" (not sure what this could be for S7... read the SLZ or something?)
    3. Use this feature as "keep alive" e.g. for the PooledDriverManager
    
    does that make sense?
    
    Julian
    
    Am 26.03.19, 13:55 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:
    
        Sure I like to contribute. I guess by that you mean checking out the 
        code and create a pull request with something working.
        
        
        I like your idear with the ping check. I will focus on implementing a 
        function for the ping check, which can be reused later.
        
        
        Gunther
        
        > Hi Gunther,
        >
        > good catch : )
        > In fact, the isConnected() implementation is currently not soo god.
        > In fact it checks if the underlying communication channel from netty is connected (which does not know that it is disconnected yet, in your case).
        > We already had discussions to introduce a real "request" based implementation like "ping()" which sends a request.
        >
        > Furthermore, for your use case there is the PooledDriverManager which does implicitly what you do... throws away a not working connection and issues a new one, if needed, but that’s a separate topic.
        >
        > I think we should spend some effort into this "ping" functionality.
        > Perhaps you can even assist with the implementation Gunther, what do you think?
        >
        > Julian
        >
        > Am 26.03.19, 11:19 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:
        >
        >      Put it another way, isConnected does not work as i expect it
        >      
        >      plcConnection.isConnected() returns true even when i disconnect the vpn (maybe of some tcp/ip keepalive?)
        >      
        >      this is the snippet of code which i expect to work (instead of the thread which reconnects ever 10 minutes)
        >      while (doCollect) {
        >      
        >        try {
        >          if (plcConnection == null || plcConnection.isConnected() == false) {
        >            plcConnection = initPLC(config.get(CONNECTION_KEY));
        >          }
        >        } catch (PlcConnectionException e) {
        >          logger.log(Level.WARNING, "error connecting with driver", e);
        >          plcConnection = null;
        >          incrementalSleep();
        >          break;
        >        }
        >      
        >        // Create a new read request:
        >        // - Give the single item requested the alias name "value"
        >        PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
        >      
        >      Gunther Gruber
        >      
        >      
        >
        
        
    
    


Re: Reconnect of driver 2

Posted by Julian Feinauer <j....@pragmaticminds.de>.
Hi Gunther,

thats really great to hear : )
When I remember correctly the idea was...

1. Extend the PlcConnection interface with a "ping()" method (Boolean? Throw Exception if not possible?)
2. Implement the Ping functionality for each plc with a sensible "operation" (not sure what this could be for S7... read the SLZ or something?)
3. Use this feature as "keep alive" e.g. for the PooledDriverManager

does that make sense?

Julian

Am 26.03.19, 13:55 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:

    Sure I like to contribute. I guess by that you mean checking out the 
    code and create a pull request with something working.
    
    
    I like your idear with the ping check. I will focus on implementing a 
    function for the ping check, which can be reused later.
    
    
    Gunther
    
    > Hi Gunther,
    >
    > good catch : )
    > In fact, the isConnected() implementation is currently not soo god.
    > In fact it checks if the underlying communication channel from netty is connected (which does not know that it is disconnected yet, in your case).
    > We already had discussions to introduce a real "request" based implementation like "ping()" which sends a request.
    >
    > Furthermore, for your use case there is the PooledDriverManager which does implicitly what you do... throws away a not working connection and issues a new one, if needed, but that’s a separate topic.
    >
    > I think we should spend some effort into this "ping" functionality.
    > Perhaps you can even assist with the implementation Gunther, what do you think?
    >
    > Julian
    >
    > Am 26.03.19, 11:19 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:
    >
    >      Put it another way, isConnected does not work as i expect it
    >      
    >      plcConnection.isConnected() returns true even when i disconnect the vpn (maybe of some tcp/ip keepalive?)
    >      
    >      this is the snippet of code which i expect to work (instead of the thread which reconnects ever 10 minutes)
    >      while (doCollect) {
    >      
    >        try {
    >          if (plcConnection == null || plcConnection.isConnected() == false) {
    >            plcConnection = initPLC(config.get(CONNECTION_KEY));
    >          }
    >        } catch (PlcConnectionException e) {
    >          logger.log(Level.WARNING, "error connecting with driver", e);
    >          plcConnection = null;
    >          incrementalSleep();
    >          break;
    >        }
    >      
    >        // Create a new read request:
    >        // - Give the single item requested the alias name "value"
    >        PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
    >      
    >      Gunther Gruber
    >      
    >      
    >
    
    


Re: Reconnect of driver 2

Posted by Gunther Gruber <gu...@IDA-Analytics.de>.
Sure I like to contribute. I guess by that you mean checking out the 
code and create a pull request with something working.


I like your idear with the ping check. I will focus on implementing a 
function for the ping check, which can be reused later.


Gunther

> Hi Gunther,
>
> good catch : )
> In fact, the isConnected() implementation is currently not soo god.
> In fact it checks if the underlying communication channel from netty is connected (which does not know that it is disconnected yet, in your case).
> We already had discussions to introduce a real "request" based implementation like "ping()" which sends a request.
>
> Furthermore, for your use case there is the PooledDriverManager which does implicitly what you do... throws away a not working connection and issues a new one, if needed, but that’s a separate topic.
>
> I think we should spend some effort into this "ping" functionality.
> Perhaps you can even assist with the implementation Gunther, what do you think?
>
> Julian
>
> Am 26.03.19, 11:19 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:
>
>      Put it another way, isConnected does not work as i expect it
>      
>      plcConnection.isConnected() returns true even when i disconnect the vpn (maybe of some tcp/ip keepalive?)
>      
>      this is the snippet of code which i expect to work (instead of the thread which reconnects ever 10 minutes)
>      while (doCollect) {
>      
>        try {
>          if (plcConnection == null || plcConnection.isConnected() == false) {
>            plcConnection = initPLC(config.get(CONNECTION_KEY));
>          }
>        } catch (PlcConnectionException e) {
>          logger.log(Level.WARNING, "error connecting with driver", e);
>          plcConnection = null;
>          incrementalSleep();
>          break;
>        }
>      
>        // Create a new read request:
>        // - Give the single item requested the alias name "value"
>        PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
>      
>      Gunther Gruber
>      
>      
>


Re: Reconnect of driver 2

Posted by Christofer Dutz <ch...@c-ware.de>.
Hi all,

yes definitely a "ping" is needed ... especially as this way we can really start to do some "autodiscover" stuff ...
Sort of giving PLC4X just an IP address and it listing up drivers in the classpath that are able to communicate with that device.
Would definitely ease the setup process dramatically.

Chris



Am 26.03.19, 12:13 schrieb "Julian Feinauer" <j....@pragmaticminds.de>:

    Hi Gunther,
    
    good catch : )
    In fact, the isConnected() implementation is currently not soo god.
    In fact it checks if the underlying communication channel from netty is connected (which does not know that it is disconnected yet, in your case).
    We already had discussions to introduce a real "request" based implementation like "ping()" which sends a request.
    
    Furthermore, for your use case there is the PooledDriverManager which does implicitly what you do... throws away a not working connection and issues a new one, if needed, but that’s a separate topic.
    
    I think we should spend some effort into this "ping" functionality.
    Perhaps you can even assist with the implementation Gunther, what do you think?
    
    Julian
    
    Am 26.03.19, 11:19 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:
    
        Put it another way, isConnected does not work as i expect it
        
        plcConnection.isConnected() returns true even when i disconnect the vpn (maybe of some tcp/ip keepalive?)
        
        this is the snippet of code which i expect to work (instead of the thread which reconnects ever 10 minutes)
        while (doCollect) {
        
          try {
            if (plcConnection == null || plcConnection.isConnected() == false) {
              plcConnection = initPLC(config.get(CONNECTION_KEY));
            }
          } catch (PlcConnectionException e) {
            logger.log(Level.WARNING, "error connecting with driver", e);
            plcConnection = null;
            incrementalSleep();
            break;
          }
        
          // Create a new read request:
          // - Give the single item requested the alias name "value"
          PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
        
        Gunther Gruber
        
        
    
    


Re: Reconnect of driver 2

Posted by Julian Feinauer <j....@pragmaticminds.de>.
Hi Gunther,

good catch : )
In fact, the isConnected() implementation is currently not soo god.
In fact it checks if the underlying communication channel from netty is connected (which does not know that it is disconnected yet, in your case).
We already had discussions to introduce a real "request" based implementation like "ping()" which sends a request.

Furthermore, for your use case there is the PooledDriverManager which does implicitly what you do... throws away a not working connection and issues a new one, if needed, but that’s a separate topic.

I think we should spend some effort into this "ping" functionality.
Perhaps you can even assist with the implementation Gunther, what do you think?

Julian

Am 26.03.19, 11:19 schrieb "Gunther Gruber" <gu...@IDA-Analytics.de>:

    Put it another way, isConnected does not work as i expect it
    
    plcConnection.isConnected() returns true even when i disconnect the vpn (maybe of some tcp/ip keepalive?)
    
    this is the snippet of code which i expect to work (instead of the thread which reconnects ever 10 minutes)
    while (doCollect) {
    
      try {
        if (plcConnection == null || plcConnection.isConnected() == false) {
          plcConnection = initPLC(config.get(CONNECTION_KEY));
        }
      } catch (PlcConnectionException e) {
        logger.log(Level.WARNING, "error connecting with driver", e);
        plcConnection = null;
        incrementalSleep();
        break;
      }
    
      // Create a new read request:
      // - Give the single item requested the alias name "value"
      PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
    
    Gunther Gruber
    
    


Reconnect of driver 2

Posted by Gunther Gruber <gu...@IDA-Analytics.de>.
Put it another way, isConnected does not work as i expect it

plcConnection.isConnected() returns true even when i disconnect the vpn (maybe of some tcp/ip keepalive?)

this is the snippet of code which i expect to work (instead of the thread which reconnects ever 10 minutes)
while (doCollect) {

  try {
    if (plcConnection == null || plcConnection.isConnected() == false) {
      plcConnection = initPLC(config.get(CONNECTION_KEY));
    }
  } catch (PlcConnectionException e) {
    logger.log(Level.WARNING, "error connecting with driver", e);
    plcConnection = null;
    incrementalSleep();
    break;
  }

  // Create a new read request:
  // - Give the single item requested the alias name "value"
  PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();

Gunther Gruber


Re: Please don't commit or push anything ... We're working on the syncing of pull requests

Posted by Christofer Dutz <ch...@c-ware.de>.
Hi all,

so we tried a lot of different things ... in the end we deleted gitbox and re-clonned from github as infra didn't have any more clues as to what was causing the problems.
Now things should work again ... so feel free to push and from now on it shouldn't matter if you push to github or gitbox and merging PRs in the GitHub web-ui should be fine also.

Now I have to finish some not quite working stuff in the cpp maven build as I had to comit something that wasn't done to produce a new PR ;-)

So all keep your fingers crossed and:
https://www.youtube.com/watch?v=vCadcBR95oU

Chris



Am 22.03.19, 08:47 schrieb "Christofer Dutz" <ch...@c-ware.de>:

    We're working with infra to get the sync work in the direction from GitHub ... So please don't do any commits and especially no pushing for now.
    
    I'll inform you as soon as we can continue.
    
    https://issues.apache.org/jira/plugins/servlet/mobile#issue/INFRA-18056
    
    
    Chris
    
    Outlook für Android<https://aka.ms/ghei36> herunterladen