Skip to content

Commit

Permalink
fix(plc4py): Add in default reader/writer/browser
Browse files Browse the repository at this point in the history
  • Loading branch information
hutcheb committed May 26, 2024
1 parent 0977349 commit abdd3f9
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 52 deletions.
20 changes: 3 additions & 17 deletions plc4py/plc4py/drivers/mock/MockConnection.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@
from plc4py.api.value.PlcValue import PlcResponseCode
from plc4py.drivers.PlcDriverLoader import PlcDriverLoader
from plc4py.drivers.mock.MockTag import MockTagBuilder
from plc4py.spi.messages.PlcReader import PlcReader
from plc4py.spi.messages.PlcReader import DefaultPlcReader
from plc4py.spi.messages.PlcRequest import DefaultReadRequestBuilder
from plc4py.spi.messages.PlcWriter import PlcWriter
from plc4py.spi.messages.PlcWriter import DefaultPlcWriter
from plc4py.spi.messages.utils.ResponseItem import ResponseItem
from plc4py.spi.transport.MockTransport import MockTransport
from plc4py.spi.transport.Plc4xBaseTransport import Plc4xBaseTransport
Expand Down Expand Up @@ -73,7 +73,7 @@ async def read(


@dataclass
class MockConnection(PlcConnection, PlcReader, PlcWriter, PlcConnectionMetaData):
class MockConnection(PlcConnection, DefaultPlcReader, DefaultPlcWriter):
_device: MockDevice = field(default_factory=lambda: MockDevice())
_transport: Union[Plc4xBaseTransport, None] = None

Expand Down Expand Up @@ -112,20 +112,6 @@ async def execute(self, request: PlcRequest) -> PlcResponse:

return self._default_failed_request(PlcResponseCode.NOT_CONNECTED)

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 MockDriver(PlcDriver):
def __init__(self):
Expand Down
32 changes: 7 additions & 25 deletions plc4py/plc4py/drivers/modbus/ModbusConnection.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,39 +17,35 @@
# under the License.
#
import asyncio
import logging
from typing import Type, Awaitable
from typing import Type

import plc4py
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,
PlcWriteResponse,
PlcTagResponse,
)
from plc4py.api.messages.PlcRequest import (
ReadRequestBuilder,
PlcRequest,
PlcReadRequest,
PlcWriteRequest,
)
from plc4py.api.messages.PlcResponse import (
PlcResponse,
)
from plc4py.api.value.PlcValue import PlcResponseCode
from plc4py.drivers.PlcDriverLoader import PlcDriverLoader
from plc4py.drivers.modbus.ModbusConfiguration import ModbusConfiguration
from plc4py.drivers.modbus.ModbusDevice import ModbusDevice
from plc4py.drivers.modbus.ModbusProtocol import ModbusProtocol
from plc4py.drivers.modbus.ModbusTag import ModbusTagBuilder
from plc4py.spi.messages.PlcReader import PlcReader
from plc4py.spi.messages.PlcReader import DefaultPlcReader
from plc4py.spi.messages.PlcRequest import DefaultReadRequestBuilder
from plc4py.spi.messages.PlcWriter import PlcWriter
from plc4py.spi.messages.PlcWriter import DefaultPlcWriter
from plc4py.spi.transport.Plc4xBaseTransport import Plc4xBaseTransport
from plc4py.spi.transport.TCPTransport import TCPTransport


