This is an automated email from the ASF dual-hosted git repository.

jfeinauer pushed a commit to branch feature/PLC4X-111-interop-server
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git

commit 11b7f14f905c42a506de99c0e12defd82cbe6863
Author: julian <[email protected]>
AuthorDate: Sun Apr 21 13:45:50 2019 +0200

    PLC4X-111 Imported Python support for the Interop Server. Currently 
possible for S7.
---
 plc4j/utils/interop/pom.xml                        |  63 ++-
 .../org/apache/plc4x/interop/impl/Handler.java     |   6 +-
 .../java/org/apache/plc4x/interop/impl/Server.java |  58 +-
 plc4py/__init__.py                                 |   0
 plc4py/copy_server.sh                              |   4 +
 plc4py/generate_thrift.sh                          |   8 +
 plc4py/lib/log4j2.xml                              |  13 +
 plc4py/org/__init__.py                             |   0
 plc4py/org/apache/__init__.py                      |   0
 plc4py/org/apache/plc4x/InteropClient.py           |  29 +
 plc4py/org/apache/plc4x/PlcConnection.py           |  58 ++
 plc4py/org/apache/plc4x/PlcDriverManager.py        |  62 +++
 plc4py/org/apache/plc4x/__init__.py                |   0
 .../org/apache/plc4x/interop/InteropServer-remote  |  99 ++++
 plc4py/org/apache/plc4x/interop/InteropServer.py   | 593 +++++++++++++++++++++
 plc4py/org/apache/plc4x/interop/__init__.py        |   1 +
 plc4py/org/apache/plc4x/interop/constants.py       |   9 +
 plc4py/org/apache/plc4x/interop/ttypes.py          | 429 +++++++++++++++
 plc4py/test/__init__.py                            |   0
 plc4py/test/test_PlcDriverManager.py               |  95 ++++
 20 files changed, 1489 insertions(+), 38 deletions(-)

diff --git a/plc4j/utils/interop/pom.xml b/plc4j/utils/interop/pom.xml
index 41136de..7aa8957 100644
--- a/plc4j/utils/interop/pom.xml
+++ b/plc4j/utils/interop/pom.xml
@@ -21,26 +21,73 @@
       <groupId>org.apache.plc4x</groupId>
       <artifactId>plc4j-api</artifactId>
       <version>0.4.0-SNAPSHOT</version>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.plc4x</groupId>
-      <artifactId>plc4j-protocol-driver-base-test</artifactId>
-      <version>0.4.0-SNAPSHOT</version>
     </dependency>
+<!--    <dependency>-->
+<!--      <groupId>org.apache.plc4x</groupId>-->
+<!--      <artifactId>plc4j-protocol-driver-base-test</artifactId>-->
+<!--      <version>0.4.0-SNAPSHOT</version>-->
+<!--    </dependency>-->
     <dependency>
       <groupId>org.apache.plc4x</groupId>
       <artifactId>plc4j-driver-s7</artifactId>
       <version>0.4.0-SNAPSHOT</version>
-      <scope>runtime</scope>
+      <scope>compile</scope>
     </dependency>
     <dependency>
       <groupId>commons-lang</groupId>
       <artifactId>commons-lang</artifactId>
       <version>20030203.000129</version>
-      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-slf4j-impl</artifactId>
+      <version>2.11.2</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-api</artifactId>
+      <version>2.11.2</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-core</artifactId>
+      <version>2.11.2</version>
     </dependency>
   </dependencies>
 
+  <build>
+    <plugins>
+      <!-- Create a fat jar -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <version>2.4.1</version>
+        <configuration>
+          <!-- get all project dependencies -->
+          <descriptorRefs>
+            <descriptorRef>jar-with-dependencies</descriptorRef>
+          </descriptorRefs>
+          <!-- MainClass in mainfest make a executable jar -->
+          <archive>
+            <manifest>
+              <mainClass>org.apache.plc4x.interop.impl.Server</mainClass>
+            </manifest>
+          </archive>
+
+        </configuration>
+        <executions>
+          <execution>
+            <id>make-assembly</id>
+            <!-- bind to the packaging phase -->
+            <phase>package</phase>
+            <goals>
+              <goal>single</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
 
 </project>
