You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by hu...@apache.org on 2024/02/15 19:12:40 UTC

(plc4x) branch fix/plc4py/documentation updated: fix(plc4py): Continue working through help docs. Implemented metadata

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

hutcheb pushed a commit to branch fix/plc4py/documentation
in repository https://gitbox.apache.org/repos/asf/plc4x.git


The following commit(s) were added to refs/heads/fix/plc4py/documentation by this push:
     new 591e908b3d fix(plc4py): Continue working through help docs. Implemented metadata
591e908b3d is described below

commit 591e908b3d6b082a10c6b41ba7edb740a205094b
Author: Ben Hutcheson <be...@gmail.com>
AuthorDate: Thu Feb 15 20:12:30 2024 +0100

    fix(plc4py): Continue working through help docs. Implemented metadata
---
 sandbox/plc4py/plc4py/api/PlcConnection.py         | 35 ++++++++++++++++++
 .../plc4py/drivers/modbus/ModbusConnection.py      | 32 +++++++++++++++--
 .../asciidoc/users/getting-started/plc4py.adoc     | 41 +++++++++++-----------
 3 files changed, 85 insertions(+), 23 deletions(-)

diff --git a/sandbox/plc4py/plc4py/api/PlcConnection.py b/sandbox/plc4py/plc4py/api/PlcConnection.py
index 94e43319c8..7a2da9c3da 100644
--- a/sandbox/plc4py/plc4py/api/PlcConnection.py
+++ b/sandbox/plc4py/plc4py/api/PlcConnection.py
@@ -75,3 +75,38 @@ class PlcConnection(GenericGenerator):
         future = loop.create_future()
         future.set_result(PlcResponse(code))
         return future
+
+
+class PlcConnectionMetaData:
+
+    @abstractmethod
+    def is_read_supported(self) -> bool:
+        """
+        Indicates if the connection supports read requests.
+        :return: True if connection supports reading, False otherwise
+        """
+        pass
+
+    @abstractmethod
+    def is_write_supported(self) -> bool:
+        """
+        Indicates if the connection supports write requests.
+        :return: True if connection supports writing, False otherwise
+        """
+        pass
+
+    @abstractmethod
+    def is_subscribe_supported(self) -> bool:
+        """
+        Indicates if the connection supports subscription requests.
+        :return: True if connection supports subscriptions, False otherwise
+        """
+        pass
+
+    @abstractmethod
+    def is_browse_supported(self) -> bool:
+        """
+        Indicates if the connection supports browsing requests.
+        :return: True if connection supports browsing, False otherwise
+        """
+        pass
diff --git a/sandbox/plc4py/plc4py/drivers/modbus/ModbusConnection.py b/sandbox/plc4py/plc4py/drivers/modbus/ModbusConnection.py
index 670ba77d14..dd1060a27a 100644
--- a/sandbox/plc4py/plc4py/drivers/modbus/ModbusConnection.py
+++ b/sandbox/plc4py/plc4py/drivers/modbus/ModbusConnection.py
@@ -21,7 +21,7 @@ import logging
 from typing import Type, Awaitable
 
 import plc4py
-from plc4py.api.PlcConnection import PlcConnection
+from plc4py.api.PlcConnection import PlcConnection, PlcConnectionMetaData
 from plc4py.api.PlcDriver import PlcDriver
 from plc4py.api.authentication.PlcAuthentication import PlcAuthentication
 from plc4py.api.messages.PlcResponse import PlcResponse, PlcReadResponse
@@ -41,7 +41,7 @@ from plc4py.spi.transport.Plc4xBaseTransport import Plc4xBaseTransport
 from plc4py.spi.transport.TCPTransport import TCPTransport
 
 
-class ModbusConnection(PlcConnection):
+class ModbusConnection(PlcConnection, PlcConnectionMetaData):
     """
     Modbus TCP PLC connection implementation
     """
@@ -132,6 +132,34 @@ class ModbusConnection(PlcConnection):
         future = asyncio.ensure_future(_request(request, self._device))
         return future
 
