You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2020/10/22 19:07:47 UTC

[plc4x] branch feature/plc4go updated: - Implemented the missing read request types - Implemented the generation of the DataIo for lists

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

cdutz pushed a commit to branch feature/plc4go
in repository https://gitbox.apache.org/repos/asf/plc4x.git


The following commit(s) were added to refs/heads/feature/plc4go by this push:
     new 0a14c9b  - Implemented the missing read request types - Implemented the generation of the DataIo for lists
0a14c9b is described below

commit 0a14c9bf97e3c7b7f82a8ca75cc0d991341108b1
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Thu Oct 22 21:07:39 2020 +0200

    - Implemented the missing read request types
    - Implemented the generation of the DataIo for lists
---
 .../resources/templates/go/data-io-template.ftlh   |   7 ++
 .../main/resources/protocols/modbus/modbus.mspec   |   2 +-
 .../plc4go/internal/plc4go/modbus/ModbusReader.go  |  44 +++++---
 .../plc4go/modbus/readwrite/model/DataItem.go      | 121 ++++++++++++++++++++-
 .../internal/plc4go/s7/readwrite/model/DataItem.go |  28 +++++
 sandbox/plc4go/internal/plc4go/utils/CastUtils.go  |  28 +++++
 6 files changed, 210 insertions(+), 20 deletions(-)