\ No newline at end of file
diff --git 
a/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/impl/Handler.java 
b/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/impl/Handler.java
index 02ed94d..7d1e111 100644
--- 
a/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/impl/Handler.java
+++ 
b/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/impl/Handler.java
@@ -63,11 +63,15 @@ public class Handler implements InteropServer.Iface {
 
     @Override public void close(ConnectionHandle handle) throws TException {
         LOGGER.debug("Receiving new close request for handle {}", 
handle.getConnectionId());
+        if (!connections.containsKey(handle)) {
+            LOGGER.warn("Handle for close request {} does not exist. Perhaps 
already closed?", handle.getConnectionId());
+            return;
+        }
         try {
             connections.get(handle).close();
             connections.remove(handle);
         } catch (Exception e) {
-            e.printStackTrace();
+            LOGGER.warn("Unable to close the conn / remove the handle", e);
         }
 
     }
diff --git 
a/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/impl/Server.java 
b/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/impl/Server.java
index 01274ae..e697c2b 100644
--- 
a/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/impl/Server.java
+++ 
b/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/impl/Server.java
@@ -10,8 +10,8 @@ import org.apache.plc4x.java.api.model.PlcSubscriptionHandle;
 import org.apache.plc4x.java.api.types.PlcResponseCode;
 import org.apache.plc4x.java.base.messages.items.BaseDefaultFieldItem;
 import org.apache.plc4x.java.base.messages.items.DefaultLongFieldItem;
-import org.apache.plc4x.java.mock.MockDevice;
-import org.apache.plc4x.java.mock.PlcMockConnection;
+//import org.apache.plc4x.java.mock.MockDevice;
+//import org.apache.plc4x.java.mock.PlcMockConnection;
 import org.apache.thrift.server.TServer;
 import org.apache.thrift.server.TSimpleServer;
 import org.apache.thrift.transport.TServerSocket;
@@ -26,9 +26,9 @@ public class Server {
         final PlcDriverManager driverManager = new PlcDriverManager();
 
         // Do some mocking
-        final PlcMockConnection mockConnection = (PlcMockConnection) 
driverManager.getConnection("mock:a");
+//        final PlcMockConnection mockConnection = (PlcMockConnection) 
driverManager.getConnection("mock:a");
 
-        mockConnection.setDevice(new MyMockDevice());
+//        mockConnection.setDevice(new MyMockDevice());
 
         final Handler handler = new Handler(driverManager);
         final InteropServer.Processor<Handler> processor = new 
InteropServer.Processor<>(handler);
@@ -44,29 +44,29 @@ public class Server {
         }
     }
 
-    private static class MyMockDevice implements MockDevice {
-        @Override public Pair<PlcResponseCode, BaseDefaultFieldItem> 
read(String fieldQuery) {
-            return Pair.of(PlcResponseCode.OK, new DefaultLongFieldItem(100L));
-        }
-
-        @Override public PlcResponseCode write(String fieldQuery, Object 
value) {
-            return null;
-        }
-
-        @Override public Pair<PlcResponseCode, PlcSubscriptionHandle> 
subscribe(String fieldQuery) {
-            return null;
-        }
-
-        @Override public void unsubscribe() {
-
-        }
-
-        @Override public PlcConsumerRegistration 
register(Consumer<PlcSubscriptionEvent> consumer, 
Collection<PlcSubscriptionHandle> handles) {
-            return null;
-        }
-
-        @Override public void unregister(PlcConsumerRegistration registration) 
{
-
-        }
-    }
+//    private static class MyMockDevice implements MockDevice {
+//        @Override public Pair<PlcResponseCode, BaseDefaultFieldItem> 
read(String fieldQuery) {
+//            return Pair.of(PlcResponseCode.OK, new 
DefaultLongFieldItem(100L));
+//        }
+//
+//        @Override public PlcResponseCode write(String fieldQuery, Object 
value) {
+//            return null;
+//        }
+//
+//        @Override public Pair<PlcResponseCode, PlcSubscriptionHandle> 
subscribe(String fieldQuery) {
+//            return null;
+//        }
+//
+//        @Override public void unsubscribe() {
+//
+//        }
+//
+//        @Override public PlcConsumerRegistration 
register(Consumer<PlcSubscriptionEvent> consumer, 
Collection<PlcSubscriptionHandle> handles) {
+//            return null;
+//        }
+//
+//        @Override public void unregister(PlcConsumerRegistration 
registration) {
+//
+//        }
+//    }
 }
diff --git a/plc4py/__init__.py b/plc4py/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/plc4py/copy_server.sh b/plc4py/copy_server.sh
new file mode 100755
index 0000000..57f7f27
--- /dev/null
+++ b/plc4py/copy_server.sh
@@ -0,0 +1,4 @@
+#!/usr/bin/env bash
+
+# Moves the server from the target folder here
+cp ../plc4j/utils/interop/target/apache-plc4x-incubating-* lib/
\ No newline at end of file
diff --git a/plc4py/generate_thrift.sh b/plc4py/generate_thrift.sh
new file mode 100644
index 0000000..d687fa7
--- /dev/null
+++ b/plc4py/generate_thrift.sh
@@ -0,0 +1,8 @@
+#!/usr/bin/env bash
+
+# Requires thrift 0.12.0
+# Generates the "generated" files in the right dir structure
+
+# Please be cautious with this, as there was some manual fixing necessary to 
get everything running (for me at least)
+
+thrift --gen py:python3 -out ./ 
../plc4j/utils/interop/src/main/thrift/interop.thrift
\ No newline at end of file
diff --git a/plc4py/lib/log4j2.xml b/plc4py/lib/log4j2.xml
new file mode 100644
index 0000000..c537397
--- /dev/null
+++ b/plc4py/lib/log4j2.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration>
+    <Appenders>
+        <Console name="Console" target="SYSTEM_OUT">
+            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} 
- %msg%n"/>
+        </Console>
+    </Appenders>
+    <Loggers>
+        <Root level="WARN">
+            <AppenderRef ref="Console"/>
+        </Root>
+    </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/plc4py/org/__init__.py b/plc4py/org/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/plc4py/org/apache/__init__.py b/plc4py/org/apache/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/plc4py/org/apache/plc4x/InteropClient.py 
b/plc4py/org/apache/plc4x/InteropClient.py
new file mode 100644
index 0000000..6ac1073
--- /dev/null
+++ b/plc4py/org/apache/plc4x/InteropClient.py
@@ -0,0 +1,29 @@
+from thrift.protocol import TBinaryProtocol
+from thrift.transport import TSocket, TTransport
+from thrift.transport.TTransport import TTransportException
+
+from org.apache.plc4x.interop.InteropServer import Client, PlcException
+from org.apache.plc4x.interop.ttypes import Request
+
+transport = TSocket.TSocket('localhost', 9090)
+transport = TTransport.TBufferedTransport(transport)
+protocol = TBinaryProtocol.TBinaryProtocol(transport)
+
+client = Client(protocol)
+
+try:
+    transport.open()
+    connect = None
+    try:
+        connect = client.connect("mock:a")
+
+        res = client.execute(connect, Request(fields={"field1": "asdf"}))
+
+        print(res)
+    finally:
+        if connect is not None:
+            client.close(connect)
+except TTransportException:
+    print("Unable to connect to the Interop Server, is the Server really 
running???")
+finally:
+    transport.close()
diff --git a/plc4py/org/apache/plc4x/PlcConnection.py 
b/plc4py/org/apache/plc4x/PlcConnection.py
new file mode 100644
index 0000000..010187e
--- /dev/null
+++ b/plc4py/org/apache/plc4x/PlcConnection.py
@@ -0,0 +1,58 @@
+from org.apache.plc4x.interop.ttypes import PlcException, FieldResponse
+
+
+class PlcConnection:
+
+    def __init__(self, client, url):
+        self.client = client
+        # Try to get a handle
+        try:
+            self.handle = self.client.connect(url)
+        except:
+            raise PlcException("Unable to connect to the given url " + url)
+
+    def execute(self, request):
+        response = self.client.execute(self.handle, request)
+        return PlcResponse(response)
+
+    def close(self):
+        self.client.close(self.handle)
+
+
+class PlcResponse:
+    fields: dict
+
+    def __init__(self, response):
+        self.fields = response.fields
+
+    def get_fields(self):
+        return list(self.fields.keys())
+
+    def get_field(self, field_name):
+        if field_name in self.fields:
+            return PlcResponseItem(self.fields.get(field_name))
+        else:
+            raise Exception("A field with name '" + field_name + "' is not 
contained in the response");
+
+
+class PlcResponseItem:
+
+    fieldResponse: FieldResponse
+
+    def __init__(self, fieldResponse):
+        self.fieldResponse = fieldResponse
+
+    def get_response_code(self):
+        return self.fieldResponse.responseCode
+
+    def get_int_value(self):
+        return self.fieldResponse.longValue
+
+    def get_bool_value(self):
+        return self.fieldResponse.boolValue
+
+    def get_double_value(self):
+        return self.fieldResponse.doubleValue
+
+    def get_string_value(self):
+        return self.fieldResponse.stringValue
\ No newline at end of file
diff --git a/plc4py/org/apache/plc4x/PlcDriverManager.py 
b/plc4py/org/apache/plc4x/PlcDriverManager.py
new file mode 100644
index 0000000..14557fc
--- /dev/null
+++ b/plc4py/org/apache/plc4x/PlcDriverManager.py
@@ -0,0 +1,62 @@
+import subprocess
+import time
+import warnings
+
+from thrift.protocol import TBinaryProtocol
+from thrift.transport import TSocket, TTransport
+from thrift.transport.TTransport import TTransportException
+
+from org.apache.plc4x.PlcConnection import PlcConnection
+from org.apache.plc4x.interop.InteropServer import Client, PlcException
+
+
+class PlcDriverManager:
+
+    """
+    constructor, initialize the server
+    """
+    def __init__(self, embedded_server=True):
+        self.embedded_server = embedded_server
+        # Start the Server in the background
+        if embedded_server:
+            self.interop_proc = subprocess.Popen(
+                ["java", "-Dlog4j.configurationFile=../lib/log4j2.xml",
+                 "-jar", 
"../lib/apache-plc4x-incubating-0.4.0-SNAPSHOT-jar-with-dependencies.jar"])
+            try:
+                print("Started server under pid " + str(self.interop_proc.pid))
+            except:
+                print("Encountered an Exception while starting Interop Server")
+                raise PlcException("Unable to start the Interop Server!")
+
+            time.sleep(2)
+            poll = self.interop_proc.poll()
+            if poll is None:
+                print("Sucesfully started the Interop Server...")
+            else:
+                warnings.warn("Interop Server died after starting up...")
+                raise PlcException(
+                    "Unable to start the Interop Server. Is another Server 
still running under the same port?")
+
+        self.transport = TSocket.TSocket('localhost', 9090)
+        self.transport = TTransport.TBufferedTransport(self.transport)
+
+        self.protocol = TBinaryProtocol.TBinaryProtocol(self.transport)
+
+        try:
+            self.transport.open()
+        except TTransportException:
+            raise PlcException("Unable to connect to the Interop Server, is 
the Server really running???")
+
+    def _get_client(self):
+        return Client(self.protocol)
+
+    def get_connection(self, url):
+        return PlcConnection(self._get_client(), url)
+
+    def close(self):
+        print("Closing the Interop Server")
+        try:
+            self.transport.close()
+        finally:
+            if self.embedded_server:
+                self.interop_proc.terminate()
diff --git a/plc4py/org/apache/plc4x/__init__.py 
b/plc4py/org/apache/plc4x/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/plc4py/org/apache/plc4x/interop/InteropServer-remote 
b/plc4py/org/apache/plc4x/interop/InteropServer-remote
new file mode 100755
index 0000000..1f8f8c2
--- /dev/null
+++ b/plc4py/org/apache/plc4x/interop/InteropServer-remote
@@ -0,0 +1,99 @@
+#!/usr/bin/env python
+#
+# Autogenerated by Thrift Compiler (0.7.0)
+#
+# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+#
+
+import sys
+import pprint
+from urlparse import urlparse
+from thrift.transport import TTransport
+from thrift.transport import TSocket
+from thrift.transport import THttpClient
+from thrift.protocol import TBinaryProtocol
+
+import InteropServer
+from ttypes import *
+
+if len(sys.argv) <= 1 or sys.argv[1] == '--help':
+  print ''
+  print 'Usage: ' + sys.argv[0] + ' [-h host:port] [-u url] [-f[ramed]] 
function [arg1 [arg2...]]'
+  print ''
+  print 'Functions:'
+  print '  ConnectionHandle connect(string connectionString)'
+  print '  Response execute(ConnectionHandle handle, Request request)'
+  print '  void close(ConnectionHandle handle)'
+  print ''
+  sys.exit(0)
+
+pp = pprint.PrettyPrinter(indent = 2)
+host = 'localhost'
+port = 9090
+uri = ''
+framed = False
+http = False
+argi = 1
+
+if sys.argv[argi] == '-h':
+  parts = sys.argv[argi+1].split(':')
+  host = parts[0]
+  port = int(parts[1])
+  argi += 2
+
+if sys.argv[argi] == '-u':
+  url = urlparse(sys.argv[argi+1])
+  parts = url[1].split(':')
+  host = parts[0]
+  if len(parts) > 1:
+    port = int(parts[1])
+  else:
+    port = 80
+  uri = url[2]
+  if url[4]:
+    uri += '?%s' % url[4]
+  http = True
+  argi += 2
+
+if sys.argv[argi] == '-f' or sys.argv[argi] == '-framed':
+  framed = True
+  argi += 1
+
+cmd = sys.argv[argi]
+args = sys.argv[argi+1:]
+
+if http:
+  transport = THttpClient.THttpClient(host, port, uri)
+else:
+  socket = TSocket.TSocket(host, port)
+  if framed:
+    transport = TTransport.TFramedTransport(socket)
+  else:
+    transport = TTransport.TBufferedTransport(socket)
+protocol = TBinaryProtocol.TBinaryProtocol(transport)
+client = InteropServer.Client(protocol)
+transport.open()
+
+if cmd == 'connect':
+  if len(args) != 1:
+    print 'connect requires 1 args'
+    sys.exit(1)
+  pp.pprint(client.connect(args[0],))
+
+elif cmd == 'execute':
+  if len(args) != 2:
+    print 'execute requires 2 args'
+    sys.exit(1)
+  pp.pprint(client.execute(eval(args[0]),eval(args[1]),))
+
+elif cmd == 'close':
+  if len(args) != 1:
+    print 'close requires 1 args'
+    sys.exit(1)
+  pp.pprint(client.close(eval(args[0]),))
+
+else:
+  print 'Unrecognized method %s' % cmd
+  sys.exit(1)
+
+transport.close()
diff --git a/plc4py/org/apache/plc4x/interop/InteropServer.py 
b/plc4py/org/apache/plc4x/interop/InteropServer.py
new file mode 100644
index 0000000..a1d646e
--- /dev/null
+++ b/plc4py/org/apache/plc4x/interop/InteropServer.py
@@ -0,0 +1,593 @@
+#
+# Autogenerated by Thrift Compiler (0.7.0)
+#
+# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+#
+
+from thrift.Thrift import *
+from org.apache.plc4x.interop.ttypes import *
+from thrift.Thrift import TProcessor
+from thrift.transport import TTransport
+from thrift.protocol import TBinaryProtocol, TProtocol
+
+from org.apache.plc4x.interop.ttypes import PlcException, ConnectionHandle, 
Request
+
+try:
+  from thrift.protocol import fastbinary
+except:
+  fastbinary = None
+
+
+class Iface:
+  def connect(self, connectionString):
+    """
+    Parameters:
+     - connectionString
+    """
+    pass
+
+  def execute(self, handle, request):
+    """
+    Parameters:
+     - handle
+     - request
+    """
+    pass
+
+  def close(self, handle):
+    """
+    Parameters:
+     - handle
+    """
+    pass
+
+
+class Client(Iface):
+  def __init__(self, iprot, oprot=None):
+    self._iprot = self._oprot = iprot
+    if oprot is not None:
+      self._oprot = oprot
+    self._seqid = 0
+
+  def connect(self, connectionString):
+    """
+    Parameters:
+     - connectionString
+    """
+    self.send_connect(connectionString)
+    return self.recv_connect()
+
+  def send_connect(self, connectionString):
+    self._oprot.writeMessageBegin('connect', TMessageType.CALL, self._seqid)
+    args = connect_args()
+    args.connectionString = connectionString
+    args.write(self._oprot)
+    self._oprot.writeMessageEnd()
+    self._oprot.trans.flush()
+
+  def recv_connect(self, ):
+    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    if mtype == TMessageType.EXCEPTION:
+      x = TApplicationException()
+      x.read(self._iprot)
+      self._iprot.readMessageEnd()
+      raise x
+    result = connect_result()
+    result.read(self._iprot)
+    self._iprot.readMessageEnd()
+    if result.success is not None:
+      return result.success
+    if result.connectionException is not None:
+      raise result.connectionException
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "connect 
failed: unknown result");
+
+  def execute(self, handle, request):
+    """
+    Parameters:
+     - handle
+     - request
+    """
+    self.send_execute(handle, request)
+    return self.recv_execute()
+
+  def send_execute(self, handle, request):
+    self._oprot.writeMessageBegin('execute', TMessageType.CALL, self._seqid)
+    args = execute_args()
+    args.handle = handle
+    args.request = request
+    args.write(self._oprot)
+    self._oprot.writeMessageEnd()
+    self._oprot.trans.flush()
+
+  def recv_execute(self, ):
+    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    if mtype == TMessageType.EXCEPTION:
+      x = TApplicationException()
+      x.read(self._iprot)
+      self._iprot.readMessageEnd()
+      raise x
+    result = execute_result()
+    result.read(self._iprot)
+    self._iprot.readMessageEnd()
+    if result.success is not None:
+      return result.success
+    if result.executionException is not None:
+      raise result.executionException
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "execute 
failed: unknown result");
+
+  def close(self, handle):
+    """
+    Parameters:
+     - handle
+    """
+    self.send_close(handle)
+    self.recv_close()
+
+  def send_close(self, handle):
+    self._oprot.writeMessageBegin('close', TMessageType.CALL, self._seqid)
+    args = close_args()
+    args.handle = handle
+    args.write(self._oprot)
+    self._oprot.writeMessageEnd()
+    self._oprot.trans.flush()
+
+  def recv_close(self, ):
+    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    if mtype == TMessageType.EXCEPTION:
+      x = TApplicationException()
+      x.read(self._iprot)
+      self._iprot.readMessageEnd()
+      raise x
+    result = close_result()
+    result.read(self._iprot)
+    self._iprot.readMessageEnd()
+    return
+
+
+class Processor(Iface, TProcessor):
+  def __init__(self, handler):
+    self._handler = handler
+    self._processMap = {}
+    self._processMap["connect"] = Processor.process_connect
+    self._processMap["execute"] = Processor.process_execute
+    self._processMap["close"] = Processor.process_close
+
+  def process(self, iprot, oprot):
+    (name, type, seqid) = iprot.readMessageBegin()
+    if name not in self._processMap:
+      iprot.skip(TType.STRUCT)
+      iprot.readMessageEnd()
+      x = TApplicationException(TApplicationException.UNKNOWN_METHOD, 'Unknown 
function %s' % (name))
+      oprot.writeMessageBegin(name, TMessageType.EXCEPTION, seqid)
+      x.write(oprot)
+      oprot.writeMessageEnd()
+      oprot.trans.flush()
+      return
+    else:
+      self._processMap[name](self, seqid, iprot, oprot)
+    return True
+
+  def process_connect(self, seqid, iprot, oprot):
+    args = connect_args()
+    args.read(iprot)
+    iprot.readMessageEnd()
+    result = connect_result()
+    try:
+      result.success = self._handler.connect(args.connectionString)
+    except PlcException as connectionException:
+      result.connectionException = connectionException
+    oprot.writeMessageBegin("connect", TMessageType.REPLY, seqid)
+    result.write(oprot)
+    oprot.writeMessageEnd()
+    oprot.trans.flush()
+
+  def process_execute(self, seqid, iprot, oprot):
+    args = execute_args()
+    args.read(iprot)
+    iprot.readMessageEnd()
+    result = execute_result()
+    try:
+      result.success = self._handler.execute(args.handle, args.request)
+    except PlcException as executionException:
+      result.executionException = executionException
+    oprot.writeMessageBegin("execute", TMessageType.REPLY, seqid)
+    result.write(oprot)
+    oprot.writeMessageEnd()
+    oprot.trans.flush()
+
+  def process_close(self, seqid, iprot, oprot):
+    args = close_args()
+    args.read(iprot)
+    iprot.readMessageEnd()
+    result = close_result()
+    self._handler.close(args.handle)
+    oprot.writeMessageBegin("close", TMessageType.REPLY, seqid)
+    result.write(oprot)
+    oprot.writeMessageEnd()
+    oprot.trans.flush()
+
+
+# HELPER FUNCTIONS AND STRUCTURES
+
+class connect_args:
+  """
+  Attributes:
+   - connectionString
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRING, 'connectionString', None, None, ), # 1
+  )
+
+  def __init__(self, connectionString=None,):
+    self.connectionString = connectionString
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and 
isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is 
not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, 
self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRING:
+          self.connectionString = iprot.readString();
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and 
self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, 
self.thrift_spec)))
+      return
+    oprot.writeStructBegin('connect_args')
+    if self.connectionString is not None:
+      oprot.writeFieldBegin('connectionString', TType.STRING, 1)
+      oprot.writeString(self.connectionString)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == 
other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class connect_result:
+  """
+  Attributes:
+   - success
+   - connectionException
+  """
+
+  thrift_spec = (
+    (0, TType.STRUCT, 'success', (ConnectionHandle, 
ConnectionHandle.thrift_spec), None, ), # 0
+    (1, TType.STRUCT, 'connectionException', (PlcException, 
PlcException.thrift_spec), None, ), # 1
+  )
+
+  def __init__(self, success=None, connectionException=None,):
+    self.success = success
+    self.connectionException = connectionException
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and 
isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is 
not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, 
self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 0:
+        if ftype == TType.STRUCT:
+          self.success = ConnectionHandle()
+          self.success.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 1:
+        if ftype == TType.STRUCT:
+          self.connectionException = PlcException()
+          self.connectionException.read(iprot)
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and 
self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, 
self.thrift_spec)))
+      return
+    oprot.writeStructBegin('connect_result')
+    if self.success is not None:
+      oprot.writeFieldBegin('success', TType.STRUCT, 0)
+      self.success.write(oprot)
+      oprot.writeFieldEnd()
+    if self.connectionException is not None:
+      oprot.writeFieldBegin('connectionException', TType.STRUCT, 1)
+      self.connectionException.write(oprot)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == 
other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class execute_args:
+  """
+  Attributes:
+   - handle
+   - request
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRUCT, 'handle', (ConnectionHandle, 
ConnectionHandle.thrift_spec), None, ), # 1
+    (2, TType.STRUCT, 'request', (Request, Request.thrift_spec), None, ), # 2
+  )
+
+  def __init__(self, handle=None, request=None,):
+    self.handle = handle
+    self.request = request
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and 
isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is 
not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, 
self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRUCT:
+          self.handle = ConnectionHandle()
+          self.handle.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRUCT:
+          self.request = Request()
+          self.request.read(iprot)
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and 
self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, 
self.thrift_spec)))
+      return
+    oprot.writeStructBegin('execute_args')
+    if self.handle is not None:
+      oprot.writeFieldBegin('handle', TType.STRUCT, 1)
+      self.handle.write(oprot)
+      oprot.writeFieldEnd()
+    if self.request is not None:
+      oprot.writeFieldBegin('request', TType.STRUCT, 2)
+      self.request.write(oprot)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == 
other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class execute_result:
+  """
+  Attributes:
+   - success
+   - executionException
+  """
+
+  thrift_spec = (
+    (0, TType.STRUCT, 'success', (Response, Response.thrift_spec), None, ), # 0
+    (1, TType.STRUCT, 'executionException', (PlcException, 
PlcException.thrift_spec), None, ), # 1
+  )
+
+  def __init__(self, success=None, executionException=None,):
+    self.success = success
+    self.executionException = executionException
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and 
isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is 
not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, 
self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 0:
+        if ftype == TType.STRUCT:
+          self.success = Response()
+          self.success.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 1:
+        if ftype == TType.STRUCT:
+          self.executionException = PlcException()
+          self.executionException.read(iprot)
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and 
self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, 
self.thrift_spec)))
+      return
+    oprot.writeStructBegin('execute_result')
+    if self.success is not None:
+      oprot.writeFieldBegin('success', TType.STRUCT, 0)
+      self.success.write(oprot)
+      oprot.writeFieldEnd()
+    if self.executionException is not None:
+      oprot.writeFieldBegin('executionException', TType.STRUCT, 1)
+      self.executionException.write(oprot)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == 
other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class close_args:
+  """
+  Attributes:
+   - handle
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRUCT, 'handle', (ConnectionHandle, 
ConnectionHandle.thrift_spec), None, ), # 1
+  )
+
+  def __init__(self, handle=None,):
+    self.handle = handle
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and 
isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is 
not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, 
self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRUCT:
+          self.handle = ConnectionHandle()
+          self.handle.read(iprot)
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and 
self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, 
self.thrift_spec)))
+      return
+    oprot.writeStructBegin('close_args')
+    if self.handle is not None:
+      oprot.writeFieldBegin('handle', TType.STRUCT, 1)
+      self.handle.write(oprot)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == 
other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class close_result:
+
+  thrift_spec = (
+  )
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and 
isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is 
not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, 
self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and 
self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, 
self.thrift_spec)))
+      return
+    oprot.writeStructBegin('close_result')
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == 
other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
diff --git a/plc4py/org/apache/plc4x/interop/__init__.py 
b/plc4py/org/apache/plc4x/interop/__init__.py
new file mode 100644
index 0000000..d6615b7
--- /dev/null
+++ b/plc4py/org/apache/plc4x/interop/__init__.py
@@ -0,0 +1 @@
+__all__ = ['ttypes', 'constants', 'InteropServer']
diff --git a/plc4py/org/apache/plc4x/interop/constants.py 
b/plc4py/org/apache/plc4x/interop/constants.py
new file mode 100644
index 0000000..6816906
--- /dev/null
+++ b/plc4py/org/apache/plc4x/interop/constants.py
@@ -0,0 +1,9 @@
+#
+# Autogenerated by Thrift Compiler (0.7.0)
+#
+# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+#
+
+from thrift.Thrift import *
+from org.apache.plc4x.interop.ttypes import *
+
diff --git a/plc4py/org/apache/plc4x/interop/ttypes.py 
b/plc4py/org/apache/plc4x/interop/ttypes.py
new file mode 100644
index 0000000..adec8fc
--- /dev/null
+++ b/plc4py/org/apache/plc4x/interop/ttypes.py
@@ -0,0 +1,429 @@
+#
+# Autogenerated by Thrift Compiler (0.7.0)
+#
+# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+#
+from pip._vendor.urllib3.connectionpool import xrange
+from thrift.Thrift import *
+
+from thrift.transport import TTransport
+from thrift.protocol import TBinaryProtocol, TProtocol
+try:
+  from thrift.protocol import fastbinary
+except:
+  fastbinary = None
+
+
+class RESPONSE_CODE:
+  OK = 1
+  NOT_FOUND = 2
+  ACCESS_DENIED = 3
+  INVALID_ADDRESS = 4
+  INVALID_DATATYPE = 5
+  INTERNAL_ERROR = 6
+  RESPONSE_PENDING = 7
+
+  _VALUES_TO_NAMES = {
+    1: "OK",
+    2: "NOT_FOUND",
+    3: "ACCESS_DENIED",
+    4: "INVALID_ADDRESS",
+    5: "INVALID_DATATYPE",
+    6: "INTERNAL_ERROR",
+    7: "RESPONSE_PENDING",
+  }
+
+  _NAMES_TO_VALUES = {
+    "OK": 1,
+    "NOT_FOUND": 2,
+    "ACCESS_DENIED": 3,
+    "INVALID_ADDRESS": 4,
+    "INVALID_DATATYPE": 5,
+    "INTERNAL_ERROR": 6,
+    "RESPONSE_PENDING": 7,
+  }
+
+
+class ConnectionHandle:
+  """
+  Attributes:
+   - connectionId
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.I64, 'connectionId', None, None, ), # 1
+  )
+
+  def __init__(self, connectionId=None,):
+    self.connectionId = connectionId
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and 
isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is 
not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, 
self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.I64:
+          self.connectionId = iprot.readI64();
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and 
self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, 
self.thrift_spec)))
+      return
+    oprot.writeStructBegin('ConnectionHandle')
+    if self.connectionId is not None:
+      oprot.writeFieldBegin('connectionId', TType.I64, 1)
+      oprot.writeI64(self.connectionId)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == 
other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class PlcException(Exception):
+  """
+  Attributes:
+   - url
+   - exceptionString
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRING, 'url', None, None, ), # 1
+    (2, TType.STRING, 'exceptionString', None, None, ), # 2
+  )
+
+  def __init__(self, url=None, exceptionString=None,):
+    self.url = url
+    self.exceptionString = exceptionString
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and 
isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is 
not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, 
self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRING:
+          self.url = iprot.readString();
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRING:
+          self.exceptionString = iprot.readString();
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and 
self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, 
self.thrift_spec)))
+      return
+    oprot.writeStructBegin('PlcException')
+    if self.url is not None:
+      oprot.writeFieldBegin('url', TType.STRING, 1)
+      oprot.writeString(self.url)
+      oprot.writeFieldEnd()
+    if self.exceptionString is not None:
+      oprot.writeFieldBegin('exceptionString', TType.STRING, 2)
+      oprot.writeString(self.exceptionString)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __str__(self):
+    return repr(self)
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == 
other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class Request:
+  """
+  Attributes:
+   - fields
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.MAP, 'fields', (TType.STRING,None,TType.STRING,None), None, ), # 
1
+  )
+
+  def __init__(self, fields=None,):
+    self.fields = fields
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and 
isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is 
not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, 
self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.MAP:
+          self.fields = {}
+          (_ktype1, _vtype2, _size0 ) = iprot.readMapBegin() 
+          for _i4 in xrange(_size0):
+            _key5 = iprot.readString();
+            _val6 = iprot.readString();
+            self.fields[_key5] = _val6
+          iprot.readMapEnd()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and 
self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, 
self.thrift_spec)))
+      return
+    oprot.writeStructBegin('Request')
+    if self.fields is not None:
+      oprot.writeFieldBegin('fields', TType.MAP, 1)
+      oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.fields))
+      for kiter7,viter8 in self.fields.items():
+        oprot.writeString(kiter7)
+        oprot.writeString(viter8)
+      oprot.writeMapEnd()
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == 
other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class FieldResponse:
+  """
+  Attributes:
+   - responseCode
+   - boolValue
+   - longValue
+   - doubleValue
+   - stringValue
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.I32, 'responseCode', None, None, ), # 1
+    (2, TType.BOOL, 'boolValue', None, None, ), # 2
+    (3, TType.I64, 'longValue', None, None, ), # 3
+    (4, TType.DOUBLE, 'doubleValue', None, None, ), # 4
+    (5, TType.STRING, 'stringValue', None, None, ), # 5
+  )
+
+  def __init__(self, responseCode=None, boolValue=None, longValue=None, 
doubleValue=None, stringValue=None,):
+    self.responseCode = responseCode
+    self.boolValue = boolValue
+    self.longValue = longValue
+    self.doubleValue = doubleValue
+    self.stringValue = stringValue
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and 
isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is 
not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, 
self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.I32:
+          self.responseCode = iprot.readI32();
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.BOOL:
+          self.boolValue = iprot.readBool();
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.I64:
+          self.longValue = iprot.readI64();
+        else:
+          iprot.skip(ftype)
+      elif fid == 4:
+        if ftype == TType.DOUBLE:
+          self.doubleValue = iprot.readDouble();
+        else:
+          iprot.skip(ftype)
+      elif fid == 5:
+        if ftype == TType.STRING:
+          self.stringValue = iprot.readString();
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and 
self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, 
self.thrift_spec)))
+      return
+    oprot.writeStructBegin('FieldResponse')
+    if self.responseCode is not None:
+      oprot.writeFieldBegin('responseCode', TType.I32, 1)
+      oprot.writeI32(self.responseCode)
+      oprot.writeFieldEnd()
+    if self.boolValue is not None:
+      oprot.writeFieldBegin('boolValue', TType.BOOL, 2)
+      oprot.writeBool(self.boolValue)
+      oprot.writeFieldEnd()
+    if self.longValue is not None:
+      oprot.writeFieldBegin('longValue', TType.I64, 3)
+      oprot.writeI64(self.longValue)
+      oprot.writeFieldEnd()
+    if self.doubleValue is not None:
+      oprot.writeFieldBegin('doubleValue', TType.DOUBLE, 4)
+      oprot.writeDouble(self.doubleValue)
+      oprot.writeFieldEnd()
+    if self.stringValue is not None:
+      oprot.writeFieldBegin('stringValue', TType.STRING, 5)
+      oprot.writeString(self.stringValue)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.items()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == 
other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class Response:
+  """
+  Attributes:
+   - fields
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.MAP, 'fields', (TType.STRING,None,TType.STRUCT,(FieldResponse, 
FieldResponse.thrift_spec)), None, ), # 1
+  )
+
+  def __init__(self, fields=None,):
+    self.fields = fields
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and 
isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is 
not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, 
self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.MAP:
+          self.fields = {}
+          (_ktype10, _vtype11, _size9 ) = iprot.readMapBegin() 
+          for _i13 in xrange(_size9):
+            _key14 = iprot.readString();
+            _val15 = FieldResponse()
+            _val15.read(iprot)
+            self.fields[_key14] = _val15
+          iprot.readMapEnd()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and 
self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, 
self.thrift_spec)))
+      return
+    oprot.writeStructBegin('Response')
+    if self.fields is not None:
+      oprot.writeFieldBegin('fields', TType.MAP, 1)
+      oprot.writeMapBegin(TType.STRING, TType.STRUCT, len(self.fields))
+      for kiter16,viter17 in self.fields.items():
+        oprot.writeString(kiter16)
+        viter17.write(oprot)
+      oprot.writeMapEnd()
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.items()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == 
other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
diff --git a/plc4py/test/__init__.py b/plc4py/test/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/plc4py/test/test_PlcDriverManager.py 
b/plc4py/test/test_PlcDriverManager.py
new file mode 100644
index 0000000..4a5e898
--- /dev/null
+++ b/plc4py/test/test_PlcDriverManager.py
@@ -0,0 +1,95 @@
+import time
+import unittest
+from subprocess import Popen
+from unittest import TestCase
+
+from org.apache.plc4x.PlcDriverManager import PlcDriverManager
+from org.apache.plc4x.interop.InteropServer import Client, Request, 
PlcException
+
+if __name__ == '__main__':
+    unittest.main()
+
+
+class TestPlcDriverManager(TestCase):
+
+    def test_callLib(self):
+        try:
+            proc = Popen(["java", "-jar", 
"../lib/apache-plc4x-incubating-0.4.0-SNAPSHOT-jar-with-dependencies.jar"])
+            print("Started server under pid " + str(proc.pid))
+            time.sleep(5)
+            poll = proc.poll()
+            if poll is None:
+                print("Still running...")
+            else:
+                print("Unable to start the Interop Server...")
+        except:
+            print("Unable to start proces")
+        finally:
+            proc.terminate()
+
+    def test_startAndStopServer(self):
+        try:
+            manager = PlcDriverManager()
+
+            ## Do some magic here
+            client = manager._get_client()
+            connection = client.connect("mock:a")
+
+            result = client.execute(connection, Request(fields={"field1": 
"asdf"}))
+
+            print(result)
+
+            client.close(connection)
+        finally:
+            manager.close()
+
+    def test_withPlcConnection(self):
+        try:
+            manager = PlcDriverManager()
+
+            try:
+                connection = manager.get_connection("mock:a")
+                result = connection.execute(Request(fields={"field1": "asdf"}))
+                print(result)
+            finally:
+                connection.close()
+        finally:
+            manager.close()
+
+    def test_withRealPLC_forDebug(self):
+        try:
+            manager = PlcDriverManager(embedded_server=False)
+
+            connection = None
+            try:
+                connection = manager.get_connection("s7://192.168.167.210/0/1")
+                result = connection.execute(Request(fields={"field1": 
"%M0:USINT"}))
+                print(result)
+            except PlcException as e:
+                raise Exception(str(e.url))
+            finally:
+                if connection is not None:
+                    connection.close()
+        finally:
+            manager.close()
+
+    def test_withRealPLC(self):
+        try:
+            manager = PlcDriverManager()
+
+            connection = None
+            try:
+                connection = manager.get_connection("s7://192.168.167.210/0/1")
+                for _ in range(100):
+                    result = connection.execute(Request(fields={"field1": 
"%M0:USINT"}))
+                    print("Response Code is " + 
str(result.get_field("field1").get_response_code()))
+                    # We now that we want to get an int...
+                    print("Response Value is " + 
str(result.get_field("field1").get_int_value()))
+
+            except PlcException as e:
+                raise Exception(str(e.url))
+            finally:
+                if connection is not None:
+                    connection.close()
+        finally:
+            manager.close()
\ No newline at end of file

Reply via email to