+    def is_read_supported(self) -> bool:
+        """
+        Indicates if the connection supports read requests.
+        :return: True if connection supports reading, False otherwise
+        """
+        return True
+
+    def is_write_supported(self) -> bool:
+        """
+        Indicates if the connection supports write requests.
+        :return: True if connection supports writing, False otherwise
+        """
+        return False
+
+    def is_subscribe_supported(self) -> bool:
+        """
+        Indicates if the connection supports subscription requests.
+        :return: True if connection supports subscriptions, False otherwise
+        """
+        return False
+
+    def is_browse_supported(self) -> bool:
+        """
+        Indicates if the connection supports browsing requests.
+        :return: True if connection supports browsing, False otherwise
+        """
+        return False
+
 
 class ModbusDriver(PlcDriver):
     def __init__(self):
diff --git a/src/site/asciidoc/users/getting-started/plc4py.adoc b/src/site/asciidoc/users/getting-started/plc4py.adoc
index e8dd2ba699..c10936eb59 100644
--- a/src/site/asciidoc/users/getting-started/plc4py.adoc
+++ b/src/site/asciidoc/users/getting-started/plc4py.adoc
@@ -19,15 +19,17 @@
 
 === Using the PLC4Py API directly
 
-Currently, you need to install PLC4Py from the GitHub repository instead of pypi. Navigate to the sandbox/plc4py directory
-and run. This will install plc4py in your global repository.
+Currently, you need to install PLC4Py from the GitHub repository instead of pypi.
+Once we have decided that PLC4Py is in a position to release we will publish to pypi.
+
+Navigate to the sandbox/plc4py directory and run. This will install plc4py in your global repository.
 
 [subs=attributes+]
 ----
    pip install .
 ----
 
-You now should be able to use PLC4PY in your application. A short example is shown below.
+You now should be able to use PLC4Py in your application. A minimal example is shown below.
 
 ----
 from plc4py.PlcDriverManager import PlcDriverManager
@@ -50,11 +52,11 @@ PLC4X generally supports a very limited set of functions, which is not due to th
 
 The basic functions supported by PLCs and therefore supported by PLC4X are:
 
-* Discover Devices
+* Discover Devices (Not yet available for PLC4Py)
 * List resources in the PLC
 * Read data
-* Write data
-* Subscribe for data
+* Write data (Not yet available for PLC4Py)
+* Subscribe for data (Not yet available for PLC4Py)
 
 In general, we will try to offer as many features as possible.
 So if a protocol doesn't support subscription based communication it is our goal to simulate this by polling in the background, so it is transparent for the users (This simulation feature hasn't been implemented yet though, but it's on our roadmap).
@@ -62,32 +64,29 @@ So if a protocol doesn't support subscription based communication it is our goal
 But there are some cases in which we can't simulate or features are simply disabled intentionally:
 
 * If a PLC and/or protocol don't support writing or browsing, we simply can't provide this functionality.
-* Also do we plan on providing stripped down versions of drivers, that for example intentionally don't support any writing of data.
 
 Therefore, we use metadata to check programmatically, if a given feature is available.
 
 ==== Reading Data
 
 ----
-// Check if this connection support reading of data.
-if (!plcConnection.getMetadata().isReadSupported()) {
-  logger.error("This connection doesn't support reading.");
-  return;
-}
+
+# Check if this connection support reading of data.
+if connection.is_read_supported():
+    logger.error("This connection doesn't support reading.")
+
 ----
 
 As soon as you have ensured that a feature is available, you are ready to build a first request.
-This is done by getting a `PlcReadRequest.Builder`:
+This is done by getting a `ReadRequestBuilder`:
 
 ----
-// Create a new read request:
-// - Give the single item requested an alias name
-PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
-builder.addTagAddress("value-1", "%Q0.4:BOOL");
-builder.addTagAddress("value-2", "%Q0:BYTE");
-builder.addTagAddress("value-3", "%I0.2:BOOL");
-builder.addTagAddress("value-4", "%DB.DB1.4:INT");
-PlcReadRequest readRequest = builder.build();
+# Create a new read request:
+# - Give the single item requested an alias name
+with connection.read_request_builder() as builder:
+    builder.add_item("Random Tag", "4x00001[10]")
+    builder.add_item("Random Tag", "4x00011")
+    request = builder.build()
 ----
 
 So, as you can see, you prepare a request, by adding tag addresses to the request and in the end by calling the `build` method.