From fed0b5a3c0f26e2a1abc92d0f301b77d12aba15c Mon Sep 17 00:00:00 2001 From: Ben Hutcheson Date: Fri, 10 Nov 2023 07:26:48 +0100 Subject: [PATCH] chore(plc4py): Start writing modbus logic :) --- .../plc4py/drivers/modbus/ModbusConnection.py | 9 +++-- .../plc4py/drivers/modbus/ModbusField.py | 27 +++++++++++++ .../plc4py/plc4py/spi/messages/PlcRequest.py | 39 +++++++++++++++++++ .../drivers/modbus/test_modbus_codegen.py | 2 - .../drivers/modbus/test_modbus_connection.py | 20 ++++++++-- 5 files changed, 88 insertions(+), 9 deletions(-) create mode 100644 sandbox/plc4py/plc4py/drivers/modbus/ModbusField.py create mode 100644 sandbox/plc4py/plc4py/spi/messages/PlcRequest.py diff --git a/sandbox/plc4py/plc4py/drivers/modbus/ModbusConnection.py b/sandbox/plc4py/plc4py/drivers/modbus/ModbusConnection.py index 2eca71e3342..b2b41aa4b8a 100644 --- a/sandbox/plc4py/plc4py/drivers/modbus/ModbusConnection.py +++ b/sandbox/plc4py/plc4py/drivers/modbus/ModbusConnection.py @@ -24,10 +24,11 @@ from plc4py.api.PlcDriver import PlcDriver from plc4py.api.authentication.PlcAuthentication import PlcAuthentication from plc4py.api.messages.PlcResponse import PlcResponse -from plc4py.api.messages.PlcRequest import ReadRequestBuilder +from plc4py.api.messages.PlcRequest import ReadRequestBuilder, PlcRequest from plc4py.drivers.PlcDriverLoader import PlcDriverLoader from plc4py.drivers.modbus.ModbusConfiguration import ModbusConfiguration from plc4py.drivers.modbus.ModbusProtocol import ModbusProtocol +from plc4py.spi.messages.PlcRequest import DefaultReadRequestBuilder from plc4py.spi.transport.Plc4xBaseTransport import Plc4xBaseTransport from plc4py.spi.transport.TCPTransport import TCPTransport @@ -74,12 +75,12 @@ def read_request_builder(self) -> ReadRequestBuilder: """ :return: read request builder. """ - pass + return DefaultReadRequestBuilder() - def execute(self, PlcRequest) -> Awaitable[PlcResponse]: + def execute(self, request: PlcRequest) -> Awaitable[PlcResponse]: """ Executes a PlcRequest as long as it's already connected - :param PlcRequest: Plc Request to execute + :param request: Plc Request to execute :return: The response from the Plc/Device """ pass diff --git a/sandbox/plc4py/plc4py/drivers/modbus/ModbusField.py b/sandbox/plc4py/plc4py/drivers/modbus/ModbusField.py new file mode 100644 index 00000000000..a6594f3e369 --- /dev/null +++ b/sandbox/plc4py/plc4py/drivers/modbus/ModbusField.py @@ -0,0 +1,27 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +from dataclasses import dataclass + +from plc4py.api.value.PlcValue import PlcValue + + +@dataclass +class ModbusField: + name: str + value: PlcValue diff --git a/sandbox/plc4py/plc4py/spi/messages/PlcRequest.py b/sandbox/plc4py/plc4py/spi/messages/PlcRequest.py new file mode 100644 index 00000000000..e6ce4652e2a --- /dev/null +++ b/sandbox/plc4py/plc4py/spi/messages/PlcRequest.py @@ -0,0 +1,39 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +from abc import abstractmethod +from dataclasses import dataclass +from typing import Union + +from plc4py.api.messages.PlcField import PlcField +from plc4py.api.messages.PlcRequest import PlcFieldRequest, PlcReadRequest, ReadRequestBuilder + + +class DefaultReadRequestBuilder(ReadRequestBuilder): + + def __init__(self): + super().__init__() + self.read_request = PlcReadRequest() + + def build(self) -> PlcReadRequest: + return self.read_request + + def add_item(self, field_query: Union[str, PlcField]) -> None: + if isinstance(field_query, str): + field_query = PlcField(field_query) + self.read_request.fields.append(field_query) diff --git a/sandbox/plc4py/tests/unit/plc4py/drivers/modbus/test_modbus_codegen.py b/sandbox/plc4py/tests/unit/plc4py/drivers/modbus/test_modbus_codegen.py index 5fb07040ac1..357bf79c9a9 100644 --- a/sandbox/plc4py/tests/unit/plc4py/drivers/modbus/test_modbus_codegen.py +++ b/sandbox/plc4py/tests/unit/plc4py/drivers/modbus/test_modbus_codegen.py @@ -16,9 +16,7 @@ # specific language governing permissions and limitations # under the License. # -from bitarray import bitarray -from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU from plc4py.protocols.modbus.readwrite.ModbusTcpADU import ModbusTcpADUBuilder from plc4py.spi.generation.WriteBuffer import WriteBufferByteBased diff --git a/sandbox/plc4py/tests/unit/plc4py/drivers/modbus/test_modbus_connection.py b/sandbox/plc4py/tests/unit/plc4py/drivers/modbus/test_modbus_connection.py index 295b9ee539d..86595dba0e9 100644 --- a/sandbox/plc4py/tests/unit/plc4py/drivers/modbus/test_modbus_connection.py +++ b/sandbox/plc4py/tests/unit/plc4py/drivers/modbus/test_modbus_connection.py @@ -19,11 +19,25 @@ from plc4py.PlcDriverManager import PlcDriverManager +from plc4py.api.messages.PlcRequest import PlcReadRequest +from plc4py.drivers.modbus.ModbusField import ModbusField +from plc4py.spi.values.PlcINT import PlcINT -async def manual_test_plc_driver_modbus_connect(): +async def test_plc_driver_modbus_connect(): driver_manager = PlcDriverManager() - async with driver_manager.connection("modbus://127.0.0.1:502") as connection: + async with driver_manager.connection("modbus://127.0.0.1:5555") as connection: assert connection.is_connected() - assert not connection.is_connected() + + +async def test_plc_driver_modbus_read(): + driver_manager = PlcDriverManager() + async with driver_manager.connection("modbus://127.0.0.1:5555") as connection: + + with connection.read_request_builder() as builder: + builder.add_item(ModbusField("Random Name", PlcINT(-1))) + request = builder.build() + connection.execute(request) + + pass \ No newline at end of file