class ModbusConnection(PlcConnection, PlcReader, PlcWriter, PlcConnectionMetaData):
class ModbusConnection(PlcConnection, DefaultPlcReader, DefaultPlcWriter):
"""
Modbus TCP PLC connection implementation
"""
Expand Down Expand Up @@ -140,20 +136,6 @@ def read_request_builder(self) -> ReadRequestBuilder:
"""
return DefaultReadRequestBuilder(ModbusTagBuilder)

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):
Expand Down
13 changes: 3 additions & 10 deletions plc4py/plc4py/drivers/umas/UmasConnection.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
from plc4py.drivers.umas.UmasDevice import UmasDevice
from plc4py.drivers.umas.UmasProtocol import UmasProtocol
from plc4py.drivers.umas.UmasTag import UmasTagBuilder
from plc4py.spi.messages.PlcBrowser import PlcBrowser
from plc4py.spi.messages.PlcReader import PlcReader
from plc4py.spi.messages.PlcBrowser import DefaultPlcBrowser
from plc4py.spi.messages.PlcReader import DefaultPlcReader
from plc4py.spi.messages.PlcRequest import (
DefaultReadRequestBuilder,
DefaultBrowseRequestBuilder,
Expand All @@ -51,7 +51,7 @@
from plc4py.spi.transport.TCPTransport import TCPTransport


class UmasConnection(PlcConnection, PlcReader, PlcBrowser, PlcConnectionMetaData):
class UmasConnection(PlcConnection, DefaultPlcReader, DefaultPlcBrowser):
"""
Umas TCP PLC connection implementation
"""
Expand Down Expand Up @@ -137,13 +137,6 @@ def execute(self, request: PlcRequest) -> Awaitable[PlcResponse]:

return self._default_failed_request(PlcResponseCode.NOT_CONNECTED)

def is_subscribe_supported(self) -> bool:
"""
Indicates if the connection supports subscription requests.
:return: True if connection supports subscriptions, False otherwise
"""
return False


class UmasDriver(PlcDriver):
def __init__(self):
Expand Down
22 changes: 22 additions & 0 deletions plc4py/plc4py/spi/messages/PlcBrowser.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#
import asyncio
import logging
from abc import abstractmethod

from plc4py.api.messages.PlcRequest import PlcBrowseRequest
from plc4py.api.messages.PlcResponse import PlcBrowseResponse
Expand All @@ -29,6 +30,27 @@ class PlcBrowser:
Interface implemented by all PlcConnections that are able to read from remote resources.
"""

@abstractmethod
async def _browse(self, request: PlcBrowseRequest) -> PlcBrowseResponse:
"""
Executes a PlcBrowseRequest
"""
pass

@abstractmethod
def is_browse_supported(self) -> bool:
"""
Indicates if the connection supports browsing requests.
:return: True if connection supports browsing, False otherwise
"""
pass


class DefaultPlcBrowser(PlcBrowser):
"""
Interface implemented by all PlcConnections that are able to read from remote resources.
"""

def __init__(self):
self._transport = None
self._device = None
Expand Down
32 changes: 32 additions & 0 deletions plc4py/plc4py/spi/messages/PlcReader.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#
import asyncio
import logging
from abc import abstractmethod

from plc4py.api.messages.PlcRequest import PlcReadRequest
from plc4py.api.messages.PlcResponse import PlcReadResponse
Expand All @@ -29,6 +30,37 @@ class PlcReader:
Interface implemented by all PlcConnections that are able to read from remote resources.
"""

@abstractmethod
async def _read(self, request: PlcReadRequest) -> PlcReadResponse:
"""
Executes a PlcReadRequest
This method sends a read request to the connected device and waits for a response.
The response is then returned as a PlcReadResponse.
If no device is set, an error is logged and a PlcResponseCode.NOT_CONNECTED is returned.
If an error occurs during the execution of the read request, a PlcResponseCode.INTERNAL_ERROR is
returned.
:param request: PlcReadRequest to execute
:return: PlcReadResponse
"""
pass

@abstractmethod
def is_read_supported(self) -> bool:
"""
Indicates if the connection supports read requests.
:return: True if connection supports reading, False otherwise
"""
pass


class DefaultPlcReader(PlcReader):
"""
Interface implemented by all PlcConnections that are able to read from remote resources.
"""

def __init__(self):
self._transport = None
self._device = None
Expand Down
33 changes: 33 additions & 0 deletions plc4py/plc4py/spi/messages/PlcWriter.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#
import asyncio
import logging
from abc import abstractmethod

from plc4py.api.messages.PlcRequest import PlcWriteRequest
from plc4py.api.messages.PlcResponse import PlcWriteResponse
Expand All @@ -29,6 +30,38 @@ class PlcWriter:
Interface implemented by all PlcConnections that are able to write from remote resources.
"""

@abstractmethod
async def _write(self, request: PlcWriteRequest) -> PlcWriteResponse:
"""
Executes a PlcWriteRequest
This method sends a write request to the connected Modbus device and waits for a response.
The response is then returned as a PlcWriteResponse.
If no device is set, an error is logged and a PlcWriteResponse with the
PlcResponseCode.NOT_CONNECTED code is returned.
If an error occurs during the execution of the write request, a
PlcWriteResponse with the PlcResponseCode.INTERNAL_ERROR code is returned.
:param request: PlcWriteRequest to execute
:return: PlcWriteResponse
"""
pass

@abstractmethod
def is_write_supported(self) -> bool:
"""
Indicates if the connection supports write requests.
:return: True if connection supports writing, False otherwise
"""
pass


class DefaultPlcWriter(PlcWriter):
"""
Interface implemented by all PlcConnections that are able to write from remote resources.
"""

def __init__(self):
self._transport = None
self._device = None
Expand Down

0 comments on commit abdd3f9

Please sign in to comment.