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
+}
+