diff --git a/build-utils/language-go/src/main/resources/templates/go/data-io-template.ftlh b/build-utils/language-go/src/main/resources/templates/go/data-io-template.ftlh
index cc21075..ca63d83 100644
--- a/build-utils/language-go/src/main/resources/templates/go/data-io-template.ftlh
+++ b/build-utils/language-go/src/main/resources/templates/go/data-io-template.ftlh
@@ -84,6 +84,13 @@ func ${type.name}Parse(io *spi.ReadBuffer<#if type.parserArguments?has_content>,
 
             // Array Field (${field.name})
             var ${field.name} []api.PlcValue
+            for i := 0; i < int(${helper.toParseExpression(null, field.loopExpression, type.parserArguments)}); i++ {
+                _item, _itemErr := DataItemParse(io, ${type.parserArguments[0].name}, ${helper.getLanguageTypeNameForTypeReference(type.parserArguments[1].type)}(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                ${field.name} = append(${field.name}, _item)
+            }
                     <#if field.name == "value">
                         <#assign valueDefined=true>
                     </#if>
diff --git a/protocols/modbus/src/main/resources/protocols/modbus/modbus.mspec b/protocols/modbus/src/main/resources/protocols/modbus/modbus.mspec
index e7e05f0..7e18661 100644
--- a/protocols/modbus/src/main/resources/protocols/modbus/modbus.mspec
+++ b/protocols/modbus/src/main/resources/protocols/modbus/modbus.mspec
@@ -270,7 +270,7 @@
     [array      int 8      'recordData'     length  'recordLength']
 ]
 
-[dataIo 'DataItem' [string 'dataType', uint 8 'numberOfValues']
+[dataIo 'DataItem' [string 'dataType', uint 16 'numberOfValues']
     [typeSwitch 'dataType','numberOfValues'
         ['IEC61131_BOOL','1' BOOL
             [reserved uint 7 '0x00']
diff --git a/sandbox/plc4go/internal/plc4go/modbus/ModbusReader.go b/sandbox/plc4go/internal/plc4go/modbus/ModbusReader.go
index 1413327..b21ab91 100644
--- a/sandbox/plc4go/internal/plc4go/modbus/ModbusReader.go
+++ b/sandbox/plc4go/internal/plc4go/modbus/ModbusReader.go
@@ -25,6 +25,7 @@ import (
     modbusModel "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/modbus/readwrite/model"
     plc4goModel "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model"
     "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+    "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
     "plc4x.apache.org/plc4go-modbus-driver/v0/pkg/plc4go/model"
     "plc4x.apache.org/plc4go-modbus-driver/v0/pkg/plc4go/values"
     "sync/atomic"
@@ -161,37 +162,44 @@ func (m ModbusReader) Read(readRequest model.PlcReadRequest) <-chan model.PlcRea
 }
 
 func toPlc4xResponse(requestAdu modbusModel.ModbusTcpADU, responseAdu modbusModel.ModbusTcpADU, readRequest model.PlcReadRequest) (model.PlcReadResponse,error) {
+    var data []uint8
     switch responseAdu.Pdu.(type) {
     case modbusModel.ModbusPDUReadDiscreteInputsResponse:
         pdu := modbusModel.CastModbusPDUReadDiscreteInputsResponse(responseAdu.Pdu)
-        fmt.Printf("ModbusPDUReadDiscreteInputsResponse %d", pdu)
+        data = utils.Int8ToUint8(pdu.Value)
         // Pure Boolean ...
     case modbusModel.ModbusPDUReadCoilsResponse:
         pdu := modbusModel.CastModbusPDUReadCoilsResponse(&responseAdu.Pdu)
-        fmt.Printf("ModbusPDUReadCoilsResponse %d", pdu)
+        data = utils.Int8ToUint8(pdu.Value)
         // Pure Boolean ...
     case modbusModel.ModbusPDUReadInputRegistersResponse:
         pdu := modbusModel.CastModbusPDUReadInputRegistersResponse(responseAdu.Pdu)
-        fmt.Printf("ModbusPDUReadInputRegistersResponse %d", pdu)
+        data = utils.Int8ToUint8(pdu.Value)
         // DataIo ...
     case modbusModel.ModbusPDUReadHoldingRegistersResponse:
         pdu := modbusModel.CastModbusPDUReadHoldingRegistersResponse(responseAdu.Pdu)
-        _casted := make([]uint8, len(pdu.Value))
-        for i,_val := range pdu.Value {
-            _casted[i] = uint8(_val)
-        }
-        rb := spi.ReadBufferNew(_casted)
-        fieldName := readRequest.GetFieldNames()[0]
-        field := readRequest.GetField(fieldName)
+        data = utils.Int8ToUint8(pdu.Value)
+    default:
+        return nil, errors.New("unsupported response type")
+    }
 
-        value, err := modbusModel.DataItemParse(rb, field.GetTypeName(), 1)
-        if err != nil {
-            return nil, err
-        }
-        values := map[string]values.PlcValue{}
-        values[fieldName] = value
-        return plc4goModel.NewDefaultPlcReadResponse(values), nil
+    // Get the field from the request
+    fieldName := readRequest.GetFieldNames()[0]
+    field, err := CastFromPlcField(readRequest.GetField(fieldName))
+    if err != nil {
+        return nil, errors.New("error casting to modbus-field")
+    }
+
+    // Decode the data according to the information from the request
+    rb := spi.ReadBufferNew(data)
+    value, err := modbusModel.DataItemParse(rb, field.Datatype, field.Quantity)
+    if err != nil {
+        return nil, err
     }
-    return nil, errors.New("unsupported response type")
+    values := map[string]values.PlcValue{}
+    values[fieldName] = value
+
+    // Return the response
+    return plc4goModel.NewDefaultPlcReadResponse(values), nil
 }
 
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/DataItem.go b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/DataItem.go
index 3329e41..e60410f 100644
--- a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/DataItem.go
+++ b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/DataItem.go
@@ -25,7 +25,7 @@ import (
     api "plc4x.apache.org/plc4go-modbus-driver/v0/pkg/plc4go/values"
 )
 
-func DataItemParse(io *spi.ReadBuffer, dataType string, numberOfValues uint8) (api.PlcValue, error) {
+func DataItemParse(io *spi.ReadBuffer, dataType string, numberOfValues uint16) (api.PlcValue, error) {
     switch {
         case dataType == "IEC61131_BOOL" && numberOfValues == 1: // BOOL
 
@@ -42,6 +42,13 @@ func DataItemParse(io *spi.ReadBuffer, dataType string, numberOfValues uint8) (a
 
             // Array Field (value)
             var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
             return values.NewPlcList(value), nil
         case dataType == "IEC61131_BYTE" && numberOfValues == 1: // BYTE
 
@@ -55,6 +62,13 @@ func DataItemParse(io *spi.ReadBuffer, dataType string, numberOfValues uint8) (a
 
             // Array Field (value)
             var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
             return values.NewPlcList(value), nil
         case dataType == "IEC61131_WORD" && numberOfValues == 1: // WORD
 
@@ -68,6 +82,13 @@ func DataItemParse(io *spi.ReadBuffer, dataType string, numberOfValues uint8) (a
 
             // Array Field (value)
             var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
             return values.NewPlcList(value), nil
         case dataType == "IEC61131_DWORD" && numberOfValues == 1: // DWORD
 
@@ -81,6 +102,13 @@ func DataItemParse(io *spi.ReadBuffer, dataType string, numberOfValues uint8) (a
 
             // Array Field (value)
             var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
             return values.NewPlcList(value), nil
         case dataType == "IEC61131_LWORD" && numberOfValues == 1: // LWORD
 
@@ -94,6 +122,13 @@ func DataItemParse(io *spi.ReadBuffer, dataType string, numberOfValues uint8) (a
 
             // Array Field (value)
             var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
             return values.NewPlcList(value), nil
         case dataType == "IEC61131_SINT" && numberOfValues == 1: // SINT
 
@@ -107,6 +142,13 @@ func DataItemParse(io *spi.ReadBuffer, dataType string, numberOfValues uint8) (a
 
             // Array Field (value)
             var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
             return values.NewPlcList(value), nil
         case dataType == "IEC61131_INT" && numberOfValues == 1: // INT
 
@@ -120,6 +162,13 @@ func DataItemParse(io *spi.ReadBuffer, dataType string, numberOfValues uint8) (a
 
             // Array Field (value)
             var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
             return values.NewPlcList(value), nil
         case dataType == "IEC61131_DINT" && numberOfValues == 1: // DINT
 
@@ -133,6 +182,13 @@ func DataItemParse(io *spi.ReadBuffer, dataType string, numberOfValues uint8) (a
 
             // Array Field (value)
             var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
             return values.NewPlcList(value), nil
         case dataType == "IEC61131_LINT" && numberOfValues == 1: // LINT
 
@@ -146,6 +202,13 @@ func DataItemParse(io *spi.ReadBuffer, dataType string, numberOfValues uint8) (a
 
             // Array Field (value)
             var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
             return values.NewPlcList(value), nil
         case dataType == "IEC61131_USINT" && numberOfValues == 1: // USINT
 
@@ -159,6 +222,13 @@ func DataItemParse(io *spi.ReadBuffer, dataType string, numberOfValues uint8) (a
 
             // Array Field (value)
             var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
             return values.NewPlcList(value), nil
         case dataType == "IEC61131_UINT" && numberOfValues == 1: // UINT
 
@@ -172,6 +242,13 @@ func DataItemParse(io *spi.ReadBuffer, dataType string, numberOfValues uint8) (a
 
             // Array Field (value)
             var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
             return values.NewPlcList(value), nil
         case dataType == "IEC61131_UDINT" && numberOfValues == 1: // UDINT
 
@@ -185,6 +262,13 @@ func DataItemParse(io *spi.ReadBuffer, dataType string, numberOfValues uint8) (a
 
             // Array Field (value)
             var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
             return values.NewPlcList(value), nil
         case dataType == "IEC61131_ULINT" && numberOfValues == 1: // ULINT
 
@@ -198,6 +282,13 @@ func DataItemParse(io *spi.ReadBuffer, dataType string, numberOfValues uint8) (a
 
             // Array Field (value)
             var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
             return values.NewPlcList(value), nil
         case dataType == "IEC61131_REAL" && numberOfValues == 1: // REAL
 
@@ -211,6 +302,13 @@ func DataItemParse(io *spi.ReadBuffer, dataType string, numberOfValues uint8) (a
 
             // Array Field (value)
             var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
             return values.NewPlcList(value), nil
         case dataType == "IEC61131_LREAL" && numberOfValues == 1: // LREAL
 
@@ -224,6 +322,13 @@ func DataItemParse(io *spi.ReadBuffer, dataType string, numberOfValues uint8) (a
 
             // Array Field (value)
             var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
             return values.NewPlcList(value), nil
         case dataType == "IEC61131_CHAR" && numberOfValues == 1: // CHAR
 
@@ -237,6 +342,13 @@ func DataItemParse(io *spi.ReadBuffer, dataType string, numberOfValues uint8) (a
 
             // Array Field (value)
             var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
             return values.NewPlcList(value), nil
         case dataType == "IEC61131_WCHAR" && numberOfValues == 1: // WCHAR
 
@@ -250,6 +362,13 @@ func DataItemParse(io *spi.ReadBuffer, dataType string, numberOfValues uint8) (a
 
             // Array Field (value)
             var value []api.PlcValue
+            for i := 0; i < int(numberOfValues); i++ {
+                _item, _itemErr := DataItemParse(io, dataType, uint16(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
             return values.NewPlcList(value), nil
     }
     return nil, errors.New("unsupported type")
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/DataItem.go b/sandbox/plc4go/internal/plc4go/s7/readwrite/model/DataItem.go
index aa71a0f..c1e47aa 100644
--- a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/DataItem.go
+++ b/sandbox/plc4go/internal/plc4go/s7/readwrite/model/DataItem.go
@@ -42,21 +42,49 @@ func DataItemParse(io *spi.ReadBuffer, dataProtocolId uint8, stringLength int32)
 
             // Array Field (value)
             var value []api.PlcValue
+            for i := 0; i < int((8)); i++ {
+                _item, _itemErr := DataItemParse(io, dataProtocolId, int32(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
             return values.NewPlcList(value), nil
         case dataProtocolId == 12: // BOOL
 
             // Array Field (value)
             var value []api.PlcValue
+            for i := 0; i < int((16)); i++ {
+                _item, _itemErr := DataItemParse(io, dataProtocolId, int32(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
             return values.NewPlcList(value), nil
         case dataProtocolId == 13: // BOOL
 
             // Array Field (value)
             var value []api.PlcValue
+            for i := 0; i < int((32)); i++ {
+                _item, _itemErr := DataItemParse(io, dataProtocolId, int32(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
             return values.NewPlcList(value), nil
         case dataProtocolId == 14: // BOOL
 
             // Array Field (value)
             var value []api.PlcValue
+            for i := 0; i < int((64)); i++ {
+                _item, _itemErr := DataItemParse(io, dataProtocolId, int32(1))
+                if _itemErr != nil {
+                    return nil, errors.New("Error parsing 'value' field " + _itemErr.Error())
+                }
+                value = append(value, _item)
+            }
             return values.NewPlcList(value), nil
         case dataProtocolId == 21: // SINT
 
diff --git a/sandbox/plc4go/internal/plc4go/utils/CastUtils.go b/sandbox/plc4go/internal/plc4go/utils/CastUtils.go
new file mode 100644
index 0000000..5e61297
--- /dev/null
+++ b/sandbox/plc4go/internal/plc4go/utils/CastUtils.go
@@ -0,0 +1,28 @@
+//
+// 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
+//
+//      http://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.
+//
+package utils
+
+func Int8ToUint8(input []int8) []uint8 {
+    output := make([]uint8, len(input))
+    for i, _val := range input {
+        output[i] = uint8(_val)
+    }
+    return output
+}
+