diff --git a/RELEASE_NOTES b/RELEASE_NOTES index a299b253540..9dc43e96d8c 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -29,6 +29,12 @@ Incompatible changes efficient PlcRawByteArray type is used, that gives users direct access to the bytes returned from the PLC instead of a list of PlcValues. +- The builders for read- and write-requests now process tags + and values on a per-field level. If one field has an invalid + address it will now only fail the one item related to that. + Same applies to values. Only the tag who's value was invalid + will be considered failed and no longer an exception should + be thrown. Bug Fixes --------- diff --git a/plc4go/assets/testing/protocols/ads/DriverTestsuite.xml b/plc4go/assets/testing/protocols/ads/DriverTestsuite.xml index 73ddc897851..3770e9d267e 100644 --- a/plc4go/assets/testing/protocols/ads/DriverTestsuite.xml +++ b/plc4go/assets/testing/protocols/ads/DriverTestsuite.xml @@ -1150,9 +1150,13 @@ - - MAIN.hurz_Struct - + + + + MAIN.hurz_Struct + + + @@ -1160,7 +1164,7 @@ - + OK @@ -1232,7 +1236,7 @@ - + @@ -1580,12 +1584,12 @@ - + OK true - + @@ -1754,20 +1758,20 @@ - + OK true - + - + OK true - + @@ -2040,12 +2044,12 @@ - + OK false - + @@ -2319,12 +2323,12 @@ - + OK false - + @@ -2474,12 +2478,12 @@ - + OK false - + diff --git a/plc4go/assets/testing/protocols/eip/DriverTestsuite.xml b/plc4go/assets/testing/protocols/eip/DriverTestsuite.xml index b18faac99d3..b6eca5cd50c 100644 --- a/plc4go/assets/testing/protocols/eip/DriverTestsuite.xml +++ b/plc4go/assets/testing/protocols/eip/DriverTestsuite.xml @@ -398,11 +398,15 @@ - - %rate - DINT - 1 - + + + + %rate + DINT + 1 + + + @@ -410,12 +414,12 @@ - + OK 369229824 - + diff --git a/plc4go/assets/testing/protocols/modbus/tcp/DriverTestsuite.xml b/plc4go/assets/testing/protocols/modbus/tcp/DriverTestsuite.xml index cad5d8eb6f7..b88fd463e35 100644 --- a/plc4go/assets/testing/protocols/modbus/tcp/DriverTestsuite.xml +++ b/plc4go/assets/testing/protocols/modbus/tcp/DriverTestsuite.xml @@ -109,12 +109,12 @@ - + OK 3.1415927410125732 - + @@ -202,7 +202,7 @@ - + OK @@ -210,7 +210,7 @@ 3.1415927410125732 - + @@ -357,20 +357,20 @@ - + OK 3.1415927410125732 - + - + OK 3.1415927410125732 - + diff --git a/plc4go/assets/testing/protocols/modbus/tcp/DriverTestsuiteOptimized.xml b/plc4go/assets/testing/protocols/modbus/tcp/DriverTestsuiteOptimized.xml index ebd8db39865..ac935f38bee 100644 --- a/plc4go/assets/testing/protocols/modbus/tcp/DriverTestsuiteOptimized.xml +++ b/plc4go/assets/testing/protocols/modbus/tcp/DriverTestsuiteOptimized.xml @@ -97,11 +97,15 @@ - -
0
- 1 - REAL -
+ + + +
0
+ 1 + REAL +
+
+
@@ -109,12 +113,12 @@ - + OK 3.1415927410125732 - + @@ -190,11 +194,15 @@ - -
0
- 2 - REAL -
+ + + +
0
+ 2 + REAL +
+
+
@@ -202,7 +210,7 @@ - + OK @@ -210,7 +218,7 @@ 3.1415927410125732 - + @@ -290,18 +298,26 @@ - -
0
- 1 - REAL -
+ + + +
0
+ 1 + REAL +
+
+
- -
2
- 1 - REAL -
+ + + +
2
+ 1 + REAL +
+
+
@@ -309,20 +325,20 @@ - + OK 3.1415927410125732 - + - + OK 3.1415927410125732 - + @@ -401,19 +417,21 @@ - -
0
- 1 - REAL -
+ + + +
0
+ 1 + REAL +
+
+ + 3.1415927410125732 + +
- - - 3.1415927410125732 - - @@ -498,22 +516,24 @@ - -
0
- 2 - REAL -
+ + + +
0
+ 2 + REAL +
+
+ + + 3.1415927410125732 + 3.1415927410125732 + + +
- - - - 3.1415927410125732 - 3.1415927410125732 - - - diff --git a/plc4go/assets/testing/protocols/modbus/tcp/Modbus-all-datatypes-little-endian.xml b/plc4go/assets/testing/protocols/modbus/tcp/Modbus-all-datatypes-little-endian.xml index 1c01f468725..7e46dc7933f 100644 --- a/plc4go/assets/testing/protocols/modbus/tcp/Modbus-all-datatypes-little-endian.xml +++ b/plc4go/assets/testing/protocols/modbus/tcp/Modbus-all-datatypes-little-endian.xml @@ -101,11 +101,15 @@ - -
0
- 1 - BOOL -
+ + + +
0
+ 1 + BOOL +
+
+
@@ -113,12 +117,12 @@ - + OK true - + @@ -197,19 +201,21 @@ - -
0
- 1 - BOOL -
+ + + +
0
+ 1 + BOOL +
+
+ + true + +
- - - true - - @@ -290,11 +296,15 @@ - -
1
- 1 - BYTE -
+ + + +
1
+ 1 + BYTE +
+
+
@@ -302,12 +312,12 @@ - + OK 42 - + @@ -386,19 +396,21 @@ - -
1
- 1 - BYTE -
+ + + +
1
+ 1 + BYTE +
+
+ + 42 + +
- - - 42 - - @@ -479,11 +491,15 @@ - -
2
- 1 - WORD -
+ + + +
2
+ 1 + WORD +
+
+
@@ -491,12 +507,12 @@ - + OK 42424 - + @@ -575,19 +591,21 @@ - -
2
- 1 - WORD -
+ + + +
2
+ 1 + WORD +
+
+ + 42424 + +
- - - 42424 - - @@ -668,11 +686,15 @@ - -
3
- 1 - DWORD -
+ + + +
3
+ 1 + DWORD +
+
+
@@ -680,12 +702,12 @@ - + OK 4242442424 - + @@ -764,19 +786,21 @@ - -
3
- 1 - DWORD -
+ + + +
3
+ 1 + DWORD +
+
+ + 4242442424 + +
- - - 4242442424 - - @@ -857,11 +881,15 @@ - -
9
- 1 - SINT -
+ + + +
9
+ 1 + SINT +
+
+
@@ -869,12 +897,12 @@ - + OK -42 - + @@ -953,19 +981,21 @@ - -
9
- 1 - SINT -
+ + + +
9
+ 1 + SINT +
+
+ + -42 + +
- - - -42 - - @@ -1046,11 +1076,15 @@ - -
10
- 1 - USINT -
+ + + +
10
+ 1 + USINT +
+
+
@@ -1058,12 +1092,12 @@ - + OK 42 - + @@ -1142,19 +1176,21 @@ - -
10
- 1 - USINT -
+ + + +
10
+ 1 + USINT +
+
+ + 42 + +
- - - 42 - - @@ -1235,11 +1271,15 @@ - -
11
- 1 - INT -
+ + + +
11
+ 1 + INT +
+
+
@@ -1247,12 +1287,12 @@ - + OK -2424 - + @@ -1331,19 +1371,21 @@ - -
11
- 1 - INT -
+ + + +
11
+ 1 + INT +
+
+ + -2424 + +
- - - -2424 - - @@ -1424,11 +1466,15 @@ - -
12
- 1 - UINT -
+ + + +
12
+ 1 + UINT +
+
+
@@ -1436,12 +1482,12 @@ - + OK 42424 - + @@ -1520,19 +1566,21 @@ - -
12
- 1 - UINT -
+ + + +
12
+ 1 + UINT +
+
+ + 42424 + +
- - - 42424 - - @@ -1613,11 +1661,15 @@ - -
13
- 1 - DINT -
+ + + +
13
+ 1 + DINT +
+
+
@@ -1625,12 +1677,12 @@ - + OK -242442424 - + @@ -1709,19 +1761,21 @@ - -
13
- 1 - DINT -
+ + + +
13
+ 1 + DINT +
+
+ + -242442424 + +
- - - -242442424 - - @@ -1802,11 +1856,15 @@ - -
15
- 1 - UDINT -
+ + + +
15
+ 1 + UDINT +
+
+
@@ -1814,12 +1872,12 @@ - + OK 4242442424 - + @@ -1898,19 +1956,21 @@ - -
15
- 1 - UDINT -
+ + + +
15
+ 1 + UDINT +
+
+ + 4242442424 + +
- - - 4242442424 - - @@ -1991,11 +2051,15 @@ - -
17
- 1 - LINT -
+ + + +
17
+ 1 + LINT +
+
+
@@ -2003,12 +2067,12 @@ - + OK -4242442424242424242 - + @@ -2087,19 +2151,21 @@ - -
17
- 1 - LINT -
+ + + +
17
+ 1 + LINT +
+
+ + -4242442424242424242 + +
- - - -4242442424242424242 - - @@ -2180,11 +2246,15 @@ - -
21
- 1 - ULINT -
+ + + +
21
+ 1 + ULINT +
+
+
@@ -2192,12 +2262,12 @@ - + OK 4242442424242424242 - + @@ -2276,19 +2346,21 @@ - -
21
- 1 - ULINT -
+ + + +
21
+ 1 + ULINT +
+
+ + 4242442424242424242 + +
- - - 4242442424242424242 - - @@ -2369,11 +2441,15 @@ - -
25
- 1 - REAL -
+ + + +
25
+ 1 + REAL +
+
+
@@ -2381,12 +2457,12 @@ - + OK 3.1415929794311523 - + @@ -2465,19 +2541,21 @@ - -
25
- 1 - REAL -
+ + + +
25
+ 1 + REAL +
+
+ + 3.1415929794311523 + +
- - - 3.1415929794311523 - - @@ -2558,11 +2636,15 @@ - -
27
- 1 - LREAL -
+ + + +
27
+ 1 + LREAL +
+
+
@@ -2570,12 +2652,12 @@ - + OK 2.71828182846 - + @@ -2654,19 +2736,21 @@ - -
27
- 1 - LREAL -
+ + + +
27
+ 1 + LREAL +
+
+ + 2.71828182846 + +
- - - 2.71828182846 - - diff --git a/plc4go/assets/testing/protocols/modbus/tcp/Modbus-all-datatypes.xml b/plc4go/assets/testing/protocols/modbus/tcp/Modbus-all-datatypes.xml index b3c7d9050c3..938027aff6f 100644 --- a/plc4go/assets/testing/protocols/modbus/tcp/Modbus-all-datatypes.xml +++ b/plc4go/assets/testing/protocols/modbus/tcp/Modbus-all-datatypes.xml @@ -95,11 +95,15 @@ - -
0
- 1 - BOOL -
+ + + +
0
+ 1 + BOOL +
+
+
@@ -107,12 +111,12 @@ - + OK true - + @@ -191,19 +195,21 @@ - -
0
- 1 - BOOL -
+ + + +
0
+ 1 + BOOL +
+
+ + true + +
- - - true - - @@ -284,11 +290,15 @@ - -
1
- 1 - BYTE -
+ + + +
1
+ 1 + BYTE +
+
+
@@ -296,12 +306,12 @@ - + OK 42 - + @@ -380,19 +390,21 @@ - -
1
- 1 - BYTE -
+ + + +
1
+ 1 + BYTE +
+
+ + 42 + +
- - - 42 - - @@ -473,11 +485,15 @@ - -
2
- 1 - WORD -
+ + + +
2
+ 1 + WORD +
+
+
@@ -485,12 +501,12 @@ - + OK 42424 - + @@ -569,19 +585,21 @@ - -
2
- 1 - WORD -
+ + + +
2
+ 1 + WORD +
+
+ + 42424 + +
- - - 42424 - - @@ -662,11 +680,15 @@ - -
3
- 1 - DWORD -
+ + + +
3
+ 1 + DWORD +
+
+
@@ -674,12 +696,12 @@ - + OK 4242442424 - + @@ -758,19 +780,21 @@ - -
3
- 1 - DWORD -
+ + + +
3
+ 1 + DWORD +
+
+ + 4242442424 + +
- - - 4242442424 - - @@ -851,11 +875,15 @@ - -
9
- 1 - SINT -
+ + + +
9
+ 1 + SINT +
+
+
@@ -863,12 +891,12 @@ - + OK -42 - + @@ -947,19 +975,21 @@ - -
9
- 1 - SINT -
+ + + +
9
+ 1 + SINT +
+
+ + -42 + +
- - - -42 - - @@ -1040,11 +1070,15 @@ - -
10
- 1 - USINT -
+ + + +
10
+ 1 + USINT +
+
+
@@ -1052,12 +1086,12 @@ - + OK 42 - + @@ -1136,19 +1170,21 @@ - -
10
- 1 - USINT -
+ + + +
10
+ 1 + USINT +
+
+ + 42 + +
- - - 42 - - @@ -1229,11 +1265,15 @@ - -
11
- 1 - INT -
+ + + +
11
+ 1 + INT +
+
+
@@ -1241,12 +1281,12 @@ - + OK -2424 - + @@ -1325,19 +1365,21 @@ - -
11
- 1 - INT -
+ + + +
11
+ 1 + INT +
+
+ + -2424 + +
- - - -2424 - - @@ -1418,11 +1460,15 @@ - -
12
- 1 - UINT -
+ + + +
12
+ 1 + UINT +
+
+
@@ -1430,12 +1476,12 @@ - + OK 42424 - + @@ -1514,19 +1560,21 @@ - -
12
- 1 - UINT -
+ + + +
12
+ 1 + UINT +
+
+ + 42424 + +
- - - 42424 - - @@ -1607,11 +1655,15 @@ - -
13
- 1 - DINT -
+ + + +
13
+ 1 + DINT +
+
+
@@ -1619,12 +1671,12 @@ - + OK -242442424 - + @@ -1703,19 +1755,21 @@ - -
13
- 1 - DINT -
+ + + +
13
+ 1 + DINT +
+
+ + -242442424 + +
- - - -242442424 - - @@ -1796,11 +1850,15 @@ - -
15
- 1 - UDINT -
+ + + +
15
+ 1 + UDINT +
+
+
@@ -1808,12 +1866,12 @@ - + OK 4242442424 - + @@ -1892,19 +1950,21 @@ - -
15
- 1 - UDINT -
+ + + +
15
+ 1 + UDINT +
+
+ + 4242442424 + +
- - - 4242442424 - - @@ -1985,11 +2045,15 @@ - -
17
- 1 - LINT -
+ + + +
17
+ 1 + LINT +
+
+
@@ -1997,12 +2061,12 @@ - + OK -4242442424242424242 - + @@ -2081,19 +2145,21 @@ - -
17
- 1 - LINT -
+ + + +
17
+ 1 + LINT +
+
+ + -4242442424242424242 + +
- - - -4242442424242424242 - - @@ -2174,11 +2240,15 @@ - -
21
- 1 - ULINT -
+ + + +
21
+ 1 + ULINT +
+
+
@@ -2186,12 +2256,12 @@ - + OK 4242442424242424242 - + @@ -2270,19 +2340,21 @@ - -
21
- 1 - ULINT -
+ + + +
21
+ 1 + ULINT +
+
+ + 4242442424242424242 + +
- - - 4242442424242424242 - - @@ -2363,11 +2435,15 @@ - -
25
- 1 - REAL -
+ + + +
25
+ 1 + REAL +
+
+
@@ -2375,12 +2451,12 @@ - + OK 3.1415929794311523 - + @@ -2459,19 +2535,21 @@ - -
25
- 1 - REAL -
+ + + +
25
+ 1 + REAL +
+
+ + 3.1415929794311523 + +
- - - 3.1415929794311523 - - @@ -2552,11 +2630,15 @@ - -
27
- 1 - LREAL -
+ + + +
27
+ 1 + LREAL +
+
+
@@ -2564,12 +2646,12 @@ - + OK 2.71828182846 - + @@ -2648,19 +2730,21 @@ - -
27
- 1 - LREAL -
+ + + +
27
+ 1 + LREAL +
+
+ + 2.71828182846 + +
- - - 2.71828182846 - - diff --git a/plc4go/assets/testing/protocols/s7/DriverTestsuite.xml b/plc4go/assets/testing/protocols/s7/DriverTestsuite.xml index d870c8b0caa..a62da145862 100644 --- a/plc4go/assets/testing/protocols/s7/DriverTestsuite.xml +++ b/plc4go/assets/testing/protocols/s7/DriverTestsuite.xml @@ -582,12 +582,12 @@ - + OK true - + @@ -730,12 +730,12 @@ - + ACCESS_DENIED - + diff --git a/plc4go/spi/model/DefaultPlcReadResponse.go b/plc4go/spi/model/DefaultPlcReadResponse.go index db3172364aa..23bd17b768a 100644 --- a/plc4go/spi/model/DefaultPlcReadResponse.go +++ b/plc4go/spi/model/DefaultPlcReadResponse.go @@ -30,14 +30,14 @@ var _ apiModel.PlcReadResponse = &DefaultPlcReadResponse{} //go:generate plc4xGenerator -type=DefaultPlcReadResponse type DefaultPlcReadResponse struct { request apiModel.PlcReadRequest - values map[string]*ResponseItem + values map[string]*PlcResponseItem } func NewDefaultPlcReadResponse(request apiModel.PlcReadRequest, responseCodes map[string]apiModel.PlcResponseCode, values map[string]apiValues.PlcValue) apiModel.PlcReadResponse { - valueMap := map[string]*ResponseItem{} + valueMap := map[string]*PlcResponseItem{} for name, code := range responseCodes { value := values[name] - valueMap[name] = NewResponseItem(code, value) + valueMap[name] = NewPlcResponseItem(code, value) } return &DefaultPlcReadResponse{ request: request, diff --git a/plc4go/spi/model/DefaultPlcReadResponse_test.go b/plc4go/spi/model/DefaultPlcReadResponse_test.go index 8f3cd2ae2ee..693ba984c7c 100644 --- a/plc4go/spi/model/DefaultPlcReadResponse_test.go +++ b/plc4go/spi/model/DefaultPlcReadResponse_test.go @@ -32,7 +32,7 @@ import ( func TestDefaultPlcReadResponse_GetRequest(t *testing.T) { type fields struct { request apiModel.PlcReadRequest - values map[string]*ResponseItem + values map[string]*PlcResponseItem } tests := []struct { name string @@ -57,7 +57,7 @@ func TestDefaultPlcReadResponse_GetRequest(t *testing.T) { func TestDefaultPlcReadResponse_GetResponseCode(t *testing.T) { type fields struct { request apiModel.PlcReadRequest - values map[string]*ResponseItem + values map[string]*PlcResponseItem } type args struct { name string @@ -75,7 +75,7 @@ func TestDefaultPlcReadResponse_GetResponseCode(t *testing.T) { { name: "get it", fields: fields{ - values: map[string]*ResponseItem{ + values: map[string]*PlcResponseItem{ "something": { code: apiModel.PlcResponseCode_OK, }, @@ -101,7 +101,7 @@ func TestDefaultPlcReadResponse_GetResponseCode(t *testing.T) { func TestDefaultPlcReadResponse_GetTagNames(t *testing.T) { type fields struct { request apiModel.PlcReadRequest - values map[string]*ResponseItem + values map[string]*PlcResponseItem } tests := []struct { name string @@ -112,7 +112,7 @@ func TestDefaultPlcReadResponse_GetTagNames(t *testing.T) { name: "get it", fields: fields{ request: NewDefaultPlcReadRequest(nil, []string{"tag1", "tag2"}, nil, nil), - values: map[string]*ResponseItem{ + values: map[string]*PlcResponseItem{ "tag1": nil, "tag2": nil, }, @@ -134,7 +134,7 @@ func TestDefaultPlcReadResponse_GetTagNames(t *testing.T) { func TestDefaultPlcReadResponse_GetValue(t *testing.T) { type fields struct { request apiModel.PlcReadRequest - values map[string]*ResponseItem + values map[string]*PlcResponseItem } type args struct { name string @@ -152,7 +152,7 @@ func TestDefaultPlcReadResponse_GetValue(t *testing.T) { { name: "get it", fields: fields{ - values: map[string]*ResponseItem{ + values: map[string]*PlcResponseItem{ "something": { code: apiModel.PlcResponseCode_OK, value: spiValues.NewPlcSTRING("yes"), @@ -179,7 +179,7 @@ func TestDefaultPlcReadResponse_GetValue(t *testing.T) { func TestDefaultPlcReadResponse_IsAPlcMessage(t *testing.T) { type fields struct { request apiModel.PlcReadRequest - values map[string]*ResponseItem + values map[string]*PlcResponseItem } tests := []struct { name string @@ -215,7 +215,7 @@ func TestNewDefaultPlcReadResponse(t *testing.T) { }{ { name: "create it", - want: &DefaultPlcReadResponse{values: map[string]*ResponseItem{}}, + want: &DefaultPlcReadResponse{values: map[string]*PlcResponseItem{}}, }, } for _, tt := range tests { diff --git a/plc4go/spi/model/ResponseItem.go b/plc4go/spi/model/PlcResponseItem.go similarity index 77% rename from plc4go/spi/model/ResponseItem.go rename to plc4go/spi/model/PlcResponseItem.go index 4a08cfc3e4e..92217cca62f 100644 --- a/plc4go/spi/model/ResponseItem.go +++ b/plc4go/spi/model/PlcResponseItem.go @@ -24,23 +24,23 @@ import ( "github.com/apache/plc4x/plc4go/pkg/api/values" ) -//go:generate plc4xGenerator -type=ResponseItem -type ResponseItem struct { +//go:generate plc4xGenerator -type=PlcResponseItem +type PlcResponseItem struct { code apiModel.PlcResponseCode `stringer:"true"` value values.PlcValue } -func NewResponseItem(code apiModel.PlcResponseCode, value values.PlcValue) *ResponseItem { - return &ResponseItem{ +func NewPlcResponseItem(code apiModel.PlcResponseCode, value values.PlcValue) *PlcResponseItem { + return &PlcResponseItem{ code: code, value: value, } } -func (r *ResponseItem) GetCode() apiModel.PlcResponseCode { +func (r *PlcResponseItem) GetCode() apiModel.PlcResponseCode { return r.code } -func (r *ResponseItem) GetValue() values.PlcValue { +func (r *PlcResponseItem) GetValue() values.PlcValue { return r.value } diff --git a/plc4go/spi/model/ResponseItem_plc4xgen.go b/plc4go/spi/model/PlcResponseItem_plc4xgen.go similarity index 85% rename from plc4go/spi/model/ResponseItem_plc4xgen.go rename to plc4go/spi/model/PlcResponseItem_plc4xgen.go index 636f712936e..de9d217a615 100644 --- a/plc4go/spi/model/ResponseItem_plc4xgen.go +++ b/plc4go/spi/model/PlcResponseItem_plc4xgen.go @@ -17,7 +17,7 @@ * under the License. */ -// Code generated by "plc4xGenerator -type=ResponseItem"; DO NOT EDIT. +// Code generated by "plc4xGenerator -type=PlcResponseItem"; DO NOT EDIT. package model @@ -30,7 +30,7 @@ import ( var _ = fmt.Printf -func (d *ResponseItem) Serialize() ([]byte, error) { +func (d *PlcResponseItem) Serialize() ([]byte, error) { if d == nil { return nil, fmt.Errorf("(*DeviceInfoCache)(nil)") } @@ -41,11 +41,11 @@ func (d *ResponseItem) Serialize() ([]byte, error) { return wb.GetBytes(), nil } -func (d *ResponseItem) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error { +func (d *PlcResponseItem) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error { if d == nil { return fmt.Errorf("(*DeviceInfoCache)(nil)") } - if err := writeBuffer.PushContext("ResponseItem"); err != nil { + if err := writeBuffer.PushContext("PlcResponseItem"); err != nil { return err } @@ -71,13 +71,13 @@ func (d *ResponseItem) SerializeWithWriteBuffer(ctx context.Context, writeBuffer } } } - if err := writeBuffer.PopContext("ResponseItem"); err != nil { + if err := writeBuffer.PopContext("PlcResponseItem"); err != nil { return err } return nil } -func (d *ResponseItem) String() string { +func (d *PlcResponseItem) String() string { if alternateStringer, ok := any(d).(utils.AlternateStringer); ok { if alternateString, use := alternateStringer.AlternateString(); use { return alternateString diff --git a/plc4go/spi/model/render_test.go b/plc4go/spi/model/render_test.go index a20556995b1..84e45c1f271 100644 --- a/plc4go/spi/model/render_test.go +++ b/plc4go/spi/model/render_test.go @@ -67,7 +67,7 @@ func TestRenderTest(t *testing.T) { &DefaultPlcWriteRequest{DefaultPlcTagRequest: NewDefaultPlcTagRequest(nil, nil)}, &DefaultPlcWriteRequestResult{}, &DefaultPlcWriteResponse{}, - &ResponseItem{}, + &PlcResponseItem{}, } for _, sut := range suts { t.Run(fmt.Sprintf("%T", sut), func(t *testing.T) { diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/PlcConnection.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/PlcConnection.java index 560e29c9395..54cde7c211b 100644 --- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/PlcConnection.java +++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/PlcConnection.java @@ -22,6 +22,7 @@ import org.apache.plc4x.java.api.messages.*; import org.apache.plc4x.java.api.metadata.PlcConnectionMetadata; import org.apache.plc4x.java.api.model.PlcTag; +import org.apache.plc4x.java.api.value.PlcValue; import java.util.Optional; import java.util.concurrent.CompletableFuture; @@ -63,6 +64,8 @@ public interface PlcConnection extends AutoCloseable { */ Optional parseTagAddress(String tagAddress); + Optional parseTagValue(PlcTag tag, Object... values); + /** * Provides connection metadata. */ diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/exceptions/PlcTagNotFoundException.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/exceptions/PlcTagNotFoundException.java new file mode 100644 index 00000000000..e417d18b9c4 --- /dev/null +++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/exceptions/PlcTagNotFoundException.java @@ -0,0 +1,43 @@ +/* + * 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. + */ +package org.apache.plc4x.java.api.exceptions; + +/** + * Indicates an invalid tag address. + */ +public class PlcTagNotFoundException extends PlcRuntimeException { + + private static final long serialVersionUID = 1L; + private final String tagToBeParsed; + + public PlcTagNotFoundException(String tagToBeParsed) { + super(tagToBeParsed + " not found"); + this.tagToBeParsed = tagToBeParsed; + } + + public PlcTagNotFoundException(String tagToBeParsed, Throwable cause) { + super(tagToBeParsed + " not found", cause); + this.tagToBeParsed = tagToBeParsed; + } + + public String getTagToBeParsed() { + return tagToBeParsed; + } + +} diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcTagRequest.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcTagRequest.java index 3b98fdd01aa..b6a9f08e0e2 100644 --- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcTagRequest.java +++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcTagRequest.java @@ -19,6 +19,7 @@ package org.apache.plc4x.java.api.messages; import org.apache.plc4x.java.api.model.PlcTag; +import org.apache.plc4x.java.api.types.PlcResponseCode; import java.util.LinkedHashSet; import java.util.List; @@ -33,7 +34,9 @@ public interface PlcTagRequest extends PlcRequest { LinkedHashSet getTagNames(); - PlcTag getTag(String name); + PlcResponseCode getTagResponseCode(String tagName); + + PlcTag getTag(String tagName); List getTags(); diff --git a/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/AbEthDriver.java b/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/AbEthDriver.java index c088dc74102..877d8b8274b 100644 --- a/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/AbEthDriver.java +++ b/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/AbEthDriver.java @@ -22,13 +22,11 @@ import org.apache.plc4x.java.abeth.configuration.AbEthConfiguration; import org.apache.plc4x.java.abeth.configuration.AbEthTcpTransportConfiguration; import org.apache.plc4x.java.abeth.tag.AbEthTag; -import org.apache.plc4x.java.abeth.tag.AbEthTagHandler; import org.apache.plc4x.java.abeth.protocol.AbEthProtocolLogic; import org.apache.plc4x.java.abeth.readwrite.CIPEncapsulationPacket; import org.apache.plc4x.java.spi.configuration.PlcConnectionConfiguration; import org.apache.plc4x.java.spi.configuration.PlcTransportConfiguration; import org.apache.plc4x.java.api.model.PlcTag; -import org.apache.plc4x.java.spi.values.PlcValueHandler; import org.apache.plc4x.java.spi.connection.GeneratedDriverBase; import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer; import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer; @@ -77,16 +75,6 @@ protected List getSupportedTransportCodes() { return Collections.singletonList("tcp"); } - @Override - protected AbEthTagHandler getTagHandler() { - return new AbEthTagHandler(); - } - - @Override - protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() { - return new PlcValueHandler(); - } - /** * This protocol doesn't have a disconnect procedure, so there is no need to wait for a login to finish. * @return false diff --git a/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/protocol/AbEthProtocolLogic.java b/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/protocol/AbEthProtocolLogic.java index 35e0d93aa39..d5c25986a23 100644 --- a/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/protocol/AbEthProtocolLogic.java +++ b/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/protocol/AbEthProtocolLogic.java @@ -21,6 +21,7 @@ import org.apache.plc4x.java.abeth.configuration.AbEthConfiguration; import org.apache.plc4x.java.abeth.readwrite.*; import org.apache.plc4x.java.abeth.tag.AbEthTag; +import org.apache.plc4x.java.abeth.tag.AbEthTagHandler; import org.apache.plc4x.java.api.messages.PlcReadRequest; import org.apache.plc4x.java.api.messages.PlcReadResponse; import org.apache.plc4x.java.api.messages.PlcResponse; @@ -30,11 +31,13 @@ import org.apache.plc4x.java.spi.ConversationContext; import org.apache.plc4x.java.spi.Plc4xProtocolBase; import org.apache.plc4x.java.spi.configuration.HasConfiguration; +import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; import org.apache.plc4x.java.spi.transaction.RequestTransactionManager; +import org.apache.plc4x.java.spi.values.DefaultPlcValueHandler; import org.apache.plc4x.java.spi.values.PlcINT; -import org.apache.plc4x.java.spi.values.PlcValueHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -67,6 +70,11 @@ public void setConfiguration(AbEthConfiguration configuration) { this.tm = new RequestTransactionManager(1); } + @Override + public PlcTagHandler getTagHandler() { + return new AbEthTagHandler(); + } + @Override public void close(ConversationContext context) { tm.shutdown(); @@ -74,7 +82,7 @@ public void close(ConversationContext context) { @Override public void onConnect(ConversationContext context) { - logger.debug("Sending COTP Connection Request"); + logger.debug("Sending Connection Request"); CIPEncapsulationConnectionRequest connectionRequest = new CIPEncapsulationConnectionRequest(0L, 0L, emptySenderContext, 0L); context.sendRequest(connectionRequest) @@ -89,7 +97,7 @@ public void onConnect(ConversationContext context) { @Override public CompletableFuture read(PlcReadRequest readRequest) { - // TODO: Warning ... we are senging one request per tag ... the result has to be merged back together ... + // TODO: Warning ... we are sending one request per tag ... the result has to be merged back together ... for (String tagName : readRequest.getTagNames()) { PlcTag tag = readRequest.getTag(tagName); if (!(tag instanceof AbEthTag)) { @@ -115,7 +123,7 @@ public CompletableFuture read(PlcReadRequest readRequest) { CompletableFuture future = new CompletableFuture<>(); RequestTransactionManager.RequestTransaction transaction = tm.startRequest(); - transaction.submit(() -> context.sendRequest(read) + transaction.submit(() -> conversationContext.sendRequest(read) .expectResponse(CIPEncapsulationPacket.class, REQUEST_TIMEOUT) .onTimeout(future::completeExceptionally) .onError((p, e) -> future.completeExceptionally(e)) @@ -141,7 +149,7 @@ public CompletableFuture read(PlcReadRequest readRequest) { private PlcResponse decodeReadResponse( CIPEncapsulationReadResponse plcReadResponse, PlcReadRequest plcReadRequest) { - Map> values = new HashMap<>(); + Map> values = new HashMap<>(); for (String tagName : plcReadRequest.getTagNames()) { AbEthTag tag = (AbEthTag) plcReadRequest.getTag(tagName); PlcResponseCode responseCode = decodeResponseCode(plcReadResponse.getResponse().getStatus()); @@ -157,7 +165,7 @@ private PlcResponse decodeReadResponse( if (data.size() == 1) { plcValue = new PlcINT(data.get(0)); } else { - plcValue = PlcValueHandler.of(data); + plcValue = DefaultPlcValueHandler.of(tag, data); } } break; @@ -166,9 +174,9 @@ private PlcResponse decodeReadResponse( DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse(); List data = df1PTLR.getData(); if (((data.get(1) >> 7) & 1) == 0) { - plcValue = PlcValueHandler.of((data.get(1) << 8) + data.get(0)); // positive number + plcValue = DefaultPlcValueHandler.of(tag, (data.get(1) << 8) + data.get(0)); // positive number } else { - plcValue = PlcValueHandler.of((((~data.get(1) & 0b01111111) << 8) + (-data.get(0) & 0b11111111)) * -1); // negative number + plcValue = DefaultPlcValueHandler.of(tag, (((~data.get(1) & 0b01111111) << 8) + (-data.get(0) & 0b11111111)) * -1); // negative number } } break; @@ -177,9 +185,9 @@ private PlcResponse decodeReadResponse( DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse(); List data = df1PTLR.getData(); if (((data.get(3) >> 7) & 1) == 0) { - plcValue = PlcValueHandler.of((data.get(3) << 24) + (data.get(2) << 16) + (data.get(1) << 8) + data.get(0)); // positive number + plcValue = DefaultPlcValueHandler.of(tag, (data.get(3) << 24) + (data.get(2) << 16) + (data.get(1) << 8) + data.get(0)); // positive number } else { - plcValue = PlcValueHandler.of((((~data.get(3) & 0b01111111) << 24) + ((-data.get(2) & 0b11111111) << 16) + ((-data.get(1) & 0b11111111) << 8) + (-data.get(0) & 0b11111111)) * -1); // negative number + plcValue = DefaultPlcValueHandler.of(tag, (((~data.get(3) & 0b01111111) << 24) + ((-data.get(2) & 0b11111111) << 16) + ((-data.get(1) & 0b11111111) << 8) + (-data.get(0) & 0b11111111)) * -1); // negative number } } break; @@ -188,9 +196,9 @@ private PlcResponse decodeReadResponse( DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse(); List data = df1PTLR.getData(); if (tag.getBitNumber() < 8) { - plcValue = PlcValueHandler.of((data.get(0) & (1 << tag.getBitNumber())) != 0); // read from first byte + plcValue = DefaultPlcValueHandler.of(tag, (data.get(0) & (1 << tag.getBitNumber())) != 0); // read from first byte } else { - plcValue = PlcValueHandler.of((data.get(1) & (1 << (tag.getBitNumber() - 8))) != 0); // read from second byte + plcValue = DefaultPlcValueHandler.of(tag, (data.get(1) & (1 << (tag.getBitNumber() - 8))) != 0); // read from second byte } } break; @@ -202,7 +210,7 @@ private PlcResponse decodeReadResponse( logger.warn("Some other error occurred casting tag {}, TagInformation: {}", tagName, tag, e); } } - ResponseItem result = new ResponseItem<>(responseCode, plcValue); + PlcResponseItem result = new DefaultPlcResponseItem<>(responseCode, plcValue); values.put(tagName, result); } diff --git a/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/protocol/Plc4xAbEthProtocol.java b/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/protocol/Plc4xAbEthProtocol.java index 6c00ce572f1..0d1b1e85b5e 100644 --- a/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/protocol/Plc4xAbEthProtocol.java +++ b/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/protocol/Plc4xAbEthProtocol.java @@ -34,9 +34,9 @@ import org.apache.plc4x.java.spi.events.ConnectedEvent; import org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse; import org.apache.plc4x.java.spi.messages.PlcRequestContainer; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; import org.apache.plc4x.java.spi.values.*; -import org.apache.plc4x.java.spi.values.PlcValueHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -163,7 +163,7 @@ private PlcResponse decodeReadResponse( PlcReadRequest plcReadRequest = (PlcReadRequest) requestContainer.getRequest(); - Map> values = new HashMap<>(); + Map> values = new HashMap<>(); for (String tagName : plcReadRequest.getTagNames()) { AbEthTag tag = (AbEthTag) plcReadRequest.getTag(tagName); PlcResponseCode responseCode = decodeResponseCode(plcReadResponse.getResponse().getStatus()); @@ -179,7 +179,7 @@ private PlcResponse decodeReadResponse( if(data.size() == 1) { plcValue = new PlcINT(data.get(0)); } else { - plcValue = PlcValueHandler.of(data); + plcValue = DefaultPlcValueHandler.of(tag, data); } } break; @@ -188,9 +188,9 @@ private PlcResponse decodeReadResponse( DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse(); List data = df1PTLR.getData(); if (((data.get(1)>> 7) & 1) == 0) { - plcValue = PlcValueHandler.of((data.get(1) << 8) + data.get(0)); // positive number + plcValue = DefaultPlcValueHandler.of(tag, (data.get(1) << 8) + data.get(0)); // positive number } else { - plcValue = PlcValueHandler.of((((~data.get(1) & 0b01111111) << 8) + (-data.get(0) & 0b11111111)) * -1); // negative number + plcValue = DefaultPlcValueHandler.of(tag, (((~data.get(1) & 0b01111111) << 8) + (-data.get(0) & 0b11111111)) * -1); // negative number } } break; @@ -199,9 +199,9 @@ private PlcResponse decodeReadResponse( DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse(); List data = df1PTLR.getData(); if (((data.get(3)>> 7) & 1) == 0) { - plcValue = PlcValueHandler.of((data.get(3) << 24) + (data.get(2) << 16) + (data.get(1) << 8) + data.get(0)); // positive number + plcValue = DefaultPlcValueHandler.of(tag, (data.get(3) << 24) + (data.get(2) << 16) + (data.get(1) << 8) + data.get(0)); // positive number } else { - plcValue = PlcValueHandler.of((((~data.get(3) & 0b01111111) << 24) + ((-data.get(2) & 0b11111111) << 16)+ ((-data.get(1) & 0b11111111) << 8) + (-data.get(0) & 0b11111111)) * -1); // negative number + plcValue = DefaultPlcValueHandler.of(tag, (((~data.get(3) & 0b01111111) << 24) + ((-data.get(2) & 0b11111111) << 16)+ ((-data.get(1) & 0b11111111) << 8) + (-data.get(0) & 0b11111111)) * -1); // negative number } } break; @@ -210,9 +210,9 @@ private PlcResponse decodeReadResponse( DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse(); List data = df1PTLR.getData(); if (tag.getBitNumber() < 8) { - plcValue = PlcValueHandler.of((data.get(0) & (1 << tag.getBitNumber())) != 0); // read from first byte + plcValue = DefaultPlcValueHandler.of(tag, (data.get(0) & (1 << tag.getBitNumber())) != 0); // read from first byte } else { - plcValue = PlcValueHandler.of((data.get(1) & (1 << (tag.getBitNumber() - 8) )) != 0); // read from second byte + plcValue = DefaultPlcValueHandler.of(tag, (data.get(1) & (1 << (tag.getBitNumber() - 8) )) != 0); // read from second byte } } break; @@ -225,7 +225,7 @@ private PlcResponse decodeReadResponse( logger.warn("Some other error occurred casting field {}, TagInformation: {}",tagName, tag,e); } } - ResponseItem result = new ResponseItem<>(responseCode, plcValue); + PlcResponseItem result = new DefaultPlcResponseItem<>(responseCode, plcValue); values.put(tagName, result); } diff --git a/plc4j/drivers/ab-eth/src/test/resources/logback-test.xml b/plc4j/drivers/ab-eth/src/test/resources/logback-test.xml index 2b9cea25dc8..941f1546f84 100644 --- a/plc4j/drivers/ab-eth/src/test/resources/logback-test.xml +++ b/plc4j/drivers/ab-eth/src/test/resources/logback-test.xml @@ -29,7 +29,7 @@ - + diff --git a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/AdsPlcDriver.java b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/AdsPlcDriver.java index 5ea45433677..641bc781afb 100644 --- a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/AdsPlcDriver.java +++ b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/AdsPlcDriver.java @@ -22,14 +22,12 @@ import org.apache.plc4x.java.ads.configuration.AdsConfiguration; import org.apache.plc4x.java.ads.configuration.AdsTcpTransportConfiguration; import org.apache.plc4x.java.ads.discovery.AdsPlcDiscoverer; -import org.apache.plc4x.java.ads.tag.AdsTagHandler; import org.apache.plc4x.java.ads.protocol.AdsProtocolLogic; import org.apache.plc4x.java.ads.readwrite.AmsTCPPacket; import org.apache.plc4x.java.spi.configuration.PlcConnectionConfiguration; import org.apache.plc4x.java.spi.configuration.PlcTransportConfiguration; import org.apache.plc4x.java.api.messages.PlcDiscoveryRequest; import org.apache.plc4x.java.spi.messages.DefaultPlcDiscoveryRequest; -import org.apache.plc4x.java.spi.values.PlcValueHandler; import org.apache.plc4x.java.spi.connection.GeneratedDriverBase; import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer; import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer; @@ -116,16 +114,6 @@ protected List getSupportedTransportCodes() { return Collections.singletonList("tcp"); } - @Override - protected AdsTagHandler getTagHandler() { - return new AdsTagHandler(); - } - - @Override - protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() { - return new PlcValueHandler(); - } - /** * This protocol doesn't have a disconnect procedure, so there is no need to wait for a login to finish. * @return false diff --git a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java index bc4e3089286..5a7e9e47bc1 100644 --- a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java +++ b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java @@ -24,6 +24,7 @@ import org.apache.plc4x.java.ads.model.AdsSubscriptionHandle; import org.apache.plc4x.java.ads.readwrite.*; import org.apache.plc4x.java.ads.tag.AdsTag; +import org.apache.plc4x.java.ads.tag.AdsTagHandler; import org.apache.plc4x.java.ads.tag.DirectAdsStringTag; import org.apache.plc4x.java.ads.tag.DirectAdsTag; import org.apache.plc4x.java.ads.tag.SymbolicAdsTag; @@ -40,9 +41,11 @@ import org.apache.plc4x.java.spi.ConversationContext; import org.apache.plc4x.java.spi.Plc4xProtocolBase; import org.apache.plc4x.java.spi.configuration.HasConfiguration; +import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.generation.*; import org.apache.plc4x.java.spi.messages.*; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; import org.apache.plc4x.java.spi.model.DefaultArrayInfo; import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration; import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionTag; @@ -112,6 +115,11 @@ public void setConfiguration(AdsConfiguration configuration) { this.configuration = configuration; } + @Override + public PlcTagHandler getTagHandler() { + return new AdsTagHandler(); + } + @Override public void onConnect(ConversationContext context) { @@ -247,7 +255,7 @@ protected CompletableFuture setupAmsRoute(PlcUsernamePasswordAuthenticatio new Thread(() -> { LOGGER.debug("Setting up remote AMS routes."); - SocketAddress localSocketAddress = context.getChannel().localAddress(); + SocketAddress localSocketAddress = conversationContext.getChannel().localAddress(); InetAddress localAddress = ((InetSocketAddress) localSocketAddress).getAddress(); // Prepare the request message. @@ -274,7 +282,7 @@ protected CompletableFuture setupAmsRoute(PlcUsernamePasswordAuthenticatio addOrUpdateRouteRequest.serialize(writeBuffer); // Get the target IP from the connection - SocketAddress remoteSocketAddress = context.getChannel().remoteAddress(); + SocketAddress remoteSocketAddress = conversationContext.getChannel().remoteAddress(); InetAddress remoteAddress = ((InetSocketAddress) remoteSocketAddress).getAddress(); // Create the UDP packet to the broadcast address. @@ -513,7 +521,7 @@ public CompletableFuture browseWithInterceptor(PlcBrowseReque itemArrayInfo.add(new DefaultPlcBrowseItemArrayInfo( adsDataTypeArrayInfo.getLowerBound(), adsDataTypeArrayInfo.getUpperBound())); } - DefaultListPlcBrowseItem item = new DefaultListPlcBrowseItem(new SymbolicAdsTag(symbol.getName(), plc4xPlcValueType, arrayInfo), symbol.getName(), + DefaultPlcBrowseItemList item = new DefaultPlcBrowseItemList(new SymbolicAdsTag(symbol.getName(), plc4xPlcValueType, arrayInfo), symbol.getName(), true, !symbol.getFlagReadOnly(), true, false, childMap, options, itemArrayInfo); // Check if this item should be added to the result @@ -576,7 +584,7 @@ protected List getBrowseItems(String basePath, long baseGroupId, adsDataTypeArrayInfo.getLowerBound(), adsDataTypeArrayInfo.getUpperBound())); } // Add the type itself. - values.add(new DefaultListPlcBrowseItem(new SymbolicAdsTag( + values.add(new DefaultPlcBrowseItemList(new SymbolicAdsTag( basePath + "." + child.getPropertyName(), plc4xPlcValueType, arrayInfo), child.getPropertyName(), true, parentWritable, true, false, childMap, options, itemArrayInfo)); } @@ -592,10 +600,10 @@ public CompletableFuture ping(PlcPingRequest pingRequest) { configuration.getSourceAmsNetId(), 800, 0, getInvokeId()); RequestTransactionManager.RequestTransaction readDeviceInfoTx = tm.startRequest(); - readDeviceInfoTx.submit(() -> context.sendRequest(new AmsTCPPacket(readDeviceInfoRequest)) + readDeviceInfoTx.submit(() -> conversationContext.sendRequest(new AmsTCPPacket(readDeviceInfoRequest)) .expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest())) - .onTimeout(e -> context.getChannel().pipeline().fireExceptionCaught(e)) - .onError((p, e) -> context.getChannel().pipeline().fireExceptionCaught(e)) + .onTimeout(e -> conversationContext.getChannel().pipeline().fireExceptionCaught(e)) + .onError((p, e) -> conversationContext.getChannel().pipeline().fireExceptionCaught(e)) .unwrap(AmsTCPPacket::getUserdata) .check(userdata -> userdata.getInvokeId() == readDeviceInfoRequest.getInvokeId()) .only(AdsReadDeviceInfoResponse.class) @@ -672,7 +680,7 @@ protected CompletableFuture singleRead(PlcReadRequest readReque if(directAdsTag == null) { return CompletableFuture.completedFuture(new DefaultPlcReadResponse(readRequest, Collections.singletonMap( readRequest.getTagNames().stream().findFirst().orElseThrow(), - new ResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null)))); + new DefaultPlcResponseItem<>(PlcResponseCode.NOT_FOUND, null)))); } CompletableFuture future = new CompletableFuture<>(); @@ -693,7 +701,7 @@ protected CompletableFuture singleRead(PlcReadRequest readReque // Start a new request-transaction (Is ended in the response-handler) RequestTransactionManager.RequestTransaction transaction = tm.startRequest(); - transaction.submit(() -> context.sendRequest(amsTCPPacket) + transaction.submit(() -> conversationContext.sendRequest(amsTCPPacket) .expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest())) .onTimeout(future::completeExceptionally) .onError((p, e) -> future.completeExceptionally(e)) @@ -766,7 +774,7 @@ protected CompletableFuture multiRead(PlcReadRequest readReques // Start a new request-transaction (Is ended in the response-handler) RequestTransactionManager.RequestTransaction transaction = tm.startRequest(); - transaction.submit(() -> context.sendRequest(amsTCPPacket) + transaction.submit(() -> conversationContext.sendRequest(amsTCPPacket) .expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest())) .onTimeout(future::completeExceptionally) .onError((p, e) -> future.completeExceptionally(e)) @@ -822,11 +830,11 @@ protected PlcReadResponse convertToPlc4xReadResponse(PlcReadRequest readRequest, // Read the values next if (readBuffer != null) { - Map> values = new HashMap<>(); + Map> values = new HashMap<>(); for (String tagName : readRequest.getTagNames()) { // If the response-code was anything but OK, we don't need to parse the payload. if(responseCodes.get(tagName) != PlcResponseCode.OK) { - values.put(tagName, new ResponseItem<>(responseCodes.get(tagName), null)); + values.put(tagName, new DefaultPlcResponseItem<>(responseCodes.get(tagName), null)); } // If the response-code was ok, parse the data returned. else { @@ -849,7 +857,7 @@ private PlcResponseCode parsePlcResponseCode(ReturnCode adsResult) { } } - private ResponseItem parseResponseItem(DirectAdsTag tag, ReadBuffer readBuffer) { + private PlcResponseItem parseResponseItem(DirectAdsTag tag, ReadBuffer readBuffer) { try { String dataTypeName = tag.getPlcDataType(); AdsDataTypeTableEntry adsDataTypeTableEntry; @@ -872,7 +880,7 @@ private ResponseItem parseResponseItem(DirectAdsTag tag, ReadBuffer re // Sometimes the ADS device just sends shorter strings than we asked for. int remainingBytes = readBufferByteBased.getTotalBytes() - readBufferByteBased.getPos(); final int singleStringLength = Math.min(remainingBytes - 1, stringLength); - return new ResponseItem<>(PlcResponseCode.OK, parsePlcValue(plcValueType, adsDataTypeTableEntry, singleStringLength, readBuffer)); + return new DefaultPlcResponseItem<>(PlcResponseCode.OK, parsePlcValue(plcValueType, adsDataTypeTableEntry, singleStringLength, readBuffer)); } else { // Fetch all final PlcValue[] resultItems = IntStream.range(0, tag.getNumberOfElements()).mapToObj(i -> { @@ -883,11 +891,11 @@ private ResponseItem parseResponseItem(DirectAdsTag tag, ReadBuffer re } return null; }).toArray(PlcValue[]::new); - return new ResponseItem<>(PlcResponseCode.OK, PlcValueHandler.of(resultItems)); + return new DefaultPlcResponseItem<>(PlcResponseCode.OK, DefaultPlcValueHandler.of(tag, resultItems)); } } catch (Exception e) { LOGGER.warn(String.format("Error parsing tag item of type: '%s'", tag.getPlcDataType()), e); - return new ResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null); + return new DefaultPlcResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null); } } @@ -1046,7 +1054,7 @@ protected CompletableFuture singleWrite(PlcWriteRequest writeR // Start a new request-transaction (Is ended in the response-handler) RequestTransactionManager.RequestTransaction transaction = tm.startRequest(); - transaction.submit(() -> context.sendRequest(amsTCPPacket) + transaction.submit(() -> conversationContext.sendRequest(amsTCPPacket) .expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest())) .onTimeout(future::completeExceptionally) .onError((p, e) -> future.completeExceptionally(e)) @@ -1124,7 +1132,7 @@ protected CompletableFuture multiWrite(PlcWriteRequest writeRe // Start a new request-transaction (Is ended in the response-handler) RequestTransactionManager.RequestTransaction transaction = tm.startRequest(); - transaction.submit(() -> context.sendRequest(amsTCPPacket) + transaction.submit(() -> conversationContext.sendRequest(amsTCPPacket) .expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest())) .onTimeout(future::completeExceptionally) .onError((p, e) -> future.completeExceptionally(e)) @@ -1329,7 +1337,7 @@ private CompletableFuture executeSubscribe(PlcSubscript }) .collect(Collectors.toList()); - Map> responses = new HashMap<>(); + Map> responses = new HashMap<>(); // Start the first request-transaction (it is ended in the response-handler). RequestTransactionManager.RequestTransaction transaction = tm.startRequest(); @@ -1347,7 +1355,7 @@ private CompletableFuture executeSubscribe(PlcSubscript private Runnable subscribeRecursively(PlcSubscriptionRequest subscriptionRequest, Iterator tagNames, Map resolvedTags, - Map> responses, + Map> responses, CompletableFuture future, Iterator amsTCPPackets, RequestTransactionManager.RequestTransaction transaction) { @@ -1355,7 +1363,7 @@ private Runnable subscribeRecursively(PlcSubscriptionRequest subscriptionRequest AmsTCPPacket packet = amsTCPPackets.next(); boolean hasMorePackets = amsTCPPackets.hasNext(); String tagName = tagNames.next(); - context.sendRequest(packet) + conversationContext.sendRequest(packet) .expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest())) .onTimeout(future::completeExceptionally) .onError((p, e) -> future.completeExceptionally(e)) @@ -1368,7 +1376,7 @@ private Runnable subscribeRecursively(PlcSubscriptionRequest subscriptionRequest AdsDataTypeTableEntry adsDataTypeTableEntry = dataTypeTable.get((resolvedTags.get((AdsTag) subscriptionTag.getTag())).getPlcDataType()); // Collect notification handle from individual response. - responses.put(tagName, new ResponseItem<>( + responses.put(tagName, new DefaultPlcResponseItem<>( parsePlcResponseCode(response.getResult()), new AdsSubscriptionHandle(this, tagName, @@ -1436,7 +1444,7 @@ private Runnable unsubscribeRecursively(PlcUnsubscriptionRequest unsubscriptionR return () -> { AmsTCPPacket packet = amsTCPPackets.next(); boolean hasMorePackets = amsTCPPackets.hasNext(); - context.sendRequest(packet) + conversationContext.sendRequest(packet) .expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest())) .onTimeout(future::completeExceptionally) .onError((p, e) -> future.completeExceptionally(e)) @@ -1498,11 +1506,11 @@ protected void decode(ConversationContext context, AmsTCPPacket ms } } - private Map> convertSampleToPlc4XResult(AdsSubscriptionHandle subscriptionHandle, byte[] data) throws + private Map> convertSampleToPlc4XResult(AdsSubscriptionHandle subscriptionHandle, byte[] data) throws ParseException { - Map> values = new HashMap<>(); + Map> values = new HashMap<>(); ReadBufferByteBased readBuffer = new ReadBufferByteBased(data, ByteOrder.LITTLE_ENDIAN); - values.put(subscriptionHandle.getTagName(), new ResponseItem<>(PlcResponseCode.OK, + values.put(subscriptionHandle.getTagName(), new DefaultPlcResponseItem<>(PlcResponseCode.OK, DataItem.staticParse(readBuffer, getPlcValueTypeForAdsDataType(subscriptionHandle.getAdsDataType()), data.length))); return values; } @@ -1614,7 +1622,7 @@ protected CompletableFuture resolveSingleSymbolicAddress(SymbolicAdsTag sy // Start a new request-transaction (Is ended in the response-handler) RequestTransactionManager.RequestTransaction transaction = tm.startRequest(); - transaction.submit(() -> context.sendRequest(amsTCPPacket) + transaction.submit(() -> conversationContext.sendRequest(amsTCPPacket) .expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest())) .onTimeout(future::completeExceptionally) .onError((p, e) -> future.completeExceptionally(e)) @@ -1665,7 +1673,7 @@ protected CompletableFuture resolveMultipleSymbolicAddresses(List context.sendRequest(amsTCPPacket) + transaction.submit(() -> conversationContext.sendRequest(amsTCPPacket) .expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest())) .onTimeout(future::completeExceptionally) .onError((p, e) -> future.completeExceptionally(e)) diff --git a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/tag/SymbolicAdsTag.java b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/tag/SymbolicAdsTag.java index 8aa5c41cdee..a708ee97a94 100644 --- a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/tag/SymbolicAdsTag.java +++ b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/tag/SymbolicAdsTag.java @@ -37,8 +37,7 @@ */ public class SymbolicAdsTag implements AdsTag { - // TODO: Model the end of this address to allow usage of multi-dimensional arrays. - private static final Pattern SYMBOLIC_ADDRESS_PATTERN = Pattern.compile("^(?.+)"); + private static final Pattern SYMBOLIC_ADDRESS_PATTERN = Pattern.compile("^([\\w_]+)(\"[\"\\d*]\")*(\\.(\\w+)(\"[\"\\d*]\")*)*"); private final String symbolicAddress; @@ -57,9 +56,7 @@ public static SymbolicAdsTag of(String address) { if (!matcher.matches()) { throw new PlcInvalidTagException(address, SYMBOLIC_ADDRESS_PATTERN, "{address}"); } - String symbolicAddress = matcher.group("symbolicAddress"); - - return new SymbolicAdsTag(symbolicAddress, null, Collections.emptyList()); + return new SymbolicAdsTag(address, null, Collections.emptyList()); } public static boolean matches(String address) { @@ -120,4 +117,5 @@ public void serialize(WriteBuffer writeBuffer) throws SerializationException { writeBuffer.popContext(getClass().getSimpleName()); } + } diff --git a/plc4j/drivers/ads/src/test/java/org/apache/plc4x/java/ads/tag/SymbolicAdsTagTest.java b/plc4j/drivers/ads/src/test/java/org/apache/plc4x/java/ads/tag/SymbolicAdsTagTest.java new file mode 100644 index 00000000000..8ec9bc0038c --- /dev/null +++ b/plc4j/drivers/ads/src/test/java/org/apache/plc4x/java/ads/tag/SymbolicAdsTagTest.java @@ -0,0 +1,34 @@ +/* + * 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 org.apache.plc4x.java.ads.tag; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class SymbolicAdsTagTest { + + @Test + void of() { + + + } + +} \ No newline at end of file diff --git a/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/AdsDriverIT.java b/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/AdsDriverIT.java index 15a827b81fc..6f1f5c2c7d9 100644 --- a/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/AdsDriverIT.java +++ b/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/AdsDriverIT.java @@ -24,7 +24,7 @@ public class AdsDriverIT extends DriverTestsuiteRunner { public AdsDriverIT() { - super("/protocols/ads/DriverTestsuite.xml"); + super("/protocols/ads/DriverTestsuite.xml", true); } } diff --git a/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/ManualAdsBrowse.java b/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/ManualAdsBrowse.java index f9240a3c871..5c850d372ea 100644 --- a/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/ManualAdsBrowse.java +++ b/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/ManualAdsBrowse.java @@ -21,14 +21,15 @@ import org.apache.plc4x.java.api.PlcConnection; import org.apache.plc4x.java.api.PlcDriverManager; -import org.apache.plc4x.java.api.messages.PlcBrowseResponse; public class ManualAdsBrowse { public static void main(String[] args) throws Exception { try (PlcConnection connection = PlcDriverManager.getDefault().getConnectionManager().getConnection("ads:tcp://192.168.23.20:48898?target-ams-port=851&source-ams-port=65534&source-ams-net-id=192.168.23.220.1.1&target-ams-net-id=192.168.23.20.1.1")){ - PlcBrowseResponse browseResponse = connection.browseRequestBuilder().addQuery("all", "*").build().execute().get(); - System.out.println(browseResponse); + connection.browseRequestBuilder().addQuery("all", "*").build().executeWithInterceptor(item -> { + System.out.printf("- %s%n", item.getTag().getAddressString()); + return true; + }).get(); } } } diff --git a/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/ManualAdsDriverTest.java b/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/ManualAdsDriverTest.java index b04acbbdf5e..d623a701c00 100644 --- a/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/ManualAdsDriverTest.java +++ b/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/ManualAdsDriverTest.java @@ -26,6 +26,7 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +import java.time.OffsetDateTime; import java.util.HashMap; import java.util.Map; @@ -129,8 +130,12 @@ public static void main(String[] args) throws Exception { children.put("hurz_LTIME", new PlcLTIME(Duration.parse("PT24015H23M12.034002044S"))); children.put("hurz_DATE", new PlcDATE(LocalDate.parse("1978-03-28"))); children.put("hurz_TIME_OF_DAY", new PlcTIME_OF_DAY(LocalTime.parse("15:36:30.123"))); - children.put("hurz_DATE_AND_TIME", new PlcDATE_AND_TIME(LocalDateTime.parse("1996-05-06T15:36:30"))); + children.put("hurz_DATE_AND_TIME", new PlcDATE_AND_TIME(LocalDateTime.parse("1996-05-06T15:36:30").atOffset(OffsetDateTime.now().getOffset()).toLocalDateTime())); test.addTestCase("MAIN.hurz_Struct", new PlcStruct(children)); + //test.addTestCase("MAIN.thisVariableDoesntExist", PlcResponseCode.NOT_FOUND); + // TODO: Add some complex array path + //test.addTestCase("...3323(/987", PlcResponseCode.INVALID_ADDRESS); + //test.addTestCase("MAIN.hurz_UDT_array[4].hurz_INT_array[2].someProperty", PlcResponseCode.NOT_FOUND); test.run(); } diff --git a/plc4j/drivers/bacnet/src/main/java/org/apache/plc4x/java/bacnetip/BacNetIpDriver.java b/plc4j/drivers/bacnet/src/main/java/org/apache/plc4x/java/bacnetip/BacNetIpDriver.java index 28d1e9a2f12..ccffd6ddf5a 100644 --- a/plc4j/drivers/bacnet/src/main/java/org/apache/plc4x/java/bacnetip/BacNetIpDriver.java +++ b/plc4j/drivers/bacnet/src/main/java/org/apache/plc4x/java/bacnetip/BacNetIpDriver.java @@ -25,13 +25,11 @@ import org.apache.plc4x.java.bacnetip.configuration.BacNetPcapReplayTransportConfiguration; import org.apache.plc4x.java.bacnetip.configuration.BacNetRawSocketTransportConfiguration; import org.apache.plc4x.java.bacnetip.configuration.BacNetUdpTransportConfiguration; -import org.apache.plc4x.java.bacnetip.tag.BacNetIpTagHandler; import org.apache.plc4x.java.bacnetip.protocol.BacNetIpProtocolLogic; import org.apache.plc4x.java.bacnetip.readwrite.BVLC; import org.apache.plc4x.java.spi.connection.GeneratedDriverBase; import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer; import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer; -import org.apache.plc4x.java.spi.values.PlcValueHandler; import java.util.Arrays; import java.util.List; @@ -94,16 +92,6 @@ protected boolean canSubscribe() { return true; } - @Override - protected BacNetIpTagHandler getTagHandler() { - return new BacNetIpTagHandler(); - } - - @Override - protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() { - return new PlcValueHandler(); - } - @Override protected ProtocolStackConfigurer getStackConfigurer() { return SingleProtocolStackConfigurer.builder(BVLC.class, BVLC::staticParse) diff --git a/plc4j/drivers/bacnet/src/main/java/org/apache/plc4x/java/bacnetip/protocol/BacNetIpProtocolLogic.java b/plc4j/drivers/bacnet/src/main/java/org/apache/plc4x/java/bacnetip/protocol/BacNetIpProtocolLogic.java index 2eddb897e5b..ecf8b79d403 100644 --- a/plc4j/drivers/bacnet/src/main/java/org/apache/plc4x/java/bacnetip/protocol/BacNetIpProtocolLogic.java +++ b/plc4j/drivers/bacnet/src/main/java/org/apache/plc4x/java/bacnetip/protocol/BacNetIpProtocolLogic.java @@ -32,17 +32,19 @@ import org.apache.plc4x.java.bacnetip.ede.model.EdeModel; import org.apache.plc4x.java.bacnetip.tag.BacNetIpTag; import org.apache.plc4x.java.bacnetip.readwrite.*; +import org.apache.plc4x.java.bacnetip.tag.BacNetIpTagHandler; import org.apache.plc4x.java.spi.ConversationContext; import org.apache.plc4x.java.spi.Plc4xProtocolBase; import org.apache.plc4x.java.spi.configuration.HasConfiguration; +import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionEvent; import org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionResponse; import org.apache.plc4x.java.spi.messages.PlcSubscriber; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration; import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionHandle; import org.apache.plc4x.java.spi.values.*; -import org.apache.plc4x.java.spi.values.PlcValueHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -85,6 +87,11 @@ public void setConfiguration(BacNetIpConfiguration configuration) { } } + @Override + public PlcTagHandler getTagHandler() { + return new BacNetIpTagHandler(); + } + @Override public void onConnect(ConversationContext context) { if (context.isPassive()) { @@ -163,8 +170,8 @@ private void decodeConfirmedRequest(APDUConfirmedRequest apduConfirmedRequest) { enrichedPlcValue.put("address", new PlcSTRING(toString(curTag))); // From the original BACNet tag - enrichedPlcValue.put("tagNumber", PlcValueHandler.of(propertyValue.getPeekedTagHeader().getActualTagNumber())); - enrichedPlcValue.put("lengthValueType", PlcValueHandler.of(propertyValue.getPeekedTagHeader().getActualLength())); + enrichedPlcValue.put("tagNumber", new PlcUSINT(propertyValue.getPeekedTagHeader().getActualTagNumber())); + enrichedPlcValue.put("lengthValueType", new PlcUSINT(propertyValue.getPeekedTagHeader().getActualLength())); // Use the information in the edeModel to enrich the information. if (edeModel != null) { @@ -214,8 +221,8 @@ private void decodeUnconfirmedRequest(APDUUnconfirmedRequest unconfirmedRequest) enrichedPlcValue.put("address", new PlcSTRING(toString(curTag))); // From the original BACNet tag - enrichedPlcValue.put("tagNumber", PlcValueHandler.of(baCnetTag.getActualTagNumber())); - enrichedPlcValue.put("lengthValueType", PlcValueHandler.of(baCnetTag.getActualLength())); + enrichedPlcValue.put("tagNumber", new PlcUSINT(baCnetTag.getActualTagNumber())); + enrichedPlcValue.put("lengthValueType", new PlcUSINT(baCnetTag.getActualLength())); // Use the information in the edeModel to enrich the information. if (edeModel != null) { @@ -244,9 +251,9 @@ private void decodeUnconfirmedRequest(APDUUnconfirmedRequest unconfirmedRequest) @Override public CompletableFuture subscribe(PlcSubscriptionRequest subscriptionRequest) { - Map> values = new HashMap<>(); + Map> values = new HashMap<>(); for (String tagName : subscriptionRequest.getTagNames()) { - values.put(tagName, new ResponseItem<>(PlcResponseCode.OK, new DefaultPlcSubscriptionHandle(this))); + values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, new DefaultPlcSubscriptionHandle(this))); } return CompletableFuture.completedFuture(new DefaultPlcSubscriptionResponse(subscriptionRequest, values)); } @@ -268,7 +275,7 @@ public void unregister(PlcConsumerRegistration plcConsumerRegistration) { protected void publishEvent(BacNetIpTag tag, PlcValue plcValue) { // Create a subscription event from the input. final PlcSubscriptionEvent event = new DefaultPlcSubscriptionEvent(Instant.now(), - Collections.singletonMap("event", new ResponseItem<>(PlcResponseCode.OK, plcValue))); + Collections.singletonMap("event", new DefaultPlcResponseItem<>(PlcResponseCode.OK, plcValue))); // Send the subscription event to all listeners. for (Consumer consumer : consumerIdMap.values()) { diff --git a/plc4j/drivers/bacnet/src/test/resources/logback-test.xml b/plc4j/drivers/bacnet/src/test/resources/logback-test.xml index ad561b1796c..898c2820e6c 100644 --- a/plc4j/drivers/bacnet/src/test/resources/logback-test.xml +++ b/plc4j/drivers/bacnet/src/test/resources/logback-test.xml @@ -28,7 +28,7 @@ - + diff --git a/plc4j/drivers/c-bus/src/main/java/org/apache/plc4x/java/cbus/CBusDriver.java b/plc4j/drivers/c-bus/src/main/java/org/apache/plc4x/java/cbus/CBusDriver.java index 300ffa9450f..1065a50c1bf 100644 --- a/plc4j/drivers/c-bus/src/main/java/org/apache/plc4x/java/cbus/CBusDriver.java +++ b/plc4j/drivers/c-bus/src/main/java/org/apache/plc4x/java/cbus/CBusDriver.java @@ -19,19 +19,15 @@ package org.apache.plc4x.java.cbus; import io.netty.buffer.ByteBuf; -import org.apache.plc4x.java.cbus.readwrite.CBusMessage; import org.apache.plc4x.java.cbus.readwrite.CBusOptions; -import org.apache.plc4x.java.cbus.readwrite.RequestContext; import org.apache.plc4x.java.spi.configuration.PlcConnectionConfiguration; import org.apache.plc4x.java.spi.configuration.PlcTransportConfiguration; -import org.apache.plc4x.java.api.value.PlcValueHandler; import org.apache.plc4x.java.cbus.configuration.CBusConfiguration; import org.apache.plc4x.java.cbus.configuration.CBusTcpTransportConfiguration; import org.apache.plc4x.java.cbus.context.CBusDriverContext; import org.apache.plc4x.java.cbus.protocol.CBusProtocolLogic; import org.apache.plc4x.java.cbus.readwrite.CBusCommand; import org.apache.plc4x.java.spi.connection.GeneratedDriverBase; -import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer; import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer; @@ -83,16 +79,6 @@ protected List getSupportedTransportCodes() { return Collections.singletonList("tcp"); } - @Override - protected PlcTagHandler getTagHandler() { - return null; - } - - @Override - protected PlcValueHandler getValueHandler() { - return null; - } - @Override protected ProtocolStackConfigurer getStackConfigurer() { return SingleProtocolStackConfigurer.builder(CBusCommand.class, io -> diff --git a/plc4j/drivers/c-bus/src/main/java/org/apache/plc4x/java/cbus/protocol/CBusProtocolLogic.java b/plc4j/drivers/c-bus/src/main/java/org/apache/plc4x/java/cbus/protocol/CBusProtocolLogic.java index 7bed821a080..41d27fe5a6e 100644 --- a/plc4j/drivers/c-bus/src/main/java/org/apache/plc4x/java/cbus/protocol/CBusProtocolLogic.java +++ b/plc4j/drivers/c-bus/src/main/java/org/apache/plc4x/java/cbus/protocol/CBusProtocolLogic.java @@ -22,6 +22,7 @@ import org.apache.plc4x.java.cbus.readwrite.CBusCommand; import org.apache.plc4x.java.spi.ConversationContext; import org.apache.plc4x.java.spi.Plc4xProtocolBase; +import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.context.DriverContext; import org.apache.plc4x.java.spi.messages.*; import org.apache.plc4x.java.spi.transaction.RequestTransactionManager; @@ -48,6 +49,11 @@ public void setDriverContext(DriverContext driverContext) { this.tm = new RequestTransactionManager(1); } + @Override + public PlcTagHandler getTagHandler() { + return null; + } + @Override public void close(ConversationContext context) { tm.shutdown(); diff --git a/plc4j/drivers/c-bus/src/test/resources/logback-test.xml b/plc4j/drivers/c-bus/src/test/resources/logback-test.xml index 264277d573f..37b5020ad53 100644 --- a/plc4j/drivers/c-bus/src/test/resources/logback-test.xml +++ b/plc4j/drivers/c-bus/src/test/resources/logback-test.xml @@ -25,7 +25,7 @@ - + diff --git a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/CANDriverAdapter.java b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/CANDriverAdapter.java index 13eecb84536..bbffecdb60e 100644 --- a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/CANDriverAdapter.java +++ b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/CANDriverAdapter.java @@ -32,6 +32,7 @@ import org.apache.plc4x.java.can.adapter.conversation.ConversationContextWrapper; import org.apache.plc4x.java.spi.ConversationContext; import org.apache.plc4x.java.spi.Plc4xProtocolBase; +import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.context.DriverContext; import org.apache.plc4x.java.transport.can.CANTransport.FrameHandler; import org.apache.plc4x.java.transport.can.FrameData; @@ -42,12 +43,14 @@ public class CANDriverAdapter extends Plc4xProtocolBase { private final Class wireType; private final Function adapter; private final FrameHandler frameHandler; + private final PlcTagHandler tagHandler; - public CANDriverAdapter(Plc4xCANProtocolBase delegate, Class wireType, Function adapter, FrameHandler frameHandler) { + public CANDriverAdapter(Plc4xCANProtocolBase delegate, Class wireType, Function adapter, FrameHandler frameHandler, PlcTagHandler tagHandler) { this.delegate = delegate; this.wireType = wireType; this.adapter = adapter; this.frameHandler = frameHandler; + this.tagHandler = tagHandler; } @Override @@ -61,8 +64,13 @@ public DriverContext getDriverContext() { } @Override - public void setContext(ConversationContext context) { - delegate.setContext(new ConversationContextWrapper<>(context, wireType, adapter, frameHandler, context.getAuthentication())); + public void setConversationContext(ConversationContext conversationContext) { + delegate.setConversationContext(new ConversationContextWrapper<>(conversationContext, wireType, adapter, frameHandler, conversationContext.getAuthentication())); + } + + @Override + public PlcTagHandler getTagHandler() { + return tagHandler; } @Override diff --git a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/conversation/DeferredRequestContextWrapper.java b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/conversation/DeferredRequestContextWrapper.java index 0f75fd407a6..c7c31754268 100644 --- a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/conversation/DeferredRequestContextWrapper.java +++ b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/conversation/DeferredRequestContextWrapper.java @@ -19,6 +19,7 @@ package org.apache.plc4x.java.can.adapter.conversation; import java.time.Duration; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeoutException; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -67,6 +68,13 @@ public ContextHandler handle(Consumer packetConsumer) { return delegate.handle(packetConsumer); } + @Override + public CompletableFuture toFuture() { + CompletableFuture future = new CompletableFuture<>(); + handle(future::complete); + return future; + } + @Override public SendRequestContext onTimeout(Consumer packetConsumer) { return new DeferredRequestContextWrapper<>(name, delegate, completer, packetConsumer, errorConsumer); diff --git a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/conversation/ResolvedSendRequestContextWrapper.java b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/conversation/ResolvedSendRequestContextWrapper.java index fa2d7d60535..5fe07e33429 100644 --- a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/conversation/ResolvedSendRequestContextWrapper.java +++ b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/conversation/ResolvedSendRequestContextWrapper.java @@ -19,6 +19,7 @@ package org.apache.plc4x.java.can.adapter.conversation; import java.time.Duration; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeoutException; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -65,6 +66,13 @@ public ContextHandler handle(Consumer packetConsumer) { return delegate.handle(packetConsumer); } + @Override + public CompletableFuture toFuture() { + CompletableFuture future = new CompletableFuture<>(); + handle(future::complete); + return future; + } + @Override public SendRequestContext onTimeout(Consumer packetConsumer) { timeoutHandler.setHandler(packetConsumer); diff --git a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/conversation/SendRequestContextWrapper.java b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/conversation/SendRequestContextWrapper.java index d17e2c0f745..bba458ddabe 100644 --- a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/conversation/SendRequestContextWrapper.java +++ b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/conversation/SendRequestContextWrapper.java @@ -19,6 +19,7 @@ package org.apache.plc4x.java.can.adapter.conversation; import java.time.Duration; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeoutException; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -77,6 +78,13 @@ public ContextHandler handle(Consumer packetConsumer) { throw new IllegalStateException("Not implemented"); } + @Override + public CompletableFuture toFuture() { + CompletableFuture future = new CompletableFuture<>(); + handle(future::complete); + return future; + } + @Override public SendRequestContext onTimeout(Consumer packetConsumer) { throw new IllegalStateException("Not implemented"); diff --git a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/generic/GenericCANDriver.java b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/generic/GenericCANDriver.java index 4d31b799a08..2c7c1413f96 100644 --- a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/generic/GenericCANDriver.java +++ b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/generic/GenericCANDriver.java @@ -18,12 +18,12 @@ */ package org.apache.plc4x.java.can.generic; +import org.apache.plc4x.java.can.generic.tag.GenericCANTagHandler; import org.apache.plc4x.java.spi.configuration.PlcConnectionConfiguration; import org.apache.plc4x.java.api.exceptions.PlcRuntimeException; import org.apache.plc4x.java.can.adapter.CANDriverAdapter; import org.apache.plc4x.java.can.generic.configuration.GenericCANConfiguration; import org.apache.plc4x.java.can.generic.context.GenericCANDriverContext; -import org.apache.plc4x.java.can.generic.tag.GenericCANTagHandler; import org.apache.plc4x.java.can.generic.protocol.GenericCANProtocolLogic; import org.apache.plc4x.java.can.generic.transport.GenericCANFrameDataHandler; import org.apache.plc4x.java.spi.configuration.ConfigurationFactory; @@ -33,7 +33,6 @@ import org.apache.plc4x.java.spi.generation.Message; import org.apache.plc4x.java.spi.optimizer.BaseOptimizer; import org.apache.plc4x.java.spi.transport.Transport; -import org.apache.plc4x.java.spi.values.PlcValueHandler; import org.apache.plc4x.java.transport.can.CANTransport; import java.util.Optional; @@ -80,16 +79,6 @@ protected boolean canWrite() { return true; } - @Override - protected GenericCANTagHandler getTagHandler() { - return new GenericCANTagHandler(); - } - - @Override - protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() { - return new PlcValueHandler(); - } - /** * This protocol doesn't have a disconnect procedure, so there is no need to wait for a login to finish. * @return false @@ -122,7 +111,8 @@ protected ProtocolStackConfigurer getStackConfigurer(Transport transpor ConfigurationFactory.configure(cfg, protocolLogic); return new CANDriverAdapter<>(protocolLogic, canTransport.getMessageType(), canTransport.adapter(), - new GenericCANFrameDataHandler(canTransport::getTransportFrameBuilder) + new GenericCANFrameDataHandler(canTransport::getTransportFrameBuilder), + new GenericCANTagHandler() ); }) .withDriverContext(cfg -> new GenericCANDriverContext()) diff --git a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/generic/protocol/GenericCANProtocolLogic.java b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/generic/protocol/GenericCANProtocolLogic.java index 6d36b2d7b21..f5704b3b6b2 100644 --- a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/generic/protocol/GenericCANProtocolLogic.java +++ b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/generic/protocol/GenericCANProtocolLogic.java @@ -29,16 +29,18 @@ import org.apache.plc4x.java.api.value.PlcValue; import org.apache.plc4x.java.can.adapter.Plc4xCANProtocolBase; import org.apache.plc4x.java.can.generic.tag.GenericCANTag; +import org.apache.plc4x.java.can.generic.tag.GenericCANTagHandler; import org.apache.plc4x.java.can.generic.transport.GenericFrame; import org.apache.plc4x.java.genericcan.readwrite.DataItem; import org.apache.plc4x.java.spi.ConversationContext; +import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.context.DriverContext; import org.apache.plc4x.java.spi.generation.*; import org.apache.plc4x.java.spi.messages.*; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration; import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionTag; -import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionHandle; import org.apache.plc4x.java.spi.transaction.RequestTransactionManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -68,8 +70,13 @@ public void close(ConversationContext context) { } @Override - public void setContext(ConversationContext context) { - super.setContext(context); + public void setConversationContext(ConversationContext conversationContext) { + super.setConversationContext(conversationContext); + } + + @Override + public PlcTagHandler getTagHandler() { + return new GenericCANTagHandler(); } @Override @@ -89,7 +96,7 @@ public void decode(ConversationContext context, GenericFrame msg) Consumer consumer = entry.getValue(); for (PlcSubscriptionHandle handle : registration.getSubscriptionHandles()) { GenericCANSubscriptionHandle subscription = (GenericCANSubscriptionHandle) handle; - Map> tags = new LinkedHashMap<>(); + Map> tags = new LinkedHashMap<>(); ReadBuffer buffer = new ReadBufferByteBased(msg.getData(), ByteOrder.LITTLE_ENDIAN); buffer.pullContext("readTags"); if (subscription.matches(msg.getNodeId())) { @@ -99,12 +106,12 @@ public void decode(ConversationContext context, GenericFrame msg) try { PlcValue value = read(readBuffer, tag.getValue(), data.length); if (value == null) { - tags.put(tag.getKey(), new ResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null)); + tags.put(tag.getKey(), new DefaultPlcResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null)); } else { - tags.put(tag.getKey(), new ResponseItem<>(PlcResponseCode.OK, value)); + tags.put(tag.getKey(), new DefaultPlcResponseItem<>(PlcResponseCode.OK, value)); } } catch (ParseException e) { - tags.put(tag.getKey(), new ResponseItem<>(PlcResponseCode.INVALID_DATA, null)); + tags.put(tag.getKey(), new DefaultPlcResponseItem<>(PlcResponseCode.INVALID_DATA, null)); } } consumer.accept(new DefaultPlcSubscriptionEvent(Instant.now(), tags)); @@ -177,7 +184,7 @@ public CompletableFuture write(PlcWriteRequest writeRequest) { if (!discarded) { byte[] data = message.getValue().getBytes(); logger.debug("Writing message with id {} and {} bytes of data", message.getKey(), data.length); - context.sendToWire(new GenericFrame(message.getKey(), data)); + conversationContext.sendToWire(new GenericFrame(message.getKey(), data)); } } @@ -192,23 +199,23 @@ public CompletableFuture write(PlcWriteRequest writeRequest) { public CompletableFuture subscribe(PlcSubscriptionRequest request) { DefaultPlcSubscriptionRequest rq = (DefaultPlcSubscriptionRequest) request; - Map> answers = new LinkedHashMap<>(); + Map> answers = new LinkedHashMap<>(); DefaultPlcSubscriptionResponse response = new DefaultPlcSubscriptionResponse(rq, answers); Map handles = new LinkedHashMap<>(); for (String key : rq.getTagNames()) { DefaultPlcSubscriptionTag subscription = (DefaultPlcSubscriptionTag) rq.getTag(key); if (subscription.getPlcSubscriptionType() != PlcSubscriptionType.EVENT) { - answers.put(key, new ResponseItem<>(PlcResponseCode.UNSUPPORTED, null)); + answers.put(key, new DefaultPlcResponseItem<>(PlcResponseCode.UNSUPPORTED, null)); } else if (subscription.getTag() instanceof GenericCANTag) { GenericCANTag canTag = (GenericCANTag) subscription.getTag(); GenericCANSubscriptionHandle subscriptionHandle = handles.computeIfAbsent(canTag.getNodeId(), node -> new GenericCANSubscriptionHandle(this, node) ); - answers.put(key, new ResponseItem<>(PlcResponseCode.OK, subscriptionHandle)); + answers.put(key, new DefaultPlcResponseItem<>(PlcResponseCode.OK, subscriptionHandle)); subscriptionHandle.add(key, canTag); } else { - answers.put(key, new ResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null)); + answers.put(key, new DefaultPlcResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null)); } } diff --git a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/generic/tag/GenericCANTag.java b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/generic/tag/GenericCANTag.java index c21db4dfe10..ea8a2d34fef 100644 --- a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/generic/tag/GenericCANTag.java +++ b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/generic/tag/GenericCANTag.java @@ -65,7 +65,7 @@ public PlcValueType getPlcValueType() { @Override public List getArrayInfo() { - if(arraySize != 1) { + if(arraySize > 1) { return Collections.singletonList(new DefaultArrayInfo(0, arraySize)); } return Collections.emptyList(); diff --git a/plc4j/drivers/can/src/test/java/org/apache/plc4x/java/can/generic/GenericCANDriverTest.java b/plc4j/drivers/can/src/test/java/org/apache/plc4x/java/can/generic/GenericCANDriverTest.java index 9ac60d6d3ac..7abd581efe7 100644 --- a/plc4j/drivers/can/src/test/java/org/apache/plc4x/java/can/generic/GenericCANDriverTest.java +++ b/plc4j/drivers/can/src/test/java/org/apache/plc4x/java/can/generic/GenericCANDriverTest.java @@ -19,23 +19,11 @@ package org.apache.plc4x.java.can.generic; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; -import io.netty.buffer.ByteBufUtil; -import io.netty.buffer.Unpooled; -import io.netty.buffer.UnpooledDirectByteBuf; import io.netty.channel.Channel; -import io.netty.channel.ChannelHandlerAdapter; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; -import io.netty.channel.ChannelOutboundHandlerAdapter; -import io.netty.channel.ChannelPromise; -import io.netty.channel.embedded.EmbeddedChannel; import io.netty.channel.embedded.Plc4xEmbeddedChannel; import java.lang.reflect.Array; -import java.util.Arrays; import java.util.Map; import java.util.Map.Entry; -import java.util.Optional; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicReference; @@ -43,14 +31,12 @@ import org.apache.plc4x.java.api.PlcConnection; import org.apache.plc4x.java.api.exceptions.PlcConnectionException; import org.apache.plc4x.java.api.messages.PlcSubscriptionEvent; +import org.apache.plc4x.java.api.messages.PlcSubscriptionRequest; import org.apache.plc4x.java.api.messages.PlcSubscriptionRequest.Builder; import org.apache.plc4x.java.api.messages.PlcWriteRequest; -import org.apache.plc4x.java.api.model.PlcTag; import org.apache.plc4x.java.spi.connection.ChannelExposingConnection; -import org.apache.plc4x.java.spi.values.PlcBYTE; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import org.mockito.internal.util.Primitives; import static java.util.Map.entry; import static org.junit.jupiter.api.Assertions.*; @@ -134,7 +120,8 @@ void subscribeAndWrite(Map> entries) throws Except subscriptionRequestBuilder.addEventTagAddress(k, v.getKey()); }); - subscriptionRequestBuilder.build().execute().whenComplete((reply, error) -> { + PlcSubscriptionRequest subscriptionRequest = subscriptionRequestBuilder.build(); + subscriptionRequest.execute().whenComplete((reply, error) -> { if (error != null) { fail(error); return; @@ -150,7 +137,8 @@ void subscribeAndWrite(Map> entries) throws Except entries.forEach((k, v) -> { writeRequestBuilder.addTagAddress(k, v.getKey(), v.getValue()); }); - writeRequestBuilder.build().execute().whenComplete((reply, error) -> { + PlcWriteRequest writeRequest = writeRequestBuilder.build(); + writeRequest.execute().whenComplete((reply, error) -> { if (error != null) { fail(error); } diff --git a/plc4j/drivers/can/src/test/resources/logback-test.xml b/plc4j/drivers/can/src/test/resources/logback-test.xml index 2b9cea25dc8..941f1546f84 100644 --- a/plc4j/drivers/can/src/test/resources/logback-test.xml +++ b/plc4j/drivers/can/src/test/resources/logback-test.xml @@ -29,7 +29,7 @@ - + diff --git a/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/CANOpenPlcDriver.java b/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/CANOpenPlcDriver.java index 39dce5bd6fa..6d7d6f08dea 100644 --- a/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/CANOpenPlcDriver.java +++ b/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/CANOpenPlcDriver.java @@ -18,6 +18,7 @@ */ package org.apache.plc4x.java.canopen; +import org.apache.plc4x.java.canopen.tag.CANOpenTagHandler; import org.apache.plc4x.java.spi.configuration.PlcConnectionConfiguration; import org.apache.plc4x.java.api.exceptions.PlcRuntimeException; import org.apache.plc4x.java.api.model.PlcTag; @@ -25,7 +26,6 @@ import org.apache.plc4x.java.can.adapter.CANDriverAdapter; import org.apache.plc4x.java.canopen.configuration.CANOpenConfiguration; import org.apache.plc4x.java.canopen.context.CANOpenDriverContext; -import org.apache.plc4x.java.canopen.tag.CANOpenTagHandler; import org.apache.plc4x.java.canopen.protocol.CANOpenProtocolLogic; import org.apache.plc4x.java.canopen.transport.CANOpenFrameDataHandler; import org.apache.plc4x.java.spi.configuration.ConfigurationFactory; @@ -36,6 +36,7 @@ import org.apache.plc4x.java.spi.optimizer.BaseOptimizer; import org.apache.plc4x.java.spi.optimizer.SingleTagOptimizer; import org.apache.plc4x.java.spi.transport.Transport; +import org.apache.plc4x.java.spi.values.DefaultPlcValueHandler; import org.apache.plc4x.java.spi.values.PlcValueHandler; import org.apache.plc4x.java.spi.values.PlcList; import org.apache.plc4x.java.transport.can.CANTransport; @@ -82,13 +83,8 @@ protected Optional getDefaultTransportCode() { } @Override - protected CANOpenTagHandler getTagHandler() { - return new CANOpenTagHandler(); - } - - @Override - protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() { - return new PlcValueHandler() { + protected PlcValueHandler getValueHandler() { + return new DefaultPlcValueHandler() { @Override public PlcValue newPlcValue(PlcTag tag, Object[] values) { if (values[0] instanceof PlcList) { @@ -131,7 +127,8 @@ protected ProtocolStackConfigurer getStackConfigurer(Transport transpor ConfigurationFactory.configure(cfg, protocolLogic); return new CANDriverAdapter<>(protocolLogic, canTransport.getMessageType(), canTransport.adapter(), - new CANOpenFrameDataHandler(canTransport::getTransportFrameBuilder) + new CANOpenFrameDataHandler(canTransport::getTransportFrameBuilder), + new CANOpenTagHandler() ); }) .withDriverContext(cfg -> new CANOpenDriverContext()) diff --git a/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/protocol/CANOpenProtocolLogic.java b/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/protocol/CANOpenProtocolLogic.java index 5caa22a3b50..9124cab003d 100644 --- a/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/protocol/CANOpenProtocolLogic.java +++ b/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/protocol/CANOpenProtocolLogic.java @@ -56,6 +56,7 @@ import org.apache.plc4x.java.canopen.readwrite.NMTStateRequest; import org.apache.plc4x.java.spi.ConversationContext; import org.apache.plc4x.java.spi.configuration.HasConfiguration; +import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.context.DriverContext; import org.apache.plc4x.java.spi.generation.*; import org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse; @@ -66,7 +67,8 @@ import org.apache.plc4x.java.spi.messages.DefaultPlcWriteRequest; import org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse; import org.apache.plc4x.java.spi.messages.PlcSubscriber; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration; import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionTag; import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionHandle; @@ -124,6 +126,11 @@ public void setDriverContext(DriverContext driverContext) { this.tm = new RequestTransactionManager(1); } + @Override + public PlcTagHandler getTagHandler() { + return new CANOpenTagHandler(); + } + @Override public void close(ConversationContext context) { tm.shutdown(); @@ -154,9 +161,9 @@ public void run() { } @Override - public void setContext(ConversationContext context) { - super.setContext(context); - this.conversation = new CANTransportConversation(configuration.getNodeId(), context, configuration.getRequestTimeout()); + public void setConversationContext(ConversationContext conversationContext) { + super.setConversationContext(conversationContext); + this.conversation = new CANTransportConversation(configuration.getNodeId(), conversationContext, configuration.getRequestTimeout()); } private CANOpenFrame createFrame(CANOpenHeartbeatPayload state) throws ParseException { @@ -224,7 +231,7 @@ private void writeInternally(DefaultPlcWriteRequest writeRequest, CANOpenPDOTag WriteBufferByteBased writeBuffer = new WriteBufferByteBased(DataItem.getLengthInBytes(writeValue, tag.getCanOpenDataType(), writeValue.getLength()), ByteOrder.LITTLE_ENDIAN); DataItem.staticSerialize(writeBuffer, writeValue, tag.getCanOpenDataType(), writeValue.getLength(), ByteOrder.LITTLE_ENDIAN); final CANOpenPDOPayload payload = new CANOpenPDOPayload(new CANOpenPDO(writeBuffer.getBytes())); - context.sendToWire(new CANOpenFrame((short) tag.getNodeId(), tag.getService(), payload)); + conversationContext.sendToWire(new CANOpenFrame((short) tag.getNodeId(), tag.getService(), payload)); response.complete(new DefaultPlcWriteResponse(writeRequest, Collections.singletonMap(tagName, PlcResponseCode.OK))); } catch (Exception e) { response.completeExceptionally(e); @@ -257,27 +264,27 @@ public CompletableFuture read(PlcReadRequest readRequest) { public CompletableFuture subscribe(PlcSubscriptionRequest request) { DefaultPlcSubscriptionRequest rq = (DefaultPlcSubscriptionRequest) request; - Map> answers = new LinkedHashMap<>(); + Map> answers = new LinkedHashMap<>(); DefaultPlcSubscriptionResponse response = new DefaultPlcSubscriptionResponse(rq, answers); for (String key : rq.getTagNames()) { DefaultPlcSubscriptionTag subscription = (DefaultPlcSubscriptionTag) rq.getTag(key); if (subscription.getPlcSubscriptionType() != PlcSubscriptionType.EVENT) { - answers.put(key, new ResponseItem<>(PlcResponseCode.UNSUPPORTED, null)); + answers.put(key, new DefaultPlcResponseItem<>(PlcResponseCode.UNSUPPORTED, null)); } else if ((subscription.getTag() instanceof CANOpenPDOTag)) { - answers.put(key, new ResponseItem<>(PlcResponseCode.OK, + answers.put(key, new DefaultPlcResponseItem<>(PlcResponseCode.OK, new CANOpenSubscriptionHandle(this, key, (CANOpenPDOTag) subscription.getTag()) )); } else if ((subscription.getTag() instanceof CANOpenNMTTag)) { - answers.put(key, new ResponseItem<>(PlcResponseCode.OK, + answers.put(key, new DefaultPlcResponseItem<>(PlcResponseCode.OK, new CANOpenSubscriptionHandle(this, key, (CANOpenNMTTag) subscription.getTag()) )); } else if ((subscription.getTag() instanceof CANOpenHeartbeatTag)) { - answers.put(key, new ResponseItem<>(PlcResponseCode.OK, + answers.put(key, new DefaultPlcResponseItem<>(PlcResponseCode.OK, new CANOpenSubscriptionHandle(this, key, (CANOpenHeartbeatTag) subscription.getTag()) )); } else { - answers.put(key, new ResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null)); + answers.put(key, new DefaultPlcResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null)); } } @@ -302,11 +309,11 @@ private void readInternally(PlcReadRequest readRequest, CANOpenSDOTag tag, Compl CompletableFuture callback = new CompletableFuture<>(); callback.whenComplete((value, error) -> { if (error != null) { - Map> tags = new HashMap<>(); + Map> tags = new HashMap<>(); if (error instanceof CANOpenAbortException) { - tags.put(tagName, new ResponseItem<>(PlcResponseCode.REMOTE_ERROR, new PlcLINT(((CANOpenAbortException) error).getAbortCode()))); + tags.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.REMOTE_ERROR, new PlcLINT(((CANOpenAbortException) error).getAbortCode()))); } else { - tags.put(tagName, new ResponseItem<>(PlcResponseCode.REMOTE_ERROR, null)); + tags.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.REMOTE_ERROR, null)); } response.complete(new DefaultPlcReadResponse(readRequest, tags)); transaction.endRequest(); @@ -314,8 +321,8 @@ private void readInternally(PlcReadRequest readRequest, CANOpenSDOTag tag, Compl return; } - Map> tags = new HashMap<>(); - tags.put(tagName, new ResponseItem<>(PlcResponseCode.OK, value)); + Map> tags = new HashMap<>(); + tags.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, value)); response.complete(new DefaultPlcReadResponse(readRequest, tags)); transaction.endRequest(); }); @@ -363,7 +370,7 @@ private void publishEvent(CANOpenService service, int nodeId, CANOpenPayload pay Instant.now(), Collections.singletonMap( handle.getName(), - new ResponseItem<>(PlcResponseCode.OK, value) + new DefaultPlcResponseItem<>(PlcResponseCode.OK, value) ) ); consumer.accept(event); @@ -373,7 +380,7 @@ private void publishEvent(CANOpenService service, int nodeId, CANOpenPayload pay Instant.now(), Collections.singletonMap( handle.getName(), - new ResponseItem<>(PlcResponseCode.INVALID_DATA, new PlcNull()) + new DefaultPlcResponseItem<>(PlcResponseCode.INVALID_DATA, new PlcNull()) ) ); consumer.accept(event); @@ -393,7 +400,7 @@ private void publishEvent(CANOpenService service, int nodeId, CANOpenPayload pay Instant.now(), Collections.singletonMap( handle.getName(), - new ResponseItem<>(PlcResponseCode.OK, struct) + new DefaultPlcResponseItem<>(PlcResponseCode.OK, struct) ) ); consumer.accept(event); @@ -412,7 +419,7 @@ private void publishEvent(CANOpenService service, int nodeId, CANOpenPayload pay Instant.now(), Collections.singletonMap( handle.getName(), - new ResponseItem<>(PlcResponseCode.OK, struct) + new DefaultPlcResponseItem<>(PlcResponseCode.OK, struct) ) ); consumer.accept(event); diff --git a/plc4j/drivers/canopen/src/test/resources/logback-test.xml b/plc4j/drivers/canopen/src/test/resources/logback-test.xml index 2b9cea25dc8..941f1546f84 100644 --- a/plc4j/drivers/canopen/src/test/resources/logback-test.xml +++ b/plc4j/drivers/canopen/src/test/resources/logback-test.xml @@ -29,7 +29,7 @@ - + diff --git a/plc4j/drivers/ctrlx/src/main/java/org/apache/plc4x/java/ctrlx/readwrite/connection/CtrlXConnection.java b/plc4j/drivers/ctrlx/src/main/java/org/apache/plc4x/java/ctrlx/readwrite/connection/CtrlXConnection.java index df09c0bb757..dfff73c39bc 100644 --- a/plc4j/drivers/ctrlx/src/main/java/org/apache/plc4x/java/ctrlx/readwrite/connection/CtrlXConnection.java +++ b/plc4j/drivers/ctrlx/src/main/java/org/apache/plc4x/java/ctrlx/readwrite/connection/CtrlXConnection.java @@ -19,18 +19,19 @@ package org.apache.plc4x.java.ctrlx.readwrite.connection; -import com.hrakaroo.glob.GlobPattern; import com.hrakaroo.glob.MatchingEngine; import org.apache.plc4x.java.api.PlcConnection; import org.apache.plc4x.java.api.exceptions.PlcConnectionException; import org.apache.plc4x.java.api.exceptions.PlcInvalidTagException; import org.apache.plc4x.java.api.exceptions.PlcProtocolException; +import org.apache.plc4x.java.api.exceptions.PlcRuntimeException; import org.apache.plc4x.java.api.messages.*; import org.apache.plc4x.java.api.metadata.PlcConnectionMetadata; import org.apache.plc4x.java.api.model.PlcQuery; import org.apache.plc4x.java.api.model.PlcTag; import org.apache.plc4x.java.api.types.PlcResponseCode; import org.apache.plc4x.java.api.types.PlcValueType; +import org.apache.plc4x.java.api.value.PlcValue; import org.apache.plc4x.java.ctrlx.readwrite.rest.datalayer.ApiClient; import org.apache.plc4x.java.ctrlx.readwrite.rest.datalayer.ApiException; import org.apache.plc4x.java.ctrlx.readwrite.rest.datalayer.api.DataLayerInformationAndSettingsApi; @@ -42,6 +43,8 @@ import org.apache.plc4x.java.ctrlx.readwrite.tag.CtrlXTagHandler; import org.apache.plc4x.java.ctrlx.readwrite.utils.ApiClientFactory; import org.apache.plc4x.java.spi.messages.*; +import org.apache.plc4x.java.spi.values.DefaultPlcValueHandler; +import org.apache.plc4x.java.spi.values.PlcValueHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -60,6 +63,7 @@ public class CtrlXConnection implements PlcConnection, PlcPinger, PlcBrowser { private final String password; private final ExecutorService executorService; + private PlcValueHandler valueHandler; private ApiClient apiClient; private NodesApi nodesApi; @@ -72,6 +76,18 @@ public CtrlXConnection(String baseUrl, String username, String password) { this.username = username; this.password = password; this.executorService = Executors.newFixedThreadPool(10); + this.valueHandler = new DefaultPlcValueHandler(); + } + + @Override + public Optional parseTagValue(PlcTag tag, Object... values) { + PlcValue plcValue; + try { + plcValue = valueHandler.newPlcValue(tag, values); + } catch (Exception e) { + throw new PlcRuntimeException("Error parsing tag value " + tag, e); + } + return Optional.of(plcValue); } @Override @@ -258,7 +274,7 @@ public CompletableFuture browseWithInterceptor(PlcBrowseReque e.printStackTrace(); }*/ matchingQueryNames.forEach(queryName -> responseItems.get(queryName).add( - new DefaultListPlcBrowseItem( + new DefaultPlcBrowseItemList( new CtrlXTag(curNode, PlcValueType.BOOL, Collections.emptyList()), curNode, true, true, true, false, Collections.emptyMap(), Collections.emptyMap(), Collections.emptyList()))); diff --git a/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/base/EIPDriver.java b/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/base/EIPDriver.java index a6d731526bb..02f4be1d48a 100644 --- a/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/base/EIPDriver.java +++ b/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/base/EIPDriver.java @@ -29,7 +29,6 @@ import org.apache.plc4x.java.eip.base.configuration.EipTcpTransportConfiguration; import org.apache.plc4x.java.eip.base.tag.EipTag; import org.apache.plc4x.java.eip.base.protocol.EipProtocolLogic; -import org.apache.plc4x.java.eip.base.tag.EipTagHandler; import org.apache.plc4x.java.eip.readwrite.EipPacket; import org.apache.plc4x.java.spi.configuration.ConfigurationFactory; import org.apache.plc4x.java.spi.configuration.HasConfiguration; @@ -38,8 +37,6 @@ import org.apache.plc4x.java.spi.messages.DefaultPlcDiscoveryRequest; import org.apache.plc4x.java.spi.transport.Transport; -import org.apache.plc4x.java.api.value.PlcValueHandler; - import java.util.Collections; import java.util.List; import java.util.Optional; @@ -92,16 +89,6 @@ protected List getSupportedTransportCodes() { return Collections.singletonList("tcp"); } - @Override - protected PlcTagHandler getTagHandler() { - return new EipTagHandler(); - } - - @Override - protected PlcValueHandler getValueHandler() { - return new org.apache.plc4x.java.spi.values.PlcValueHandler(); - } - @Override public PlcDiscoveryRequest.Builder discoveryRequestBuilder() { return new DefaultPlcDiscoveryRequest.Builder(new EipPlcDiscoverer()); @@ -222,7 +209,6 @@ public PlcConnection getConnection(String connectionString) throws PlcConnection return new DefaultNettyPlcConnection( canPing(), canRead(), canWrite(), canSubscribe(), canBrowse(), - getTagHandler(), getValueHandler(), configuration, channelFactory, diff --git a/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/base/protocol/EipProtocolLogic.java b/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/base/protocol/EipProtocolLogic.java index 1e75cf460e4..14b26360e72 100644 --- a/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/base/protocol/EipProtocolLogic.java +++ b/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/base/protocol/EipProtocolLogic.java @@ -30,11 +30,13 @@ import org.apache.plc4x.java.api.value.PlcValue; import org.apache.plc4x.java.eip.base.configuration.EIPConfiguration; import org.apache.plc4x.java.eip.base.tag.EipTag; +import org.apache.plc4x.java.eip.base.tag.EipTagHandler; import org.apache.plc4x.java.eip.logix.configuration.LogixConfiguration; import org.apache.plc4x.java.eip.readwrite.*; import org.apache.plc4x.java.spi.ConversationContext; import org.apache.plc4x.java.spi.Plc4xProtocolBase; import org.apache.plc4x.java.spi.configuration.HasConfiguration; +import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.generation.ParseException; import org.apache.plc4x.java.spi.generation.ReadBufferByteBased; import org.apache.plc4x.java.spi.generation.SerializationException; @@ -43,7 +45,8 @@ import org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse; import org.apache.plc4x.java.spi.messages.DefaultPlcWriteRequest; import org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; import org.apache.plc4x.java.spi.transaction.RequestTransactionManager; import org.apache.plc4x.java.spi.values.*; import org.slf4j.Logger; @@ -146,6 +149,11 @@ public void setConfiguration(EIPConfiguration configuration) { this.tm = new RequestTransactionManager(1); } + @Override + public PlcTagHandler getTagHandler() { + return new EipTagHandler(); + } + @Override public void close(ConversationContext context) { tm.shutdown(); @@ -445,7 +453,7 @@ public void onDisconnectUnregisterSession(ConversationContext context private CompletableFuture readWithoutMessageRouter(PlcReadRequest readRequest) { CompletableFuture future = new CompletableFuture<>(); - Map> values = new HashMap<>(); + Map> values = new HashMap<>(); List> internalFutures = new ArrayList<>(); PathSegment classSegment = new LogicalSegment(new ClassID((byte) 0, (short) 6)); PathSegment instanceSegment = new LogicalSegment(new InstanceID((byte) 0, (short) 1)); @@ -482,7 +490,7 @@ private CompletableFuture readWithoutMessageRouter(PlcReadReque typeIds); RequestTransactionManager.RequestTransaction transaction = tm.startRequest(); - transaction.submit(() -> context.sendRequest(rrdata) + transaction.submit(() -> conversationContext.sendRequest(rrdata) .expectResponse(EipPacket.class, REQUEST_TIMEOUT) .onTimeout(internalFuture::completeExceptionally) .onError((p, e) -> internalFuture.completeExceptionally(e)) @@ -494,11 +502,11 @@ private CompletableFuture readWithoutMessageRouter(PlcReadReque UnConnectedDataItem dataItem = (UnConnectedDataItem) responseTypeIds.get(1); // If the response indicates an error, handle this. if((dataItem.getService() instanceof CipConnectedResponse) && (((CipConnectedResponse) dataItem.getService()).getStatus() == 0x03)) { - values.put(tagName, new ResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null)); + values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null)); } // Otherwise process the response. else { - Map> readResponse = decodeSingleReadResponse(dataItem.getService(), tagName, eipTag); + Map> readResponse = decodeSingleReadResponse(dataItem.getService(), tagName, eipTag); values.putAll(readResponse); } internalFuture.complete(null); @@ -585,7 +593,7 @@ private CompletableFuture readWithoutConnectionManager(PlcReadR typeIds ); - transaction.submit(() -> context.sendRequest(pkt) + transaction.submit(() -> conversationContext.sendRequest(pkt) .expectResponse(EipPacket.class, REQUEST_TIMEOUT) .onTimeout(future::completeExceptionally) .onError((p, e) -> future.completeExceptionally(e)) @@ -662,7 +670,7 @@ private CompletableFuture readWithConnectionManager(PlcReadRequ this.sequenceCount += 1; - transaction.submit(() -> context.sendRequest(pkt) + transaction.submit(() -> conversationContext.sendRequest(pkt) .expectResponse(EipPacket.class, REQUEST_TIMEOUT) .onTimeout(future::completeExceptionally) .onError((p, e) -> future.completeExceptionally(e)) @@ -732,7 +740,7 @@ public static byte[] toAnsi(String tag) throws SerializationException { } private PlcReadResponse decodeReadResponse(CipService p, PlcReadRequest readRequest) { - Map> values = new HashMap<>(); + Map> values = new HashMap<>(); // only 1 field if (p instanceof CipReadResponse) { CipReadResponse resp = (CipReadResponse) p; @@ -745,7 +753,7 @@ private PlcReadResponse decodeReadResponse(CipService p, PlcReadRequest readRequ if (code == PlcResponseCode.OK) { plcValue = parsePlcValue(tag, data, type); } - ResponseItem result = new ResponseItem<>(code, plcValue); + PlcResponseItem result = new DefaultPlcResponseItem<>(code, plcValue); values.put(fieldName, result); } //Multiple response @@ -790,7 +798,7 @@ else if (p instanceof MultipleServiceResponse) { if (code == PlcResponseCode.OK) { plcValue = parsePlcValue(tag, data, type); } - ResponseItem result = new ResponseItem<>(code, plcValue); + PlcResponseItem result = new DefaultPlcResponseItem<>(code, plcValue); values.put(fieldName, result); } } @@ -798,8 +806,8 @@ else if (p instanceof MultipleServiceResponse) { return new DefaultPlcReadResponse(readRequest, values); } - private Map> decodeSingleReadResponse(CipService p, String tagName, PlcTag tag) { - Map> values = new HashMap<>(); + private Map> decodeSingleReadResponse(CipService p, String tagName, PlcTag tag) { + Map> values = new HashMap<>(); CipReadResponse resp = (CipReadResponse) p; PlcResponseCode code = decodeResponseCode(resp.getStatus()); PlcValue plcValue = null; @@ -808,7 +816,7 @@ private Map> decodeSingleReadResponse(CipService if (code == PlcResponseCode.OK) { plcValue = parsePlcValue((EipTag) tag, data, type); } - ResponseItem result = new ResponseItem<>(code, plcValue); + PlcResponseItem result = new DefaultPlcResponseItem<>(code, plcValue); values.put(tagName, result); return values; } @@ -967,7 +975,7 @@ public CompletableFuture writeWithoutMessageRouter(PlcWriteReq typeIds); RequestTransactionManager.RequestTransaction transaction = tm.startRequest(); - transaction.submit(() -> context.sendRequest(rrdata) + transaction.submit(() -> conversationContext.sendRequest(rrdata) .expectResponse(EipPacket.class, REQUEST_TIMEOUT) .onTimeout(internalFuture::completeExceptionally) .onError((p, e) -> internalFuture.completeExceptionally(e)) @@ -1049,7 +1057,7 @@ public CompletableFuture writeWithoutConnectionManager(PlcWrit 0, typeIds); - transaction.submit(() -> context.sendRequest(rrdata) + transaction.submit(() -> conversationContext.sendRequest(rrdata) .expectResponse(EipPacket.class, REQUEST_TIMEOUT) .onTimeout(future::completeExceptionally) .onError((p, e) -> future.completeExceptionally(e)) @@ -1104,7 +1112,7 @@ public CompletableFuture writeWithoutConnectionManager(PlcWrit 0, typeIds); - transaction.submit(() -> context.sendRequest(pkt) + transaction.submit(() -> conversationContext.sendRequest(pkt) .expectResponse(EipPacket.class, REQUEST_TIMEOUT) .onTimeout(future::completeExceptionally) .onError((p, e) -> future.completeExceptionally(e)) @@ -1168,7 +1176,7 @@ public CompletableFuture writeWithConnectionManager(PlcWriteRe 0, typeIds); - transaction.submit(() -> context.sendRequest(rrdata) + transaction.submit(() -> conversationContext.sendRequest(rrdata) .expectResponse(EipPacket.class, REQUEST_TIMEOUT) .onTimeout(future::completeExceptionally) .onError((p, e) -> future.completeExceptionally(e)) @@ -1214,7 +1222,7 @@ public CompletableFuture writeWithConnectionManager(PlcWriteRe 0, typeIds); - transaction.submit(() -> context.sendRequest(pkt) + transaction.submit(() -> conversationContext.sendRequest(pkt) .expectResponse(EipPacket.class, REQUEST_TIMEOUT) .onTimeout(future::completeExceptionally) .onError((p, e) -> future.completeExceptionally(e)) diff --git a/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/logix/LogixDriver.java b/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/logix/LogixDriver.java index b8bb251d2a9..3a1d971cc1b 100644 --- a/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/logix/LogixDriver.java +++ b/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/logix/LogixDriver.java @@ -21,13 +21,11 @@ import io.netty.buffer.ByteBuf; import org.apache.plc4x.java.spi.configuration.PlcConnectionConfiguration; import org.apache.plc4x.java.spi.configuration.PlcTransportConfiguration; -import org.apache.plc4x.java.api.value.PlcValueHandler; import org.apache.plc4x.java.eip.base.tag.EipTag; import org.apache.plc4x.java.eip.base.protocol.EipProtocolLogic; import org.apache.plc4x.java.eip.logix.configuration.LogixConfiguration; import org.apache.plc4x.java.eip.logix.configuration.LogixTcpTransportConfiguration; import org.apache.plc4x.java.eip.readwrite.EipPacket; -import org.apache.plc4x.java.eip.base.tag.EipTagHandler; import org.apache.plc4x.java.spi.connection.*; import java.util.Collections; @@ -72,16 +70,6 @@ protected List getSupportedTransportCodes() { return Collections.singletonList("tcp"); } - @Override - protected PlcTagHandler getTagHandler() { - return new EipTagHandler(); - } - - @Override - protected PlcValueHandler getValueHandler() { - return new org.apache.plc4x.java.spi.values.PlcValueHandler(); - } - @Override protected boolean awaitDisconnectComplete() { return true; diff --git a/plc4j/drivers/eip/src/test/java/org/apache/plc4x/java/eip/base/EIPDriverIT.java b/plc4j/drivers/eip/src/test/java/org/apache/plc4x/java/eip/base/EIPDriverIT.java index dd18cc68597..0502fbba9b4 100644 --- a/plc4j/drivers/eip/src/test/java/org/apache/plc4x/java/eip/base/EIPDriverIT.java +++ b/plc4j/drivers/eip/src/test/java/org/apache/plc4x/java/eip/base/EIPDriverIT.java @@ -23,7 +23,7 @@ public class EIPDriverIT extends DriverTestsuiteRunner { public EIPDriverIT() { - super("/protocols/eip/DriverTestsuite.xml"); + super("/protocols/eip/DriverTestsuite.xml", false); } } diff --git a/plc4j/drivers/eip/src/test/resources/logback-test.xml b/plc4j/drivers/eip/src/test/resources/logback-test.xml index 2b9cea25dc8..941f1546f84 100644 --- a/plc4j/drivers/eip/src/test/resources/logback-test.xml +++ b/plc4j/drivers/eip/src/test/resources/logback-test.xml @@ -29,7 +29,7 @@ - + diff --git a/plc4j/drivers/firmata/src/main/java/org/apache/plc4x/java/firmata/readwrite/FirmataDriver.java b/plc4j/drivers/firmata/src/main/java/org/apache/plc4x/java/firmata/readwrite/FirmataDriver.java index de494150400..8c38c2d8188 100644 --- a/plc4j/drivers/firmata/src/main/java/org/apache/plc4x/java/firmata/readwrite/FirmataDriver.java +++ b/plc4j/drivers/firmata/src/main/java/org/apache/plc4x/java/firmata/readwrite/FirmataDriver.java @@ -24,11 +24,8 @@ import org.apache.plc4x.java.firmata.readwrite.configuration.FirmataConfiguration; import org.apache.plc4x.java.firmata.readwrite.context.FirmataDriverContext; import org.apache.plc4x.java.firmata.readwrite.tag.FirmataTag; -import org.apache.plc4x.java.firmata.readwrite.tag.FirmataTagHandler; import org.apache.plc4x.java.firmata.readwrite.protocol.FirmataProtocolLogic; -import org.apache.plc4x.java.spi.values.PlcValueHandler; import org.apache.plc4x.java.spi.connection.GeneratedDriverBase; -import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer; import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer; @@ -75,16 +72,6 @@ protected boolean canSubscribe() { return true; } - @Override - protected PlcTagHandler getTagHandler() { - return new FirmataTagHandler(); - } - - @Override - protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() { - return new PlcValueHandler(); - } - /** * This protocol doesn't have a disconnect procedure, so there is no need to wait for a login to finish. * @return false diff --git a/plc4j/drivers/firmata/src/main/java/org/apache/plc4x/java/firmata/readwrite/protocol/FirmataProtocolLogic.java b/plc4j/drivers/firmata/src/main/java/org/apache/plc4x/java/firmata/readwrite/protocol/FirmataProtocolLogic.java index 946414fd141..53179a5fef7 100644 --- a/plc4j/drivers/firmata/src/main/java/org/apache/plc4x/java/firmata/readwrite/protocol/FirmataProtocolLogic.java +++ b/plc4j/drivers/firmata/src/main/java/org/apache/plc4x/java/firmata/readwrite/protocol/FirmataProtocolLogic.java @@ -31,13 +31,16 @@ import org.apache.plc4x.java.firmata.readwrite.tag.FirmataTag; import org.apache.plc4x.java.firmata.readwrite.tag.FirmataTagAnalog; import org.apache.plc4x.java.firmata.readwrite.tag.FirmataTagDigital; +import org.apache.plc4x.java.firmata.readwrite.tag.FirmataTagHandler; import org.apache.plc4x.java.spi.ConversationContext; import org.apache.plc4x.java.spi.Plc4xProtocolBase; +import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionEvent; import org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionResponse; import org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse; import org.apache.plc4x.java.spi.messages.PlcSubscriber; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration; import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionTag; import org.apache.plc4x.java.spi.values.PlcBOOL; @@ -69,6 +72,11 @@ public class FirmataProtocolLogic extends Plc4xProtocolBase impl private final Map> consumers = new ConcurrentHashMap<>(); + @Override + public PlcTagHandler getTagHandler() { + return new FirmataTagHandler(); + } + @Override public void onConnect(ConversationContext context) { LOGGER.debug("Sending Firmata Reset Command"); @@ -106,7 +114,7 @@ public CompletableFuture write(PlcWriteRequest writeRequest) { final List firmataMessages = ((FirmataDriverContext) getDriverContext()).processWriteRequest(writeRequest); for (FirmataMessage firmataMessage : firmataMessages) { - context.sendToWire(firmataMessage); + conversationContext.sendToWire(firmataMessage); } // There's unfortunately no ack response :-( Map result = new HashMap<>(); @@ -127,14 +135,14 @@ public CompletableFuture subscribe(PlcSubscriptionReque final List firmataMessages = ((FirmataDriverContext) getDriverContext()).processSubscriptionRequest(subscriptionRequest); for (FirmataMessage firmataMessage : firmataMessages) { - context.sendToWire(firmataMessage); + conversationContext.sendToWire(firmataMessage); } - Map> result = new HashMap<>(); + Map> result = new HashMap<>(); for (String tagName : subscriptionRequest.getTagNames()) { DefaultPlcSubscriptionTag subscriptionTag = (DefaultPlcSubscriptionTag) subscriptionRequest.getTag(tagName); FirmataTag tag = (FirmataTag) subscriptionTag.getTag(); - result.put(tagName, new ResponseItem<>(PlcResponseCode.OK, + result.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, new FirmataSubscriptionHandle(this, tagName, tag))); } future.complete(new DefaultPlcSubscriptionResponse(subscriptionRequest, result)); @@ -279,13 +287,13 @@ protected void sendUpdateEvents(Consumer consumer, String // If it's just one element, return this as a direct PlcValue if (values.size() == 1) { final PlcSubscriptionEvent event = new DefaultPlcSubscriptionEvent(Instant.now(), - Collections.singletonMap(tagName, new ResponseItem<>(PlcResponseCode.OK, values.get(0)))); + Collections.singletonMap(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, values.get(0)))); consumer.accept(event); } // If it's more, return a PlcList instead. else { final PlcSubscriptionEvent event = new DefaultPlcSubscriptionEvent(Instant.now(), - Collections.singletonMap(tagName, new ResponseItem<>(PlcResponseCode.OK, new PlcList(values)))); + Collections.singletonMap(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, new PlcList(values)))); consumer.accept(event); } } diff --git a/plc4j/drivers/iec-60870/src/main/java/org/apache/plc4x/java/iec608705104/readwrite/Iec60870514PlcDriver.java b/plc4j/drivers/iec-60870/src/main/java/org/apache/plc4x/java/iec608705104/readwrite/Iec60870514PlcDriver.java index 559dde03160..bd0e5c80453 100644 --- a/plc4j/drivers/iec-60870/src/main/java/org/apache/plc4x/java/iec608705104/readwrite/Iec60870514PlcDriver.java +++ b/plc4j/drivers/iec-60870/src/main/java/org/apache/plc4x/java/iec608705104/readwrite/Iec60870514PlcDriver.java @@ -24,11 +24,9 @@ import org.apache.plc4x.java.iec608705104.readwrite.configuration.Iec608705014Configuration; import org.apache.plc4x.java.iec608705104.readwrite.configuration.Iec608705014TcpTransportConfiguration; import org.apache.plc4x.java.iec608705104.readwrite.protocol.Iec608705104Protocol; -import org.apache.plc4x.java.iec608705104.readwrite.tag.Iec608705104TagHandler; import org.apache.plc4x.java.spi.connection.GeneratedDriverBase; import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer; import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer; -import org.apache.plc4x.java.spi.values.PlcValueHandler; import java.util.Collections; import java.util.List; @@ -83,16 +81,6 @@ protected List getSupportedTransportCodes() { return Collections.singletonList("tcp"); } - @Override - protected Iec608705104TagHandler getTagHandler() { - return new Iec608705104TagHandler(); - } - - @Override - protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() { - return new PlcValueHandler(); - } - /** * This protocol doesn't have a disconnect procedure, so there is no need to wait for a login to finish. * @return false diff --git a/plc4j/drivers/iec-60870/src/main/java/org/apache/plc4x/java/iec608705104/readwrite/messages/Iec608705104PlcSubscriptionEvent.java b/plc4j/drivers/iec-60870/src/main/java/org/apache/plc4x/java/iec608705104/readwrite/messages/Iec608705104PlcSubscriptionEvent.java index 25e732f9823..9c336c99ce3 100644 --- a/plc4j/drivers/iec-60870/src/main/java/org/apache/plc4x/java/iec608705104/readwrite/messages/Iec608705104PlcSubscriptionEvent.java +++ b/plc4j/drivers/iec-60870/src/main/java/org/apache/plc4x/java/iec608705104/readwrite/messages/Iec608705104PlcSubscriptionEvent.java @@ -22,7 +22,7 @@ import org.apache.plc4x.java.api.model.PlcTag; import org.apache.plc4x.java.api.value.PlcValue; import org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionEvent; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; import java.time.Instant; import java.util.Map; @@ -30,7 +30,7 @@ public class Iec608705104PlcSubscriptionEvent extends DefaultPlcSubscriptionEvent { private final Map tags; - public Iec608705104PlcSubscriptionEvent(Instant timestamp, Map tags, Map> values) { + public Iec608705104PlcSubscriptionEvent(Instant timestamp, Map tags, Map> values) { super(timestamp, values); this.tags = tags; } diff --git a/plc4j/drivers/iec-60870/src/main/java/org/apache/plc4x/java/iec608705104/readwrite/protocol/Iec608705104Protocol.java b/plc4j/drivers/iec-60870/src/main/java/org/apache/plc4x/java/iec608705104/readwrite/protocol/Iec608705104Protocol.java index 12522494817..61e4a41e2cb 100644 --- a/plc4j/drivers/iec-60870/src/main/java/org/apache/plc4x/java/iec608705104/readwrite/protocol/Iec608705104Protocol.java +++ b/plc4j/drivers/iec-60870/src/main/java/org/apache/plc4x/java/iec608705104/readwrite/protocol/Iec608705104Protocol.java @@ -31,13 +31,16 @@ import org.apache.plc4x.java.iec608705104.readwrite.messages.Iec608705104PlcSubscriptionEvent; import org.apache.plc4x.java.iec608705104.readwrite.model.Iec608705104SubscriptionHandle; import org.apache.plc4x.java.iec608705104.readwrite.tag.Iec608705104Tag; +import org.apache.plc4x.java.iec608705104.readwrite.tag.Iec608705104TagHandler; import org.apache.plc4x.java.spi.ConversationContext; import org.apache.plc4x.java.spi.Plc4xProtocolBase; import org.apache.plc4x.java.spi.configuration.HasConfiguration; +import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionResponse; import org.apache.plc4x.java.spi.messages.PlcBrowser; import org.apache.plc4x.java.spi.messages.PlcSubscriber; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration; import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionTag; import org.apache.plc4x.java.spi.transaction.RequestTransactionManager; @@ -70,6 +73,11 @@ public void setConfiguration(Iec608705014Configuration configuration) { this.configuration = configuration; } + @Override + public PlcTagHandler getTagHandler() { + return new Iec608705104TagHandler(); + } + @Override public void close(ConversationContext context) { tm.shutdown(); @@ -130,13 +138,13 @@ else if (msg instanceof APDUIFormat) { @Override public CompletableFuture subscribe(PlcSubscriptionRequest subscriptionRequest) { - Map> values = new HashMap<>(); + Map> values = new HashMap<>(); for (String tagName : subscriptionRequest.getTagNames()) { final DefaultPlcSubscriptionTag tag = (DefaultPlcSubscriptionTag) subscriptionRequest.getTag(tagName); if (!(tag.getTag() instanceof Iec608705104Tag)) { - values.put(tagName, new ResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null)); + values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null)); } else { - values.put(tagName, new ResponseItem<>(PlcResponseCode.OK, + values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, new Iec608705104SubscriptionHandle(this, (Iec608705104Tag) tag.getTag()))); } } @@ -208,7 +216,7 @@ protected void publishEvent(LocalDateTime timeStamp, Iec608705104Tag tag, PlcVal timeStamp.atZone(ZoneId.systemDefault()).toInstant(), Collections.singletonMap(tag.toString(), tag), Collections.singletonMap(tag.toString(), - new ResponseItem<>(PlcResponseCode.OK, plcValue))); + new DefaultPlcResponseItem<>(PlcResponseCode.OK, plcValue))); // Try sending the subscription event to all listeners. for (Map.Entry> entry : consumers.entrySet()) { diff --git a/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/KnxNetIpDriver.java b/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/KnxNetIpDriver.java index fda82f4442d..5718f34b8cc 100644 --- a/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/KnxNetIpDriver.java +++ b/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/KnxNetIpDriver.java @@ -30,12 +30,9 @@ import org.apache.plc4x.java.knxnetip.context.KnxNetIpDriverContext; import org.apache.plc4x.java.knxnetip.tag.KnxNetIpTag; import org.apache.plc4x.java.knxnetip.readwrite.KnxNetIpMessage; -import org.apache.plc4x.java.knxnetip.tag.KnxNetIpTagHandler; import org.apache.plc4x.java.knxnetip.protocol.KnxNetIpProtocolLogic; import org.apache.plc4x.java.spi.messages.DefaultPlcDiscoveryRequest; -import org.apache.plc4x.java.spi.values.PlcValueHandler; import org.apache.plc4x.java.spi.connection.GeneratedDriverBase; -import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer; import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer; import org.apache.plc4x.java.spi.optimizer.BaseOptimizer; @@ -123,16 +120,6 @@ protected BaseOptimizer getOptimizer() { return new SingleTagOptimizer(); } - @Override - protected PlcTagHandler getTagHandler() { - return new KnxNetIpTagHandler(); - } - - @Override - protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() { - return new PlcValueHandler(); - } - @Override protected boolean awaitDisconnectComplete() { return true; } diff --git a/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/protocol/KnxNetIpProtocolLogic.java b/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/protocol/KnxNetIpProtocolLogic.java index 962cbeb06d2..7b258a86ec6 100644 --- a/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/protocol/KnxNetIpProtocolLogic.java +++ b/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/protocol/KnxNetIpProtocolLogic.java @@ -32,12 +32,15 @@ import org.apache.plc4x.java.knxnetip.model.KnxNetIpSubscriptionHandle; import org.apache.plc4x.java.knxnetip.readwrite.*; import org.apache.plc4x.java.knxnetip.tag.KnxNetIpTag; +import org.apache.plc4x.java.knxnetip.tag.KnxNetIpTagHandler; import org.apache.plc4x.java.spi.ConversationContext; import org.apache.plc4x.java.spi.Plc4xProtocolBase; +import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.context.DriverContext; import org.apache.plc4x.java.spi.generation.*; import org.apache.plc4x.java.spi.messages.*; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration; import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionTag; import org.apache.plc4x.java.spi.transaction.RequestTransactionManager; @@ -80,6 +83,11 @@ public void setDriverContext(DriverContext driverContext) { this.tm = new RequestTransactionManager(1); } + @Override + public PlcTagHandler getTagHandler() { + return new KnxNetIpTagHandler(); + } + @Override public void close(ConversationContext context) { tm.shutdown(); @@ -258,7 +266,7 @@ public CompletableFuture ping(PlcPingRequest pingRequest) { new HPAIControlEndpoint(HostProtocolCode.IPV4_UDP, knxNetIpDriverContext.getLocalIPAddress(), knxNetIpDriverContext.getLocalPort())); - context.sendRequest(connectionStateRequest) + conversationContext.sendRequest(connectionStateRequest) .expectResponse(KnxNetIpMessage.class, Duration.ofMillis(1000)) .only(ConnectionStateResponse.class) .handle(connectionStateResponse -> { @@ -374,7 +382,7 @@ public CompletableFuture write(PlcWriteRequest writeRequest) { // Start a new request-transaction (Is ended in the response-handler) RequestTransactionManager.RequestTransaction transaction = tm.startRequest(); // Start a new request-transaction (Is ended in the response-handler) - transaction.submit(() -> context.sendRequest(knxRequest) + transaction.submit(() -> conversationContext.sendRequest(knxRequest) .expectResponse(KnxNetIpMessage.class, REQUEST_TIMEOUT) .onTimeout(future::completeExceptionally) .onError((tr, e) -> future.completeExceptionally(e)) @@ -540,13 +548,13 @@ protected void processCemiData(KnxAddress sourceAddress, byte[] destinationGroup @Override public CompletableFuture subscribe(PlcSubscriptionRequest subscriptionRequest) { - Map> values = new HashMap<>(); + Map> values = new HashMap<>(); for (String tagName : subscriptionRequest.getTagNames()) { final DefaultPlcSubscriptionTag tag = (DefaultPlcSubscriptionTag) subscriptionRequest.getTag(tagName); if (!(tag.getTag() instanceof KnxNetIpTag)) { - values.put(tagName, new ResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null)); + values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null)); } else { - values.put(tagName, new ResponseItem<>(PlcResponseCode.OK, + values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, new KnxNetIpSubscriptionHandle(this, (KnxNetIpTag) tag.getTag()))); } } @@ -572,7 +580,7 @@ protected void publishEvent(GroupAddress groupAddress, PlcValue plcValue) { // Create a subscription event from the input. // TODO: Check this ... this is sort of not really right ... final PlcSubscriptionEvent event = new DefaultPlcSubscriptionEvent(Instant.now(), - Collections.singletonMap("knxData", new ResponseItem<>(PlcResponseCode.OK, plcValue))); + Collections.singletonMap("knxData", new DefaultPlcResponseItem<>(PlcResponseCode.OK, plcValue))); // Try sending the subscription event to all listeners. for (Map.Entry> entry : consumers.entrySet()) { diff --git a/plc4j/drivers/knxnetip/src/test/java/org/apache/plc4x/java/knxnetip/ManualKnxNetIp.java b/plc4j/drivers/knxnetip/src/test/java/org/apache/plc4x/java/knxnetip/ManualKnxNetIp.java index 7e3a1b32eaa..9cadd0191d6 100644 --- a/plc4j/drivers/knxnetip/src/test/java/org/apache/plc4x/java/knxnetip/ManualKnxNetIp.java +++ b/plc4j/drivers/knxnetip/src/test/java/org/apache/plc4x/java/knxnetip/ManualKnxNetIp.java @@ -38,8 +38,8 @@ public class ManualKnxNetIp { // */*/101: Power Line 1 public static void main(String[] args) throws Exception { - //final PlcConnection connection = new PlcDriverManager().getConnection("knxnet-ip://192.168.42.11?knxproj-file-path=/Users/christofer.dutz/Projects/Apache/PLC4X-Documents/KNX/Stettiner%20Str.%2013/StettinerStr-Soll-Ist-Temperatur.knxproj"); - final PlcConnection connection = new DefaultPlcDriverManager().getConnection("knxnet-ip:pcap:///Users/christofer.dutz/Projects/Apache/PLC4X-Documents/KNX/Recording-01.03.2020-2.pcapng?knxproj-file-path=/Users/christofer.dutz/Projects/Apache/PLC4X-Documents/KNX/Stettiner%20Str.%2013/StettinerStr-Soll-Ist-Temperatur.knxproj"); + final PlcConnection connection = new DefaultPlcDriverManager().getConnection("knxnet-ip://192.168.42.11?knxproj-file-path=/Users/christofer.dutz/Projects/Apache/PLC4X-Documents/KNX/Stettiner%20Str.%2013/StettinerStr-Soll-Ist-Temperatur.knxproj"); + //final PlcConnection connection = new DefaultPlcDriverManager().getConnection("knxnet-ip:pcap:///Users/christofer.dutz/Projects/Apache/PLC4X-Documents/KNX/Recording-01.03.2020-2.pcapng?knxproj-file-path=/Users/christofer.dutz/Projects/Apache/PLC4X-Documents/KNX/Stettiner%20Str.%2013/StettinerStr-Soll-Ist-Temperatur.knxproj"); // Make sure we hang up correctly when terminating. Runtime.getRuntime().addShutdownHook(new Thread(() -> { try { diff --git a/plc4j/drivers/knxnetip/src/test/resources/logback-test.xml b/plc4j/drivers/knxnetip/src/test/resources/logback-test.xml index 33ae65561c2..16b83b4882c 100644 --- a/plc4j/drivers/knxnetip/src/test/resources/logback-test.xml +++ b/plc4j/drivers/knxnetip/src/test/resources/logback-test.xml @@ -27,7 +27,7 @@ - + diff --git a/plc4j/drivers/mock/src/main/java/org/apache/plc4x/java/mock/connection/MockConnection.java b/plc4j/drivers/mock/src/main/java/org/apache/plc4x/java/mock/connection/MockConnection.java index 0ad98b39e66..b3c4d3a3712 100644 --- a/plc4j/drivers/mock/src/main/java/org/apache/plc4x/java/mock/connection/MockConnection.java +++ b/plc4j/drivers/mock/src/main/java/org/apache/plc4x/java/mock/connection/MockConnection.java @@ -21,6 +21,7 @@ import org.apache.commons.lang3.Validate; import org.apache.plc4x.java.api.PlcConnection; import org.apache.plc4x.java.api.authentication.PlcAuthentication; +import org.apache.plc4x.java.api.exceptions.PlcRuntimeException; import org.apache.plc4x.java.api.messages.*; import org.apache.plc4x.java.api.metadata.PlcConnectionMetadata; import org.apache.plc4x.java.api.model.PlcConsumerRegistration; @@ -30,7 +31,8 @@ import org.apache.plc4x.java.api.value.PlcValue; import org.apache.plc4x.java.mock.tag.MockTagHandler; import org.apache.plc4x.java.spi.messages.*; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; +import org.apache.plc4x.java.spi.values.DefaultPlcValueHandler; import org.apache.plc4x.java.spi.values.PlcValueHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,6 +50,8 @@ public class MockConnection implements PlcConnection, PlcReader, PlcWriter, PlcS private static final Logger LOGGER = LoggerFactory.getLogger(MockConnection.class); + private PlcValueHandler valueHandler; + private final PlcAuthentication authentication; private MockDevice device; @@ -63,9 +67,21 @@ public MockDevice getDevice() { private final MockTagHandler mockTagHandler = new MockTagHandler(); public void setDevice(MockDevice device) { LOGGER.info("Set Mock Device on Mock Connection {} with device {}", this, device); + this.valueHandler = new DefaultPlcValueHandler(); this.device = device; } + @Override + public Optional parseTagValue(PlcTag tag, Object... values) { + PlcValue plcValue; + try { + plcValue = valueHandler.newPlcValue(tag, values); + } catch (Exception e) { + throw new PlcRuntimeException("Error parsing tag value " + tag, e); + } + return Optional.of(plcValue); + } + @Override public void connect() { // do nothing @@ -145,7 +161,7 @@ public CompletableFuture read(PlcReadRequest readRequest) { return CompletableFuture.supplyAsync(() -> { Validate.notNull(device, "No device is set in the mock connection!"); LOGGER.debug("Sending read request to MockDevice"); - Map> response = readRequest.getTagNames().stream() + Map> response = readRequest.getTagNames().stream() .collect(Collectors.toMap( Function.identity(), name -> device.read(readRequest.getTag(name).getAddressString()) @@ -175,7 +191,7 @@ public CompletableFuture subscribe(PlcSubscriptionReque return CompletableFuture.supplyAsync(() -> { Validate.notNull(device, "No device is set in the mock connection!"); LOGGER.debug("Sending subsribe request to MockDevice"); - Map> response = subscriptionRequest.getTagNames().stream() + Map> response = subscriptionRequest.getTagNames().stream() .collect(Collectors.toMap( Function.identity(), name -> device.subscribe(subscriptionRequest.getTag(name).getAddressString()) @@ -207,7 +223,7 @@ public void unregister(PlcConsumerRegistration registration) { @Override public PlcWriteRequest.Builder writeRequestBuilder() { - return new DefaultPlcWriteRequest.Builder(this, mockTagHandler, new PlcValueHandler()); + return new DefaultPlcWriteRequest.Builder(this, mockTagHandler, new DefaultPlcValueHandler()); } @Override diff --git a/plc4j/drivers/mock/src/main/java/org/apache/plc4x/java/mock/connection/MockDevice.java b/plc4j/drivers/mock/src/main/java/org/apache/plc4x/java/mock/connection/MockDevice.java index 7537a60fc21..da616037423 100644 --- a/plc4j/drivers/mock/src/main/java/org/apache/plc4x/java/mock/connection/MockDevice.java +++ b/plc4j/drivers/mock/src/main/java/org/apache/plc4x/java/mock/connection/MockDevice.java @@ -18,13 +18,12 @@ */ package org.apache.plc4x.java.mock.connection; -import org.apache.commons.lang3.tuple.Pair; import org.apache.plc4x.java.api.messages.PlcSubscriptionEvent; import org.apache.plc4x.java.api.model.PlcConsumerRegistration; import org.apache.plc4x.java.api.model.PlcSubscriptionHandle; import org.apache.plc4x.java.api.types.PlcResponseCode; import org.apache.plc4x.java.api.value.PlcValue; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; import java.util.Collection; import java.util.function.Consumer; @@ -34,11 +33,11 @@ */ public interface MockDevice { - ResponseItem read(String tagQuery); + PlcResponseItem read(String tagQuery); PlcResponseCode write(String tagQuery, Object value); - ResponseItem subscribe(String tagQuery); + PlcResponseItem subscribe(String tagQuery); void unsubscribe(); diff --git a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/ascii/ModbusAsciiDriver.java b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/ascii/ModbusAsciiDriver.java index c698b342ff8..20006d99fc9 100644 --- a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/ascii/ModbusAsciiDriver.java +++ b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/ascii/ModbusAsciiDriver.java @@ -22,14 +22,11 @@ import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.binary.Hex; import org.apache.plc4x.java.modbus.ascii.context.ModbusAsciiContext; -import org.apache.plc4x.java.modbus.readwrite.ModbusADU; -import org.apache.plc4x.java.modbus.readwrite.ModbusRtuADU; import org.apache.plc4x.java.spi.configuration.PlcConnectionConfiguration; import org.apache.plc4x.java.spi.configuration.PlcTransportConfiguration; import org.apache.plc4x.java.modbus.ascii.config.ModbusAsciiConfiguration; import org.apache.plc4x.java.modbus.ascii.protocol.ModbusAsciiProtocolLogic; import org.apache.plc4x.java.modbus.base.tag.ModbusTag; -import org.apache.plc4x.java.modbus.base.tag.ModbusTagHandler; import org.apache.plc4x.java.modbus.readwrite.DriverType; import org.apache.plc4x.java.modbus.readwrite.ModbusAsciiADU; import org.apache.plc4x.java.modbus.tcp.config.ModbusTcpTransportConfiguration; @@ -39,7 +36,6 @@ import org.apache.plc4x.java.spi.generation.*; import org.apache.plc4x.java.spi.optimizer.BaseOptimizer; import org.apache.plc4x.java.spi.optimizer.SingleTagOptimizer; -import org.apache.plc4x.java.spi.values.PlcValueHandler; import java.nio.charset.StandardCharsets; import java.util.Arrays; @@ -122,16 +118,6 @@ protected BaseOptimizer getOptimizer() { return new SingleTagOptimizer(); } - @Override - protected ModbusTagHandler getTagHandler() { - return new ModbusTagHandler(); - } - - @Override - protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() { - return new PlcValueHandler(); - } - @Override protected ProtocolStackConfigurer getStackConfigurer() { return SingleProtocolStackConfigurer.builder(ModbusAsciiADU.class, new ModbusAsciiInput(), new ModbusAsciiOutput()) diff --git a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/ascii/protocol/ModbusAsciiProtocolLogic.java b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/ascii/protocol/ModbusAsciiProtocolLogic.java index 47b5a86da62..f3f9084eae8 100644 --- a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/ascii/protocol/ModbusAsciiProtocolLogic.java +++ b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/ascii/protocol/ModbusAsciiProtocolLogic.java @@ -26,13 +26,15 @@ import org.apache.plc4x.java.modbus.ascii.config.ModbusAsciiConfiguration; import org.apache.plc4x.java.modbus.base.tag.ModbusTag; import org.apache.plc4x.java.modbus.base.protocol.ModbusProtocolLogic; +import org.apache.plc4x.java.modbus.base.tag.ModbusTagHandler; import org.apache.plc4x.java.modbus.readwrite.*; import org.apache.plc4x.java.modbus.types.ModbusByteOrder; import org.apache.plc4x.java.spi.ConversationContext; import org.apache.plc4x.java.spi.configuration.HasConfiguration; +import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.generation.ParseException; import org.apache.plc4x.java.spi.messages.*; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; import org.apache.plc4x.java.spi.transaction.RequestTransactionManager; import java.time.Duration; @@ -53,6 +55,11 @@ public void setConfiguration(ModbusAsciiConfiguration configuration) { this.tm = new RequestTransactionManager(1); } + @Override + public PlcTagHandler getTagHandler() { + return new ModbusTagHandler(); + } + @Override public void close(ConversationContext context) { tm.shutdown(); @@ -70,7 +77,7 @@ public CompletableFuture ping(PlcPingRequest pingRequest) { ModbusAsciiADU modbusTcpADU = new ModbusAsciiADU(unitId, readRequestPdu); RequestTransactionManager.RequestTransaction transaction = tm.startRequest(); - transaction.submit(() -> context.sendRequest(modbusTcpADU) + transaction.submit(() -> conversationContext.sendRequest(modbusTcpADU) .expectResponse(ModbusAsciiADU.class, requestTimeout) .onTimeout(future::completeExceptionally) .onError((p, e) -> future.completeExceptionally(e)) @@ -106,7 +113,7 @@ public CompletableFuture read(PlcReadRequest readRequest) { ModbusAsciiADU modbusAsciiADU = new ModbusAsciiADU(unitId, requestPdu); RequestTransactionManager.RequestTransaction transaction = tm.startRequest(); - transaction.submit(() -> context.sendRequest(modbusAsciiADU) + transaction.submit(() -> conversationContext.sendRequest(modbusAsciiADU) .expectResponse(ModbusAsciiADU.class, requestTimeout) .onTimeout(future::completeExceptionally) .onError((p, e) -> future.completeExceptionally(e)) @@ -135,7 +142,7 @@ public CompletableFuture read(PlcReadRequest readRequest) { // Prepare the response. PlcReadResponse response = new DefaultPlcReadResponse(request, - Collections.singletonMap(tagName, new ResponseItem<>(responseCode, plcValue))); + Collections.singletonMap(tagName, new DefaultPlcResponseItem<>(responseCode, plcValue))); // Pass the response back to the application. future.complete(response); @@ -169,7 +176,7 @@ public CompletableFuture write(PlcWriteRequest writeRequest) { final short unitId = getUnitId(tag); ModbusAsciiADU modbusAsciiADU = new ModbusAsciiADU(unitId, requestPdu); RequestTransactionManager.RequestTransaction transaction = tm.startRequest(); - transaction.submit(() -> context.sendRequest(modbusAsciiADU) + transaction.submit(() -> conversationContext.sendRequest(modbusAsciiADU) .expectResponse(ModbusAsciiADU.class, requestTimeout) .onTimeout(future::completeExceptionally) .onError((p, e) -> future.completeExceptionally(e)) diff --git a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/base/optimizer/ModbusOptimizer.java b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/base/optimizer/ModbusOptimizer.java index d88998472b1..78b092282c7 100644 --- a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/base/optimizer/ModbusOptimizer.java +++ b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/base/optimizer/ModbusOptimizer.java @@ -45,7 +45,10 @@ import org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest; import org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse; import org.apache.plc4x.java.spi.messages.PlcReader; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcTagItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcTagItem; import org.apache.plc4x.java.spi.optimizer.SingleTagOptimizer; import org.apache.plc4x.java.spi.values.PlcBOOL; import org.slf4j.Logger; @@ -179,12 +182,12 @@ protected PlcReadResponse processReadResponses(PlcReadRequest readRequest, Map

> values = new HashMap<>(); + Map> values = new HashMap<>(); for (String tagName : readRequest.getTagNames()) { ModbusTag modbusTag = (ModbusTag) readRequest.getTag(tagName); String tagType = modbusTag.getClass().getSimpleName().substring("ModbusTag".length()); if (!responses.containsKey(tagType)) { - values.put(tagName, new ResponseItem<>(PlcResponseCode.NOT_FOUND, null)); + values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.NOT_FOUND, null)); continue; } // Go through all responses till we find one where that contains the current tag's data. @@ -197,7 +200,7 @@ protected PlcReadResponse processReadResponses(PlcReadRequest readRequest, Map

(response.getResponseCode(), null)); + values.put(tagName, new DefaultPlcResponseItem<>(response.getResponseCode(), null)); break; } @@ -210,7 +213,7 @@ protected PlcReadResponse processReadResponses(PlcReadRequest readRequest, Map

(PlcResponseCode.OK, new PlcBOOL(isBitSet))); + values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, new PlcBOOL(isBitSet))); break; } } @@ -222,7 +225,7 @@ else if (response.matchesRegister(modbusTag)) { // current request exceeds the address range, all items in this chunk will fail, even // if only one element was invalid. if(response.getResponseCode() != PlcResponseCode.OK) { - values.put(tagName, new ResponseItem<>(response.getResponseCode(), null)); + values.put(tagName, new DefaultPlcResponseItem<>(response.getResponseCode(), null)); break; } @@ -232,16 +235,16 @@ else if (response.matchesRegister(modbusTag)) { PlcValue plcValue = DataItem.staticParse(readBuffer, modbusTag.getDataType(), modbusTag.getNumberOfElements(), modbusContext.getByteOrder() == ModbusByteOrder.BIG_ENDIAN); - values.put(tagName, new ResponseItem<>(PlcResponseCode.OK, plcValue)); + values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, plcValue)); } catch (ParseException e) { - values.put(tagName, new ResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null)); + values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null)); } break; } } // If no response was found that contains the data, that's probably something we need to fix. if (!values.containsKey(tagName)) { - values.put(tagName, new ResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null)); + values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null)); } } @@ -302,8 +305,8 @@ protected List processCoilRequests(TreeSet tags, PlcR // finish this one and start a new one. if (tag.getAddress() + (sizeInCoils * tag.getNumberOfElements()) > maxCoilCurRequest) { // Finish the current sub-request - LinkedHashMap subTags = new LinkedHashMap<>(); - subTags.put("coils" + subRequests.size(), new ModbusTagCoil(firstCoil, lastCoil - firstCoil, ModbusDataType.BYTE, Collections.emptyMap())); + LinkedHashMap subTags = new LinkedHashMap<>(); + subTags.put("coils" + subRequests.size(), new DefaultPlcTagItem(new ModbusTagCoil(firstCoil, lastCoil - firstCoil, ModbusDataType.BYTE, Collections.emptyMap()))); subRequests.add(new DefaultPlcReadRequest(reader, subTags)); // Re-initialize the structures for the next request. @@ -318,8 +321,8 @@ protected List processCoilRequests(TreeSet tags, PlcR } // Finish the last sub-request - LinkedHashMap subTags = new LinkedHashMap<>(); - subTags.put("coils" + subRequests.size(), new ModbusTagCoil(firstCoil, lastCoil - firstCoil, ModbusDataType.BYTE, Collections.emptyMap())); + LinkedHashMap subTags = new LinkedHashMap<>(); + subTags.put("coils" + subRequests.size(), new DefaultPlcTagItem(new ModbusTagCoil(firstCoil, lastCoil - firstCoil, ModbusDataType.BYTE, Collections.emptyMap()))); subRequests.add(new DefaultPlcReadRequest(reader, subTags)); return subRequests; } @@ -343,8 +346,8 @@ protected List processRegisterRequests(TreeSet tags, // finish this one and start a new one. if (tag.getAddress() + (sizeInRegisters * tag.getNumberOfElements()) > maxRegisterCurRequest) { // Finish the current sub-request - LinkedHashMap subTags = new LinkedHashMap<>(); - subTags.put("registers" + subRequests.size(), tagFactory.createTag(firstRegister, lastRegister - firstRegister, ModbusDataType.WORD)); + LinkedHashMap subTags = new LinkedHashMap<>(); + subTags.put("registers" + subRequests.size(), new DefaultPlcTagItem(tagFactory.createTag(firstRegister, lastRegister - firstRegister, ModbusDataType.WORD))); subRequests.add(new DefaultPlcReadRequest(reader, subTags)); // Re-initialize the structures for the next request. @@ -359,8 +362,8 @@ protected List processRegisterRequests(TreeSet tags, } // Finish the last sub-request - LinkedHashMap subTags = new LinkedHashMap<>(); - subTags.put("registers" + subRequests.size(), tagFactory.createTag(firstRegister, lastRegister - firstRegister, ModbusDataType.WORD)); + LinkedHashMap subTags = new LinkedHashMap<>(); + subTags.put("registers" + subRequests.size(), new DefaultPlcTagItem(tagFactory.createTag(firstRegister, lastRegister - firstRegister, ModbusDataType.WORD))); subRequests.add(new DefaultPlcReadRequest(reader, subTags)); return subRequests; } diff --git a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/base/tag/ModbusTag.java b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/base/tag/ModbusTag.java index ba571f9ae12..2f8baa1e54d 100644 --- a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/base/tag/ModbusTag.java +++ b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/base/tag/ModbusTag.java @@ -75,7 +75,7 @@ public String getAddressString() { address += ":" + getDataType().name(); } if(!getArrayInfo().isEmpty()) { - address += "[" + getArrayInfo().get(0).getUpperBound() + "]"; + address += "[" + (getArrayInfo().get(0).getUpperBound() + 1) + "]"; } return address; } @@ -158,7 +158,7 @@ public PlcValueType getPlcValueType() { @Override public List getArrayInfo() { if(quantity != 1) { - return Collections.singletonList(new DefaultArrayInfo(0, quantity)); + return Collections.singletonList(new DefaultArrayInfo(0, quantity - 1)); } return Collections.emptyList(); } diff --git a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/rtu/ModbusRtuDriver.java b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/rtu/ModbusRtuDriver.java index 176f6758ae8..19a0e872ddb 100644 --- a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/rtu/ModbusRtuDriver.java +++ b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/rtu/ModbusRtuDriver.java @@ -24,7 +24,6 @@ import org.apache.plc4x.java.spi.configuration.PlcConnectionConfiguration; import org.apache.plc4x.java.spi.configuration.PlcTransportConfiguration; import org.apache.plc4x.java.modbus.base.tag.ModbusTag; -import org.apache.plc4x.java.modbus.base.tag.ModbusTagHandler; import org.apache.plc4x.java.modbus.readwrite.DriverType; import org.apache.plc4x.java.modbus.readwrite.ModbusRtuADU; import org.apache.plc4x.java.modbus.rtu.config.ModbusRtuConfiguration; @@ -33,12 +32,10 @@ import org.apache.plc4x.java.spi.connection.GeneratedDriverBase; import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer; import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer; -import org.apache.plc4x.java.spi.generation.MessageInput; import org.apache.plc4x.java.spi.generation.ParseException; import org.apache.plc4x.java.spi.generation.ReadBufferByteBased; import org.apache.plc4x.java.spi.optimizer.BaseOptimizer; import org.apache.plc4x.java.spi.optimizer.SingleTagOptimizer; -import org.apache.plc4x.java.spi.values.PlcValueHandler; import java.util.Arrays; import java.util.List; @@ -119,16 +116,6 @@ protected BaseOptimizer getOptimizer() { return new SingleTagOptimizer(); } - @Override - protected ModbusTagHandler getTagHandler() { - return new ModbusTagHandler(); - } - - @Override - protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() { - return new PlcValueHandler(); - } - @Override protected ProtocolStackConfigurer getStackConfigurer() { return SingleProtocolStackConfigurer.builder(ModbusRtuADU.class, io -> (ModbusRtuADU) ModbusRtuADU.staticParse(io, DriverType.MODBUS_RTU, true)) diff --git a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/rtu/protocol/ModbusRtuProtocolLogic.java b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/rtu/protocol/ModbusRtuProtocolLogic.java index e3ad6e07b12..486ccb7fad6 100644 --- a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/rtu/protocol/ModbusRtuProtocolLogic.java +++ b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/rtu/protocol/ModbusRtuProtocolLogic.java @@ -25,14 +25,16 @@ import org.apache.plc4x.java.api.value.PlcValue; import org.apache.plc4x.java.modbus.base.tag.ModbusTag; import org.apache.plc4x.java.modbus.base.protocol.ModbusProtocolLogic; +import org.apache.plc4x.java.modbus.base.tag.ModbusTagHandler; import org.apache.plc4x.java.modbus.readwrite.*; import org.apache.plc4x.java.modbus.rtu.config.ModbusRtuConfiguration; import org.apache.plc4x.java.modbus.types.ModbusByteOrder; import org.apache.plc4x.java.spi.ConversationContext; import org.apache.plc4x.java.spi.configuration.HasConfiguration; +import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.generation.ParseException; import org.apache.plc4x.java.spi.messages.*; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; import org.apache.plc4x.java.spi.transaction.RequestTransactionManager; import java.time.Duration; @@ -53,6 +55,11 @@ public void setConfiguration(ModbusRtuConfiguration configuration) { this.tm = new RequestTransactionManager(1); } + @Override + public PlcTagHandler getTagHandler() { + return new ModbusTagHandler(); + } + @Override public void close(ConversationContext context) { tm.shutdown(); @@ -70,7 +77,7 @@ public CompletableFuture ping(PlcPingRequest pingRequest) { ModbusRtuADU modbusRtuADU = new ModbusRtuADU(unitId, readRequestPdu); RequestTransactionManager.RequestTransaction transaction = tm.startRequest(); - transaction.submit(() -> context.sendRequest(modbusRtuADU) + transaction.submit(() -> conversationContext.sendRequest(modbusRtuADU) .expectResponse(ModbusRtuADU.class, requestTimeout) .onTimeout(future::completeExceptionally) .onError((p, e) -> future.completeExceptionally(e)) @@ -106,7 +113,7 @@ public CompletableFuture read(PlcReadRequest readRequest) { ModbusRtuADU modbusRtuADU = new ModbusRtuADU(unitId, requestPdu); RequestTransactionManager.RequestTransaction transaction = tm.startRequest(); - transaction.submit(() -> context.sendRequest(modbusRtuADU) + transaction.submit(() -> conversationContext.sendRequest(modbusRtuADU) .expectResponse(ModbusRtuADU.class, requestTimeout) .onTimeout(future::completeExceptionally) .onError((p, e) -> future.completeExceptionally(e)) @@ -135,7 +142,7 @@ public CompletableFuture read(PlcReadRequest readRequest) { // Prepare the response. PlcReadResponse response = new DefaultPlcReadResponse(request, - Collections.singletonMap(tagName, new ResponseItem<>(responseCode, plcValue))); + Collections.singletonMap(tagName, new DefaultPlcResponseItem<>(responseCode, plcValue))); // Pass the response back to the application. future.complete(response); @@ -169,7 +176,7 @@ public CompletableFuture write(PlcWriteRequest writeRequest) { final short unitId = getUnitId(tag); ModbusRtuADU modbusRtuADU = new ModbusRtuADU(unitId, requestPdu); RequestTransactionManager.RequestTransaction transaction = tm.startRequest(); - transaction.submit(() -> context.sendRequest(modbusRtuADU) + transaction.submit(() -> conversationContext.sendRequest(modbusRtuADU) .expectResponse(ModbusRtuADU.class, requestTimeout) .onTimeout(future::completeExceptionally) .onError((p, e) -> future.completeExceptionally(e)) diff --git a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/tcp/ModbusTcpDriver.java b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/tcp/ModbusTcpDriver.java index 09fff6f3156..a0bd18b9c66 100644 --- a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/tcp/ModbusTcpDriver.java +++ b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/tcp/ModbusTcpDriver.java @@ -29,12 +29,9 @@ import org.apache.plc4x.java.modbus.tcp.config.ModbusTcpConfiguration; import org.apache.plc4x.java.modbus.tcp.config.ModbusTcpTransportConfiguration; import org.apache.plc4x.java.modbus.tcp.discovery.ModbusPlcDiscoverer; -import org.apache.plc4x.java.modbus.base.tag.ModbusTagHandler; import org.apache.plc4x.java.modbus.readwrite.ModbusTcpADU; import org.apache.plc4x.java.modbus.tcp.protocol.ModbusTcpProtocolLogic; import org.apache.plc4x.java.spi.messages.DefaultPlcDiscoveryRequest; -import org.apache.plc4x.java.spi.optimizer.SingleTagOptimizer; -import org.apache.plc4x.java.spi.values.PlcValueHandler; import org.apache.plc4x.java.spi.connection.GeneratedDriverBase; import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer; import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer; @@ -124,16 +121,6 @@ protected BaseOptimizer getOptimizer() { return new /*SingleTagOptimizer();/*/ModbusOptimizer(); } - @Override - protected ModbusTagHandler getTagHandler() { - return new ModbusTagHandler(); - } - - @Override - protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() { - return new PlcValueHandler(); - } - @Override protected ProtocolStackConfigurer getStackConfigurer() { return SingleProtocolStackConfigurer.builder(ModbusTcpADU.class, (io) -> (ModbusTcpADU) ModbusTcpADU.staticParse(io, DriverType.MODBUS_TCP, true)) diff --git a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/tcp/protocol/ModbusTcpProtocolLogic.java b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/tcp/protocol/ModbusTcpProtocolLogic.java index ced1e1396db..e1615118a9e 100644 --- a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/tcp/protocol/ModbusTcpProtocolLogic.java +++ b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/tcp/protocol/ModbusTcpProtocolLogic.java @@ -31,9 +31,10 @@ import org.apache.plc4x.java.modbus.types.ModbusByteOrder; import org.apache.plc4x.java.spi.ConversationContext; import org.apache.plc4x.java.spi.configuration.HasConfiguration; +import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.generation.ParseException; import org.apache.plc4x.java.spi.messages.*; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; import org.apache.plc4x.java.spi.transaction.RequestTransactionManager; import java.time.Duration; @@ -55,6 +56,11 @@ public void setConfiguration(ModbusTcpConfiguration configuration) { this.tm = new RequestTransactionManager(1); } + @Override + public PlcTagHandler getTagHandler() { + return new ModbusTagHandler(); + } + @Override public void close(ConversationContext context) { tm.shutdown(); @@ -77,7 +83,7 @@ public CompletableFuture ping(PlcPingRequest pingRequest) { ModbusTcpADU modbusTcpADU = new ModbusTcpADU(transactionIdentifier, unitId, readRequestPdu); RequestTransactionManager.RequestTransaction transaction = tm.startRequest(); - transaction.submit(() -> context.sendRequest(modbusTcpADU) + transaction.submit(() -> conversationContext.sendRequest(modbusTcpADU) .expectResponse(ModbusTcpADU.class, requestTimeout) .onTimeout(future::completeExceptionally) .onError((p, e) -> future.completeExceptionally(e)) @@ -120,7 +126,7 @@ public CompletableFuture read(PlcReadRequest readRequest) { } ModbusTcpADU modbusTcpADU = new ModbusTcpADU(transactionIdentifier, unitId, requestPdu); RequestTransactionManager.RequestTransaction transaction = tm.startRequest(); - transaction.submit(() -> context.sendRequest(modbusTcpADU) + transaction.submit(() -> conversationContext.sendRequest(modbusTcpADU) .expectResponse(ModbusTcpADU.class, requestTimeout) .onTimeout(future::completeExceptionally) .onError((p, e) -> future.completeExceptionally(e)) @@ -151,7 +157,7 @@ public CompletableFuture read(PlcReadRequest readRequest) { // Prepare the response. PlcReadResponse response = new DefaultPlcReadResponse(request, - Collections.singletonMap(tagName, new ResponseItem<>(responseCode, plcValue))); + Collections.singletonMap(tagName, new DefaultPlcResponseItem<>(responseCode, plcValue))); // Pass the response back to the application. future.complete(response); @@ -190,7 +196,7 @@ public CompletableFuture write(PlcWriteRequest writeRequest) { } ModbusTcpADU modbusTcpADU = new ModbusTcpADU(transactionIdentifier, unitId, requestPdu); RequestTransactionManager.RequestTransaction transaction = tm.startRequest(); - transaction.submit(() -> context.sendRequest(modbusTcpADU) + transaction.submit(() -> conversationContext.sendRequest(modbusTcpADU) .expectResponse(ModbusTcpADU.class, requestTimeout) .onTimeout(future::completeExceptionally) .onError((p, e) -> future.completeExceptionally(e)) diff --git a/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/ModbusEncodeTest.java b/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/ModbusEncodeTest.java index a88d37e3ec4..8e6426ccec9 100644 --- a/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/ModbusEncodeTest.java +++ b/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/ModbusEncodeTest.java @@ -21,7 +21,7 @@ import org.apache.plc4x.java.api.value.PlcValue; import org.apache.plc4x.java.modbus.base.tag.ModbusTagCoil; import org.apache.plc4x.java.modbus.base.tag.ModbusTagHoldingRegister; -import org.apache.plc4x.java.spi.values.PlcValueHandler; +import org.apache.plc4x.java.spi.values.DefaultPlcValueHandler; import org.apache.plc4x.java.spi.values.PlcList; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -32,143 +32,143 @@ public class ModbusEncodeTest { @Test public void testEncodeBooleanBOOL() { Boolean[] object = {true,false,true,false,true,false,true,true,false}; - ModbusTagCoil coils = ModbusTagCoil.of("coil:8:BOOL"); - PlcList list = (PlcList) PlcValueHandler.of(coils, object); + ModbusTagCoil coils = ModbusTagCoil.of("coil:8:BOOL[9]"); + PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(coils, object); Assertions.assertEquals("[true,false,true,false,true,false,true,true,false]", list.toString()); } @Test public void testEncodeIntegerSINT() { Integer[] object = {1,-1,127,-128,5,6,7,8}; - ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:8:SINT{unit-id: 10}"); - Assertions.assertEquals((short) 10, holdingregister.getUnitId()); - PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object); + ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:8:SINT[8]{unit-id: 10}"); + Assertions.assertEquals((short) 10, holdingRegister.getUnitId()); + PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object); Assertions.assertEquals("[1,-1,127,-128,5,6,7,8]", list.toString()); } @Test public void testEncodeIntegerUSINT() { Integer[] object = {1,255,0,4,5,6,7,8}; - ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:8:USINT"); - PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object); + ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:8:USINT[8]"); + PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object); Assertions.assertEquals("[1,255,0,4,5,6,7,8]", list.toString()); } @Test public void testEncodeIntegerBYTE() { Integer[] object = {1,255,0,4,5,6,7,8}; - ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:8:BYTE"); - PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object); + ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:8:BYTE[8]"); + PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object); Assertions.assertEquals("[1,255,0,4,5,6,7,8]", list.toString()); } @Test public void testEncodeIntegerINT() { Integer[] object = {1,-1,32000,-32000,5,6,7}; - ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:7:INT"); - PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object); + ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:7:INT[7]"); + PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object); Assertions.assertEquals("[1,-1,32000,-32000,5,6,7]", list.toString()); } @Test public void testEncodeIntegerUINT() { Integer[] object = {1,65535,10,55000,5,6,7}; - ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:7:UINT"); - PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object); + ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:7:UINT[7]"); + PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object); Assertions.assertEquals("[1,65535,10,55000,5,6,7]", list.toString()); } @Test public void testEncodeIntegerWORD() { Integer[] object = {1,65535,10,55000,5,6,7}; - ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:7:WORD"); - PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object); + ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:7:WORD[7]"); + PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object); Assertions.assertEquals("[1,65535,10,55000,5,6,7]", list.toString()); } @Test public void testEncodeIntegerDINT() { Integer[] object = {1,655354775,-2147483648,2147483647,5,6,7}; - ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:7:DINT"); - PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object); + ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:7:DINT[7]"); + PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object); Assertions.assertEquals("[1,655354775,-2147483648,2147483647,5,6,7]", list.toString()); } @Test public void testEncodeLongUDINT() { Long[] object = {1L,655354775L,0L,4294967295L,5L,6L,7L}; - ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:7:UDINT"); - PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object); + ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:7:UDINT[7]"); + PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object); Assertions.assertEquals("[1,655354775,0,4294967295,5,6,7]", list.toString()); } @Test public void testEncodeLongDWORD() { Long[] object = {1L,655354775L,0L,4294967295L,5L,6L,7L}; - ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:7:DWORD"); - PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object); + ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:7:DWORD[7]"); + PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object); Assertions.assertEquals("[1,655354775,0,4294967295,5,6,7]", list.toString()); } @Test public void testEncodeLongLINT() { Long[] object = {1L,655354775L,-9223372036854775808L,9223372036854775807L,5L,6L,7L}; - ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:7:LINT"); - PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object); + ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:7:LINT[7]"); + PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object); Assertions.assertEquals("[1,655354775,-9223372036854775808,9223372036854775807,5,6,7]", list.toString()); } @Test public void testEncodeBigIntegerULINT() { BigInteger[] object = {BigInteger.valueOf(1L),BigInteger.valueOf(655354775L),BigInteger.valueOf(0),new BigInteger("18446744073709551615"),BigInteger.valueOf(5L),BigInteger.valueOf(6L),BigInteger.valueOf(7L)}; - ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:7:ULINT"); - PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object); + ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:7:ULINT[7]"); + PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object); Assertions.assertEquals("[1,655354775,0,18446744073709551615,5,6,7]", list.toString()); } @Test public void testEncodeBigIntegerLWORD() { BigInteger[] object = {BigInteger.valueOf(1L),BigInteger.valueOf(655354775L),BigInteger.valueOf(0),new BigInteger("18446744073709551615"),BigInteger.valueOf(5L),BigInteger.valueOf(6L),BigInteger.valueOf(7L)}; - ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:7:LWORD"); - PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object); + ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:7:LWORD[7]"); + PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object); Assertions.assertEquals("[1,655354775,0,18446744073709551615,5,6,7]", list.toString()); } @Test public void testEncodeFloatREAL() { Float[] object = {1.1f,1000.1f,100000.1f,3.4028232E38f,-3.4028232E38f,-1f,10384759934840.0f}; - ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:7:REAL"); - PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object); + ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:7:REAL[7]"); + PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object); //! When using Java 19 it seems the toString method uses a different precision than the previous versions, //! so we need to check differently in this case. for (int i = 0; i < list.getLength(); i++) { PlcValue plcValue = list.getIndex(i); Float referenceValue = object[i]; - Assertions.assertEquals(referenceValue, plcValue.getFloat()); + Assertions.assertEquals(referenceValue, plcValue.getFloat(), 0.001); } } @Test public void testEncodeDoubleLREAL() { Double[] object = {1.1,1000.1,100000.1,1.7E308,-1.7E308,-1d,10384759934840.0}; - ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:7:LREAL"); - PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object); + ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:7:LREAL[7]"); + PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object); Assertions.assertEquals("[1.1,1000.1,100000.1,1.7E308,-1.7E308,-1.0,1.038475993484E13]", list.toString()); } /*@Test public void testEncodeStringSTRING() { String[] object = {"Hello Toddy!"}; - ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:8:STRING"); - PlcList list = (PlcList) handler.encodeString(holdingregister, object); + ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:8:STRING"); + PlcList list = (PlcList) handler.encodeString(holdingRegister, object); Assertions.assertEquals("[H,e,l,l,o, ,T,o,d,d,y,!]", list.toString()); } @Test public void testEncodeStringWSTRING() { String[] object = {"Hello Toddy!"}; - ModbusTagHoldingRegister holdingregister = ModbusTagdHoldingRegister.of("holding-register:8:WSTRING"); - PlcList list = (PlcList) handler.encodeString(holdingregister, object); + ModbusTagHoldingRegister holdingRegister = ModbusTagdHoldingRegister.of("holding-register:8:WSTRING"); + PlcList list = (PlcList) handler.encodeString(holdingRegister, object); Assertions.assertEquals("[H,e,l,l,o, ,T,o,d,d,y,!]", list.toString()); } */ } diff --git a/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/ModbusTagTest.java b/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/ModbusTagTest.java index 746922b2152..bf94f285919 100644 --- a/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/ModbusTagTest.java +++ b/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/ModbusTagTest.java @@ -39,7 +39,7 @@ private void verifyModbusTag(List tagPatterns, int allowedMax, Class expectedClass, int expectedAddressShift) { - // Ensure all tagpatterns compile to the right tag + // Ensure all tag patterns compile to the right tag for (int i = 1; i <= allowedMax; i++) { List tags = new ArrayList<>(); for (String tagPattern : tagPatterns) { diff --git a/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/base/optimizer/LittleEndianByteSwapTest.java b/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/base/optimizer/LittleEndianByteSwapTest.java index de936093e69..cad86516331 100644 --- a/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/base/optimizer/LittleEndianByteSwapTest.java +++ b/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/base/optimizer/LittleEndianByteSwapTest.java @@ -33,7 +33,7 @@ import org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest; import org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse; import org.apache.plc4x.java.spi.messages.PlcReader; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; import org.apache.plc4x.java.spi.optimizer.BaseOptimizer; import org.apache.plc4x.java.spi.values.PlcRawByteArray; import org.junit.jupiter.api.Assertions; @@ -248,13 +248,13 @@ public void testLittleEndianByteSwap() throws Exception { Map> readResponses = new HashMap<>(); readResponses.put(firstRequest, new BaseOptimizer.SubResponse<>( new DefaultPlcReadResponse(firstRequest, Map.of( - "coils0", new ResponseItem<>(PlcResponseCode.OK, new PlcRawByteArray(Hex.decodeHex("3060480c00c084000000000000000000000000000000"))))))); + "coils0", new DefaultPlcResponseItem<>(PlcResponseCode.OK, new PlcRawByteArray(Hex.decodeHex("3060480c00c084000000000000000000000000000000"))))))); readResponses.put(secondRequest, new BaseOptimizer.SubResponse<>( new DefaultPlcReadResponse(secondRequest, Map.of( - "registers0", new ResponseItem<>(PlcResponseCode.OK, new PlcRawByteArray(Hex.decodeHex("134141b000000000f80146c3000000003852c31f000000000b7841ae00000000fc0046e000000000028fc31f00000000c50441ab00000000540046dd00000000c000c31e000000006e973f32000000009998420300000000a5e33c9b00000000ccd041fc00000000020c3f2f00000000c3f9409e0000000047ae3f39000000009fbe3f3a00000000fbe83ff900000000d70a3aa30000000033333e33000000008f5c412400000000b83143d4000000005c293f5700000000c28f3f0500000000ac093f3c00000000fbe7413a0000000000000000000000000000000000000000e0df3f3b0000000023a33f3900000000a3d74220"))))))); + "registers0", new DefaultPlcResponseItem<>(PlcResponseCode.OK, new PlcRawByteArray(Hex.decodeHex("134141b000000000f80146c3000000003852c31f000000000b7841ae00000000fc0046e000000000028fc31f00000000c50441ab00000000540046dd00000000c000c31e000000006e973f32000000009998420300000000a5e33c9b00000000ccd041fc00000000020c3f2f00000000c3f9409e0000000047ae3f39000000009fbe3f3a00000000fbe83ff900000000d70a3aa30000000033333e33000000008f5c412400000000b83143d4000000005c293f5700000000c28f3f0500000000ac093f3c00000000fbe7413a0000000000000000000000000000000000000000e0df3f3b0000000023a33f3900000000a3d74220"))))))); readResponses.put(thirdRequest, new BaseOptimizer.SubResponse<>( new DefaultPlcReadResponse(thirdRequest, Map.of( - "registers1", new ResponseItem<>(PlcResponseCode.OK, new PlcRawByteArray(Hex.decodeHex("a75cbc11000000007620bc26000000002f833f3c0000000086593f38000000005c293f0f0000000013aabc50000000003ffbbc8700000000da513f3b00000000c7113f3a0000000051ec3f3800000000a75cbc11000000007620bca60000000016873ed900000000ebee3ec000000000000000000000000044e5bc3b"))))))); + "registers1", new DefaultPlcResponseItem<>(PlcResponseCode.OK, new PlcRawByteArray(Hex.decodeHex("a75cbc11000000007620bc26000000002f833f3c0000000086593f38000000005c293f0f0000000013aabc50000000003ffbbc8700000000da513f3b00000000c7113f3a0000000051ec3f3800000000a75cbc11000000007620bca60000000016873ed900000000ebee3ec000000000000000000000000044e5bc3b"))))))); //////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Process the responses diff --git a/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/base/optimizer/ModbusOptimizerTest.java b/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/base/optimizer/ModbusOptimizerTest.java index 5c8eadf3912..be18764f703 100644 --- a/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/base/optimizer/ModbusOptimizerTest.java +++ b/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/base/optimizer/ModbusOptimizerTest.java @@ -28,6 +28,8 @@ import org.apache.plc4x.java.modbus.types.ModbusByteOrder; import org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest; import org.apache.plc4x.java.spi.messages.PlcReader; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcTagItem; +import org.apache.plc4x.java.spi.messages.utils.PlcTagItem; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -225,10 +227,10 @@ void processReadRequest(PlcTag[] tags, CheckResult check) { Mockito.when(driverContext.getByteOrder()).thenReturn(ModbusByteOrder.BIG_ENDIAN); Mockito.when(driverContext.getMaxCoilsPerRequest()).thenReturn(2000); Mockito.when(driverContext.getMaxRegistersPerRequest()).thenReturn(125); - LinkedHashMap tagMap = new LinkedHashMap<>(); + LinkedHashMap tagMap = new LinkedHashMap<>(); int i = 0; for (PlcTag tag : tags) { - tagMap.put("tag" + i++, tag); + tagMap.put("tag" + i++, new DefaultPlcTagItem(tag)); } ModbusOptimizer sut = new ModbusOptimizer(); List plcReadRequests = sut.processReadRequest(new DefaultPlcReadRequest(reader, tagMap), driverContext); diff --git a/plc4j/drivers/modbus/src/test/resources/logback-test.xml b/plc4j/drivers/modbus/src/test/resources/logback-test.xml index 2b9cea25dc8..941f1546f84 100644 --- a/plc4j/drivers/modbus/src/test/resources/logback-test.xml +++ b/plc4j/drivers/modbus/src/test/resources/logback-test.xml @@ -29,7 +29,7 @@ - + diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/OpcuaPlcDriver.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/OpcuaPlcDriver.java index 6d083cfb693..f430497d03a 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/OpcuaPlcDriver.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/OpcuaPlcDriver.java @@ -25,11 +25,11 @@ import org.apache.plc4x.java.opcua.optimizer.OpcuaOptimizer; import org.apache.plc4x.java.opcua.protocol.OpcuaProtocolLogic; import org.apache.plc4x.java.opcua.readwrite.OpcuaAPU; -import org.apache.plc4x.java.opcua.tag.OpcuaPlcTagHandler; import org.apache.plc4x.java.opcua.tag.OpcuaTag; import org.apache.plc4x.java.spi.connection.GeneratedDriverBase; import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer; import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer; +import org.apache.plc4x.java.spi.values.LegacyPlcValueHandler; import org.apache.plc4x.java.spi.values.PlcValueHandler; import java.util.Collections; @@ -64,6 +64,11 @@ protected List getSupportedTransportCodes() { return Collections.singletonList("tcp"); } + @Override + protected PlcValueHandler getValueHandler() { + return new LegacyPlcValueHandler(); + } + @Override protected boolean canRead() { return true; @@ -84,16 +89,6 @@ protected OpcuaOptimizer getOptimizer() { return new OpcuaOptimizer(); } - @Override - protected OpcuaPlcTagHandler getTagHandler() { - return new OpcuaPlcTagHandler(); - } - - @Override - protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() { - return new PlcValueHandler(); - } - @Override protected boolean fireDiscoverEvent() { return true; diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/optimizer/OpcuaOptimizer.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/optimizer/OpcuaOptimizer.java index 5daec530e7b..7b61baddaf3 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/optimizer/OpcuaOptimizer.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/optimizer/OpcuaOptimizer.java @@ -19,11 +19,11 @@ package org.apache.plc4x.java.opcua.optimizer; import org.apache.plc4x.java.api.messages.PlcReadRequest; -import org.apache.plc4x.java.api.messages.PlcRequest; -import org.apache.plc4x.java.api.model.PlcTag; import org.apache.plc4x.java.opcua.tag.OpcuaTag; import org.apache.plc4x.java.spi.context.DriverContext; import org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcTagItem; +import org.apache.plc4x.java.spi.messages.utils.PlcTagItem; import org.apache.plc4x.java.spi.optimizer.BaseOptimizer; import java.util.LinkedHashMap; @@ -37,11 +37,11 @@ protected List processReadRequest(PlcReadRequest readRequest, Dr List processedRequests = new LinkedList<>(); // List of all items in the current request. - LinkedHashMap curTags = new LinkedHashMap<>(); + LinkedHashMap curTags = new LinkedHashMap<>(); for (String tagName : readRequest.getTagNames()) { OpcuaTag tag = (OpcuaTag) readRequest.getTag(tagName); - curTags.put(tagName, tag); + curTags.put(tagName, new DefaultPlcTagItem(tag)); } // Create a new PlcReadRequest from the remaining tag items. diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java index ced558a4c25..91112aef604 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java @@ -28,6 +28,7 @@ import org.apache.plc4x.java.api.messages.*; import org.apache.plc4x.java.api.model.PlcConsumerRegistration; import org.apache.plc4x.java.api.model.PlcSubscriptionHandle; +import org.apache.plc4x.java.api.model.PlcTag; import org.apache.plc4x.java.api.types.PlcResponseCode; import org.apache.plc4x.java.api.types.PlcValueType; import org.apache.plc4x.java.api.value.PlcValue; @@ -36,19 +37,22 @@ import org.apache.plc4x.java.opcua.context.OpcuaDriverContext; import org.apache.plc4x.java.opcua.context.SecureChannel; import org.apache.plc4x.java.opcua.readwrite.*; +import org.apache.plc4x.java.opcua.tag.OpcuaPlcTagHandler; import org.apache.plc4x.java.opcua.tag.OpcuaTag; import org.apache.plc4x.java.spi.ConversationContext; import org.apache.plc4x.java.spi.Plc4xProtocolBase; import org.apache.plc4x.java.spi.configuration.HasConfiguration; +import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.context.DriverContext; import org.apache.plc4x.java.spi.messages.*; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration; import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionTag; import org.apache.plc4x.java.spi.transaction.RequestTransactionManager; import org.apache.plc4x.java.spi.transaction.RequestTransactionManager.RequestTransaction; +import org.apache.plc4x.java.spi.values.LegacyPlcValueHandler; import org.apache.plc4x.java.spi.values.PlcList; -import org.apache.plc4x.java.spi.values.PlcValueHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -91,6 +95,11 @@ public void setConfiguration(OpcuaConfiguration configuration) { this.configuration = configuration; } + @Override + public PlcTagHandler getTagHandler() { + return new OpcuaPlcTagHandler(); + } + @Override public void close(ConversationContext context) { tm.shutdown(); @@ -201,9 +210,12 @@ public CompletableFuture read(PlcReadRequest readRequest) { List readValueArray = new ArrayList<>(request.getTagNames().size()); Iterator iterator = request.getTagNames().iterator(); + Map tagMap = new HashMap<>(); for (int i = 0; i < request.getTagNames().size(); i++) { String tagName = iterator.next(); + // TODO: We need to check that the tag-return-code is OK as it could also be INVALID_TAG OpcuaTag tag = (OpcuaTag) request.getTag(tagName); + tagMap.put(tagName, tag); NodeId nodeId = generateNodeId(tag); @@ -225,7 +237,7 @@ public CompletableFuture read(PlcReadRequest readRequest) { transaction.submit(() -> { conversation.submit(opcuaReadRequest, ReadResponse.class).whenComplete((response, error) -> bridge(transaction, future, response, error)); }); - return future.thenApply(response -> new DefaultPlcReadResponse(request, readResponse(request.getTagNames(), response.getResults()))); + return future.thenApply(response -> new DefaultPlcReadResponse(request, readResponse(request.getTagNames(), tagMap, response.getResults()))); } static NodeId generateNodeId(OpcuaTag tag) { @@ -250,11 +262,12 @@ static NodeId generateNodeId(OpcuaTag tag) { return nodeId; } - public Map> readResponse(LinkedHashSet tagNames, List results) { + public Map> readResponse(LinkedHashSet tagNames, Map tagMap, List results) { PlcResponseCode responseCode = null; // initialize variable - Map> response = new HashMap<>(); + Map> response = new HashMap<>(); int count = 0; for (String tagName : tagNames) { + PlcTag tag = tagMap.get(tagName); PlcValue value = null; if (results.get(count).getValueSpecified()) { Variant variant = results.get(count).getValue(); @@ -266,44 +279,44 @@ public Map> readResponse(LinkedHashSet ta for (int i = 0; i < length; i++) { tmpValue[i] = array[i] != 0; } - value = PlcValueHandler.of(tmpValue); + value = LegacyPlcValueHandler.of(tmpValue); } else if (variant instanceof VariantSByte) { byte[] array = ((VariantSByte) variant).getValue(); - value = PlcValueHandler.of(array); + value = LegacyPlcValueHandler.of(tag, array); } else if (variant instanceof VariantByte) { List array = ((VariantByte) variant).getValue(); Short[] tmpValue = array.toArray(new Short[0]); - value = PlcValueHandler.of(tmpValue); + value = LegacyPlcValueHandler.of(tmpValue); } else if (variant instanceof VariantInt16) { List array = ((VariantInt16) variant).getValue(); Short[] tmpValue = array.toArray(new Short[0]); - value = PlcValueHandler.of(tmpValue); + value = LegacyPlcValueHandler.of(tmpValue); } else if (variant instanceof VariantUInt16) { List array = ((VariantUInt16) variant).getValue(); Integer[] tmpValue = array.toArray(new Integer[0]); - value = PlcValueHandler.of(tmpValue); + value = LegacyPlcValueHandler.of(tmpValue); } else if (variant instanceof VariantInt32) { List array = ((VariantInt32) variant).getValue(); Integer[] tmpValue = array.toArray(new Integer[0]); - value = PlcValueHandler.of(tmpValue); + value = LegacyPlcValueHandler.of(tmpValue); } else if (variant instanceof VariantUInt32) { List array = ((VariantUInt32) variant).getValue(); Long[] tmpValue = array.toArray(new Long[0]); - value = PlcValueHandler.of(tmpValue); + value = LegacyPlcValueHandler.of(tmpValue); } else if (variant instanceof VariantInt64) { List array = ((VariantInt64) variant).getValue(); Long[] tmpValue = array.toArray(new Long[0]); - value = PlcValueHandler.of(tmpValue); + value = LegacyPlcValueHandler.of(tmpValue); } else if (variant instanceof VariantUInt64) { - value = PlcValueHandler.of(((VariantUInt64) variant).getValue()); + value = LegacyPlcValueHandler.of(((VariantUInt64) variant).getValue()); } else if (variant instanceof VariantFloat) { List array = ((VariantFloat) variant).getValue(); Float[] tmpValue = array.toArray(new Float[0]); - value = PlcValueHandler.of(tmpValue); + value = LegacyPlcValueHandler.of(tmpValue); } else if (variant instanceof VariantDouble) { List array = ((VariantDouble) variant).getValue(); Double[] tmpValue = array.toArray(new Double[0]); - value = PlcValueHandler.of(tmpValue); + value = LegacyPlcValueHandler.of(tmpValue); } else if (variant instanceof VariantString) { int length = ((VariantString) variant).getValue().size(); List stringArray = ((VariantString) variant).getValue(); @@ -311,7 +324,7 @@ public Map> readResponse(LinkedHashSet ta for (int i = 0; i < length; i++) { tmpValue[i] = stringArray.get(i).getStringValue(); } - value = PlcValueHandler.of(tmpValue); + value = LegacyPlcValueHandler.of(tmpValue); } else if (variant instanceof VariantDateTime) { List array = ((VariantDateTime) variant).getValue(); int length = array.size(); @@ -319,7 +332,7 @@ public Map> readResponse(LinkedHashSet ta for (int i = 0; i < length; i++) { tmpValue[i] = LocalDateTime.ofInstant(Instant.ofEpochMilli(getDateTime(array.get(i))), ZoneOffset.UTC); } - value = PlcValueHandler.of(tmpValue); + value = LegacyPlcValueHandler.of(tmpValue); } else if (variant instanceof VariantGuid) { List array = ((VariantGuid) variant).getValue(); int length = array.size(); @@ -338,7 +351,7 @@ public Map> readResponse(LinkedHashSet ta } tmpValue[i] = Long.toHexString(array.get(i).getData1()) + "-" + Integer.toHexString(array.get(i).getData2()) + "-" + Integer.toHexString(array.get(i).getData3()) + "-" + Integer.toHexString(data4) + "-" + Long.toHexString(data5); } - value = PlcValueHandler.of(tmpValue); + value = LegacyPlcValueHandler.of(tmpValue); } else if (variant instanceof VariantXmlElement) { int length = ((VariantXmlElement) variant).getValue().size(); List strings = ((VariantXmlElement) variant).getValue(); @@ -346,7 +359,7 @@ public Map> readResponse(LinkedHashSet ta for (int i = 0; i < length; i++) { tmpValue[i] = strings.get(i).getStringValue(); } - value = PlcValueHandler.of(tmpValue); + value = LegacyPlcValueHandler.of(tmpValue); } else if (variant instanceof VariantLocalizedText) { int length = ((VariantLocalizedText) variant).getValue().size(); List strings = ((VariantLocalizedText) variant).getValue(); @@ -356,7 +369,7 @@ public Map> readResponse(LinkedHashSet ta tmpValue[i] += strings.get(i).getLocaleSpecified() ? strings.get(i).getLocale().getStringValue() + "|" : ""; tmpValue[i] += strings.get(i).getTextSpecified() ? strings.get(i).getText().getStringValue() : ""; } - value = PlcValueHandler.of(tmpValue); + value = LegacyPlcValueHandler.of(tmpValue); } else if (variant instanceof VariantQualifiedName) { int length = ((VariantQualifiedName) variant).getValue().size(); List strings = ((VariantQualifiedName) variant).getValue(); @@ -364,7 +377,7 @@ public Map> readResponse(LinkedHashSet ta for (int i = 0; i < length; i++) { tmpValue[i] = "ns=" + strings.get(i).getNamespaceIndex() + ";s=" + strings.get(i).getName().getStringValue(); } - value = PlcValueHandler.of(tmpValue); + value = LegacyPlcValueHandler.of(tmpValue); } else if (variant instanceof VariantExtensionObject) { int length = ((VariantExtensionObject) variant).getValue().size(); List strings = ((VariantExtensionObject) variant).getValue(); @@ -372,7 +385,7 @@ public Map> readResponse(LinkedHashSet ta for (int i = 0; i < length; i++) { tmpValue[i] = strings.get(i).toString(); } - value = PlcValueHandler.of(tmpValue); + value = LegacyPlcValueHandler.of(tmpValue); } else if (variant instanceof VariantNodeId) { int length = ((VariantNodeId) variant).getValue().size(); List strings = ((VariantNodeId) variant).getValue(); @@ -380,7 +393,7 @@ public Map> readResponse(LinkedHashSet ta for (int i = 0; i < length; i++) { tmpValue[i] = strings.get(i).toString(); } - value = PlcValueHandler.of(tmpValue); + value = LegacyPlcValueHandler.of(tmpValue); } else if (variant instanceof VariantStatusCode) { int length = ((VariantStatusCode) variant).getValue().size(); List strings = ((VariantStatusCode) variant).getValue(); @@ -388,7 +401,7 @@ public Map> readResponse(LinkedHashSet ta for (int i = 0; i < length; i++) { tmpValue[i] = strings.get(i).toString(); } - value = PlcValueHandler.of(tmpValue); + value = LegacyPlcValueHandler.of(tmpValue); } else if (variant instanceof VariantByteString) { PlcList plcList = new PlcList(); List array = ((VariantByteString) variant).getValue(); @@ -398,7 +411,7 @@ public Map> readResponse(LinkedHashSet ta for (int i = 0; i < length; i++) { tmpValue[i] = byteStringArray.getValue().get(i); } - plcList.add(PlcValueHandler.of(tmpValue)); + plcList.add(LegacyPlcValueHandler.of(tmpValue)); } value = plcList; } else { @@ -415,7 +428,7 @@ public Map> readResponse(LinkedHashSet ta LOGGER.error("Error while reading value from OPC UA server error code: {}", results.get(count).getStatusCode().toString()); } count++; - response.put(tagName, new ResponseItem<>(responseCode, value)); + response.put(tagName, new DefaultPlcResponseItem<>(responseCode, value)); } return response; } @@ -779,13 +792,13 @@ public CompletableFuture subscribe(PlcSubscriptionReque }) .thenCompose(handle -> handle.onSubscribeCreateMonitoredItemsRequest()) .thenApply(handle -> { - Map> values = new HashMap<>(); + Map> values = new HashMap<>(); for (String tagName : subscriptionRequest.getTagNames()) { final DefaultPlcSubscriptionTag tagDefaultPlcSubscription = (DefaultPlcSubscriptionTag) subscriptionRequest.getTag(tagName); if (!(tagDefaultPlcSubscription.getTag() instanceof OpcuaTag)) { - values.put(tagName, new ResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null)); + values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null)); } else { - values.put(tagName, new ResponseItem<>(PlcResponseCode.OK, handle)); + values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, handle)); } } diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubscriptionHandle.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubscriptionHandle.java index a68a04fb4d1..ab241b0411e 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubscriptionHandle.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubscriptionHandle.java @@ -27,12 +27,14 @@ import org.apache.plc4x.java.api.messages.PlcSubscriptionEvent; import org.apache.plc4x.java.api.messages.PlcSubscriptionRequest; import org.apache.plc4x.java.api.model.PlcConsumerRegistration; +import org.apache.plc4x.java.api.model.PlcTag; import org.apache.plc4x.java.api.value.PlcValue; import org.apache.plc4x.java.opcua.context.Conversation; import org.apache.plc4x.java.opcua.tag.OpcuaTag; import org.apache.plc4x.java.opcua.readwrite.*; import org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionEvent; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcTagItem; import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration; import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionTag; import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionHandle; @@ -260,11 +262,14 @@ public void stopSubscriber() { private void onSubscriptionValue(MonitoredItemNotification[] values) { LinkedHashSet tagNameList = new LinkedHashSet<>(); List dataValues = new ArrayList<>(values.length); + Map tagMap = new LinkedHashMap<>(); for (MonitoredItemNotification value : values) { - tagNameList.add(tagNames.get((int) value.getClientHandle() - 1)); + String tagName = tagNames.get((int) value.getClientHandle() - 1); + tagNameList.add(tagName); + tagMap.put(tagName, subscriptionRequest.getTag(tagName).getTag()); dataValues.add(value.getValue()); } - Map> tags = plcSubscriber.readResponse(tagNameList, dataValues); + Map> tags = plcSubscriber.readResponse(tagNameList, tagMap, dataValues); final PlcSubscriptionEvent event = new DefaultPlcSubscriptionEvent(Instant.now(), tags); consumers.forEach(plcSubscriptionEventConsumer -> plcSubscriptionEventConsumer.accept(event)); diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/OpcuaPlcDriverTest.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/OpcuaPlcDriverTest.java index 2de1ee473de..2bb0bd79ae9 100644 --- a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/OpcuaPlcDriverTest.java +++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/OpcuaPlcDriverTest.java @@ -57,7 +57,6 @@ import org.slf4j.LoggerFactory; import java.math.BigInteger; -import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.concurrent.ExecutionException; @@ -65,9 +64,6 @@ import org.testcontainers.containers.BindMode; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.output.Slf4jLogConsumer; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; -import org.testcontainers.jib.JibImage; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @@ -82,7 +78,7 @@ public class OpcuaPlcDriverTest { private static final Logger LOGGER = LoggerFactory.getLogger(OpcuaPlcDriverTest.class); @Container - public static final GenericContainer milo = new MiloTestContainer() + public static final GenericContainer milo = new MiloTestContainer() //.withCreateContainerCmdModifier(cmd -> cmd.withHostName("test-opcua-server")) .withReuse(true) .withLogConsumer(new Slf4jLogConsumer(LOGGER)) @@ -139,17 +135,17 @@ public class OpcuaPlcDriverTest { public static final String STRING_IDENTIFIER_ONLY_ADMIN_READ_WRITE = "ns=2;s=HelloWorld/OnlyAdminCanRead/String"; // Address of local milo server, since it comes from test container its hostname and port is not static - private final String miloLocalAddress = "%s:%d/milo"; + private static final String miloLocalAddress = "%s:%d/milo"; //Tcp pattern of OPC UA - private final String opcPattern = "opcua:tcp://"; + private static final String opcPattern = "opcua:tcp://"; - private final String paramSectionDivider = "?"; - private final String paramDivider = "&"; + private static final String paramSectionDivider = "?"; + private static final String paramDivider = "&"; - private final String discoveryValidParamTrue = "discovery=true"; - private final String discoveryValidParamFalse = "discovery=false"; - private final String discoveryCorruptedParamWrongValueNum = "discovery=1"; - private final String discoveryCorruptedParamWrongName = "diskovery=false"; + private static final String discoveryValidParamTrue = "discovery=true"; + private static final String discoveryValidParamFalse = "discovery=false"; + private static final String discoveryCorruptedParamWrongValueNum = "discovery=1"; + private static final String discoveryCorruptedParamWrongName = "diskovery=false"; private String tcpConnectionAddress; private List connectionStringValidSet; diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/chunk/ChunkFactoryTest.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/chunk/ChunkFactoryTest.java index b97632b1a1d..c59b80efb21 100644 --- a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/chunk/ChunkFactoryTest.java +++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/chunk/ChunkFactoryTest.java @@ -32,10 +32,12 @@ import org.apache.plc4x.java.opcua.security.SecurityPolicy; import org.apache.plc4x.test.DisableOnJenkinsFlag; import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvFileSource; @DisableOnJenkinsFlag +@Disabled("Disabled flaky test. Tracking issue at https://github.com/apache/plc4x/issues/1764") class ChunkFactoryTest { public static final Map> CERTIFICATES = new HashMap<>(); diff --git a/plc4j/drivers/opcua/src/test/resources/logback-test.xml b/plc4j/drivers/opcua/src/test/resources/logback-test.xml index adf03c9e8c8..695109a5329 100644 --- a/plc4j/drivers/opcua/src/test/resources/logback-test.xml +++ b/plc4j/drivers/opcua/src/test/resources/logback-test.xml @@ -27,7 +27,7 @@ - + diff --git a/plc4j/drivers/open-protocol/src/main/java/org/apache/plc4x/java/openprotocol/OpenProtocolDriver.java b/plc4j/drivers/open-protocol/src/main/java/org/apache/plc4x/java/openprotocol/OpenProtocolDriver.java index 6bdf9d68434..95a3d0027b2 100644 --- a/plc4j/drivers/open-protocol/src/main/java/org/apache/plc4x/java/openprotocol/OpenProtocolDriver.java +++ b/plc4j/drivers/open-protocol/src/main/java/org/apache/plc4x/java/openprotocol/OpenProtocolDriver.java @@ -26,13 +26,11 @@ import org.apache.plc4x.java.openprotocol.protocol.OpenProtocolProtocolLogic; import org.apache.plc4x.java.openprotocol.readwrite.OpenProtocolMessage; import org.apache.plc4x.java.openprotocol.tag.OpenProtocolTag; -import org.apache.plc4x.java.openprotocol.tag.OpenProtocolTagHandler; import org.apache.plc4x.java.spi.connection.GeneratedDriverBase; import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer; import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer; import org.apache.plc4x.java.spi.optimizer.BaseOptimizer; import org.apache.plc4x.java.spi.optimizer.SingleTagOptimizer; -import org.apache.plc4x.java.spi.values.PlcValueHandler; import java.util.Collections; import java.util.List; @@ -100,16 +98,6 @@ protected BaseOptimizer getOptimizer() { return new SingleTagOptimizer(); } - @Override - protected OpenProtocolTagHandler getTagHandler() { - return new OpenProtocolTagHandler(); - } - - @Override - protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() { - return new PlcValueHandler(); - } - @Override protected ProtocolStackConfigurer getStackConfigurer() { return SingleProtocolStackConfigurer.builder(OpenProtocolMessage.class, io -> OpenProtocolMessage.staticParse(io, 1)) diff --git a/plc4j/drivers/open-protocol/src/main/java/org/apache/plc4x/java/openprotocol/protocol/OpenProtocolProtocolLogic.java b/plc4j/drivers/open-protocol/src/main/java/org/apache/plc4x/java/openprotocol/protocol/OpenProtocolProtocolLogic.java index deafb87871c..0a639c09358 100644 --- a/plc4j/drivers/open-protocol/src/main/java/org/apache/plc4x/java/openprotocol/protocol/OpenProtocolProtocolLogic.java +++ b/plc4j/drivers/open-protocol/src/main/java/org/apache/plc4x/java/openprotocol/protocol/OpenProtocolProtocolLogic.java @@ -22,8 +22,10 @@ import org.apache.plc4x.java.api.model.PlcConsumerRegistration; import org.apache.plc4x.java.api.model.PlcSubscriptionHandle; import org.apache.plc4x.java.openprotocol.readwrite.OpenProtocolMessage; +import org.apache.plc4x.java.openprotocol.tag.OpenProtocolTagHandler; import org.apache.plc4x.java.spi.ConversationContext; import org.apache.plc4x.java.spi.Plc4xProtocolBase; +import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.messages.PlcSubscriber; import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration; @@ -33,6 +35,11 @@ public class OpenProtocolProtocolLogic extends Plc4xProtocolBase implements PlcSubscriber { + @Override + public PlcTagHandler getTagHandler() { + return new OpenProtocolTagHandler(); + } + @Override public void onConnect(ConversationContext context) { } diff --git a/plc4j/drivers/open-protocol/src/test/resources/logback-test.xml b/plc4j/drivers/open-protocol/src/test/resources/logback-test.xml index 2b9cea25dc8..941f1546f84 100644 --- a/plc4j/drivers/open-protocol/src/test/resources/logback-test.xml +++ b/plc4j/drivers/open-protocol/src/test/resources/logback-test.xml @@ -29,7 +29,7 @@ - + diff --git a/plc4j/drivers/plc4x/src/main/java/org/apache/plc4x/java/plc4x/Plc4xDriver.java b/plc4j/drivers/plc4x/src/main/java/org/apache/plc4x/java/plc4x/Plc4xDriver.java index 93ea3b3f71c..cb738d53397 100644 --- a/plc4j/drivers/plc4x/src/main/java/org/apache/plc4x/java/plc4x/Plc4xDriver.java +++ b/plc4j/drivers/plc4x/src/main/java/org/apache/plc4x/java/plc4x/Plc4xDriver.java @@ -23,14 +23,11 @@ import org.apache.plc4x.java.spi.configuration.PlcTransportConfiguration; import org.apache.plc4x.java.plc4x.config.Plc4xConfiguration; import org.apache.plc4x.java.plc4x.config.Plc4xTcpTransportConfiguration; -import org.apache.plc4x.java.plc4x.tag.Plc4XTagHandler; import org.apache.plc4x.java.plc4x.protocol.Plc4xProtocolLogic; import org.apache.plc4x.java.plc4x.readwrite.Plc4xMessage; import org.apache.plc4x.java.spi.connection.GeneratedDriverBase; -import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer; import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer; -import org.apache.plc4x.java.spi.values.PlcValueHandler; import java.util.Collections; import java.util.List; @@ -74,16 +71,6 @@ protected List getSupportedTransportCodes() { return Collections.singletonList("tcp"); } - @Override - protected PlcTagHandler getTagHandler() { - return new Plc4XTagHandler(); - } - - @Override - protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() { - return new PlcValueHandler(); - } - /** * This protocol doesn't have a disconnect procedure, so there is no need to wait for a login to finish. * @return false diff --git a/plc4j/drivers/plc4x/src/main/java/org/apache/plc4x/java/plc4x/protocol/Plc4xProtocolLogic.java b/plc4j/drivers/plc4x/src/main/java/org/apache/plc4x/java/plc4x/protocol/Plc4xProtocolLogic.java index a40ef2810e7..3d9288e1e44 100644 --- a/plc4j/drivers/plc4x/src/main/java/org/apache/plc4x/java/plc4x/protocol/Plc4xProtocolLogic.java +++ b/plc4j/drivers/plc4x/src/main/java/org/apache/plc4x/java/plc4x/protocol/Plc4xProtocolLogic.java @@ -23,13 +23,16 @@ import org.apache.plc4x.java.api.value.PlcValue; import org.apache.plc4x.java.plc4x.config.Plc4xConfiguration; import org.apache.plc4x.java.plc4x.readwrite.*; +import org.apache.plc4x.java.plc4x.tag.Plc4XTagHandler; import org.apache.plc4x.java.plc4x.tag.Plc4xTag; import org.apache.plc4x.java.spi.ConversationContext; import org.apache.plc4x.java.spi.Plc4xProtocolBase; import org.apache.plc4x.java.spi.configuration.HasConfiguration; +import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse; import org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; import org.apache.plc4x.java.spi.transaction.RequestTransactionManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -60,6 +63,11 @@ public void setConfiguration(Plc4xConfiguration configuration) { this.connectionId = 0; } + @Override + public PlcTagHandler getTagHandler() { + return new Plc4XTagHandler(); + } + @Override public void close(ConversationContext context) { tm.shutdown(); @@ -109,20 +117,20 @@ public CompletableFuture read(PlcReadRequest apiReadRequest) { // Send the request and await a response. RequestTransactionManager.RequestTransaction transaction = tm.startRequest(); - context.sendRequest(plc4xReadRequest) + conversationContext.sendRequest(plc4xReadRequest) .expectResponse(Plc4xMessage.class, requestTimeout) .onTimeout(future::completeExceptionally) .check(plc4xMessage -> plc4xMessage.getRequestId() == requestId) .only(Plc4xReadResponse.class) .check(plc4xReadResponse -> plc4xReadResponse.getConnectionId() == connectionId) .handle(plc4xReadResponse -> { - Map> apiResponses = new HashMap<>(); + Map> apiResponses = new HashMap<>(); // Create the API response from the incoming message. for (Plc4xTagValueResponse plc4xTag : plc4xReadResponse.getTags()) { final Plc4xResponseCode plc4xResponseCode = plc4xTag.getResponseCode(); final PlcResponseCode apiResponseCode = PlcResponseCode.valueOf(plc4xResponseCode.name()); apiResponses.put(plc4xTag.getTag().getName(), - new ResponseItem<>(apiResponseCode, plc4xTag.getValue())); + new DefaultPlcResponseItem<>(apiResponseCode, plc4xTag.getValue())); } // Send it back to the calling process. @@ -153,7 +161,7 @@ public CompletableFuture write(PlcWriteRequest writeRequest) { // Send the request and await a response. RequestTransactionManager.RequestTransaction transaction = tm.startRequest(); - context.sendRequest(write) + conversationContext.sendRequest(write) .expectResponse(Plc4xMessage.class, requestTimeout) .onTimeout(future::completeExceptionally) .check(p -> p.getRequestId() == requestId) diff --git a/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/ProfinetDriver.java b/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/ProfinetDriver.java index adbd18f44c2..34ff1380da5 100644 --- a/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/ProfinetDriver.java +++ b/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/ProfinetDriver.java @@ -34,7 +34,6 @@ import org.apache.plc4x.java.profinet.protocol.ProfinetProtocolLogic; import org.apache.plc4x.java.profinet.readwrite.*; import org.apache.plc4x.java.profinet.tag.ProfinetTag; -import org.apache.plc4x.java.profinet.tag.ProfinetTagHandler; import org.apache.plc4x.java.spi.configuration.ConfigurationFactory; import org.apache.plc4x.java.spi.connection.GeneratedDriverBase; import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer; @@ -166,16 +165,6 @@ protected BaseOptimizer getOptimizer() { return new SingleTagOptimizer(); } - @Override - protected ProfinetTagHandler getTagHandler() { - return new ProfinetTagHandler(); - } - - @Override - protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() { - return new org.apache.plc4x.java.spi.values.PlcValueHandler(); - } - @Override protected ProtocolStackConfigurer getStackConfigurer() { return SingleProtocolStackConfigurer.builder(Ethernet_Frame.class, Ethernet_Frame::staticParse) diff --git a/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/discovery/ProfinetDiscoverer.java b/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/discovery/ProfinetDiscoverer.java index 3bf4ebad92c..d81582c7088 100644 --- a/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/discovery/ProfinetDiscoverer.java +++ b/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/discovery/ProfinetDiscoverer.java @@ -33,7 +33,7 @@ import org.apache.plc4x.java.spi.messages.DefaultPlcDiscoveryItem; import org.apache.plc4x.java.spi.messages.DefaultPlcDiscoveryResponse; import org.apache.plc4x.java.spi.messages.PlcDiscoverer; -import org.apache.plc4x.java.spi.values.PlcValues; +import org.apache.plc4x.java.spi.values.PlcSTRING; import org.apache.plc4x.java.transport.rawsocket.RawSocketTransport; import org.pcap4j.core.NotOpenException; import org.pcap4j.core.PcapHandle; @@ -230,16 +230,16 @@ public void handlePnDcpPacket(PnDcp_Pdu pdu, EthernetPacket ethernetPacket) { } Map attributes = new HashMap<>(); - attributes.put("ipAddress", PlcValues.of(remoteAddress)); - attributes.put("subnetMask", PlcValues.of(remoteSubnetMask)); - attributes.put("macAddress", PlcValues.of(srcAddr.toString())); - attributes.put("localMacAddress", PlcValues.of(dstAddr.toString())); - attributes.put("deviceTypeName", PlcValues.of(deviceTypeName)); - attributes.put("deviceName", PlcValues.of(deviceName)); - attributes.put("vendorId", PlcValues.of(vendorId)); - attributes.put("deviceId", PlcValues.of(deviceId)); - attributes.put("role", PlcValues.of(role)); - attributes.put("packetType", PlcValues.of("dcp")); + attributes.put("ipAddress", new PlcSTRING(remoteAddress)); + attributes.put("subnetMask", new PlcSTRING(remoteSubnetMask)); + attributes.put("macAddress", new PlcSTRING(srcAddr.toString())); + attributes.put("localMacAddress", new PlcSTRING(dstAddr.toString())); + attributes.put("deviceTypeName", new PlcSTRING(deviceTypeName)); + attributes.put("deviceName", new PlcSTRING(deviceName)); + attributes.put("vendorId", new PlcSTRING(vendorId)); + attributes.put("deviceId", new PlcSTRING(deviceId)); + attributes.put("role", new PlcSTRING(role)); + attributes.put("packetType", new PlcSTRING("dcp")); String name = deviceTypeName + " - " + deviceName; diff --git a/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/protocol/ProfinetProtocolLogic.java b/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/protocol/ProfinetProtocolLogic.java index 49d8df00af1..68f1c393535 100644 --- a/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/protocol/ProfinetProtocolLogic.java +++ b/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/protocol/ProfinetProtocolLogic.java @@ -33,10 +33,12 @@ import org.apache.plc4x.java.profinet.packets.PnDcpPacketFactory; import org.apache.plc4x.java.profinet.readwrite.*; import org.apache.plc4x.java.profinet.tag.ProfinetTag; +import org.apache.plc4x.java.profinet.tag.ProfinetTagHandler; import org.apache.plc4x.java.profinet.utils.ProfinetDataTypeMapper; import org.apache.plc4x.java.spi.ConversationContext; import org.apache.plc4x.java.spi.Plc4xProtocolBase; import org.apache.plc4x.java.spi.configuration.HasConfiguration; +import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.context.DriverContext; import org.apache.plc4x.java.spi.messages.DefaultPlcBrowseItem; import org.apache.plc4x.java.spi.messages.DefaultPlcBrowseResponse; @@ -78,6 +80,11 @@ public void setConfiguration(ProfinetConfiguration configuration) { this.configuration = configuration; } + @Override + public PlcTagHandler getTagHandler() { + return new ProfinetTagHandler(); + } + @Override public void onConnect(ConversationContext context) { super.onConnect(context); @@ -572,7 +579,7 @@ public CompletableFuture subscribe(PlcSubscriptionReque expectedSubmodules.add(new PnIoCm_Block_ExpectedSubmoduleReq((short) 1, (short) 0, Collections.singletonList(new PnIoCm_ExpectedSubmoduleBlockReqApi(slotNumber, 0x00000020, 0x0000, expectedSubmoduleData)))); } - RawSocketChannel rawSocketChannel = (RawSocketChannel) context.getChannel(); + RawSocketChannel rawSocketChannel = (RawSocketChannel) conversationContext.getChannel(); MacAddress remoteMacAddress = new MacAddress(rawSocketChannel.getRemoteMacAddress().getAddress()); InetSocketAddress remoteAddress = (InetSocketAddress) rawSocketChannel.getRemoteAddress(); MacAddress localMacAddress = new MacAddress(rawSocketChannel.getLocalMacAddress().getAddress()); @@ -699,7 +706,7 @@ public CompletableFuture subscribe(PlcSubscriptionReque udpFrame); CompletableFuture future = new CompletableFuture<>(); - context.sendRequest(requestEthernetFrame) + conversationContext.sendRequest(requestEthernetFrame) .name("Expect Subscription response") .expectResponse(Ethernet_Frame.class, Duration.ofMillis(1000)) .onTimeout(future::completeExceptionally) @@ -716,7 +723,7 @@ public CompletableFuture subscribe(PlcSubscriptionReque // TODO: Maybe do some checks on this. // Now we wait for an incoming ApplicationReady request and confirm that. - context.expectRequest(Ethernet_Frame.class, Duration.ofMillis(500000)) + conversationContext.expectRequest(Ethernet_Frame.class, Duration.ofMillis(500000)) .name("Expect ApplicationReady request") .onTimeout(future::completeExceptionally) .check(ethernetFrame -> ethernetFrame.getPayload() instanceof Ethernet_FramePayload_IPv4) @@ -732,8 +739,8 @@ public CompletableFuture subscribe(PlcSubscriptionReque int sessionKey = pnIoCmBlock.getSessionKey(); // Send back a response, but this is just a hack ... we need to move this into the subscribe method, or we can't complete the future that we're returning. - RawSocketChannel pnChannel = (RawSocketChannel) context.getChannel(); - PnDcpPacketFactory.sendApplicationReadyResponse(context, pnChannel, profinetDriverContext, payloadIPv4.getSourcePort(), dceRpc_packet.getActivityUuid(), arUuid, sessionKey); + RawSocketChannel pnChannel = (RawSocketChannel) conversationContext.getChannel(); + PnDcpPacketFactory.sendApplicationReadyResponse(conversationContext, pnChannel, profinetDriverContext, payloadIPv4.getSourcePort(), dceRpc_packet.getActivityUuid(), arUuid, sessionKey); connected = true; // TODO: Prepare the subscription response. @@ -741,7 +748,7 @@ public CompletableFuture subscribe(PlcSubscriptionReque }); // Now send the ParameterEnd request and wait for a response. - CompletableFuture parameterEndFuture = PnDcpPacketFactory.sendParameterEndRequest(context, rawSocketChannel, profinetDriverContext); + CompletableFuture parameterEndFuture = PnDcpPacketFactory.sendParameterEndRequest(conversationContext, rawSocketChannel, profinetDriverContext); parameterEndFuture.whenComplete((parameterEnd, throwable) -> { // We needed to put the code to expect the ApplicationReady to subscribe before sending, // as the device sends it within 4 ms, and we can't guarantee that we're done setting up diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/ProfinetDriver.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/ProfinetDriver.java index 60de10c6d04..f9e3b1f34db 100644 --- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/ProfinetDriver.java +++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/ProfinetDriver.java @@ -30,7 +30,6 @@ import org.apache.plc4x.java.profinet.protocol.ProfinetProtocolLogic; import org.apache.plc4x.java.profinet.readwrite.Ethernet_Frame; import org.apache.plc4x.java.profinet.tag.ProfinetTag; -import org.apache.plc4x.java.profinet.tag.ProfinetTagHandler; import org.apache.plc4x.java.spi.connection.GeneratedDriverBase; import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer; import org.apache.plc4x.java.spi.messages.DefaultPlcDiscoveryRequest; @@ -135,16 +134,6 @@ protected BaseOptimizer getOptimizer() { return new SingleTagOptimizer(); } - @Override - protected ProfinetTagHandler getTagHandler() { - return new ProfinetTagHandler(); - } - - @Override - protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() { - return new org.apache.plc4x.java.spi.values.PlcValueHandler(); - } - @Override protected ProtocolStackConfigurer getStackConfigurer() { return SingleProtocolStackConfigurer.builder(Ethernet_Frame.class, Ethernet_Frame::staticParse) diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetDevice.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetDevice.java index 4c000a3a27e..59c470989f8 100644 --- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetDevice.java +++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetDevice.java @@ -35,7 +35,7 @@ import org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionEvent; import org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionResponse; import org.apache.plc4x.java.spi.messages.PlcSubscriber; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration; import org.apache.plc4x.java.spi.values.PlcSTRING; import org.slf4j.Logger; @@ -145,7 +145,7 @@ private void recordIdAndSend(ProfinetCallable callable, int sourc @Override public CompletableFuture subscribe(PlcSubscriptionRequest subscriptionRequest) { return CompletableFuture.supplyAsync(() -> { - Map> values = new HashMap<>(); + Map> values = new HashMap<>(); return new DefaultPlcSubscriptionResponse(subscriptionRequest, values); }); @@ -406,7 +406,7 @@ public ProfinetDeviceContext getDeviceContext() { } public void handleRealTimeResponse(PnDcp_Pdu_RealTimeCyclic cyclicPdu) { - Map> tags = new HashMap<>(); + Map> tags = new HashMap<>(); ReadBuffer buffer = new ReadBufferByteBased(cyclicPdu.getDataUnit().getData()); if (firstMessage) { @@ -419,8 +419,8 @@ public void handleRealTimeResponse(PnDcp_Pdu_RealTimeCyclic cyclicPdu) { module.parseTags(tags, deviceContext.getDeviceName(), buffer); } - Map, Map>> response = new HashMap<>(); - for (Map.Entry> entry : tags.entrySet()) { + Map, Map>> response = new HashMap<>(); + for (Map.Entry> entry : tags.entrySet()) { boolean processTag = false; ProfinetSubscriptionHandle handle = deviceContext.getSubscriptionHandle(entry.getKey()); if (handle != null) { @@ -451,7 +451,7 @@ public void handleRealTimeResponse(PnDcp_Pdu_RealTimeCyclic cyclicPdu) { } } - for (Map.Entry, Map>> entry : response.entrySet()) { + for (Map.Entry, Map>> entry : response.entrySet()) { entry.getKey().accept(new DefaultPlcSubscriptionEvent(Instant.now(), entry.getValue())); } } catch (ParseException e) { diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetEmptyModule.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetEmptyModule.java index a35fc29a945..be1cbce016c 100644 --- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetEmptyModule.java +++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetEmptyModule.java @@ -26,7 +26,7 @@ import org.apache.plc4x.java.profinet.readwrite.PnIoCm_Submodule; import org.apache.plc4x.java.spi.generation.ParseException; import org.apache.plc4x.java.spi.generation.ReadBuffer; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; import java.util.ArrayList; import java.util.List; @@ -96,7 +96,7 @@ public int getOutputIoPsSize() { public void populateOutputCR(int ioPsOffset, int ioCsOffset) { } @Override - public Map> parseTags(Map> tags, String addressSpace, ReadBuffer buffer) throws ParseException { + public Map> parseTags(Map> tags, String addressSpace, ReadBuffer buffer) throws ParseException { return tags; } diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetModule.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetModule.java index a7f81612c41..b7c7a1c6ea1 100644 --- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetModule.java +++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetModule.java @@ -21,15 +21,13 @@ import org.apache.plc4x.java.api.messages.PlcBrowseItem; import org.apache.plc4x.java.api.value.PlcValue; -import org.apache.plc4x.java.profinet.gsdml.ProfinetVirtualSubmoduleItem; import org.apache.plc4x.java.profinet.readwrite.PnIoCm_IoCs; import org.apache.plc4x.java.profinet.readwrite.PnIoCm_IoDataObject; import org.apache.plc4x.java.profinet.readwrite.PnIoCm_Submodule; import org.apache.plc4x.java.spi.generation.ParseException; import org.apache.plc4x.java.spi.generation.ReadBuffer; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; -import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -53,5 +51,5 @@ public interface ProfinetModule { int getOutputIoPsSize(); void populateOutputCR(int ioPsOffset, int ioCsOffset); - Map> parseTags(Map> tags, String addressSpace, ReadBuffer buffer) throws ParseException; + Map> parseTags(Map> tags, String addressSpace, ReadBuffer buffer) throws ParseException; } diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetModuleImpl.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetModuleImpl.java index a1e8d2641b3..63a6f8d431c 100644 --- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetModuleImpl.java +++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetModuleImpl.java @@ -28,8 +28,8 @@ import org.apache.plc4x.java.spi.generation.ParseException; import org.apache.plc4x.java.spi.generation.ReadBuffer; import org.apache.plc4x.java.spi.messages.DefaultPlcBrowseItem; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; -import org.apache.plc4x.java.spi.values.PlcSINT; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; import org.apache.plc4x.java.spi.values.PlcSTRING; import java.util.*; @@ -303,7 +303,7 @@ public List browseTags(List browseItems, String ad } @Override - public Map> parseTags(Map> tags, String addressSpace, ReadBuffer buffer) throws ParseException { + public Map> parseTags(Map> tags, String addressSpace, ReadBuffer buffer) throws ParseException { for (PnIoCm_IoDataObject block : inputIoPsApiBlocks) { int identNumber = block.getSubSlotNumber(); for (ProfinetVirtualSubmoduleItem virtual : module.getVirtualSubmoduleList()) { @@ -314,31 +314,31 @@ public Map> parseTags(Map(PlcResponseCode.OK, DataItem.staticParse(buffer, ProfinetDataType.BOOL, 1))); + tags.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, DataItem.staticParse(buffer, ProfinetDataType.BOOL, 1))); } } else { String tagName = addressSpace + "." + this.slot + "." + block.getSubSlotNumber() + "." + item.getTextId(); ProfinetDataType datatype = ProfinetDataType.firstEnumForFieldConversion(item.getDataType().toUpperCase()); - tags.put(tagName, new ResponseItem<>(PlcResponseCode.OK, DataItem.staticParse(buffer, datatype, 1))); + tags.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, DataItem.staticParse(buffer, datatype, 1))); } } } } String statusName = addressSpace + "." + this.slot + "." + block.getSubSlotNumber() + "." + virtual.getId() + ".Status"; - tags.put(statusName, new ResponseItem<>(PlcResponseCode.OK, DataItem.staticParse(buffer, ProfinetDataType.SINT, 1))); + tags.put(statusName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, DataItem.staticParse(buffer, ProfinetDataType.SINT, 1))); } } if (module.getSystemDefinedSubmoduleList() != null) { for (ProfinetInterfaceSubmoduleItem systemInterface : module.getSystemDefinedSubmoduleList().getInterfaceSubmodules()) { if (identNumber == systemInterface.getSubslotNumber()) { String statusName = addressSpace + "." + this.slot + "." + block.getSubSlotNumber() + "." + systemInterface.getId() + ".Status"; - tags.put(statusName, new ResponseItem<>(PlcResponseCode.OK, DataItem.staticParse(buffer, ProfinetDataType.SINT, 1))); + tags.put(statusName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, DataItem.staticParse(buffer, ProfinetDataType.SINT, 1))); } } for (ProfinetPortSubmoduleItem systemPort : module.getSystemDefinedSubmoduleList().getPortSubmodules()) { if (identNumber == systemPort.getSubslotNumber()) { String statusName = addressSpace + "." + this.slot + "." + block.getSubSlotNumber() + "." + systemPort.getId() + ".Status"; - tags.put(statusName, new ResponseItem<>(PlcResponseCode.OK, DataItem.staticParse(buffer, ProfinetDataType.SINT, 1))); + tags.put(statusName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, DataItem.staticParse(buffer, ProfinetDataType.SINT, 1))); } } } diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetSubscriptionHandle.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetSubscriptionHandle.java index 8a5ddb86566..42127da5c57 100644 --- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetSubscriptionHandle.java +++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetSubscriptionHandle.java @@ -19,23 +19,11 @@ package org.apache.plc4x.java.profinet.device; -import org.apache.plc4x.java.api.messages.PlcSubscriptionEvent; -import org.apache.plc4x.java.api.model.PlcConsumerRegistration; import org.apache.plc4x.java.api.model.PlcSubscriptionTag; -import org.apache.plc4x.java.api.model.PlcTag; import org.apache.plc4x.java.api.types.PlcSubscriptionType; import org.apache.plc4x.java.api.value.PlcValue; -import org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionEvent; import org.apache.plc4x.java.spi.messages.PlcSubscriber; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; -import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration; import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionHandle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.time.Instant; -import java.util.*; -import java.util.function.Consumer; public class ProfinetSubscriptionHandle extends DefaultPlcSubscriptionHandle { diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/protocol/ProfinetProtocolLogic.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/protocol/ProfinetProtocolLogic.java index 95beb4f774e..50ea805d117 100644 --- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/protocol/ProfinetProtocolLogic.java +++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/protocol/ProfinetProtocolLogic.java @@ -32,11 +32,14 @@ import org.apache.plc4x.java.profinet.discovery.ProfinetPlcDiscoverer; import org.apache.plc4x.java.profinet.readwrite.*; import org.apache.plc4x.java.profinet.tag.ProfinetTag; +import org.apache.plc4x.java.profinet.tag.ProfinetTagHandler; import org.apache.plc4x.java.spi.ConversationContext; import org.apache.plc4x.java.spi.Plc4xProtocolBase; import org.apache.plc4x.java.spi.configuration.HasConfiguration; +import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.messages.*; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionTag; import org.apache.plc4x.java.utils.rawsockets.netty.RawSocketChannel; import org.pcap4j.core.*; @@ -92,8 +95,8 @@ public void setConfiguration(ProfinetConfiguration configuration) { } @Override - public void setContext(ConversationContext context) { - super.setContext(context); + public void setConversationContext(ConversationContext conversationContext) { + super.setConversationContext(conversationContext); // Open the receiving UDP port and keep it open. try { @@ -105,10 +108,15 @@ public void setContext(ConversationContext context) { profinetDriverContext.getHandler().setConfiguredDevices(devices); for (Map.Entry device : devices.entrySet()) { - device.getValue().setContext(context, this.profinetDriverContext.getChannel()); + device.getValue().setContext(conversationContext, this.profinetDriverContext.getChannel()); } } + @Override + public PlcTagHandler getTagHandler() { + return new ProfinetTagHandler(); + } + /** * Start a PN or LLDP discovery to find PN devices on the network. * We pass in a driverContext handler, that checks if an incoming response has the information needed for @@ -238,7 +246,7 @@ public CompletableFuture write(PlcWriteRequest writeRequest) { @Override public CompletableFuture subscribe(PlcSubscriptionRequest subscriptionRequest) { return CompletableFuture.supplyAsync(() -> { - Map> values = new HashMap<>(); + Map> values = new HashMap<>(); for (String fieldName : subscriptionRequest.getTagNames()) { PlcSubscriptionTag tag = subscriptionRequest.getTag(fieldName); @@ -250,9 +258,9 @@ public CompletableFuture subscribe(PlcSubscriptionReque device.getDeviceContext().addSubscriptionHandle(fieldDefaultPlcSubscription.getAddressString(), subscriptionHandle); if (!(fieldDefaultPlcSubscription.getTag() instanceof ProfinetTag)) { - values.put(fieldName, new ResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null)); + values.put(fieldName, new DefaultPlcResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null)); } else { - values.put(fieldName, new ResponseItem<>(PlcResponseCode.OK, subscriptionHandle)); + values.put(fieldName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, subscriptionHandle)); } } return new DefaultPlcSubscriptionResponse(subscriptionRequest, values); diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/events/S7CyclicEvent.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/events/S7CyclicEvent.java index f65076e9944..6b7c83d3bf2 100644 --- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/events/S7CyclicEvent.java +++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/events/S7CyclicEvent.java @@ -42,7 +42,7 @@ import org.apache.plc4x.java.s7.readwrite.tag.S7SubscriptionTag; import org.apache.plc4x.java.s7.readwrite.tag.S7Tag; import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionTag; -import org.apache.plc4x.java.spi.values.PlcValueHandler; +import org.apache.plc4x.java.spi.values.DefaultPlcValueHandler; public class S7CyclicEvent implements S7Event { @@ -77,7 +77,7 @@ public S7CyclicEvent(PlcSubscriptionRequest request, short jobid, S7PayloadUserD int i = n[0]; map.put(Fields.RETURNCODE_.name() + i, event.getItems().get(i).getReturnCode().getValue()); map.put(Fields.TRANSPORTSIZE_.name() + i, event.getItems().get(i).getTransportSize().getValue()); - map.put(tagname, DataToPlcValue(tagname, request, event.getItems().get(i).getData())); + map.put(tagname, dataToPlcValue(tagname, request, event.getItems().get(i).getData())); n[0]++; }); @@ -97,7 +97,7 @@ public S7CyclicEvent(PlcSubscriptionRequest request, short jobid, S7PayloadUserD int i = n[0]; map.put(Fields.RETURNCODE_.name() + i, event.getItems().get(i).getReturnCode().getValue()); map.put(Fields.TRANSPORTSIZE_.name() + i, event.getItems().get(i).getTransportSize().getValue()); - map.put(tagname, DataToPlcValue(tagname, request, event.getItems().get(i).getData())); + map.put(tagname, dataToPlcValue(tagname, request, event.getItems().get(i).getData())); n[0]++; }); @@ -117,7 +117,7 @@ public S7CyclicEvent(PlcSubscriptionRequest request, short jobid, S7PayloadUserD int i = n[0]; map.put(Fields.RETURNCODE_.name() + i, event.getItems().get(i).getReturnCode().getValue()); map.put(Fields.TRANSPORTSIZE_.name() + i, event.getItems().get(i).getTransportSize().getValue()); - map.put(tagname, DataToPlcValue(tagname, request, event.getItems().get(i).getData())); + map.put(tagname, dataToPlcValue(tagname, request, event.getItems().get(i).getData())); n[0]++; }); } @@ -136,7 +136,7 @@ public S7CyclicEvent(PlcSubscriptionRequest request, short jobid, S7PayloadUserD int i = n[0]; map.put(Fields.RETURNCODE_.name() + i, event.getItems().get(i).getReturnCode().getValue()); map.put(Fields.TRANSPORTSIZE_.name() + i, event.getItems().get(i).getTransportSize().getValue()); - map.put(tagname, DataToPlcValue(tagname, request, event.getItems().get(i).getData())); + map.put(tagname, dataToPlcValue(tagname, request, event.getItems().get(i).getData())); n[0]++; }); } @@ -744,7 +744,7 @@ public boolean equals(Object obj) { } - private static PlcValue DataToPlcValue(String tagname, PlcSubscriptionRequest request, List data){ + private static PlcValue dataToPlcValue(String tagname, PlcSubscriptionRequest request, List data){ int[] i = new int[1]; @@ -770,7 +770,7 @@ private static PlcValue DataToPlcValue(String tagname, PlcSubscriptionRequest re for (int iter = 0; iter < s7Tags[0].getNumberOfElements(); iter++) { bools[iter] = bb.readBoolean(); } - plcValue = PlcValueHandler.of(bools); + plcValue = DefaultPlcValueHandler.of(s7Tags[0], bools); break; case BYTE: // TODO: This looks suspicious @@ -778,7 +778,7 @@ private static PlcValue DataToPlcValue(String tagname, PlcSubscriptionRequest re for (Byte b:bytes) { b = Byte.valueOf(bb.readByte()); } - plcValue = PlcValueHandler.of(bytes); + plcValue = DefaultPlcValueHandler.of(s7Tags[0], bytes); break; case WORD: break; @@ -791,7 +791,7 @@ private static PlcValue DataToPlcValue(String tagname, PlcSubscriptionRequest re for (int iter = 0; iter < s7Tags[0].getNumberOfElements(); iter ++) { shorts[iter] = bb.readShort(); } - plcValue = PlcValueHandler.of(shorts); + plcValue = DefaultPlcValueHandler.of(s7Tags[0], shorts); break; case UINT: break; @@ -805,7 +805,7 @@ private static PlcValue DataToPlcValue(String tagname, PlcSubscriptionRequest re for (Integer di:integers) { di = Integer.valueOf(bb.readInt()); } - plcValue = PlcValueHandler.of(integers); + plcValue = DefaultPlcValueHandler.of(s7Tags[0], integers); break; case UDINT: break; @@ -815,7 +815,7 @@ private static PlcValue DataToPlcValue(String tagname, PlcSubscriptionRequest re for (Long l:longs) { l = bb.readLong(); } - plcValue = PlcValueHandler.of(longs); + plcValue = DefaultPlcValueHandler.of(s7Tags[0], longs); break; case ULINT: break; @@ -825,7 +825,7 @@ private static PlcValue DataToPlcValue(String tagname, PlcSubscriptionRequest re for (Float f:floats) { f = bb.readFloat(); } - plcValue = PlcValueHandler.of(floats); + plcValue = DefaultPlcValueHandler.of(s7Tags[0], floats); break; case LREAL: // TODO: This looks suspicious @@ -833,7 +833,7 @@ private static PlcValue DataToPlcValue(String tagname, PlcSubscriptionRequest re for (Double d:doubles) { d = bb.readDouble(); } - plcValue = PlcValueHandler.of(doubles); + plcValue = DefaultPlcValueHandler.of(s7Tags[0], doubles); break; case CHAR: break; diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/S7Driver.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/S7Driver.java index 047aabc6477..f814cd3a49c 100644 --- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/S7Driver.java +++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/S7Driver.java @@ -29,12 +29,10 @@ import org.apache.plc4x.java.s7.readwrite.protocol.S7HGeneratedDriverBase; import org.apache.plc4x.java.s7.readwrite.protocol.S7HSingleProtocolStackConfigurer; import org.apache.plc4x.java.s7.readwrite.protocol.S7ProtocolLogic; -import org.apache.plc4x.java.s7.readwrite.tag.S7PlcTagHandler; import org.apache.plc4x.java.s7.readwrite.tag.S7Tag; import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer; import org.apache.plc4x.java.spi.messages.DefaultPlcDiscoveryRequest; import org.apache.plc4x.java.spi.optimizer.BaseOptimizer; -import org.apache.plc4x.java.spi.values.PlcValueHandler; import org.pcap4j.core.PcapNativeException; import org.pcap4j.core.Pcaps; @@ -99,16 +97,6 @@ protected BaseOptimizer getOptimizer() { return new S7Optimizer(); } - @Override - protected S7PlcTagHandler getTagHandler() { - return new S7PlcTagHandler(); - } - - @Override - protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() { - return new PlcValueHandler(); - } - @Override public PlcDiscoveryRequest.Builder discoveryRequestBuilder() { // TODO: This should actually happen in the execute method of the discoveryRequest and not here ... diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/connection/S7HMuxImpl.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/connection/S7HMuxImpl.java index 122ce4b309d..83703f2ab21 100644 --- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/connection/S7HMuxImpl.java +++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/connection/S7HMuxImpl.java @@ -102,11 +102,11 @@ public class S7HMuxImpl extends MessageToMessageCodec implemen */ public final static AttributeKey RETRY_TIME = AttributeKey.valueOf("RETRY_TIME"); - ChannelHandlerContext embed_ctx = null; - protected Channel embeded_channel = null; - protected Channel tcp_channel = null; - protected Channel primary_channel = null; - protected Channel secondary_channel = null; + ChannelHandlerContext embedCtx = null; + protected Channel embededChannel = null; + protected Channel tcpChannel = null; + protected Channel primaryChannel = null; + protected Channel secondaryChannel = null; /* * From S7ProtocolLogic @@ -114,13 +114,15 @@ public class S7HMuxImpl extends MessageToMessageCodec implemen * the Embedded channel when we created it. */ @Override - protected void encode(ChannelHandlerContext ctx, ByteBuf outbb, List list) throws Exception { - logger.debug("ENCODE: " + outbb.toString()); - if ((embed_ctx == null) && (ctx.channel() instanceof EmbeddedChannel)) embed_ctx = ctx; - if ((tcp_channel != null) && (embed_ctx == ctx)) { - tcp_channel.writeAndFlush(outbb.copy()); + protected void encode(ChannelHandlerContext ctx, ByteBuf outBB, List list) { + logger.debug("ENCODE: {}", outBB.toString()); + if ((embedCtx == null) && (ctx.channel() instanceof EmbeddedChannel)) { + embedCtx = ctx; + } + if ((tcpChannel != null) && (embedCtx == ctx)) { + tcpChannel.writeAndFlush(outBB.copy()); } else { - list.add(outbb.copy()); + list.add(outBB.copy()); } } @@ -131,7 +133,7 @@ protected void encode(ChannelHandlerContext ctx, ByteBuf outbb, List lis */ @Override protected void decode(ChannelHandlerContext ctx, ByteBuf inbb, List list) throws Exception { - embed_ctx.fireChannelRead(inbb.copy()); + embedCtx.fireChannelRead(inbb.copy()); } @Override @@ -165,16 +167,16 @@ public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exc logger.info("{} userEventTriggered: {} Event: {}", LocalTime.now(), ctx.name(), evt); if (evt instanceof ConnectEvent) { try { - tcp_channel.pipeline().remove("watchdog"); + tcpChannel.pipeline().remove("watchdog"); } catch (Exception ex) { logger.info(ex.toString()); } try { - tcp_channel.pipeline().addFirst("watchdog", new ReadTimeoutHandler(30)); - if (tcp_channel.isActive()) { - embeded_channel.attr(IS_CONNECTED).set(true); + tcpChannel.pipeline().addFirst("watchdog", new ReadTimeoutHandler(30)); + if (tcpChannel.isActive()) { + embededChannel.attr(IS_CONNECTED).set(true); } else { - embeded_channel.attr(IS_CONNECTED).set(false); + embededChannel.attr(IS_CONNECTED).set(false); } } catch (Exception ex) { logger.info(ex.toString()); @@ -209,39 +211,39 @@ public void channelActive(ChannelHandlerContext ctx) throws Exception { public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { super.channelUnregistered(ctx); logger.debug("{} channelUnregistered: {}", LocalTime.now(), ctx.name()); - String strCanal = (tcp_channel == primary_channel) ? "PRIMARY" : "SECONDARY"; - logger.debug("Unregistered of channel: " + strCanal); + String strCanal = (tcpChannel == primaryChannel) ? "PRIMARY" : "SECONDARY"; + logger.debug("Unregistered of channel: {}", strCanal); //TODO: If embedded channel is closed, we need close all channels - if (ctx == embed_ctx) return; + if (ctx == embedCtx) return; - if (tcp_channel == ctx.channel()) - embeded_channel.attr(IS_CONNECTED).set(false); + if (tcpChannel == ctx.channel()) + embededChannel.attr(IS_CONNECTED).set(false); - logger.info(embed_ctx.executor().toString()); + logger.info(embedCtx.executor().toString()); - if ((tcp_channel == primary_channel) && - (primary_channel == ctx.channel())) - if ((!primary_channel.isActive()) && - (secondary_channel != null)) { - if (secondary_channel.isActive()) - synchronized (tcp_channel) { + if ((tcpChannel == primaryChannel) && + (primaryChannel == ctx.channel())) + if ((!primaryChannel.isActive()) && + (secondaryChannel != null)) { + if (secondaryChannel.isActive()) + synchronized (tcpChannel) { logger.info("Using secondary TCP channel."); - tcp_channel = secondary_channel; - embeded_channel.attr(IS_PRIMARY).set(false); - embeded_channel.pipeline().fireUserEventTriggered(new ConnectEvent()); + tcpChannel = secondaryChannel; + embededChannel.attr(IS_PRIMARY).set(false); + embededChannel.pipeline().fireUserEventTriggered(new ConnectEvent()); } } - if ((tcp_channel == secondary_channel) && - (secondary_channel == ctx.channel())) - if ((!secondary_channel.isActive() && - (primary_channel.isActive()))) { - synchronized (tcp_channel) { + if ((tcpChannel == secondaryChannel) && + (secondaryChannel == ctx.channel())) + if ((!secondaryChannel.isActive() && + (primaryChannel.isActive()))) { + synchronized (tcpChannel) { logger.info("Using primary TCP channel."); - tcp_channel = primary_channel; - embeded_channel.attr(IS_PRIMARY).set(true); - embeded_channel.pipeline().fireUserEventTriggered(new ConnectEvent()); + tcpChannel = primaryChannel; + embededChannel.attr(IS_PRIMARY).set(true); + embededChannel.pipeline().fireUserEventTriggered(new ConnectEvent()); } } } @@ -249,32 +251,32 @@ public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { @Override public void setEmbeddedChannel(Channel embeded_channel) { - this.embeded_channel = embeded_channel; - this.embeded_channel.attr(IS_CONNECTED).set(false); - this.embeded_channel.attr(IS_PRIMARY).set(true); - this.embeded_channel.attr(READ_TIME_OUT).set(8); - this.embeded_channel.attr(IS_PING_ACTIVE).set(false); - this.embeded_channel.attr(PING_TIME).set(-1); - this.embeded_channel.attr(RETRY_TIME).set(8); + this.embededChannel = embeded_channel; + this.embededChannel.attr(IS_CONNECTED).set(false); + this.embededChannel.attr(IS_PRIMARY).set(true); + this.embededChannel.attr(READ_TIME_OUT).set(8); + this.embededChannel.attr(IS_PING_ACTIVE).set(false); + this.embededChannel.attr(PING_TIME).set(-1); + this.embededChannel.attr(RETRY_TIME).set(8); } public void setPrimaryChannel(Channel primary_channel) { - if ((this.primary_channel == null) && (tcp_channel == null)) { + if ((this.primaryChannel == null) && (tcpChannel == null)) { if (primary_channel != null) { - this.primary_channel = primary_channel; - tcp_channel = primary_channel; - embeded_channel.attr(IS_PRIMARY).set(true); + this.primaryChannel = primary_channel; + tcpChannel = primary_channel; + embededChannel.attr(IS_PRIMARY).set(true); } - } else if ((!this.primary_channel.isActive()) && (tcp_channel == secondary_channel)) { - this.primary_channel = primary_channel; - } else if ((!this.primary_channel.isActive()) && (tcp_channel == this.primary_channel)) { - synchronized (tcp_channel) { - tcp_channel.close(); - this.primary_channel = primary_channel; - tcp_channel = primary_channel; - embeded_channel.attr(IS_PRIMARY).set(true); - if (tcp_channel.isActive()) { - embed_ctx.fireUserEventTriggered(new ConnectEvent()); + } else if ((!this.primaryChannel.isActive()) && (tcpChannel == secondaryChannel)) { + this.primaryChannel = primary_channel; + } else if ((!this.primaryChannel.isActive()) && (tcpChannel == this.primaryChannel)) { + synchronized (tcpChannel) { + tcpChannel.close(); + this.primaryChannel = primary_channel; + tcpChannel = primary_channel; + embededChannel.attr(IS_PRIMARY).set(true); + if (tcpChannel.isActive()) { + embedCtx.fireUserEventTriggered(new ConnectEvent()); } } } @@ -282,25 +284,25 @@ public void setPrimaryChannel(Channel primary_channel) { @Override public void setSecondaryChannel(Channel secondary_channel) { - if ((this.primary_channel == null) && (tcp_channel == null)) { + if ((this.primaryChannel == null) && (tcpChannel == null)) { if (secondary_channel != null) { - this.secondary_channel = secondary_channel; - tcp_channel = secondary_channel; - embeded_channel.attr(IS_PRIMARY).set(false); + this.secondaryChannel = secondary_channel; + tcpChannel = secondary_channel; + embededChannel.attr(IS_PRIMARY).set(false); } - } else if ((this.secondary_channel == null) || (tcp_channel == primary_channel)) { - this.secondary_channel = secondary_channel; - } else if ((!this.secondary_channel.isActive()) && (tcp_channel == primary_channel)) { - this.secondary_channel = secondary_channel; - } else if ((!this.secondary_channel.isActive()) && (tcp_channel == this.secondary_channel)) { - synchronized (tcp_channel) { - tcp_channel.close(); - this.secondary_channel = secondary_channel; - tcp_channel = secondary_channel; - embeded_channel.attr(IS_PRIMARY).set(false); + } else if ((this.secondaryChannel == null) || (tcpChannel == primaryChannel)) { + this.secondaryChannel = secondary_channel; + } else if ((!this.secondaryChannel.isActive()) && (tcpChannel == primaryChannel)) { + this.secondaryChannel = secondary_channel; + } else if ((!this.secondaryChannel.isActive()) && (tcpChannel == this.secondaryChannel)) { + synchronized (tcpChannel) { + tcpChannel.close(); + this.secondaryChannel = secondary_channel; + tcpChannel = secondary_channel; + embededChannel.attr(IS_PRIMARY).set(false); } - if (tcp_channel.isActive()) { - embed_ctx.fireUserEventTriggered(new ConnectEvent()); + if (tcpChannel.isActive()) { + embedCtx.fireUserEventTriggered(new ConnectEvent()); } } } diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/discovery/S7PlcDiscoverer.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/discovery/S7PlcDiscoverer.java index 50f623c7292..9a487666dc9 100644 --- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/discovery/S7PlcDiscoverer.java +++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/discovery/S7PlcDiscoverer.java @@ -46,7 +46,7 @@ import org.apache.plc4x.java.spi.messages.DefaultPlcDiscoveryItem; import org.apache.plc4x.java.spi.messages.DefaultPlcDiscoveryResponse; import org.apache.plc4x.java.spi.messages.PlcDiscoverer; -import org.apache.plc4x.java.spi.values.PlcValues; +import org.apache.plc4x.java.spi.values.PlcSTRING; import org.pcap4j.core.NotOpenException; import org.pcap4j.core.PcapHandle; import org.pcap4j.core.PcapNativeException; @@ -286,16 +286,16 @@ public void handlePnDcpPacket(PnDcp_Pdu pdu, EthernetPacket ethernetPacket) { // Only add devices we know support the S7Comm protocol. if(supportsS7Comm) { Map attributes = new HashMap<>(); - attributes.put("ipAddress", PlcValues.of(remoteAddress)); - attributes.put("subnetMask", PlcValues.of(remoteSubnetMask)); - attributes.put("macAddress", PlcValues.of(srcAddr.toString())); - attributes.put("localMacAddress", PlcValues.of(dstAddr.toString())); - attributes.put("deviceTypeName", PlcValues.of(deviceTypeName)); - attributes.put("deviceName", PlcValues.of(deviceName)); - attributes.put("vendorId", PlcValues.of(vendorId)); - attributes.put("deviceId", PlcValues.of(deviceId)); - attributes.put("role", PlcValues.of(role)); - attributes.put("packetType", PlcValues.of("dcp")); + attributes.put("ipAddress", new PlcSTRING(remoteAddress)); + attributes.put("subnetMask", new PlcSTRING(remoteSubnetMask)); + attributes.put("macAddress", new PlcSTRING(srcAddr.toString())); + attributes.put("localMacAddress", new PlcSTRING(dstAddr.toString())); + attributes.put("deviceTypeName", new PlcSTRING(deviceTypeName)); + attributes.put("deviceName", new PlcSTRING(deviceName)); + attributes.put("vendorId", new PlcSTRING(vendorId)); + attributes.put("deviceId", new PlcSTRING(deviceId)); + attributes.put("role", new PlcSTRING(role)); + attributes.put("packetType", new PlcSTRING("dcp")); String name = deviceTypeName + " - " + deviceName; diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/optimizer/S7Optimizer.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/optimizer/S7Optimizer.java index 5695bfec433..b48512c9a09 100644 --- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/optimizer/S7Optimizer.java +++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/optimizer/S7Optimizer.java @@ -22,7 +22,6 @@ import org.apache.plc4x.java.api.messages.PlcReadRequest; import org.apache.plc4x.java.api.messages.PlcReadResponse; import org.apache.plc4x.java.api.messages.PlcWriteRequest; -import org.apache.plc4x.java.api.model.PlcTag; import org.apache.plc4x.java.api.types.PlcResponseCode; import org.apache.plc4x.java.api.types.PlcValueType; import org.apache.plc4x.java.api.value.PlcValue; @@ -35,8 +34,12 @@ import org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest; import org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse; import org.apache.plc4x.java.spi.messages.DefaultPlcWriteRequest; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; -import org.apache.plc4x.java.spi.messages.utils.TagValueItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcTagItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcTagValueItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcTagItem; +import org.apache.plc4x.java.spi.messages.utils.PlcTagValueItem; import org.apache.plc4x.java.spi.optimizer.BaseOptimizer; import org.apache.plc4x.java.spi.utils.Serializable; import org.apache.plc4x.java.spi.values.PlcNull; @@ -78,14 +81,15 @@ protected List processReadRequest(PlcReadRequest readRequest, Dr // List of all items in the current request. - LinkedHashMap curTags = new LinkedHashMap<>(); + LinkedHashMap curTagItems = new LinkedHashMap<>(); for (String tagName : readRequest.getTagNames()) { //TODO: Individual processing of these types of tags. like S7StringTag if ((readRequest.getTag(tagName) instanceof S7SzlTag) || (readRequest.getTag(tagName) instanceof S7ClkTag)) { - curTags.put(tagName, readRequest.getTag(tagName)); + // We are only expecting valid tagValueItems being passed in. + curTagItems.put(tagName, new DefaultPlcTagItem(readRequest.getTag(tagName))); continue; } @@ -119,7 +123,8 @@ protected List processReadRequest(PlcReadRequest readRequest, Dr curResponseSize += readResponseItemSize; // Add the tag to the current request - curTags.put(tagName, tag); + // We are only expecting valid tagValueItems being passed in. + curTagItems.put(tagName, new DefaultPlcTagItem(tag)); } // If the current item would exceed the PDU size in the response, even if this is a new request, split // up the array to fill up the last request and create so many sub-requests that read all in total. @@ -132,8 +137,8 @@ else if (EMPTY_READ_RESPONSE_SIZE + readResponseItemSize > s7DriverContext.getPd for(int curRequest = 0; curRequest < numRequests; curRequest++) { int numCurRequestItems = Math.min(numItemsPerRequest, itemsLeft); S7Tag tagFragment = new S7Tag(tag.getDataType(), tag.getMemoryArea(), tag.getBlockNumber(), curByteOffset, (byte) 0, numCurRequestItems); - LinkedHashMap tagFragments = new LinkedHashMap<>(); - tagFragments.put(tagName, tagFragment); + LinkedHashMap tagFragments = new LinkedHashMap<>(); + tagFragments.put(tagName, new DefaultPlcTagItem(tagFragment)); processedRequests.add(new DefaultPlcReadRequest(((DefaultPlcReadRequest) readRequest).getReader(), tagFragments)); curByteOffset += numItemsPerRequest * tag.getDataType().getSizeInBytes(); itemsLeft -= numCurRequestItems; @@ -143,12 +148,12 @@ else if (EMPTY_READ_RESPONSE_SIZE + readResponseItemSize > s7DriverContext.getPd else { // Create a new PlcReadRequest containing the current tag item. processedRequests.add(new DefaultPlcReadRequest( - ((DefaultPlcReadRequest) readRequest).getReader(), curTags)); + ((DefaultPlcReadRequest) readRequest).getReader(), curTagItems)); // Reset the size and item lists. curRequestSize = EMPTY_READ_REQUEST_SIZE + readRequestItemSize; curResponseSize = EMPTY_READ_RESPONSE_SIZE + readResponseItemSize; - curTags = new LinkedHashMap<>(); + curTagItems = new LinkedHashMap<>(); // Splitting of huge tags not yet implemented, throw an exception instead. if (((curRequestSize + readRequestItemSize) > s7DriverContext.getPduSize()) && @@ -157,21 +162,22 @@ else if (EMPTY_READ_RESPONSE_SIZE + readResponseItemSize > s7DriverContext.getPd } // Add the tag to the new current request - curTags.put(tagName, tag); + // We are only expecting valid tagValueItems being passed in. + curTagItems.put(tagName, new DefaultPlcTagItem(tag)); } } // Create a new PlcReadRequest from the remaining tag items. - if (!curTags.isEmpty()) { + if (!curTagItems.isEmpty()) { processedRequests.add(new DefaultPlcReadRequest( - ((DefaultPlcReadRequest) readRequest).getReader(), curTags)); + ((DefaultPlcReadRequest) readRequest).getReader(), curTagItems)); } return processedRequests; } protected PlcReadResponse processReadResponses(PlcReadRequest readRequest, Map> readResponses, DriverContext driverContext) { - Map> tagValues = new HashMap<>(); + Map> tagValues = new HashMap<>(); for (Map.Entry> requestsEntries : readResponses.entrySet()) { PlcReadRequest curRequest = requestsEntries.getKey(); SubResponse readResponse = requestsEntries.getValue(); @@ -191,7 +197,7 @@ protected PlcReadResponse processReadResponses(PlcReadRequest readRequest, Map

existingTagItem = tagValues.get(tagName); + PlcResponseItem existingTagItem = tagValues.get(tagName); // If a previous response was invalid, we'll discard this part of it too. if(existingTagItem.getCode() != PlcResponseCode.OK) { continue; @@ -199,7 +205,7 @@ protected PlcReadResponse processReadResponses(PlcReadRequest readRequest, Map

(responseCode, existingItem)); + tagValues.put(tagName, new DefaultPlcResponseItem<>(responseCode, existingItem)); } byte[] currentItemByteArray = value.getRaw(); int elementOffset = (currentS7Tag.getByteOffset() - globalS7Tag.getByteOffset()) / globalS7Tag.getDataType().getSizeInBytes(); @@ -210,7 +216,7 @@ protected PlcReadResponse processReadResponses(PlcReadRequest readRequest, Map

existingItems; if (tagValues.containsKey(tagName)) { - ResponseItem existingTagItem = tagValues.get(tagName); + PlcResponseItem existingTagItem = tagValues.get(tagName); // If a previous response was invalid, we'll discard this part of it too. if(existingTagItem.getCode() != PlcResponseCode.OK) { continue; @@ -219,7 +225,7 @@ protected PlcReadResponse processReadResponses(PlcReadRequest readRequest, Map

(Arrays.asList(new PlcValue[globalS7Tag.getNumberOfElements()])); PlcListModifiable mergedValue = new PlcListModifiable(existingItems); - tagValues.put(tagName, new ResponseItem<>(responseCode, mergedValue)); + tagValues.put(tagName, new DefaultPlcResponseItem<>(responseCode, mergedValue)); } List currentItems = value.getList(); int elementOffset = (currentS7Tag.getByteOffset() - globalS7Tag.getByteOffset()) / globalS7Tag.getDataType().getSizeInBytes(); @@ -230,13 +236,13 @@ protected PlcReadResponse processReadResponses(PlcReadRequest readRequest, Map

(responseCode, new PlcNull())); + tagValues.put(tagName, new DefaultPlcResponseItem<>(responseCode, new PlcNull())); } } else { - tagValues.put(tagName, new ResponseItem<>(responseCode, value)); + tagValues.put(tagName, new DefaultPlcResponseItem<>(responseCode, value)); } } else { - tagValues.put(tagName, new ResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null)); + tagValues.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null)); } } } @@ -261,7 +267,7 @@ protected List processWriteRequest(PlcWriteRequest writeRequest int curResponseSize = EMPTY_WRITE_RESPONSE_SIZE; // List of all items in the current request. - LinkedHashMap curTags = new LinkedHashMap<>(); + LinkedHashMap curTags = new LinkedHashMap<>(); for (String tagName : writeRequest.getTagNames()) { S7Tag tag = (S7Tag) writeRequest.getTag(tagName); @@ -326,7 +332,8 @@ else if (tag instanceof S7StringVarLengthTag) { throw new PlcRuntimeException("Tag size exceeds maximum payload for one item."); } } - curTags.put(tagName, new TagValueItem(tag, value)); + // We are only expecting valid tagValueItems being passed in. + curTags.put(tagName, new DefaultPlcTagValueItem(tag, value)); } // Create a new PlcWriteRequest from the remaining tag items. diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7HGeneratedDriverBase.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7HGeneratedDriverBase.java index e7b54148c11..f721e664fda 100644 --- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7HGeneratedDriverBase.java +++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7HGeneratedDriverBase.java @@ -23,14 +23,12 @@ import org.apache.plc4x.java.spi.configuration.PlcConnectionConfiguration; import org.apache.plc4x.java.spi.configuration.PlcTransportConfiguration; import org.apache.plc4x.java.api.exceptions.PlcConnectionException; -import org.apache.plc4x.java.api.value.PlcValueHandler; import org.apache.plc4x.java.s7.readwrite.TPKTPacket; import org.apache.plc4x.java.s7.readwrite.configuration.S7Configuration; import org.apache.plc4x.java.s7.readwrite.configuration.S7TcpTransportConfiguration; import org.apache.plc4x.java.spi.configuration.ConfigurationFactory; import org.apache.plc4x.java.spi.connection.ChannelFactory; import org.apache.plc4x.java.spi.connection.GeneratedDriverBase; -import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer; import org.apache.plc4x.java.spi.transport.Transport; import org.slf4j.Logger; @@ -163,7 +161,6 @@ public PlcConnection getConnection(String connectionString) throws PlcConnection return new S7HPlcConnection( canPing(), canRead(), canWrite(), canSubscribe(), canBrowse(), - getTagHandler(), getValueHandler(), configuration, channelFactory, @@ -177,15 +174,6 @@ public PlcConnection getConnection(String connectionString) throws PlcConnection getAuthentication()); } - @Override - protected PlcTagHandler getTagHandler() { - throw new UnsupportedOperationException("getTagHandler, Not supported yet."); - } - - @Override - protected PlcValueHandler getValueHandler() { - throw new UnsupportedOperationException("getValueHandler, Not supported yet."); - } @Override protected ProtocolStackConfigurer getStackConfigurer() { throw new UnsupportedOperationException("getStackConfigurer, Not supported yet."); diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7HMuxImpl.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7HMuxImpl.java index 26248b1c52a..1a987940d0e 100644 --- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7HMuxImpl.java +++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7HMuxImpl.java @@ -114,24 +114,24 @@ public class S7HMuxImpl extends MessageToMessageCodec implemen */ final static AttributeKey RETRY_TIME = AttributeKey.valueOf("RETRY_TIME"); - ChannelHandlerContext embed_ctx = null; - protected Channel embeded_channel = null; - protected Channel tcp_channel = null; - protected Channel primary_channel = null; - protected Channel secondary_channel = null; + ChannelHandlerContext embedCtx = null; + protected Channel embededChannel = null; + protected Channel tcpChannel = null; + protected Channel primaryChannel = null; + protected Channel secondaryChannel = null; /* * From S7ProtocolLogic * TODO: Evaluate if the "embed_ctx" is really required since we set - * the Embeded channel when we created it. + * the Embeded channel when we created it. */ @Override - protected void encode(ChannelHandlerContext ctx, ByteBuf outbb, List list) { - if ((embed_ctx == null) && (ctx.channel() instanceof EmbeddedChannel)) embed_ctx = ctx; - if ((tcp_channel != null) && (embed_ctx == ctx)) { - tcp_channel.writeAndFlush(outbb.copy()); + protected void encode(ChannelHandlerContext ctx, ByteBuf outBB, List list) { + if ((embedCtx == null) && (ctx.channel() instanceof EmbeddedChannel)) embedCtx = ctx; + if ((tcpChannel != null) && (embedCtx == ctx)) { + tcpChannel.writeAndFlush(outBB.copy()); } else { - list.add(outbb.copy()); + list.add(outBB.copy()); } } @@ -141,8 +141,8 @@ protected void encode(ChannelHandlerContext ctx, ByteBuf outbb, List lis * the pipeline of the channel "embeded_channel" */ @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf inbb, List list) throws Exception { - embed_ctx.fireChannelRead(inbb.copy()); + protected void decode(ChannelHandlerContext ctx, ByteBuf inBB, List list) throws Exception { + embedCtx.fireChannelRead(inBB.copy()); } @Override @@ -177,19 +177,19 @@ public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exc logger.info(LocalTime.now() + " userEventTriggered: " + ctx.name() + " Event: " + evt); if (evt instanceof ConnectedEvent) { try { - tcp_channel.pipeline().remove("watchdog"); + tcpChannel.pipeline().remove("watchdog"); } catch (Exception ex) { logger.info(ex.toString()); } try { - if ((embeded_channel.attr(READ_TIME_OUT).get() > 0) && - embeded_channel.attr(IS_PING_ACTIVE).get()) - tcp_channel.pipeline().addFirst("watchdog", - new ReadTimeoutHandler(embeded_channel.attr(READ_TIME_OUT).get())); - if (tcp_channel.isActive()) { - embeded_channel.attr(IS_CONNECTED).set(true); + if ((embededChannel.attr(READ_TIME_OUT).get() > 0) && + embededChannel.attr(IS_PING_ACTIVE).get()) + tcpChannel.pipeline().addFirst("watchdog", + new ReadTimeoutHandler(embededChannel.attr(READ_TIME_OUT).get())); + if (tcpChannel.isActive()) { + embededChannel.attr(IS_CONNECTED).set(true); } else { - embeded_channel.attr(IS_CONNECTED).set(false); + embededChannel.attr(IS_CONNECTED).set(false); } } catch (Exception ex) { logger.info(ex.toString()); @@ -223,45 +223,45 @@ public void channelActive(ChannelHandlerContext ctx) throws Exception { @Override public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { super.channelUnregistered(ctx); - logger.debug(LocalTime.now().toString() + " channelUnregistered: " + ctx.name()); - String strCanal = (tcp_channel == primary_channel) ? "PRIMARY" : "SECONDARY"; - logger.info("Unregistered of channel: " + strCanal); + logger.debug("{} channelUnregistered: {}", LocalTime.now(), ctx.name()); + String strCanal = (tcpChannel == primaryChannel) ? "PRIMARY" : "SECONDARY"; + logger.info("Unregistered of channel: {}", strCanal); //TODO: If embedded channel is closed, we need close all channels - if (ctx == embed_ctx) return; + if (ctx == embedCtx) return; - if (tcp_channel == ctx.channel()) { - embeded_channel.attr(IS_CONNECTED).set(false); - embeded_channel.attr(WAS_CONNECTED).set(true); - embeded_channel.pipeline().fireUserEventTriggered(new DisconnectedEvent()); + if (tcpChannel == ctx.channel()) { + embededChannel.attr(IS_CONNECTED).set(false); + embededChannel.attr(WAS_CONNECTED).set(true); + embededChannel.pipeline().fireUserEventTriggered(new DisconnectedEvent()); } - logger.info(embed_ctx.executor().toString()); + logger.info(embedCtx.executor().toString()); - if ((tcp_channel == primary_channel) && - (primary_channel == ctx.channel())) - if ((!primary_channel.isActive()) && - (secondary_channel != null)) - if (secondary_channel.isActive()) { - synchronized (tcp_channel) { + if ((tcpChannel == primaryChannel) && + (primaryChannel == ctx.channel())) + if ((!primaryChannel.isActive()) && + (secondaryChannel != null)) + if (secondaryChannel.isActive()) { + synchronized (tcpChannel) { logger.info("Using secondary TCP channel."); - tcp_channel = secondary_channel; - embeded_channel.attr(IS_PRIMARY).set(false); - embeded_channel.pipeline().fireUserEventTriggered(new ConnectEvent()); + tcpChannel = secondaryChannel; + embededChannel.attr(IS_PRIMARY).set(false); + embededChannel.pipeline().fireUserEventTriggered(new ConnectEvent()); } } ; - if ((tcp_channel == secondary_channel) && - (secondary_channel == ctx.channel())) - if ((!secondary_channel.isActive()) && - (primary_channel != null)) - if (primary_channel.isActive()) { - synchronized (tcp_channel) { + if ((tcpChannel == secondaryChannel) && + (secondaryChannel == ctx.channel())) + if ((!secondaryChannel.isActive()) && + (primaryChannel != null)) + if (primaryChannel.isActive()) { + synchronized (tcpChannel) { logger.info("Using primary TCP channel."); - tcp_channel = primary_channel; - embeded_channel.attr(IS_PRIMARY).set(true); - embeded_channel.pipeline().fireUserEventTriggered(new ConnectEvent()); + tcpChannel = primaryChannel; + embededChannel.attr(IS_PRIMARY).set(true); + embededChannel.pipeline().fireUserEventTriggered(new ConnectEvent()); } } @@ -271,43 +271,43 @@ public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { @Override public void setEmbededhannel(Channel embeded_channel, PlcConnectionConfiguration configuration) { final S7Configuration conf = (S7Configuration) configuration; - this.embeded_channel = embeded_channel; - this.embeded_channel.attr(IS_CONNECTED).set(false); - this.embeded_channel.attr(WAS_CONNECTED).set(false); - this.embeded_channel.attr(IS_PRIMARY).set(true); + this.embededChannel = embeded_channel; + this.embededChannel.attr(IS_CONNECTED).set(false); + this.embededChannel.attr(WAS_CONNECTED).set(false); + this.embededChannel.attr(IS_PRIMARY).set(true); //From the URL - this.embeded_channel.attr(READ_TIME_OUT).set(conf.getReadTimeout()); - this.embeded_channel.attr(IS_PING_ACTIVE).set(conf.getPing()); - this.embeded_channel.attr(PING_TIME).set(conf.getPingTime()); - this.embeded_channel.attr(RETRY_TIME).set(conf.getRetryTime()); + this.embededChannel.attr(READ_TIME_OUT).set(conf.getReadTimeout()); + this.embededChannel.attr(IS_PING_ACTIVE).set(conf.getPing()); + this.embededChannel.attr(PING_TIME).set(conf.getPingTime()); + this.embededChannel.attr(RETRY_TIME).set(conf.getRetryTime()); } @Override public void setPrimaryChannel(Channel primary_channel) { - if ((this.primary_channel == null) && (tcp_channel == null)) { + if ((this.primaryChannel == null) && (tcpChannel == null)) { if (primary_channel != null) { - this.primary_channel = primary_channel; - tcp_channel = primary_channel; - embeded_channel.attr(IS_PRIMARY).set(true); + this.primaryChannel = primary_channel; + tcpChannel = primary_channel; + embededChannel.attr(IS_PRIMARY).set(true); } - } else if ((this.primary_channel == null) || - ((tcp_channel == secondary_channel)) && (tcp_channel.isActive())) { - this.primary_channel = primary_channel; + } else if ((this.primaryChannel == null) || + ((tcpChannel == secondaryChannel)) && (tcpChannel.isActive())) { + this.primaryChannel = primary_channel; - } else if ((!this.primary_channel.isActive()) && (tcp_channel == secondary_channel)) { - this.primary_channel = primary_channel; + } else if ((!this.primaryChannel.isActive()) && (tcpChannel == secondaryChannel)) { + this.primaryChannel = primary_channel; - } else if (((!this.primary_channel.isActive()) && (tcp_channel == this.primary_channel)) || + } else if (((!this.primaryChannel.isActive()) && (tcpChannel == this.primaryChannel)) || (primary_channel.isActive())) { - synchronized (tcp_channel) { - tcp_channel.close(); - this.primary_channel = primary_channel; - tcp_channel = primary_channel; - embeded_channel.attr(IS_PRIMARY).set(true); - - if (tcp_channel.isActive()) { - embed_ctx.fireUserEventTriggered(new ConnectEvent()); + synchronized (tcpChannel) { + tcpChannel.close(); + this.primaryChannel = primary_channel; + tcpChannel = primary_channel; + embededChannel.attr(IS_PRIMARY).set(true); + + if (tcpChannel.isActive()) { + embedCtx.fireUserEventTriggered(new ConnectEvent()); } } } else if (primary_channel.isActive()) { @@ -317,37 +317,37 @@ public void setPrimaryChannel(Channel primary_channel) { @Override public void setSecondaryChannel(Channel secondary_channel) { - if ((this.primary_channel == null) && (tcp_channel == null)) { + if ((this.primaryChannel == null) && (tcpChannel == null)) { if (secondary_channel != null) { - this.secondary_channel = secondary_channel; - tcp_channel = secondary_channel; - embeded_channel.attr(IS_PRIMARY).set(false); + this.secondaryChannel = secondary_channel; + tcpChannel = secondary_channel; + embededChannel.attr(IS_PRIMARY).set(false); } - } else if ((this.secondary_channel == null) || - ((tcp_channel == primary_channel)) && (tcp_channel.isActive())) { - this.secondary_channel = secondary_channel; + } else if ((this.secondaryChannel == null) || + ((tcpChannel == primaryChannel)) && (tcpChannel.isActive())) { + this.secondaryChannel = secondary_channel; - } else if ((!this.secondary_channel.isActive()) && (tcp_channel == primary_channel)) { - this.secondary_channel = secondary_channel; + } else if ((!this.secondaryChannel.isActive()) && (tcpChannel == primaryChannel)) { + this.secondaryChannel = secondary_channel; - } else if (((!this.secondary_channel.isActive()) && (tcp_channel == this.secondary_channel)) || + } else if (((!this.secondaryChannel.isActive()) && (tcpChannel == this.secondaryChannel)) || (secondary_channel.isActive())) { - synchronized (tcp_channel) { - tcp_channel.close(); - this.secondary_channel = secondary_channel; - tcp_channel = secondary_channel; - embeded_channel.attr(IS_PRIMARY).set(false); + synchronized (tcpChannel) { + tcpChannel.close(); + this.secondaryChannel = secondary_channel; + tcpChannel = secondary_channel; + embededChannel.attr(IS_PRIMARY).set(false); } - if (tcp_channel.isActive()) { - embed_ctx.fireUserEventTriggered(new ConnectEvent()); + if (tcpChannel.isActive()) { + embedCtx.fireUserEventTriggered(new ConnectEvent()); } } } @Override public Channel getTCPChannel() { - return tcp_channel; + return tcpChannel; } diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7HPlcConnection.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7HPlcConnection.java index 3bc1392b5ec..ea0a1e258b6 100644 --- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7HPlcConnection.java +++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7HPlcConnection.java @@ -34,7 +34,6 @@ import org.apache.plc4x.java.api.messages.PlcPingResponse; import org.apache.plc4x.java.api.messages.PlcReadRequest; import org.apache.plc4x.java.api.messages.PlcReadResponse; -import org.apache.plc4x.java.api.value.PlcValueHandler; import org.apache.plc4x.java.s7.readwrite.TPKTPacket; import org.apache.plc4x.java.spi.configuration.ConfigurationFactory; import org.apache.plc4x.java.spi.connection.ChannelFactory; @@ -45,6 +44,7 @@ import org.apache.plc4x.java.spi.events.ConnectedEvent; import org.apache.plc4x.java.spi.events.DisconnectEvent; import org.apache.plc4x.java.spi.optimizer.BaseOptimizer; +import org.apache.plc4x.java.spi.values.PlcValueHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -91,7 +91,6 @@ public S7HPlcConnection( boolean canWrite, boolean canSubscribe, boolean canBrowse, - PlcTagHandler tagHandler, PlcValueHandler valueHandler, PlcConnectionConfiguration configuration, ChannelFactory channelFactory, @@ -108,7 +107,6 @@ public S7HPlcConnection( canWrite, canSubscribe, canBrowse, - tagHandler, valueHandler, configuration, channelFactory, diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7ProtocolLogic.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7ProtocolLogic.java index 001dc77fca3..c50c1bd39c9 100644 --- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7ProtocolLogic.java +++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7ProtocolLogic.java @@ -41,11 +41,16 @@ import org.apache.plc4x.java.s7.utils.S7ParamErrorCode; import org.apache.plc4x.java.spi.ConversationContext; import org.apache.plc4x.java.spi.Plc4xProtocolBase; +import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.context.DriverContext; import org.apache.plc4x.java.spi.generation.*; import org.apache.plc4x.java.spi.messages.*; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; -import org.apache.plc4x.java.spi.messages.utils.TagValueItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcTagItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcTagValueItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcTagItem; +import org.apache.plc4x.java.spi.messages.utils.PlcTagValueItem; import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionTag; import org.apache.plc4x.java.spi.transaction.RequestTransactionManager; import org.apache.plc4x.java.spi.values.*; @@ -70,8 +75,6 @@ import org.apache.plc4x.java.s7.events.S7UserEvent; import org.apache.plc4x.java.s7.readwrite.utils.S7PlcSubscriptionRequest; -import javax.xml.crypto.Data; - /** * The S7 Protocol states that there can not be more then {min(maxAmqCaller, maxAmqCallee} "ongoing" requests. * So we need to limit those. @@ -143,6 +146,11 @@ public void setDriverContext(DriverContext driverContext) { eventLogic.start(); } + @Override + public PlcTagHandler getTagHandler() { + return new S7PlcTagHandler(); + } + @Override public void close(ConversationContext context) { // TODO: Find out how to close this prior to Java 19 @@ -445,7 +453,7 @@ public CompletableFuture subscribe(PlcSubscriptionReque // Start a new request-transaction (Is ended in the response-handler) RequestTransactionManager.RequestTransaction transaction = tm.startRequest(); - transaction.submit(() -> context.sendRequest(tpktPacket) + transaction.submit(() -> conversationContext.sendRequest(tpktPacket) .onTimeout(new TransactionErrorCallback<>(future, transaction)) .onError(new TransactionErrorCallback<>(future, transaction)) .expectResponse(TPKTPacket.class, REQUEST_TIMEOUT) @@ -476,7 +484,7 @@ public CompletableFuture subscribe(PlcSubscriptionReque } try { - HashMap> values = new HashMap<>(); + HashMap> values = new HashMap<>(); valuesResponse.forEach((s, p) -> { if (p != null) values.putAll(((DefaultPlcSubscriptionResponse) p).getValues()); @@ -526,7 +534,7 @@ public CompletableFuture unsubscribe(PlcUnsubscriptio // Start a new request-transaction (Is ended in the response-handler) RequestTransactionManager.RequestTransaction transaction = tm.startRequest(); - transaction.submit(() -> context.sendRequest(tpktPacket) + transaction.submit(() -> conversationContext.sendRequest(tpktPacket) .onTimeout(new TransactionErrorCallback<>(future, transaction)) .onError(new TransactionErrorCallback<>(future, transaction)) .expectResponse(TPKTPacket.class, REQUEST_TIMEOUT) @@ -616,7 +624,7 @@ private PlcSubscriptionResponse decodeEventSubscriptionResponse(String strTagNam S7Message responseMessage) throws PlcProtocolException { - Map> values = new HashMap<>(); + Map> values = new HashMap<>(); short errorClass = 0; short errorCode = 0; if (responseMessage instanceof S7MessageUserData) { @@ -648,7 +656,7 @@ private PlcSubscriptionResponse decodeEventSubscriptionResponse(String strTagNam logger.warn("Got an error response from the PLC. This particular response code usually indicates " + "that PUT/GET is not enabled on the PLC."); for (String tagName : plcSubscriptionRequest.getTagNames()) { - values.put(tagName, new ResponseItem<>(PlcResponseCode.REMOTE_ERROR, null)); + values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.REMOTE_ERROR, null)); } return new DefaultPlcSubscriptionResponse(plcSubscriptionRequest, values); } @@ -659,7 +667,7 @@ else if((errorClass == 0) && (errorCode == (short) 0x8104)) { "data on a PLC that doesn't support subscriptions (S7-1200 or S7-1500)", errorClass, errorCode); for (String tagName : plcSubscriptionRequest.getTagNames()) { - values.put(tagName, new ResponseItem<>(PlcResponseCode.UNSUPPORTED, null)); + values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.UNSUPPORTED, null)); } return new DefaultPlcSubscriptionResponse(plcSubscriptionRequest, values); } else { @@ -669,7 +677,7 @@ else if((errorClass == 0) && (errorCode == (short) 0x8104)) { "containing a capture of the communication.", errorClass, errorCode); for (String tagName : plcSubscriptionRequest.getTagNames()) { - values.put(tagName, new ResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null)); + values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null)); } return new DefaultPlcSubscriptionResponse(plcSubscriptionRequest, values); } @@ -720,12 +728,12 @@ else if((errorClass == 0) && (errorCode == (short) 0x8104)) { //String tagName = (String) plcSubscriptionRequest.getTagNames().toArray()[0]; //TODO: Chequear si tagName es el correcto //logger.info("strTagName: " + strTagName); - values.put(strTagName, new ResponseItem<>(PlcResponseCode.OK, null)); + values.put(strTagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, null)); for (short s : items.getMessageObjects()) { if (s == 0x0000) { - values.put(Integer.toHexString(s), new ResponseItem<>(PlcResponseCode.OK, null)); + values.put(Integer.toHexString(s), new DefaultPlcResponseItem<>(PlcResponseCode.OK, null)); } else if (s == 0x000a) { - values.put(Integer.toHexString(s), new ResponseItem<>(PlcResponseCode.NOT_FOUND, null)); + values.put(Integer.toHexString(s), new DefaultPlcResponseItem<>(PlcResponseCode.NOT_FOUND, null)); } } @@ -737,7 +745,7 @@ else if((errorClass == 0) && (errorCode == (short) 0x8104)) { // payloadItems.get(0); //String fieldName = (String) S7PayloadUserDataItemCyclicServicesPush .getFieldNames().toArray()[0]; //logger.warn("Request field: " + strTagName + ": " + S7ParamErrorCode.valueOf(errorCode) + " " + S7ParamErrorCode.valueOf(errorCode).getEvent()); - values.put(strTagName, new ResponseItem<>(PlcResponseCode.NOT_FOUND, null)); + values.put(strTagName, new DefaultPlcResponseItem<>(PlcResponseCode.NOT_FOUND, null)); return new DefaultPlcSubscriptionResponse(plcSubscriptionRequest, values); } else if (payloadItems.get(0) instanceof S7PayloadUserDataItemCpuFunctionAlarmQueryResponse) { @@ -809,7 +817,7 @@ else if((errorClass == 0) && (errorCode == (short) 0x8104)) { } PlcResponseCode resCode = (items.getReturnCode() == DataTransportErrorCode.OK) ? PlcResponseCode.OK : PlcResponseCode.INTERNAL_ERROR; - values.put(strTagName, new ResponseItem<>(resCode, null)); + values.put(strTagName, new DefaultPlcResponseItem<>(resCode, null)); return new DefaultPlcSubscriptionResponse(plcSubscriptionRequest, values); } else if (payloadItems.get(0) instanceof S7PayloadUserDataItemCyclicServicesSubscribeResponse) { @@ -832,7 +840,7 @@ else if((errorClass == 0) && (errorCode == (short) 0x8104)) { S7PlcSubscriptionHandle cycHandle = new S7PlcSubscriptionHandle(strTagName, EventType.CYC, eventLogic); - ResponseItem response = new ResponseItem<>(PlcResponseCode.OK, cycHandle); + PlcResponseItem response = new DefaultPlcResponseItem<>(PlcResponseCode.OK, cycHandle); plcSubscriptionRequest.getTagNames().forEach(s -> values.put(s, response)); return new DefaultPlcSubscriptionResponse(plcSubscriptionRequest, values); @@ -851,7 +859,7 @@ else if((errorClass == 0) && (errorCode == (short) 0x8104)) { eventQueue.add(cycEvent); S7PlcSubscriptionHandle cycHandle = new S7PlcSubscriptionHandle(strTagName, EventType.CYC, eventLogic); - values.put(strTagName, new ResponseItem<>(PlcResponseCode.OK, cycHandle)); + values.put(strTagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, cycHandle)); return new DefaultPlcSubscriptionResponse(plcSubscriptionRequest, values); } else if (payloadItems.get(0) instanceof S7PayloadUserDataItemCyclicServicesErrorResponse) { @@ -864,11 +872,11 @@ else if((errorClass == 0) && (errorCode == (short) 0x8104)) { /*if (errorCode == 0x8104) { values.put(strTagName, new ResponseItem(PlcResponseCode.UNSUPPORTED, null)); } else {*/ - values.put(strTagName, new ResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null)); + values.put(strTagName, new DefaultPlcResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null)); // } return new DefaultPlcSubscriptionResponse(plcSubscriptionRequest, values); } else if (payloadItems.get(0) instanceof S7PayloadUserDataItemCyclicServicesUnsubscribeResponse) { - values.put(strTagName, new ResponseItem<>(PlcResponseCode.OK, null)); + values.put(strTagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, null)); return new DefaultPlcSubscriptionResponse(plcSubscriptionRequest, values); } @@ -878,16 +886,16 @@ else if((errorClass == 0) && (errorCode == (short) 0x8104)) { S7SubscriptionTag tag = (S7SubscriptionTag) dTag.getTag(); switch (tag.getEventType()) { case MODE: - values.put(tagName, new ResponseItem<>(PlcResponseCode.OK, modeHandle)); + values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, modeHandle)); break; case SYS: - values.put(tagName, new ResponseItem<>(PlcResponseCode.OK, sysHandle)); + values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, sysHandle)); break; case USR: - values.put(tagName, new ResponseItem<>(PlcResponseCode.OK, usrHandle)); + values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, usrHandle)); break; case ALM: - values.put(tagName, new ResponseItem<>(PlcResponseCode.OK, almHandle)); + values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, almHandle)); break; } @@ -1292,19 +1300,21 @@ private CompletableFuture performVarLengthStringReadRequest(DefaultPl // Replace the var-length string fields with requests to read the // length information instead of the string content. int numVarLengthStrings = 0; - LinkedHashMap updatedRequestItems = new LinkedHashMap<>(request.getNumberOfTags()); + LinkedHashMap updatedRequestItems = new LinkedHashMap<>(request.getNumberOfTags()); for (String tagName : request.getTagNames()) { - S7Tag s7tag = (S7Tag) request.getTag(tagName); - if(s7tag instanceof S7StringVarLengthTag) { - if(s7tag.getDataType() == TransportSize.STRING) { - updatedRequestItems.put(tagName, new S7Tag(TransportSize.BYTE, s7tag.getMemoryArea(), s7tag.getBlockNumber(), s7tag.getByteOffset(), s7tag.getBitOffset(), 2)); + PlcTagItem plcTagItem = request.getTagItem(tagName); + if(plcTagItem.getTag() instanceof S7StringVarLengthTag) { + S7Tag s7Tag = (S7Tag) plcTagItem.getTag(); + TransportSize dataType = s7Tag.getDataType(); + if(dataType == TransportSize.STRING) { + updatedRequestItems.put(tagName, new DefaultPlcTagItem(new S7Tag(TransportSize.BYTE, s7Tag.getMemoryArea(), s7Tag.getBlockNumber(), s7Tag.getByteOffset(), s7Tag.getBitOffset(), 2))); numVarLengthStrings++; - } else if(s7tag.getDataType() == TransportSize.WSTRING) { - updatedRequestItems.put(tagName, new S7Tag(TransportSize.BYTE, s7tag.getMemoryArea(), s7tag.getBlockNumber(), s7tag.getByteOffset(), s7tag.getBitOffset(), 4)); + } else if(dataType == TransportSize.WSTRING) { + updatedRequestItems.put(tagName, new DefaultPlcTagItem(new S7Tag(TransportSize.BYTE, s7Tag.getMemoryArea(), s7Tag.getBlockNumber(), s7Tag.getByteOffset(), s7Tag.getBitOffset(), 4))); numVarLengthStrings++; } } else { - updatedRequestItems.put(tagName, s7tag); + updatedRequestItems.put(tagName, plcTagItem); } } @@ -1316,24 +1326,24 @@ private CompletableFuture performVarLengthStringReadRequest(DefaultPl return; } // Collect the responses for the var-length strings and read them separately. - LinkedHashMap varLengthStringTags = new LinkedHashMap<>(finalNumVarLengthStrings); + LinkedHashMap varLengthStringTags = new LinkedHashMap<>(finalNumVarLengthStrings); int curItem = 0; for (String tagName : request.getTagNames()) { S7Tag s7tag = (S7Tag) request.getTag(tagName); if(s7tag instanceof S7StringVarLengthTag) { S7VarPayloadDataItem s7VarPayloadDataItem = ((S7PayloadReadVarResponse) s7Message.getPayload()).getItems().get(curItem); - // Simply ignore processing var-lenght strings that are not ok + // Simply ignore processing var-length strings that are not ok if(s7VarPayloadDataItem.getReturnCode() == DataTransportErrorCode.OK) { ReadBuffer rb = new ReadBufferByteBased(s7VarPayloadDataItem.getData()); try { if (s7tag.getDataType() == TransportSize.STRING) { rb.readShort(8); int stringLength = rb.readShort(8); - varLengthStringTags.put(tagName, new S7StringFixedLengthTag(TransportSize.STRING, s7tag.getMemoryArea(), s7tag.getBlockNumber(), s7tag.getByteOffset(), s7tag.getBitOffset(), 1, stringLength)); + varLengthStringTags.put(tagName, new DefaultPlcTagItem(new S7StringFixedLengthTag(TransportSize.STRING, s7tag.getMemoryArea(), s7tag.getBlockNumber(), s7tag.getByteOffset(), s7tag.getBitOffset(), 1, stringLength))); } else if (s7tag.getDataType() == TransportSize.WSTRING) { rb.readInt(16); int stringLength = rb.readInt(16); - varLengthStringTags.put(tagName, new S7StringFixedLengthTag(TransportSize.WSTRING, s7tag.getMemoryArea(), s7tag.getBlockNumber(), s7tag.getByteOffset(), s7tag.getBitOffset(), 1, stringLength)); + varLengthStringTags.put(tagName, new DefaultPlcTagItem(new S7StringFixedLengthTag(TransportSize.WSTRING, s7tag.getMemoryArea(), s7tag.getBlockNumber(), s7tag.getByteOffset(), s7tag.getBitOffset(), 1, stringLength))); } } catch (Exception e) { logger.warn("Error parsing string size for tag {}", tagName, e); @@ -1428,7 +1438,7 @@ private CompletableFuture performVarLengthStringWriteRequest(DefaultP } else { // Create an alternative list of request items, where all var-length string tags are replaced with // fixed-length string tags using the string length returned by the previous request. - LinkedHashMap updatedRequestItems = new LinkedHashMap<>(request.getNumberOfTags()); + LinkedHashMap updatedRequestItems = new LinkedHashMap<>(request.getNumberOfTags()); for (String tagName : request.getTagNames()) { PlcTag tag = request.getTag(tagName); PlcValue value = request.getPlcValue(tagName); @@ -1438,9 +1448,9 @@ private CompletableFuture performVarLengthStringWriteRequest(DefaultP S7StringFixedLengthTag newTag = new S7StringFixedLengthTag(varLengthTag.getDataType(), varLengthTag.getMemoryArea(), varLengthTag.getBlockNumber(), varLengthTag.getByteOffset(), varLengthTag.getBitOffset(), varLengthTag.getNumberOfElements(), stringLength); - updatedRequestItems.put(tagName, new TagValueItem(newTag, value)); + updatedRequestItems.put(tagName, new DefaultPlcTagValueItem(newTag, value)); } else { - updatedRequestItems.put(tagName, new TagValueItem(tag, value)); + updatedRequestItems.put(tagName, new DefaultPlcTagValueItem(tag, value)); } } @@ -1497,7 +1507,7 @@ private CompletableFuture sendInternal(S7Message request) { // Start a new request-transaction (Is ended in the response-handler) RequestTransactionManager.RequestTransaction transaction = tm.startRequest(); // Send the request. - transaction.submit(() -> context.sendRequest(tpktPacket) + transaction.submit(() -> conversationContext.sendRequest(tpktPacket) .onTimeout(new TransactionErrorCallback<>(future, transaction)) .onError(new TransactionErrorCallback<>(future, transaction)) .expectResponse(TPKTPacket.class, REQUEST_TIMEOUT) @@ -1716,7 +1726,7 @@ private COTPPacketConnectionRequest createCOTPConnectionRequest(int calledTsapId } private PlcResponse decodeReadResponse(S7Message responseMessage, PlcReadRequest plcReadRequest) throws PlcProtocolException { - Map> values = new HashMap<>(); + Map> values = new HashMap<>(); short errorClass; short errorCode; @@ -1745,7 +1755,7 @@ private PlcResponse decodeReadResponse(S7Message responseMessage, PlcReadRequest logger.warn("Got an error response from the PLC. This particular response code usually indicates " + "that PUT/GET is not enabled on the PLC."); for (String tagName : plcReadRequest.getTagNames()) { - ResponseItem result = new ResponseItem<>(PlcResponseCode.ACCESS_DENIED, new PlcNull()); + PlcResponseItem result = new DefaultPlcResponseItem<>(PlcResponseCode.ACCESS_DENIED, new PlcNull()); values.put(tagName, result); } return new DefaultPlcReadResponse(plcReadRequest, values); @@ -1754,7 +1764,7 @@ private PlcResponse decodeReadResponse(S7Message responseMessage, PlcReadRequest "that we sent a too large packet or would be receiving a too large one. " + "Please report this, as this is most probably a bug."); for (String tagName : plcReadRequest.getTagNames()) { - ResponseItem result = new ResponseItem<>(PlcResponseCode.ACCESS_DENIED, new PlcNull()); + PlcResponseItem result = new DefaultPlcResponseItem<>(PlcResponseCode.ACCESS_DENIED, new PlcNull()); values.put(tagName, result); } return new DefaultPlcReadResponse(plcReadRequest, values); @@ -1765,7 +1775,7 @@ private PlcResponse decodeReadResponse(S7Message responseMessage, PlcReadRequest "containing a capture of the communication.", errorClass, errorCode); for (String tagName : plcReadRequest.getTagNames()) { - ResponseItem result = new ResponseItem<>(PlcResponseCode.INTERNAL_ERROR, new PlcNull()); + PlcResponseItem result = new DefaultPlcResponseItem<>(PlcResponseCode.INTERNAL_ERROR, new PlcNull()); values.put(tagName, result); } return new DefaultPlcReadResponse(plcReadRequest, values); @@ -1875,7 +1885,7 @@ private PlcResponse decodeReadResponse(S7Message responseMessage, PlcReadRequest plcValue = new PlcList(plcValues); } - ResponseItem result = new ResponseItem<>(responseCode, plcValue); + PlcResponseItem result = new DefaultPlcResponseItem<>(responseCode, plcValue); values.put(tagName, result); index++; } @@ -1913,7 +1923,7 @@ private PlcResponse decodeReadResponse(S7Message responseMessage, PlcReadRequest } } - ResponseItem result = new ResponseItem<>(responseCode, plcValue); + PlcResponseItem result = new DefaultPlcResponseItem<>(responseCode, plcValue); values.put(tagName, result); index++; } @@ -2059,7 +2069,7 @@ private PlcValue parsePlcValue(S7Tag tag, byte[] data) { } return null; }).toArray(PlcValue[]::new); - return PlcValueHandler.of(resultItems); + return DefaultPlcValueHandler.of(tag, resultItems); } } } catch (ParseException e) { @@ -2156,19 +2166,19 @@ protected S7Address encodeS7Address(PlcTag tag) { } private boolean isConnected() { - return context.getChannel().attr(S7HMuxImpl.IS_CONNECTED).get(); + return conversationContext.getChannel().attr(S7HMuxImpl.IS_CONNECTED).get(); //return true; } private boolean isPrimaryChannel() { - return context.getChannel().attr(S7HMuxImpl.IS_PRIMARY).get() == null || context.getChannel().attr(S7HMuxImpl.IS_PRIMARY).get(); + return conversationContext.getChannel().attr(S7HMuxImpl.IS_PRIMARY).get() == null || conversationContext.getChannel().attr(S7HMuxImpl.IS_PRIMARY).get(); } private void setChannelFeatures() { - context.getChannel().attr(S7HMuxImpl.READ_TIME_OUT).set(s7DriverContext.getReadTimeout()); - context.getChannel().attr(S7HMuxImpl.IS_PING_ACTIVE).set(s7DriverContext.getPing()); - context.getChannel().attr(S7HMuxImpl.PING_TIME).set(s7DriverContext.getPingTime()); - context.getChannel().attr(S7HMuxImpl.RETRY_TIME).set(s7DriverContext.getRetryTime()); + conversationContext.getChannel().attr(S7HMuxImpl.READ_TIME_OUT).set(s7DriverContext.getReadTimeout()); + conversationContext.getChannel().attr(S7HMuxImpl.IS_PING_ACTIVE).set(s7DriverContext.getPing()); + conversationContext.getChannel().attr(S7HMuxImpl.PING_TIME).set(s7DriverContext.getPingTime()); + conversationContext.getChannel().attr(S7HMuxImpl.RETRY_TIME).set(s7DriverContext.getRetryTime()); } @@ -2186,7 +2196,7 @@ private CompletableFuture reassembledMessage(short sequenceNu TPKTPacket request = createSzlReassembledRequest(tpduId, sequenceNumber); - context.sendRequest(request) + conversationContext.sendRequest(request) .onTimeout(e -> { logger.warn("Timeout during Connection establishing, closing channel..."); //context.getChannel().close(); @@ -2226,7 +2236,7 @@ private CompletableFuture reassembledAlarmEvents(short sequen TPKTPacket request = createAlarmQueryReassembledRequest(tpduId, sequenceNumber); - context.sendRequest(request) + conversationContext.sendRequest(request) .onTimeout(e -> { logger.warn("Timeout during Connection establishing, closing channel..."); //context.getChannel().close(); diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/tag/S7Tag.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/tag/S7Tag.java index 6f9265c21e8..c494dc881d5 100644 --- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/tag/S7Tag.java +++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/tag/S7Tag.java @@ -148,7 +148,11 @@ public static boolean matches(String tagString) { public static S7Tag of(String tagString) { Matcher matcher; if ((matcher = DATA_BLOCK_ADDRESS_PATTERN.matcher(tagString)).matches()) { - TransportSize dataType = TransportSize.valueOf(matcher.group(DATA_TYPE)); + String dataTypeName = matcher.group(DATA_TYPE); + if("RAW_BYTE_ARRAY".equals(dataTypeName)) { + dataTypeName = "BYTE"; + } + TransportSize dataType = TransportSize.valueOf(dataTypeName); MemoryArea memoryArea = MemoryArea.DATA_BLOCKS; Short transferSizeCode = getSizeCode(matcher.group(TRANSFER_SIZE_CODE)); int blockNumber = checkDataBlockNumber(Integer.parseInt(matcher.group(BLOCK_NUMBER))); @@ -171,7 +175,11 @@ public static S7Tag of(String tagString) { return new S7Tag(dataType, memoryArea, blockNumber, byteOffset, bitOffset, numElements); } else if ((matcher = DATA_BLOCK_SHORT_PATTERN.matcher(tagString)).matches()) { - TransportSize dataType = TransportSize.valueOf(matcher.group(DATA_TYPE)); + String dataTypeName = matcher.group(DATA_TYPE); + if("RAW_BYTE_ARRAY".equals(dataTypeName)) { + dataTypeName = "BYTE"; + } + TransportSize dataType = TransportSize.valueOf(dataTypeName); MemoryArea memoryArea = MemoryArea.DATA_BLOCKS; int blockNumber = checkDataBlockNumber(Integer.parseInt(matcher.group(BLOCK_NUMBER))); int byteOffset = checkByteOffset(Integer.parseInt(matcher.group(BYTE_OFFSET))); diff --git a/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/DatatypesTest.java b/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/DatatypesTest.java index 3f05a90bdb2..45d58e33091 100644 --- a/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/DatatypesTest.java +++ b/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/DatatypesTest.java @@ -56,7 +56,7 @@ public static void main(String[] args) throws Exception { builder.addTagAddress("lreal-value", "%DB2:70:LREAL"); // 3.14159265358979 builder.addTagAddress("lreal-array", "%DB2:78:LREAL[2]"); // 1.2345, -1.2345 builder.addTagAddress("string-value", "%DB2:94:STRING(10)"); // "Hurz" - // When reading a sized STRING string array, this has to be translated into multiple items + // When reading a sized STRING array, this has to be translated into multiple items //builder.addField("string-array", "%DB2:350:STRING(10)[2]"); // "Wolf", "Lamm" builder.addTagAddress("time-value", "%DB2:862:TIME"); // 1234ms builder.addTagAddress("time-array", "%DB2:866:TIME[2]"); // 123ms, 234ms diff --git a/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/ManualS71200DriverTest.java b/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/ManualS71200DriverTest.java index b9ba2262807..c02494d9be1 100644 --- a/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/ManualS71200DriverTest.java +++ b/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/ManualS71200DriverTest.java @@ -68,7 +68,7 @@ public class ManualS71200DriverTest extends ManualTest { */ public ManualS71200DriverTest(String connectionString) { - super(connectionString); + super(connectionString, true, true, true, true, 100); } public static void main(String[] args) throws Exception { @@ -95,7 +95,7 @@ public static void main(String[] args) throws Exception { test.addTestCase("%DB4:70:DATE", new PlcDATE(LocalDate.parse("1998-03-28"))); test.addTestCase("%DB4:72:TIME_OF_DAY", new PlcTIME_OF_DAY(LocalTime.parse("15:36:30.123"))); test.addTestCase("%DB4:908:CHAR[5]", new PlcList(Arrays.asList(new PlcCHAR("w"), new PlcCHAR("i"), new PlcCHAR("e"), new PlcCHAR("s"), new PlcCHAR("e")))); - test.addTestCase("%DB4:914:BYTE[11]", new PlcRawByteArray(new byte[] {(byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9, (byte) 10, (byte) 11})); + test.addTestCase("%DB4:914:RAW_BYTE_ARRAY[11]", new PlcRawByteArray(new byte[] {(byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9, (byte) 10, (byte) 11})); long start = System.currentTimeMillis(); test.run(); diff --git a/plc4j/drivers/s7/src/test/resources/logback-test.xml b/plc4j/drivers/s7/src/test/resources/logback-test.xml index 33ae65561c2..16b83b4882c 100644 --- a/plc4j/drivers/s7/src/test/resources/logback-test.xml +++ b/plc4j/drivers/s7/src/test/resources/logback-test.xml @@ -27,7 +27,7 @@ - + diff --git a/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/connection/SimulatedConnection.java b/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/connection/SimulatedConnection.java index 042393bf0fa..a14e41fd9a4 100644 --- a/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/connection/SimulatedConnection.java +++ b/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/connection/SimulatedConnection.java @@ -27,11 +27,13 @@ import org.apache.plc4x.java.simulated.tag.SimulatedTag; import org.apache.plc4x.java.simulated.tag.SimulatedTagHandler; import org.apache.plc4x.java.spi.connection.AbstractPlcConnection; +import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.messages.*; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration; import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionHandle; -import org.apache.plc4x.java.spi.values.PlcValueHandler; +import org.apache.plc4x.java.spi.values.DefaultPlcValueHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -64,10 +66,15 @@ public class SimulatedConnection extends AbstractPlcConnection implements PlcRea public SimulatedConnection(SimulatedDevice device) { super(true, true, true, true, false, - new SimulatedTagHandler(), new PlcValueHandler(), null, null); + new DefaultPlcValueHandler(), null, null); this.device = device; } + @Override + public PlcTagHandler getPlcTagHandler() { + return new SimulatedTagHandler(); + } + @Override public void connect() { connected = true; @@ -91,15 +98,15 @@ public CompletableFuture ping() { @Override public CompletableFuture read(PlcReadRequest readRequest) { - Map> tags = new HashMap<>(); + Map> tags = new HashMap<>(); for (String tagName : readRequest.getTagNames()) { SimulatedTag tag = (SimulatedTag) readRequest.getTag(tagName); Optional valueOptional = device.get(tag); - ResponseItem tagPair; + PlcResponseItem tagPair; boolean present = valueOptional.isPresent(); tagPair = present - ? new ResponseItem<>(PlcResponseCode.OK, valueOptional.get()) - : new ResponseItem<>(PlcResponseCode.NOT_FOUND, null); + ? new DefaultPlcResponseItem<>(PlcResponseCode.OK, valueOptional.get()) + : new DefaultPlcResponseItem<>(PlcResponseCode.NOT_FOUND, null); tags.put(tagName, tagPair); } PlcReadResponse response = new DefaultPlcReadResponse(readRequest, tags); @@ -110,10 +117,14 @@ public CompletableFuture read(PlcReadRequest readRequest) { public CompletableFuture write(PlcWriteRequest writeRequest) { Map tags = new HashMap<>(); for (String tagName : writeRequest.getTagNames()) { - SimulatedTag tag = (SimulatedTag) writeRequest.getTag(tagName); - PlcValue value = writeRequest.getPlcValue(tagName); - device.set(tag, value); - tags.put(tagName, PlcResponseCode.OK); + if(writeRequest.getTagResponseCode(tagName) == PlcResponseCode.OK) { + SimulatedTag tag = (SimulatedTag) writeRequest.getTag(tagName); + PlcValue value = writeRequest.getPlcValue(tagName); + device.set(tag, value); + tags.put(tagName, PlcResponseCode.OK); + } else { + tags.put(tagName, writeRequest.getTagResponseCode(tagName)); + } } PlcWriteResponse response = new DefaultPlcWriteResponse(writeRequest, tags); return CompletableFuture.completedFuture(response); @@ -133,7 +144,7 @@ public String toString() { @Override public CompletableFuture subscribe(PlcSubscriptionRequest subscriptionRequest) { LOGGER.info("subscribing {}", subscriptionRequest); - Map> values = new HashMap<>(); + Map> values = new HashMap<>(); subscriptionRequest.getTagNames().forEach(name -> { LOGGER.info("creating handle for tag name {}", name); PlcSubscriptionHandle handle = new DefaultPlcSubscriptionHandle(this); @@ -152,7 +163,7 @@ public CompletableFuture subscribe(PlcSubscriptionReque device.addEventSubscription(dispatchSubscriptionEvent(name, handle), handle, subscriptionTag); break; } - values.put(name, new ResponseItem<>(PlcResponseCode.OK, handle)); + values.put(name, new DefaultPlcResponseItem<>(PlcResponseCode.OK, handle)); }); PlcSubscriptionResponse response = new DefaultPlcSubscriptionResponse(subscriptionRequest, values); @@ -176,7 +187,7 @@ private Consumer dispatchSubscriptionEvent(String name, PlcSubscriptio consumer.accept( new DefaultPlcSubscriptionEvent( Instant.now(), - Collections.singletonMap(name, new ResponseItem<>(PlcResponseCode.OK, plcValue)) + Collections.singletonMap(name, new DefaultPlcResponseItem<>(PlcResponseCode.OK, plcValue)) ) ); }; diff --git a/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/tag/SimulatedTag.java b/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/tag/SimulatedTag.java index c3292367108..71adb0f27f2 100644 --- a/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/tag/SimulatedTag.java +++ b/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/tag/SimulatedTag.java @@ -93,7 +93,7 @@ public PlcValueType getPlcValueType() { @Override public List getArrayInfo() { - return Collections.singletonList(new DefaultArrayInfo(0, numElements)); + return Collections.singletonList(new DefaultArrayInfo(0, numElements - 1)); } public SimulatedTagType getType() { diff --git a/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/tag/SimulatedTagHandler.java b/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/tag/SimulatedTagHandler.java index 20981fa7e8d..0e7039f60e6 100644 --- a/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/tag/SimulatedTagHandler.java +++ b/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/tag/SimulatedTagHandler.java @@ -7,7 +7,7 @@ * "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 + * 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 @@ -16,11 +16,12 @@ * specific language governing permissions and limitations * under the License. */ + package org.apache.plc4x.java.simulated.tag; import org.apache.plc4x.java.api.exceptions.PlcInvalidTagException; -import org.apache.plc4x.java.api.model.PlcTag; import org.apache.plc4x.java.api.model.PlcQuery; +import org.apache.plc4x.java.api.model.PlcTag; import org.apache.plc4x.java.spi.connection.PlcTagHandler; public class SimulatedTagHandler implements PlcTagHandler { diff --git a/plc4j/drivers/simulated/src/test/java/org/apache/plc4x/java/simulated/connection/SimulatedConnectionTest.java b/plc4j/drivers/simulated/src/test/java/org/apache/plc4x/java/simulated/connection/SimulatedConnectionTest.java index ed4cb33891c..0b2bb2c8103 100644 --- a/plc4j/drivers/simulated/src/test/java/org/apache/plc4x/java/simulated/connection/SimulatedConnectionTest.java +++ b/plc4j/drivers/simulated/src/test/java/org/apache/plc4x/java/simulated/connection/SimulatedConnectionTest.java @@ -163,7 +163,7 @@ void subscription() throws Exception { .addTagAddress("state", "STATE/state:STRING", "initialstate") .addTagAddress("event", "STATE/event:STRING", "initialevent") .build(); - SUT.write(plcWriteRequest).get(1, TimeUnit.SECONDS); + PlcWriteResponse plcWriteResponse = SUT.write(plcWriteRequest).get(1, TimeUnit.SECONDS); // Note: as we don't have a subscription yet, no callback will be executed LOGGER.trace("subscribe"); diff --git a/plc4j/drivers/simulated/src/test/java/org/apache/plc4x/java/simulated/tag/SimularedTagHandlerTest.java b/plc4j/drivers/simulated/src/test/java/org/apache/plc4x/java/simulated/tag/SimularedTagHandlerTest.java deleted file mode 100644 index c570d570151..00000000000 --- a/plc4j/drivers/simulated/src/test/java/org/apache/plc4x/java/simulated/tag/SimularedTagHandlerTest.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * 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. - */ -package org.apache.plc4x.java.simulated.tag; - -import org.apache.plc4x.java.simulated.tag.SimulatedTag; -import org.apache.plc4x.java.simulated.tag.SimulatedTagHandler; -import org.assertj.core.api.WithAssertions; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class SimularedTagHandlerTest implements WithAssertions { - - final SimulatedTagHandler SUT = new SimulatedTagHandler(); - - @Mock - SimulatedTag plcTag; - - @Test - void createTag() { - assertThat(SUT.parseTag("STATE/bar:DINT")).isNotNull(); - } - - /*@Test - void encodeBoolean() { - assertThat(SUT.encodeBoolean(plcTag, new Boolean[0])).isNotNull(); - } - - @Test - void encodeByte() { - when(plcTag.getPlcDataType()).thenReturn("Byte"); - assertThat(SUT.encodeByte(plcTag, new Byte[0])).isNotNull(); - } - - @Test - void encodeShort() { - when(plcTag.getPlcDataType()).thenReturn("Short"); - assertThat(SUT.encodeShort(plcTag, new Short[0])).isNotNull(); - } - - @Test - void encodeInteger() { - when(plcTag.getPlcDataType()).thenReturn("Integer"); - assertThat(SUT.encodeInteger(plcTag, new Integer[0])).isNotNull(); - } - - @Test - void encodeBigInteger() { - when(plcTag.getPlcDataType()).thenReturn("BigInteger"); - assertThat(SUT.encodeBigInteger(plcTag, new BigInteger[0])).isNotNull(); - } - - @Test - void encodeLong() { - when(plcTag.getPlcDataType()).thenReturn("Long"); - assertThat(SUT.encodeLong(plcTag, new Long[0])).isNotNull(); - } - - @Test - void encodeFloat() { - when(plcTag.getPlcDataType()).thenReturn("Float"); - assertThat(SUT.encodeFloat(plcTag, new Float[0])).isNotNull(); - } - - @Test - void encodeBigDecimal() { - when(plcTag.getPlcDataType()).thenReturn("BigDecimal"); - assertThat(SUT.encodeBigDecimal(plcTag, new BigDecimal[0])).isNotNull(); - } - - @Test - void encodeDouble() { - when(plcTag.getPlcDataType()).thenReturn("Double"); - assertThat(SUT.encodeDouble(plcTag, new Double[0])).isNotNull(); - } - - @Test - void encodeString() { - when(plcTag.getPlcDataType()).thenReturn("String"); - assertThat(SUT.encodeString(plcTag, new String[0])).isNotNull(); - } - - @Test - void encodeTime() { - when(plcTag.getPlcDataType()).thenReturn("LocalTime"); - assertThat(SUT.encodeTime(plcTag, new LocalTime[0])).isNotNull(); - } - - @Test - void encodeDate() { - when(plcTag.getPlcDataType()).thenReturn("LocalDate"); - assertThat(SUT.encodeDate(plcTag, new LocalDate[0])).isNotNull(); - } - - @Test - void encodeDateTime() { - when(plcTag.getPlcDataType()).thenReturn("LocalDateTime"); - assertThat(SUT.encodeDateTime(plcTag, new LocalDateTime[0])).isNotNull(); - }*/ - -} diff --git a/plc4j/drivers/simulated/src/test/java/org/apache/plc4x/java/simulated/tag/SimulatedTagTest.java b/plc4j/drivers/simulated/src/test/java/org/apache/plc4x/java/simulated/tag/SimulatedTagTest.java index a8a9b658f24..6bedd43518a 100644 --- a/plc4j/drivers/simulated/src/test/java/org/apache/plc4x/java/simulated/tag/SimulatedTagTest.java +++ b/plc4j/drivers/simulated/src/test/java/org/apache/plc4x/java/simulated/tag/SimulatedTagTest.java @@ -20,7 +20,6 @@ import nl.jqno.equalsverifier.EqualsVerifier; import org.apache.plc4x.java.api.exceptions.PlcInvalidTagException; -import org.apache.plc4x.java.simulated.tag.SimulatedTag; import org.apache.plc4x.java.simulated.types.SimulatedTagType; import org.junit.jupiter.api.Test; diff --git a/plc4j/drivers/simulated/src/test/resources/logback-test.xml b/plc4j/drivers/simulated/src/test/resources/logback-test.xml index 2b9cea25dc8..941f1546f84 100644 --- a/plc4j/drivers/simulated/src/test/resources/logback-test.xml +++ b/plc4j/drivers/simulated/src/test/resources/logback-test.xml @@ -29,7 +29,7 @@ - + diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/ConversationContext.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/ConversationContext.java index 5086893b92e..a37b08548d6 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/ConversationContext.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/ConversationContext.java @@ -24,6 +24,7 @@ import org.apache.plc4x.java.api.exceptions.PlcRuntimeException; import java.time.Duration; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; import java.util.function.BiConsumer; @@ -84,6 +85,8 @@ interface SendRequestContext { */ ContextHandler handle(Consumer packetConsumer); + CompletableFuture toFuture(); + /** * allows to define a timeout handler which then calls {@code packetConsumer} * diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/Plc4xNettyWrapper.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/Plc4xNettyWrapper.java index 838c9f8e4c9..2f93345cfb2 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/Plc4xNettyWrapper.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/Plc4xNettyWrapper.java @@ -75,7 +75,7 @@ public Plc4xNettyWrapper(TimeoutManager timeoutManager, ChannelPipeline pipeline this.protocolBase = protocol; this.authentication = authentication; this.timeoutManager = timeoutManager; - this.protocolBase.setContext(new ConversationContext() { + this.protocolBase.setConversationContext(new ConversationContext() { @Override public PlcAuthentication getAuthentication() { @@ -188,7 +188,9 @@ protected void decode(ChannelHandlerContext channelHandlerContext, T payload, Li } catch (Exception e) { logger.trace("Failure while processing payload {} with handler {}", message, registration, e); BiConsumer biConsumer = registration.getErrorConsumer(); - biConsumer.accept(message, e); + if(biConsumer != null) { + biConsumer.accept(message, e); + } registration.confirmError(); } return; @@ -218,7 +220,6 @@ public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exc /** * Performs registration of packet handler and makes sure that its timeout will be handled properly. - * * Since timeouts are controlled by {@link TimeoutManager} there is a need to decorate handler * operations so both sides know what's going on. * diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/Plc4xProtocolBase.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/Plc4xProtocolBase.java index 95ace093fd4..965fe33da41 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/Plc4xProtocolBase.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/Plc4xProtocolBase.java @@ -20,13 +20,14 @@ import org.apache.commons.lang3.NotImplementedException; import org.apache.plc4x.java.api.messages.*; +import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.context.DriverContext; import java.util.concurrent.CompletableFuture; public abstract class Plc4xProtocolBase { - protected ConversationContext context; + protected ConversationContext conversationContext; protected DriverContext driverContext; @@ -38,8 +39,12 @@ public DriverContext getDriverContext() { return driverContext; } - public void setContext(ConversationContext context) { - this.context = context; + public void setConversationContext(ConversationContext conversationContext) { + this.conversationContext = conversationContext; + } + + public ConversationContext getConversationContext() { + return conversationContext; } public void onConnect(ConversationContext context) { @@ -54,10 +59,10 @@ public void onDiscover(ConversationContext context) { // Intentionally do nothing here } + public abstract PlcTagHandler getTagHandler(); + /** - * TODO document me - *

- * Can be used for non requested incoming messages + * Default callback, called if an incoming message can't be correlated with an expected response. * * @param context * @param msg diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/AbstractPlcConnection.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/AbstractPlcConnection.java index b9d25454320..6ac2ef2e8b1 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/AbstractPlcConnection.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/AbstractPlcConnection.java @@ -21,17 +21,19 @@ import org.apache.commons.lang3.NotImplementedException; import org.apache.plc4x.java.api.PlcConnection; import org.apache.plc4x.java.api.authentication.PlcAuthentication; +import org.apache.plc4x.java.api.exceptions.PlcRuntimeException; import org.apache.plc4x.java.api.exceptions.PlcUnsupportedOperationException; import org.apache.plc4x.java.api.messages.*; import org.apache.plc4x.java.api.metadata.PlcConnectionMetadata; import org.apache.plc4x.java.api.model.PlcConsumerRegistration; import org.apache.plc4x.java.api.model.PlcSubscriptionHandle; import org.apache.plc4x.java.api.model.PlcTag; +import org.apache.plc4x.java.api.value.PlcValue; import org.apache.plc4x.java.spi.Plc4xProtocolBase; import org.apache.plc4x.java.spi.generation.Message; import org.apache.plc4x.java.spi.messages.*; import org.apache.plc4x.java.spi.optimizer.BaseOptimizer; -import org.apache.plc4x.java.api.value.PlcValueHandler; +import org.apache.plc4x.java.spi.values.PlcValueHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -55,29 +57,21 @@ public abstract class AbstractPlcConnection implements PlcConnection, PlcConnect private boolean canWrite = false; private boolean canSubscribe = false; private boolean canBrowse = false; - private PlcTagHandler tagHandler; - private PlcValueHandler valueHandler; + private final PlcValueHandler valueHandler; + private final BaseOptimizer optimizer; + private final PlcAuthentication authentication; private Plc4xProtocolBase protocol; - private BaseOptimizer optimizer; - private PlcAuthentication authentication; - - /** - * @deprecated only for compatibility reasons. - */ - @Deprecated - protected AbstractPlcConnection() { - } + private PlcTagHandler tagHandler; protected AbstractPlcConnection(boolean canPing, boolean canRead, boolean canWrite, boolean canSubscribe, boolean canBrowse, - PlcTagHandler tagHandler, PlcValueHandler valueHandler, + PlcValueHandler valueHandler, BaseOptimizer optimizer, PlcAuthentication authentication) { this.canPing = canPing; this.canRead = canRead; this.canWrite = canWrite; this.canSubscribe = canSubscribe; this.canBrowse = canBrowse; - this.tagHandler = tagHandler; this.valueHandler = valueHandler; this.optimizer = optimizer; this.authentication = authentication; @@ -85,6 +79,7 @@ protected AbstractPlcConnection(boolean canPing, boolean canRead, boolean canWri public void setProtocol(Plc4xProtocolBase protocol) { this.protocol = protocol; + this.tagHandler = protocol.getTagHandler(); } public Plc4xProtocolBase getProtocol() { @@ -103,6 +98,7 @@ public CompletableFuture ping() { return future; } + @Override public boolean isReadSupported() { return canRead; @@ -241,9 +237,20 @@ public Optional parseTagAddress(String tagAddress) { try { plcTag = tagHandler.parseTag(tagAddress); } catch (Exception e) { - logger.error("Error parsing tag address {}", tagAddress); - return Optional.empty(); + throw new PlcRuntimeException("Error parsing tag address: " + tagAddress, e); } return Optional.ofNullable(plcTag); } + + @Override + public Optional parseTagValue(PlcTag tag, Object... values) { + PlcValue plcValue; + try { + plcValue = valueHandler.newPlcValue(tag, values); + } catch (Exception e) { + throw new PlcRuntimeException("Error parsing tag value " + tag, e); + } + return Optional.of(plcValue); + } + } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnection.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnection.java index 147b6db3cea..686fb36a3a1 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnection.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnection.java @@ -28,11 +28,11 @@ import org.apache.plc4x.java.api.listener.ConnectionStateListener; import org.apache.plc4x.java.api.listener.EventListener; import org.apache.plc4x.java.api.messages.PlcPingResponse; -import org.apache.plc4x.java.api.value.PlcValueHandler; import org.apache.plc4x.java.spi.configuration.ConfigurationFactory; import org.apache.plc4x.java.spi.events.*; import org.apache.plc4x.java.spi.messages.DefaultPlcPingRequest; import org.apache.plc4x.java.spi.optimizer.BaseOptimizer; +import org.apache.plc4x.java.spi.values.PlcValueHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -66,7 +66,6 @@ public DefaultNettyPlcConnection(boolean canPing, boolean canWrite, boolean canSubscribe, boolean canBrowse, - PlcTagHandler tagHandler, PlcValueHandler valueHandler, PlcConnectionConfiguration configuration, ChannelFactory channelFactory, @@ -77,7 +76,7 @@ public DefaultNettyPlcConnection(boolean canPing, ProtocolStackConfigurer stackConfigurer, BaseOptimizer optimizer, PlcAuthentication authentication) { - super(canPing, canRead, canWrite, canSubscribe, canBrowse, tagHandler, valueHandler, optimizer, authentication); + super(canPing, canRead, canWrite, canSubscribe, canBrowse, valueHandler, optimizer, authentication); this.configuration = configuration; this.channelFactory = channelFactory; this.fireDiscoverEvent = fireDiscoverEvent; diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/GeneratedDriverBase.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/GeneratedDriverBase.java index 8c037d908b2..c8a85f2c22b 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/GeneratedDriverBase.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/GeneratedDriverBase.java @@ -29,7 +29,6 @@ import org.apache.plc4x.java.api.metadata.OptionMetadata; import org.apache.plc4x.java.api.types.OptionType; import org.apache.plc4x.java.api.metadata.PlcDriverMetadata; -import org.apache.plc4x.java.api.value.PlcValueHandler; import org.apache.plc4x.java.spi.configuration.ConfigurationFactory; import org.apache.plc4x.java.spi.configuration.annotations.*; import org.apache.plc4x.java.spi.configuration.annotations.defaults.*; @@ -38,6 +37,8 @@ import org.apache.plc4x.java.spi.metadata.DefaultOptionMetadata; import org.apache.plc4x.java.spi.optimizer.BaseOptimizer; import org.apache.plc4x.java.spi.transport.Transport; +import org.apache.plc4x.java.spi.values.DefaultPlcValueHandler; +import org.apache.plc4x.java.spi.values.PlcValueHandler; import java.lang.reflect.Field; import java.util.*; @@ -284,9 +285,9 @@ protected BaseOptimizer getOptimizer() { return null; } - protected abstract PlcTagHandler getTagHandler(); - - protected abstract PlcValueHandler getValueHandler(); + protected PlcValueHandler getValueHandler() { + return new DefaultPlcValueHandler(); + } protected abstract ProtocolStackConfigurer getStackConfigurer(); @@ -397,7 +398,6 @@ public PlcConnection getConnection(String connectionString, PlcAuthentication au return new DefaultNettyPlcConnection( canPing(), canRead(), canWrite(), canSubscribe(), canBrowse(), - getTagHandler(), getValueHandler(), configuration, channelFactory, diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/internal/DefaultSendRequestContext.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/internal/DefaultSendRequestContext.java index 73af4d3a9e8..6709e3effc1 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/internal/DefaultSendRequestContext.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/internal/DefaultSendRequestContext.java @@ -24,6 +24,7 @@ import java.time.Duration; import java.util.Deque; import java.util.LinkedList; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeoutException; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -108,6 +109,13 @@ public DefaultContextHandler handle(Consumer packetConsumer) { return new DefaultContextHandler(registration, registration::cancel); } + @Override + public CompletableFuture toFuture() { + CompletableFuture future = new CompletableFuture<>(); + handle(future::complete); + return future; + } + @Override public ConversationContext.SendRequestContext onTimeout(Consumer onTimeoutConsumer) { if (this.onTimeoutConsumer != null && !(this.onTimeoutConsumer instanceof NoopTimeoutConsumer)) { diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcBrowseItem.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcBrowseItem.java index 72b1a5a2fc3..304737b5aaf 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcBrowseItem.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcBrowseItem.java @@ -137,7 +137,7 @@ public PlcBrowseItem resolveArrayItems() { @Override public void serialize(WriteBuffer writeBuffer) throws SerializationException { - writeBuffer.pushContext(getClass().getSimpleName()); + writeBuffer.pushContext("PlcBrowseItem"); writeBuffer.writeString("address", tag.getAddressString().getBytes(StandardCharsets.UTF_8).length * 8, tag.getAddressString(), WithOption.WithEncoding(StandardCharsets.UTF_8.name())); @@ -169,7 +169,7 @@ public void serialize(WriteBuffer writeBuffer) throws SerializationException { } writeBuffer.popContext("options"); } - writeBuffer.popContext(getClass().getSimpleName()); + writeBuffer.popContext("PlcBrowseItem"); } } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultListPlcBrowseItem.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcBrowseItemList.java similarity index 92% rename from plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultListPlcBrowseItem.java rename to plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcBrowseItemList.java index 56663f354d6..50ad9363a42 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultListPlcBrowseItem.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcBrowseItemList.java @@ -27,15 +27,14 @@ import org.apache.plc4x.java.spi.generation.WriteBuffer; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; import java.util.List; import java.util.Map; -public class DefaultListPlcBrowseItem extends DefaultPlcBrowseItem { +public class DefaultPlcBrowseItemList extends DefaultPlcBrowseItem { private final List arrayInformation; - public DefaultListPlcBrowseItem(PlcTag tag, + public DefaultPlcBrowseItemList(PlcTag tag, String name, boolean readable, boolean writable, @@ -80,7 +79,7 @@ protected PlcBrowseItem resolveInternal(PlcTag tag, List @Override public void serialize(WriteBuffer writeBuffer) throws SerializationException { - writeBuffer.pushContext(getClass().getSimpleName()); + writeBuffer.pushContext("PlcBrowseItemList"); writeBuffer.writeString("address", getTag().getAddressString().getBytes(StandardCharsets.UTF_8).length * 8, getTag().getAddressString(), WithOption.WithEncoding(StandardCharsets.UTF_8.name())); @@ -93,7 +92,7 @@ public void serialize(WriteBuffer writeBuffer) throws SerializationException { writeBuffer.pushContext("children"); for (PlcBrowseItem child : getChildren().values()) { writeBuffer.pushContext("child"); - ((DefaultListPlcBrowseItem) child).serialize(writeBuffer); + ((DefaultPlcBrowseItemList) child).serialize(writeBuffer); writeBuffer.popContext("child"); } writeBuffer.popContext("children"); @@ -107,12 +106,12 @@ public void serialize(WriteBuffer writeBuffer) throws SerializationException { optionEntry.getKey(), WithOption.WithEncoding(StandardCharsets.UTF_8.name())); // TODO: Find out how to serialize a PlcValue //writeBuffer.writeString("value", optionEntry.getValue().getBytes(StandardCharsets.UTF_8).length * 8, StandardCharsets.UTF_8.name(), optionEntry.getValue()); - ((DefaultListPlcBrowseItem) optionEntry).serialize(writeBuffer); + ((DefaultPlcBrowseItemList) optionEntry).serialize(writeBuffer); writeBuffer.popContext("option"); } writeBuffer.popContext("options"); } - writeBuffer.popContext(getClass().getSimpleName()); + writeBuffer.popContext("PlcBrowseItemList"); } } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcBrowseRequest.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcBrowseRequest.java index 14e523c2a2e..efc6bb8c2ef 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcBrowseRequest.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcBrowseRequest.java @@ -28,6 +28,7 @@ import java.util.LinkedHashMap; import java.util.LinkedHashSet; +import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.function.Supplier; @@ -80,8 +81,8 @@ public static class Builder implements PlcBrowseRequest.Builder { private final LinkedHashMap> queries; public Builder(PlcBrowser browser, PlcTagHandler tagHandler) { - this.browser = browser; - this.tagHandler = tagHandler; + this.browser = Objects.requireNonNull(browser); + this.tagHandler = Objects.requireNonNull(tagHandler); queries = new LinkedHashMap<>(); } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcDiscoveryItem.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcDiscoveryItem.java index bc3b6855a55..0aecb610036 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcDiscoveryItem.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcDiscoveryItem.java @@ -103,7 +103,7 @@ public String getConnectionUrl() { @Override public void serialize(WriteBuffer writeBuffer) throws SerializationException { - writeBuffer.pushContext(getClass().getSimpleName()); + writeBuffer.pushContext("PlcDiscoveryItem"); writeBuffer.writeString("protocolCode", protocolCode.getBytes(StandardCharsets.UTF_8).length * 8, @@ -134,7 +134,7 @@ public void serialize(WriteBuffer writeBuffer) throws SerializationException { name, WithOption.WithEncoding(StandardCharsets.UTF_8.name())); } - writeBuffer.popContext(getClass().getSimpleName()); + writeBuffer.popContext("PlcDiscoveryItem"); } } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcDiscoveryRequest.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcDiscoveryRequest.java index a782df78f53..9990f1ba5c8 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcDiscoveryRequest.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcDiscoveryRequest.java @@ -25,6 +25,7 @@ import java.util.LinkedHashMap; import java.util.Map; +import java.util.Objects; import java.util.concurrent.CompletableFuture; public class DefaultPlcDiscoveryRequest implements PlcDiscoveryRequest, Serializable { @@ -73,7 +74,7 @@ public static class Builder implements PlcDiscoveryRequest.Builder { private final LinkedHashMap queries; public Builder(PlcDiscoverer discoverer) { - this.discoverer = discoverer; + this.discoverer = Objects.requireNonNull(discoverer); queries = new LinkedHashMap<>(); } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcReadRequest.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcReadRequest.java index 3d189926ffd..92c64c4ebbc 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcReadRequest.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcReadRequest.java @@ -19,23 +19,28 @@ package org.apache.plc4x.java.spi.messages; import org.apache.plc4x.java.api.exceptions.PlcRuntimeException; +import org.apache.plc4x.java.api.exceptions.PlcTagNotFoundException; import org.apache.plc4x.java.api.messages.PlcReadRequest; import org.apache.plc4x.java.api.messages.PlcReadResponse; import org.apache.plc4x.java.api.messages.PlcTagRequest; import org.apache.plc4x.java.api.model.PlcTag; +import org.apache.plc4x.java.api.types.PlcResponseCode; import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.generation.SerializationException; import org.apache.plc4x.java.spi.generation.WriteBuffer; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcTagErrorItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcTagItem; +import org.apache.plc4x.java.spi.messages.utils.PlcTagItem; import org.apache.plc4x.java.spi.utils.Serializable; import java.util.LinkedHashMap; import java.util.LinkedHashSet; -import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.Optional; +import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.function.Supplier; +import java.util.stream.Collectors; import static org.apache.plc4x.java.spi.generation.WithReaderWriterArgs.WithRenderAsList; @@ -43,10 +48,10 @@ public class DefaultPlcReadRequest implements PlcReadRequest, PlcTagRequest, Ser private final PlcReader reader; // This is intentionally a linked hash map in order to keep the order of how elements were added. - private final LinkedHashMap tags; + private final LinkedHashMap tags; public DefaultPlcReadRequest(PlcReader reader, - LinkedHashMap tags) { + LinkedHashMap tags) { this.reader = reader; this.tags = tags; } @@ -67,14 +72,23 @@ public LinkedHashSet getTagNames() { return new LinkedHashSet<>(tags.keySet()); } + public PlcTagItem getTagItem(String tagName) { + return tags.get(tagName); + } + + @Override + public PlcTag getTag(String tagName) { + return tags.get(tagName).getTag(); + } + @Override - public PlcTag getTag(String name) { - return tags.get(name); + public PlcResponseCode getTagResponseCode(String tagName) { + return tags.get(tagName).getResponseCode(); } @Override public List getTags() { - return new LinkedList<>(tags.values()); + return tags.values().stream().filter(plcTagItem -> plcTagItem instanceof DefaultPlcTagItem).map(PlcTagItem::getTag).collect(Collectors.toList()); } public PlcReader getReader() { @@ -87,14 +101,14 @@ public void serialize(WriteBuffer writeBuffer) throws SerializationException { writeBuffer.pushContext("PlcTagRequest"); writeBuffer.pushContext("tags", WithRenderAsList(true)); - for (Map.Entry tagEntry : tags.entrySet()) { + for (Map.Entry tagEntry : tags.entrySet()) { String tagName = tagEntry.getKey(); writeBuffer.pushContext(tagName); - PlcTag tag = tagEntry.getValue(); - if(!(tag instanceof Serializable)) { - throw new RuntimeException("Error serializing. Tag doesn't implement Serializable"); + PlcTagItem tagItem = tagEntry.getValue(); + if (!(tagItem instanceof Serializable)) { + throw new RuntimeException("Error serializing. PlcTagItem doesn't implement Serializable"); } - ((Serializable) tag).serialize(writeBuffer); + ((Serializable) tagItem).serialize(writeBuffer); writeBuffer.popContext(tagName); } writeBuffer.popContext("tags"); @@ -107,36 +121,48 @@ public static class Builder implements PlcReadRequest.Builder { private final PlcReader reader; private final PlcTagHandler tagHandler; - private final Map> tags; + private final Map> tagItems; public Builder(PlcReader reader, PlcTagHandler tagHandler) { - this.reader = reader; - this.tagHandler = tagHandler; - tags = new LinkedHashMap<>(); + this.reader = Objects.requireNonNull(reader); + this.tagHandler = Objects.requireNonNull(tagHandler); + tagItems = new LinkedHashMap<>(); } @Override public PlcReadRequest.Builder addTagAddress(String name, String tagAddress) { - if (tags.containsKey(name)) { + if (tagItems.containsKey(name)) { throw new PlcRuntimeException("Duplicate tag definition '" + name + "'"); } - tags.put(name, () -> tagHandler.parseTag(tagAddress)); + tagItems.put(name, () -> { + try { + PlcTag tag = tagHandler.parseTag(tagAddress); + return new DefaultPlcTagItem(tag); + } catch (PlcTagNotFoundException e) { + return new DefaultPlcTagErrorItem(PlcResponseCode.NOT_FOUND); + } catch (Exception e) { + return new DefaultPlcTagErrorItem(PlcResponseCode.INVALID_ADDRESS); + } + }); return this; } @Override public PlcReadRequest.Builder addTag(String name, PlcTag tag) { - if (tags.containsKey(name)) { + if (tagItems.containsKey(name)) { throw new PlcRuntimeException("Duplicate tag definition '" + name + "'"); } - tags.put(name, () -> tag); + tagItems.put(name, () -> new DefaultPlcTagItem(tag)); return this; } @Override public PlcReadRequest build() { - LinkedHashMap parsedTags = new LinkedHashMap<>(); - tags.forEach((name, tagSupplier) -> parsedTags.put(name, tagSupplier.get())); + LinkedHashMap parsedTags = new LinkedHashMap<>(); + tagItems.forEach((name, tagItemSupplier) -> { + PlcTagItem plcTagItem = tagItemSupplier.get(); + parsedTags.put(name, plcTagItem); + }); return new DefaultPlcReadRequest(reader, parsedTags); } } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcReadResponse.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcReadResponse.java index 9984211cccf..53a514e5cb7 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcReadResponse.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcReadResponse.java @@ -25,13 +25,13 @@ import org.apache.plc4x.java.api.model.PlcTag; import org.apache.plc4x.java.api.types.PlcResponseCode; import org.apache.plc4x.java.spi.generation.SerializationException; -import org.apache.plc4x.java.spi.generation.WithWriterArgs; import org.apache.plc4x.java.spi.generation.WriteBuffer; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; import org.apache.plc4x.java.spi.utils.Serializable; import org.apache.plc4x.java.spi.values.PlcList; import org.apache.plc4x.java.api.value.PlcValue; import org.apache.plc4x.java.spi.values.PlcStruct; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; import java.math.BigDecimal; import java.math.BigInteger; @@ -45,10 +45,10 @@ public class DefaultPlcReadResponse implements PlcReadResponse, Serializable { private final PlcReadRequest request; - private final Map> values; + private final Map> values; public DefaultPlcReadResponse(PlcReadRequest request, - Map> values) { + Map> values) { this.request = request; this.values = values; } @@ -70,7 +70,7 @@ public PlcValue getAsPlcValue() { @Override public PlcValue getPlcValue(String name) { - return values.getOrDefault(name, new ResponseItem<>(null, null)).getValue(); + return values.getOrDefault(name, new DefaultPlcResponseItem<>(null, null)).getValue(); } @Override @@ -102,7 +102,7 @@ public PlcResponseCode getResponseCode(String name) { return values.get(name).getCode(); } - public Map> getValues() { + public Map> getValues() { return values; } @@ -605,11 +605,11 @@ public Collection getAllDateTimes(String name) { return Collections.singletonList(tagInternal.getDateTime()); } - public void add(String key, ResponseItem value) { + public void add(String key, PlcResponseItem value) { values.put(key, value); } - public Map> getMap() { + public Map> getMap() { return values; } @@ -653,11 +653,14 @@ public void serialize(WriteBuffer writeBuffer) throws SerializationException { writeBuffer.popContext("request"); writeBuffer.pushContext("values", WithRenderAsList(true)); - for (Map.Entry> valueEntry : values.entrySet()) { + for (Map.Entry> valueEntry : values.entrySet()) { String tagName = valueEntry.getKey(); writeBuffer.pushContext(tagName); - ResponseItem valueResponse = valueEntry.getValue(); - valueResponse.serialize(writeBuffer); + PlcResponseItem valueResponse = valueEntry.getValue(); + if (!(valueResponse instanceof Serializable)) { + throw new RuntimeException("Error serializing. PlcResponseItem doesn't implement Serializable"); + } + ((Serializable) valueResponse).serialize(writeBuffer); writeBuffer.popContext(tagName); } writeBuffer.popContext("values"); diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcSubscriptionEvent.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcSubscriptionEvent.java index da21c8358fd..2035f76e001 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcSubscriptionEvent.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcSubscriptionEvent.java @@ -21,7 +21,7 @@ import org.apache.plc4x.java.api.messages.PlcSubscriptionEvent; import org.apache.plc4x.java.api.model.PlcTag; import org.apache.plc4x.java.api.value.PlcValue; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; import java.time.Instant; import java.util.Collection; @@ -32,7 +32,7 @@ public class DefaultPlcSubscriptionEvent extends DefaultPlcReadResponse implemen public final Instant timestamp; public DefaultPlcSubscriptionEvent(Instant timestamp, - Map> tags) { + Map> tags) { super(null, tags); this.timestamp = timestamp; } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcSubscriptionRequest.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcSubscriptionRequest.java index 7264b78209a..acd6bd23ddd 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcSubscriptionRequest.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcSubscriptionRequest.java @@ -111,8 +111,8 @@ public static class Builder implements PlcSubscriptionRequest.Builder { private final LinkedHashMap>> preRegisteredConsumers; public Builder(PlcSubscriber subscriber, PlcTagHandler tagHandler) { - this.subscriber = subscriber; - this.tagHandler = tagHandler; + this.subscriber = Objects.requireNonNull(subscriber); + this.tagHandler = Objects.requireNonNull(tagHandler); this.tags = new TreeMap<>(); this.preRegisteredConsumers = new LinkedHashMap<>(); } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcSubscriptionResponse.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcSubscriptionResponse.java index 47d806eb434..10595de8317 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcSubscriptionResponse.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcSubscriptionResponse.java @@ -28,7 +28,7 @@ import org.apache.plc4x.java.api.types.PlcResponseCode; import org.apache.plc4x.java.spi.generation.SerializationException; import org.apache.plc4x.java.spi.generation.WriteBuffer; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; import org.apache.plc4x.java.spi.utils.Serializable; import java.util.Collection; @@ -39,10 +39,10 @@ public class DefaultPlcSubscriptionResponse implements PlcSubscriptionResponse, private final PlcSubscriptionRequest request; - private final Map> values; + private final Map> values; public DefaultPlcSubscriptionResponse(PlcSubscriptionRequest request, - Map> values) { + Map> values) { this.request = request; this.values = values; request.getPreRegisteredConsumers().forEach((subscriptionTagName, consumers) -> { @@ -56,7 +56,7 @@ public DefaultPlcSubscriptionResponse(PlcSubscriptionRequest request, @Override public PlcSubscriptionHandle getSubscriptionHandle(String name) { - ResponseItem response = values.get(name); + PlcResponseItem response = values.get(name); if (response == null) { return null; } @@ -78,7 +78,7 @@ public PlcSubscriptionTag getTag(String name) { @Override public PlcResponseCode getResponseCode(String name) { - ResponseItem response = values.get(name); + PlcResponseItem response = values.get(name); if (response == null) { return null; } @@ -92,10 +92,10 @@ public PlcSubscriptionRequest getRequest() { @Override public Collection getSubscriptionHandles() { - return values.values().stream().map(ResponseItem::getValue).collect(Collectors.toList()); + return values.values().stream().map(PlcResponseItem::getValue).collect(Collectors.toList()); } - public Map> getValues() { + public Map> getValues() { return values; } @@ -107,11 +107,14 @@ public void serialize(WriteBuffer writeBuffer) throws SerializationException { ((Serializable) request).serialize(writeBuffer); } writeBuffer.pushContext("values"); - for (Map.Entry> valueEntry : values.entrySet()) { + for (Map.Entry> valueEntry : values.entrySet()) { String tagName = valueEntry.getKey(); writeBuffer.pushContext(tagName); - ResponseItem valueResponse = valueEntry.getValue(); - valueResponse.serialize(writeBuffer); + PlcResponseItem valueResponse = valueEntry.getValue(); + if (!(valueResponse instanceof Serializable)) { + throw new RuntimeException("Error serializing. PlcResponseItem doesn't implement Serializable"); + } + ((Serializable) valueResponse).serialize(writeBuffer); writeBuffer.pushContext(tagName); } writeBuffer.popContext("values"); diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcUnsubscriptionRequest.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcUnsubscriptionRequest.java index a90aeea8729..64570741f83 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcUnsubscriptionRequest.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcUnsubscriptionRequest.java @@ -71,7 +71,7 @@ public static class Builder implements PlcUnsubscriptionRequest.Builder { private final List plcSubscriptionHandles; public Builder(PlcSubscriber subscriber) { - this.subscriber = subscriber; + this.subscriber = Objects.requireNonNull(subscriber); plcSubscriptionHandles = new ArrayList<>(); } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcWriteRequest.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcWriteRequest.java index d66d1f1c9c8..64f3c21ec7b 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcWriteRequest.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcWriteRequest.java @@ -18,20 +18,22 @@ */ package org.apache.plc4x.java.spi.messages; -import org.apache.commons.lang3.tuple.Pair; import org.apache.plc4x.java.api.exceptions.PlcRuntimeException; import org.apache.plc4x.java.api.messages.PlcWriteRequest; import org.apache.plc4x.java.api.messages.PlcWriteResponse; import org.apache.plc4x.java.api.model.PlcTag; +import org.apache.plc4x.java.api.types.PlcResponseCode; import org.apache.plc4x.java.api.value.PlcValue; -import org.apache.plc4x.java.api.value.PlcValueHandler; import org.apache.plc4x.java.spi.codegen.WithOption; import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.generation.SerializationException; import org.apache.plc4x.java.spi.generation.WriteBuffer; -import org.apache.plc4x.java.spi.messages.utils.TagValueItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcTagErrorItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcTagValueItem; +import org.apache.plc4x.java.spi.messages.utils.PlcTagValueItem; import org.apache.plc4x.java.spi.utils.Serializable; import org.apache.plc4x.java.spi.values.PlcList; +import org.apache.plc4x.java.spi.values.PlcValueHandler; import java.nio.charset.StandardCharsets; import java.util.*; @@ -45,10 +47,10 @@ public class DefaultPlcWriteRequest implements PlcWriteRequest, Serializable { private final PlcWriter writer; - private final LinkedHashMap tags; + private final LinkedHashMap tags; public DefaultPlcWriteRequest(PlcWriter writer, - LinkedHashMap tags) { + LinkedHashMap tags) { this.writer = writer; this.tags = tags; } @@ -69,6 +71,11 @@ public LinkedHashSet getTagNames() { return new LinkedHashSet<>(tags.keySet()); } + @Override + public PlcResponseCode getTagResponseCode(String tagName) { + return tags.get(tagName).getResponseCode(); + } + @Override public PlcTag getTag(String name) { return tags.get(name).getTag(); @@ -76,7 +83,7 @@ public PlcTag getTag(String name) { @Override public List getTags() { - return tags.values().stream().map(TagValueItem::getTag).collect(Collectors.toCollection(LinkedList::new)); + return tags.values().stream().map(PlcTagValueItem::getTag).collect(Collectors.toCollection(LinkedList::new)); } public PlcValue getPlcValue(String name) { @@ -84,7 +91,7 @@ public PlcValue getPlcValue(String name) { } public List getPlcValues() { - return tags.values().stream().map(TagValueItem::getValue).collect(Collectors.toCollection(LinkedList::new)); + return tags.values().stream().map(PlcTagValueItem::getValue).collect(Collectors.toCollection(LinkedList::new)); } public PlcWriter getWriter() { @@ -107,33 +114,19 @@ public void serialize(WriteBuffer writeBuffer) throws SerializationException { writeBuffer.pushContext("PlcTagRequest"); writeBuffer.pushContext("tags", WithRenderAsList(true)); - for (Map.Entry tagEntry : tags.entrySet()) { - TagValueItem tagValueItem = tagEntry.getValue(); + for (Map.Entry tagEntry : tags.entrySet()) { String tagName = tagEntry.getKey(); writeBuffer.pushContext(tagName); - PlcTag tag = tagValueItem.getTag(); - if (!(tag instanceof Serializable)) { - throw new RuntimeException("Error serializing. Tag doesn't implement Serializable"); + PlcTagValueItem plcTagValueItem = tagEntry.getValue(); + if (!(plcTagValueItem instanceof Serializable)) { + throw new RuntimeException("Error serializing. PlcTagValueItem doesn't implement Serializable"); } - ((Serializable) tag).serialize(writeBuffer); + ((Serializable) plcTagValueItem).serialize(writeBuffer); writeBuffer.popContext(tagName); } writeBuffer.popContext("tags"); writeBuffer.popContext("PlcTagRequest"); - writeBuffer.pushContext("values", WithRenderAsList(true)); - for (Map.Entry tagEntry : tags.entrySet()) { - TagValueItem tagValueItem = tagEntry.getValue(); - String tagName = tagEntry.getKey(); - writeBuffer.pushContext(tagName); - final PlcValue value = tagValueItem.getValue(); - if (value != null) { - serializePlcValue(value, writeBuffer); - } - writeBuffer.popContext(tagName); - } - writeBuffer.popContext("values"); - writeBuffer.popContext("PlcWriteRequest"); } @@ -154,62 +147,62 @@ public static class Builder implements PlcWriteRequest.Builder { private final PlcWriter writer; private final PlcTagHandler tagHandler; private final PlcValueHandler valueHandler; - private final Map, Object[]>> tags; + private final Map> tagValues; public Builder(PlcWriter writer, PlcTagHandler tagHandler, PlcValueHandler valueHandler) { - this.writer = writer; - this.tagHandler = tagHandler; - this.valueHandler = valueHandler; - tags = new TreeMap<>(); + this.writer = Objects.requireNonNull(writer); + this.tagHandler = Objects.requireNonNull(tagHandler); + this.valueHandler = Objects.requireNonNull(valueHandler); + tagValues = new TreeMap<>(); } @Override public Builder addTagAddress(String name, String tagAddress, Object... values) { - if (tags.containsKey(name)) { + if (tagValues.containsKey(name)) { throw new PlcRuntimeException("Duplicate tag definition '" + name + "'"); } - tags.put(name, Pair.of(() -> tagHandler.parseTag(tagAddress), values)); + tagValues.put(name, () -> { + try { + PlcTag tag = tagHandler.parseTag(tagAddress); + try { + PlcValue plcValue = parsePlcValue(tag, values); + return new DefaultPlcTagValueItem(tag, plcValue); + } catch (Exception e) { + return new DefaultPlcTagErrorItem(PlcResponseCode.INVALID_DATA); + } + } catch (Exception e) { + return new DefaultPlcTagErrorItem(PlcResponseCode.INVALID_ADDRESS); + } + }); return this; } @Override public Builder addTag(String name, PlcTag tag, Object... values) { - if (tags.containsKey(name)) { + if (tagValues.containsKey(name)) { throw new PlcRuntimeException("Duplicate tag definition '" + name + "'"); } - tags.put(name, Pair.of(() -> tag, values)); + tagValues.put(name, () -> { + try { + PlcValue plcValue = parsePlcValue(tag, values); + return new DefaultPlcTagValueItem(tag, plcValue); + } catch (Exception e) { + return new DefaultPlcTagErrorItem(PlcResponseCode.INVALID_DATA); + } + }); return this; } + protected PlcValue parsePlcValue(PlcTag tag, Object[] values) { + return valueHandler.newPlcValue(tag, values); + } + @Override public PlcWriteRequest build() { - LinkedHashMap parsedTags = new LinkedHashMap<>(); - tags.forEach((name, tagValues) -> { - // Compile the query string. - PlcTag tag = tagValues.getLeft().get(); - PlcValue plcValue; - // If this is more than one element the value itself will definitely be a list. - if(tagValues.getRight().length > 1) { - List listItems = new ArrayList<>(tagValues.getRight().length); - for (Object tagValue : tagValues.getRight()) { - if(tagValue instanceof PlcValue) { - listItems.add((PlcValue) tagValue); - } else { - PlcValue plcItemValue = valueHandler.newPlcValue(tag, tagValue); - listItems.add(plcItemValue); - } - } - plcValue = new PlcList(listItems); - } - // If the values are already PlcValues, just use them. - else if(tagValues.getRight()[0] instanceof PlcValue) { - plcValue = (PlcValue) tagValues.getRight()[0]; - } - // In all other cases use the value-handler. - else { - plcValue = valueHandler.newPlcValue(tag, tagValues.getRight()[0]); - } - parsedTags.put(name, new TagValueItem(tag, plcValue)); + LinkedHashMap parsedTags = new LinkedHashMap<>(); + tagValues.forEach((name, tagValueItemSupplier) -> { + PlcTagValueItem plcTagValueItem = tagValueItemSupplier.get(); + parsedTags.put(name, plcTagValueItem); }); return new DefaultPlcWriteRequest(writer, parsedTags); } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/ResponseItem.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/DefaultPlcResponseItem.java similarity index 88% rename from plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/ResponseItem.java rename to plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/DefaultPlcResponseItem.java index b26e06c668b..87e4dec387b 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/ResponseItem.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/DefaultPlcResponseItem.java @@ -26,27 +26,29 @@ import java.nio.charset.StandardCharsets; -public class ResponseItem implements Serializable { +public class DefaultPlcResponseItem implements Serializable, PlcResponseItem { private final PlcResponseCode code; private final T value; - public ResponseItem(PlcResponseCode code, T value) { + public DefaultPlcResponseItem(PlcResponseCode code, T value) { this.code = code; this.value = value; } + @Override public PlcResponseCode getCode() { return code; } + @Override public T getValue() { return value; } @Override public void serialize(WriteBuffer writeBuffer) throws SerializationException { - writeBuffer.pushContext("ResponseItem"); + writeBuffer.pushContext("PlcResponseItem"); String codeName = code.name(); writeBuffer.writeString("code", codeName.getBytes(StandardCharsets.UTF_8).length * 8, @@ -59,7 +61,7 @@ public void serialize(WriteBuffer writeBuffer) throws SerializationException { ((Serializable) value).serialize(writeBuffer); writeBuffer.popContext("value"); } - writeBuffer.popContext("ResponseItem"); + writeBuffer.popContext("PlcResponseItem"); } } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/DefaultPlcTagErrorItem.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/DefaultPlcTagErrorItem.java new file mode 100644 index 00000000000..211497ec632 --- /dev/null +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/DefaultPlcTagErrorItem.java @@ -0,0 +1,46 @@ +/* + * 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 org.apache.plc4x.java.spi.messages.utils; + +import org.apache.plc4x.java.api.types.PlcResponseCode; +import org.apache.plc4x.java.spi.generation.SerializationException; +import org.apache.plc4x.java.spi.generation.WriteBuffer; +import org.apache.plc4x.java.spi.utils.Serializable; + +public class DefaultPlcTagErrorItem implements PlcTagItem, PlcTagValueItem, Serializable { + + private final PlcResponseCode responseCode; + + public DefaultPlcTagErrorItem(PlcResponseCode responseCode) { + this.responseCode = responseCode; + } + + public PlcResponseCode getResponseCode() { + return responseCode; + } + + @Override + public void serialize(WriteBuffer writeBuffer) throws SerializationException { + writeBuffer.pushContext("PlcTagErrorItem"); + writeBuffer.writeString("responseCode", responseCode.name().length() * 8, responseCode.name()); + writeBuffer.popContext("PlcTagErrorItem"); + } + +} diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/DefaultPlcTagItem.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/DefaultPlcTagItem.java new file mode 100644 index 00000000000..f1b15bb4a4c --- /dev/null +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/DefaultPlcTagItem.java @@ -0,0 +1,50 @@ +/* + * 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 org.apache.plc4x.java.spi.messages.utils; + +import org.apache.plc4x.java.api.model.PlcTag; +import org.apache.plc4x.java.spi.generation.SerializationException; +import org.apache.plc4x.java.spi.generation.WriteBuffer; +import org.apache.plc4x.java.spi.utils.Serializable; + +public class DefaultPlcTagItem implements PlcTagItem, Serializable { + + private final PlcTag tag; + + public DefaultPlcTagItem(PlcTag tag) { + this.tag = tag; + } + + public PlcTag getTag() { + return tag; + } + + @Override + public void serialize(WriteBuffer writeBuffer) throws SerializationException { + writeBuffer.pushContext("PlcTagItem"); + if(tag instanceof Serializable) { + writeBuffer.pushContext("tag"); + writeBuffer.writeSerializable((Serializable) tag); + writeBuffer.popContext("tag"); + } + writeBuffer.popContext("PlcTagItem"); + } + +} diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/DefaultPlcTagValueItem.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/DefaultPlcTagValueItem.java new file mode 100644 index 00000000000..315b9c62b37 --- /dev/null +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/DefaultPlcTagValueItem.java @@ -0,0 +1,56 @@ +/* + * 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. + */ +package org.apache.plc4x.java.spi.messages.utils; + +import org.apache.plc4x.java.api.model.PlcTag; +import org.apache.plc4x.java.api.value.PlcValue; +import org.apache.plc4x.java.spi.generation.SerializationException; +import org.apache.plc4x.java.spi.generation.WriteBuffer; +import org.apache.plc4x.java.spi.utils.Serializable; + +public class DefaultPlcTagValueItem extends DefaultPlcTagItem implements PlcTagValueItem, Serializable { + + private final PlcValue value; + + public DefaultPlcTagValueItem(PlcTag tag, PlcValue value) { + super(tag); + this.value = value; + } + + public PlcValue getValue() { + return value; + } + + @Override + public void serialize(WriteBuffer writeBuffer) throws SerializationException { + writeBuffer.pushContext("PlcTagValueItem"); + if(getTag() instanceof Serializable) { + writeBuffer.pushContext("tag"); + writeBuffer.writeSerializable((Serializable) getTag()); + writeBuffer.popContext("tag"); + } + if(value instanceof Serializable) { + writeBuffer.pushContext("value"); + writeBuffer.writeSerializable((Serializable) value); + writeBuffer.popContext("value"); + } + writeBuffer.popContext("PlcTagValueItem"); + } + +} diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/PlcResponseItem.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/PlcResponseItem.java new file mode 100644 index 00000000000..582ff604fe6 --- /dev/null +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/PlcResponseItem.java @@ -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 org.apache.plc4x.java.spi.messages.utils; + +import org.apache.plc4x.java.api.types.PlcResponseCode; + +public interface PlcResponseItem { + PlcResponseCode getCode(); + + T getValue(); +} diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcValueHandler.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/PlcTagItem.java similarity index 70% rename from plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcValueHandler.java rename to plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/PlcTagItem.java index 97972a22c9f..17f6b92ee68 100644 --- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcValueHandler.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/PlcTagItem.java @@ -7,7 +7,7 @@ * "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 + * 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 @@ -16,18 +16,20 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.plc4x.java.api.value; + +package org.apache.plc4x.java.spi.messages.utils; import org.apache.plc4x.java.api.model.PlcTag; +import org.apache.plc4x.java.api.types.PlcResponseCode; -/** - * Base Valuehandler - */ -public interface PlcValueHandler { +public interface PlcTagItem { + + default PlcResponseCode getResponseCode() { + return PlcResponseCode.OK; + } - PlcValue newPlcValue(Object value); - PlcValue newPlcValue(Object[] values); - PlcValue newPlcValue(PlcTag tag, Object value); - PlcValue newPlcValue(PlcTag tag, Object[] values); + default PlcTag getTag() { + return null; + } } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/TagValueItem.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/PlcTagValueItem.java similarity index 71% rename from plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/TagValueItem.java rename to plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/PlcTagValueItem.java index 14c9540af1a..fcadabec13f 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/TagValueItem.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/PlcTagValueItem.java @@ -18,25 +18,12 @@ */ package org.apache.plc4x.java.spi.messages.utils; -import org.apache.plc4x.java.api.model.PlcTag; import org.apache.plc4x.java.api.value.PlcValue; -public class TagValueItem { +public interface PlcTagValueItem extends PlcTagItem { - private final PlcTag tag; - private final PlcValue value; - - public TagValueItem(PlcTag tag, PlcValue value) { - this.tag = tag; - this.value = value; - } - - public PlcTag getTag() { - return tag; - } - - public PlcValue getValue() { - return value; + default PlcValue getValue() { + return null; } } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/model/DefaultArrayInfo.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/model/DefaultArrayInfo.java index 140af84bd2b..98d3936e933 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/model/DefaultArrayInfo.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/model/DefaultArrayInfo.java @@ -32,7 +32,7 @@ public DefaultArrayInfo(int lowerBound, int upperBound) { @Override public int getSize() { - return upperBound - lowerBound; + return 1 + (upperBound - lowerBound); } @Override diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/BaseOptimizer.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/BaseOptimizer.java index 94f70a3f1ea..b2caf2e82bf 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/BaseOptimizer.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/BaseOptimizer.java @@ -25,7 +25,8 @@ import org.apache.plc4x.java.spi.context.DriverContext; import org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse; import org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; import java.util.Collections; import java.util.HashMap; @@ -41,7 +42,7 @@ protected List processReadRequest(PlcReadRequest readRequest, Dr } protected PlcReadResponse processReadResponses(PlcReadRequest readRequest, Map> readResponses, DriverContext driverContext) { - Map> tags = new HashMap<>(); + Map> tags = new HashMap<>(); for (Map.Entry> requestsEntries : readResponses.entrySet()) { PlcReadRequest curRequest = requestsEntries.getKey(); SubResponse readResponse = requestsEntries.getValue(); @@ -50,9 +51,9 @@ protected PlcReadResponse processReadResponses(PlcReadRequest readRequest, Map

(responseCode, value)); + tags.put(tagName, new DefaultPlcResponseItem<>(responseCode, value)); } else { - tags.put(tagName, new ResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null)); + tags.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null)); } } } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/SingleTagOptimizer.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/SingleTagOptimizer.java index 105188f3e58..79b8b93ef7e 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/SingleTagOptimizer.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/optimizer/SingleTagOptimizer.java @@ -19,14 +19,14 @@ package org.apache.plc4x.java.spi.optimizer; import org.apache.plc4x.java.api.messages.PlcReadRequest; -import org.apache.plc4x.java.api.messages.PlcRequest; import org.apache.plc4x.java.api.messages.PlcWriteRequest; import org.apache.plc4x.java.api.model.PlcTag; import org.apache.plc4x.java.api.value.PlcValue; import org.apache.plc4x.java.spi.context.DriverContext; import org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest; import org.apache.plc4x.java.spi.messages.DefaultPlcWriteRequest; -import org.apache.plc4x.java.spi.messages.utils.TagValueItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcTagItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcTagValueItem; import java.util.ArrayList; import java.util.Collections; @@ -48,7 +48,8 @@ protected List processReadRequest(PlcReadRequest readRequest, Dr PlcTag tag = readRequest.getTag(tagName); PlcReadRequest subRequest = new DefaultPlcReadRequest( ((DefaultPlcReadRequest) readRequest).getReader(), - new LinkedHashMap<>(Collections.singletonMap(tagName, tag))); + // We are only expecting valid tagItems being passed in. + new LinkedHashMap<>(Collections.singletonMap(tagName, new DefaultPlcTagItem(tag)))); subRequests.add(subRequest); } return subRequests; @@ -65,7 +66,8 @@ protected List processWriteRequest(PlcWriteRequest writeRequest PlcValue value = writeRequest.getPlcValue(tagName); PlcWriteRequest subRequest = new DefaultPlcWriteRequest( ((DefaultPlcWriteRequest) writeRequest).getWriter(), - new LinkedHashMap<>(Collections.singletonMap(tagName, new TagValueItem(tag, value)))); + // We are only expecting valid tagValueItems being passed in. + new LinkedHashMap<>(Collections.singletonMap(tagName, new DefaultPlcTagValueItem(tag, value)))); subRequests.add(subRequest); } return subRequests; diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/transaction/RequestTransactionManager.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/transaction/RequestTransactionManager.java index 49c2c345c24..ac11eeaedd8 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/transaction/RequestTransactionManager.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/transaction/RequestTransactionManager.java @@ -20,7 +20,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.slf4j.MDC; import java.util.Objects; import java.util.Queue; @@ -89,7 +88,7 @@ public void setNumberOfConcurrentRequests(int numberOfConcurrentRequests) { this.numberOfConcurrentRequests = numberOfConcurrentRequests; // As we might have increased the number, try to send some more requests. - processWorklog(); + processWorkLog(); } /* @@ -102,19 +101,18 @@ public void shutdown(){ public void submit(Consumer context) { RequestTransaction transaction = startRequest(); context.accept(transaction); - // this.submit(transaction); } void submit(RequestTransaction handle) { assert handle.operation != null; - // Add this Request with this handle i the Worklog - // Put Transaction into Worklog + // Add this Request with this handle i the work-log + // Put Transaction into work-log workLog.add(handle); - // Try to Process the Worklog - processWorklog(); + // Try to Process the work-log + processWorkLog(); } - private void processWorklog() { + private void processWorkLog() { while (runningRequests.size() < getNumberOfConcurrentRequests() && !workLog.isEmpty()) { RequestTransaction next = workLog.poll(); if (next != null) { @@ -125,7 +123,6 @@ private void processWorklog() { } } - public RequestTransaction startRequest() { return new RequestTransaction(this, transactionId.getAndIncrement()); } @@ -146,8 +143,8 @@ private void endRequest(RequestTransaction transaction) { throw new IllegalArgumentException("Unknown Transaction or Transaction already finished!"); } runningRequests.remove(transaction); - // Process the worklog, a slot should be free now - processWorklog(); + // Process the work-log, a slot should be free now + processWorkLog(); } public static class RequestTransaction { @@ -155,7 +152,7 @@ public static class RequestTransaction { private final RequestTransactionManager parent; private final int transactionId; - /** The iniital operation to perform to kick off the request */ + /** The initial operation to perform to kick off the request */ private Runnable operation; private Future completionFuture; diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/DefaultPlcValueHandler.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/DefaultPlcValueHandler.java new file mode 100644 index 00000000000..1cd73fdbc63 --- /dev/null +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/DefaultPlcValueHandler.java @@ -0,0 +1,275 @@ +/* + * 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. + */ +package org.apache.plc4x.java.spi.values; + +import org.apache.commons.lang3.NotImplementedException; +import org.apache.plc4x.java.api.exceptions.PlcRuntimeException; +import org.apache.plc4x.java.api.exceptions.PlcUnsupportedDataTypeException; +import org.apache.plc4x.java.api.model.ArrayInfo; +import org.apache.plc4x.java.api.model.PlcTag; +import org.apache.plc4x.java.api.types.PlcValueType; +import org.apache.plc4x.java.api.value.PlcValue; + +import java.math.BigInteger; +import java.time.Duration; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class DefaultPlcValueHandler implements PlcValueHandler { + + @Override + public PlcValue newPlcValue(PlcTag tag, Object value) { + return of(tag, new Object[]{value}); + } + + @Override + public PlcValue newPlcValue(PlcTag tag, Object[] values) { + return of(tag, values); + } + + public static PlcValue of(PlcTag tag, Object value) { + return of(tag, new Object[]{value}); + } + + public static PlcValue of(PlcTag tag, Object[] values) { + if(tag.getArrayInfo().isEmpty()) { + // If this is not an array type, but the input is passed in as List, if it's just one element, + // treat this single element as "value". + if (values.length == 0) { + throw new PlcRuntimeException("No value was passed in as argument"); + } + if (values.length == 1) { + // If only one element was passed hin, however this is a Collection and contains more than one element, + // this is also invalid. + if(values[0] instanceof Collection) { + if(((Collection) values[0]).size() > 1) { + throw new PlcRuntimeException("The type is not an array type, but a collection of more than one item was passed in as argument"); + } else if(((Collection) values[0]).isEmpty()) { + throw new PlcRuntimeException("An empty collection was passed in as argument"); + } + } + return ofElement(tag.getPlcValueType(), values[0]); + } + // + else { + throw new PlcRuntimeException("The type is not an array type, but more than one value was passed in as argument"); + } + } + // In all other cases, we're dealing with an array type and this needs to be handled separately. + else { + return ofElements(tag.getPlcValueType(), tag.getArrayInfo(), values); + } + } + + private static PlcValue ofElements(PlcValueType type, List arrayInfos, Object[] values) { + ArrayInfo arrayInfo = arrayInfos.get(0); + + if(values.length == 1) { + if(values[0] instanceof Object[]) { + values = (Object[]) values[0]; + } else if (values[0] instanceof Collection) { + values = ((Collection) values[0]).toArray(); + } else if(values[0] instanceof PlcList) { + values = ((PlcList) values[0]).getList().toArray(); + } else if(values[0] instanceof PlcRawByteArray) { + PlcRawByteArray plcRawByteArray = (PlcRawByteArray) values[0]; + if(plcRawByteArray.getRaw().length != arrayInfo.getSize()) { + throw new PlcRuntimeException(String.format("Expecting %d items, but got %d", arrayInfo.getSize(), plcRawByteArray.getRaw().length)); + } + return plcRawByteArray; + } + } + + List plcValues = new ArrayList<>(arrayInfo.getSize()); + // In the last layer we'll create a list of PlcValues + if(arrayInfos.size() == 1) { + if(values.length != arrayInfo.getSize()) { + throw new PlcRuntimeException(String.format("Expecting %d items, but got %d", arrayInfo.getSize(), values.length)); + } + // TODO: Add some size-checks here ... + for (Object value : values) { + plcValues.add(ofElement(type, value)); + } + } + // In intermediate layers we'll add a list of PlcLists + else { + // TODO: Add some size-checks here ... + for (Object value : values) { + plcValues.add(ofElements(type, arrayInfos.subList(1, arrayInfos.size()), (Object[]) value)); + } + } + return new PlcList(plcValues); + } + + private static PlcValue ofElement(PlcValueType type, Object value) { + // This is a temporary hack for drivers that don't have type information in their tags (ADS) + if(type == null) { + return of(value); + } + switch (type) { + case BOOL: + return PlcBOOL.of(value); + case BYTE: + return PlcBYTE.of(value); + case SINT: + return PlcSINT.of(value); + case USINT: + return PlcUSINT.of(value); + case INT: + return PlcINT.of(value); + case UINT: + return PlcUINT.of(value); + case WORD: + return PlcWORD.of(value); + case DINT: + return PlcDINT.of(value); + case UDINT: + return PlcUDINT.of(value); + case DWORD: + return PlcDWORD.of(value); + case LINT: + return PlcLINT.of(value); + case ULINT: + return PlcULINT.of(value); + case LWORD: + return PlcLWORD.of(value); + case REAL: + return PlcREAL.of(value); + case LREAL: + return PlcLREAL.of(value); + case CHAR: + return PlcCHAR.of(value); + case WCHAR: + return PlcWCHAR.of(value); + case STRING: + return PlcSTRING.of(value); + case WSTRING: + return PlcWSTRING.of(value); + case TIME: + return PlcTIME.of(value); + case LTIME: + return PlcLTIME.of(value); + case DATE: + return PlcDATE.of(value); + case LDATE: + return PlcLDATE.of(value); + case TIME_OF_DAY: + return PlcTIME_OF_DAY.of(value); + case LTIME_OF_DAY: + return PlcLTIME_OF_DAY.of(value); + case DATE_AND_TIME: + return PlcDATE_AND_TIME.of(value); + case DATE_AND_LTIME: + return PlcDATE_AND_LTIME.of(value); + case LDATE_AND_TIME: + return PlcLDATE_AND_TIME.of(value); + case RAW_BYTE_ARRAY: + return PlcRawByteArray.of(value); + case List: + // TODO: A tag type LIST actually doesn't make any sense ... + // if it's an array, the array information is provided anyway. So I think we should most + // probably remove this type from the PlcValueType enumeration. + throw new NotImplementedException("Not implemented yet"); + case Struct: + // TODO: It is pretty much impossible to interpret a java object as struct. + // We probably shouldn't even try to do so. It might be an interesting option, if we defined + // annotations that could be added to Java types what allow the conversion to PlcStruct types + // but right now here is nothing we can do. + throw new NotImplementedException("Not implemented yet"); + case NULL: + return new PlcNull(); + default: + throw new PlcUnsupportedDataTypeException("Data Type " + value.getClass() + + " Is not supported"); + } + } + + /** + * This is a legacy helper that should help with protocols, that currently don't have PlcValueType information + * available at the request-building-time. Such as the ADS driver. We should remove this option as soon as all + * drivers are fully PlcValueType-aware. + * @param value value + * @return PlcValue for the given type + */ + private static PlcValue of(Object value) { + /*if (values.length != 1) { + PlcList list = new PlcList(); + for (Object value : values) { + list.add(of(new Object[]{value})); + } + return list; + } + Object value = values[0];*/ + if (value instanceof Boolean) { + return PlcBOOL.of(value); + } + if (value instanceof Byte) { + return PlcSINT.of(value); + } + if (value instanceof byte[]) { + return PlcRawByteArray.of(value); + } + if (value instanceof Short) { + return PlcINT.of(value); + } + if (value instanceof Integer) { + return PlcDINT.of(value); + } + if (value instanceof Long) { + return PlcLINT.of(value); + } + if (value instanceof BigInteger) { + return PlcLINT.of(value); + } + if (value instanceof Float) { + return PlcREAL.of(value); + } + if (value instanceof Double) { + return PlcLREAL.of(value); + } + if (value instanceof Duration) { + return new PlcTIME((Duration) value); + } + if (value instanceof LocalTime) { + return new PlcTIME_OF_DAY((LocalTime) value); + } + if (value instanceof LocalDate) { + return new PlcDATE((LocalDate) value); + } + if (value instanceof LocalDateTime) { + return new PlcDATE_AND_TIME((LocalDateTime) value); + } + if (value instanceof String) { + return new PlcSTRING((String) value); + } + if (value instanceof PlcValue) { + return (PlcValue) value; + } + throw new PlcUnsupportedDataTypeException("Data Type " + value.getClass() + + " Is not supported"); + } + +/* public static PlcValue customDataType(Object[] values) { + return of(values); + }*/ +} diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/LegacyPlcValueHandler.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/LegacyPlcValueHandler.java new file mode 100644 index 00000000000..0343bc4434d --- /dev/null +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/LegacyPlcValueHandler.java @@ -0,0 +1,264 @@ +/* + * 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 org.apache.plc4x.java.spi.values; + +import org.apache.plc4x.java.api.exceptions.PlcRuntimeException; +import org.apache.plc4x.java.api.exceptions.PlcUnsupportedDataTypeException; +import org.apache.plc4x.java.api.model.PlcTag; +import org.apache.plc4x.java.api.value.PlcValue; + +import java.math.BigInteger; +import java.time.Duration; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.List; + +public class LegacyPlcValueHandler implements PlcValueHandler { + + public PlcValue newPlcValue(Object value) { + return of(new Object[]{value}); + } + + public PlcValue newPlcValue(Object[] values) { + return of(values); + } + + public PlcValue newPlcValue(PlcTag tag, Object value) { + return of(tag, new Object[]{value}); + } + + public PlcValue newPlcValue(PlcTag tag, Object[] values) { + return of(tag, values); + } + + public static PlcValue of(Object value) { + return of(new Object[]{value}); + } + + public static PlcValue of(List value) { + return of(value.toArray()); + } + + public static PlcValue of(Object[] values) { + if (values.length != 1) { + PlcList list = new PlcList(); + for (Object value : values) { + list.add(of(new Object[]{value})); + } + return list; + } + Object value = values[0]; + if (value instanceof Boolean) { + return PlcBOOL.of(value); + } + if (value instanceof Byte) { + return PlcSINT.of(value); + } + if (value instanceof byte[]) { + return PlcRawByteArray.of(value); + } + if (value instanceof Short) { + return PlcINT.of(value); + } + if (value instanceof Integer) { + return PlcDINT.of(value); + } + if (value instanceof Long) { + return PlcLINT.of(value); + } + if (value instanceof BigInteger) { + return PlcLINT.of(value); + } + if (value instanceof Float) { + return PlcREAL.of(value); + } + if (value instanceof Double) { + return PlcLREAL.of(value); + } + if (value instanceof Duration) { + return new PlcTIME((Duration) value); + } + if (value instanceof LocalTime) { + return new PlcTIME_OF_DAY((LocalTime) value); + } + if (value instanceof LocalDate) { + return new PlcDATE((LocalDate) value); + } + if (value instanceof LocalDateTime) { + return new PlcDATE_AND_TIME((LocalDateTime) value); + } + if (value instanceof String) { + return new PlcSTRING((String) value); + } + if (value instanceof PlcValue) { + return (PlcValue) value; + } + throw new PlcUnsupportedDataTypeException("Data Type " + value.getClass() + + " Is not supported"); + } + + + public static PlcValue of(PlcTag tag, Object value) { + return of(tag, new Object[]{value}); + } + + + public static PlcValue of(PlcTag tag, Object[] values) { + if (values.length == 1) { + Object value = values[0]; + if(tag.getPlcValueType() == null) { + // TODO: This is a hacky shortcut .. + if(value instanceof PlcValue) { + return (PlcValue) value; + } + return new PlcNull(); + } + if (value instanceof PlcValue) { + PlcValue plcValue = (PlcValue) value; + if (plcValue.getPlcValueType() == tag.getPlcValueType()) { + return (PlcValue) value; + } else { + throw new PlcRuntimeException("Expected PlcValue of type " + tag.getPlcValueType().name() + " but got " + plcValue.getPlcValueType().name()); + } + } + switch (tag.getPlcValueType()) { + case BOOL: + return PlcBOOL.of(value); + case BYTE: + if(value instanceof Short) { + return new PlcBYTE((short) value); + } else if(value instanceof Integer) { + return new PlcBYTE(((Integer) value).shortValue()); + } else if(value instanceof Long) { + return new PlcBYTE(((Long) value).shortValue()); + } else if(value instanceof BigInteger) { + return new PlcBYTE(((BigInteger) value).shortValue()); + } else if(value instanceof String) { + try { + return new PlcBYTE(Short.valueOf((String) value)); + } catch (NumberFormatException e) { + throw new PlcRuntimeException("Value of " + value + " not parseable as Byte"); + } + } + throw new PlcRuntimeException("BYTE requires short"); + case SINT: + return PlcSINT.of(value); + case USINT: + return PlcUSINT.of(value); + case INT: + return PlcINT.of(value); + case UINT: + return PlcUINT.of(value); + case WORD: + if(value instanceof Short) { + return new PlcWORD((int) value); + } else if(value instanceof Integer) { + return new PlcWORD((int) value); + } else if(value instanceof Long) { + return new PlcWORD(((Long) value).intValue()); + } else if(value instanceof BigInteger) { + return new PlcWORD(((BigInteger) value).intValue()); + } else if(value instanceof String) { + try { + return new PlcWORD(Integer.valueOf((String) value)); + } catch (NumberFormatException e) { + throw new PlcRuntimeException("Value of " + value + " not parseable as Integer"); + } + } + throw new PlcRuntimeException("WORD requires int"); + case DINT: + return PlcDINT.of(value); + case UDINT: + return PlcUDINT.of(value); + case DWORD: + if(value instanceof Short) { + return new PlcDWORD((long) value); + } else if(value instanceof Integer) { + return new PlcDWORD((long) value); + } else if(value instanceof Long) { + return new PlcDWORD((long) value); + } else if(value instanceof BigInteger) { + return new PlcDWORD(((BigInteger) value).longValue()); + } else if(value instanceof String) { + try { + return new PlcDWORD(Long.valueOf((String) value)); + } catch (NumberFormatException e) { + throw new PlcRuntimeException("Value of " + value + " not parseable as Long"); + } + } + throw new PlcRuntimeException("DWORD requires long"); + case LINT: + return PlcLINT.of(value); + case ULINT: + return PlcULINT.of(value); + case LWORD: + if(value instanceof Short) { + return new PlcLWORD(BigInteger.valueOf((long) value)); + } else if(value instanceof Integer) { + return new PlcLWORD(BigInteger.valueOf((long) value)); + } else if(value instanceof Long) { + return new PlcLWORD(BigInteger.valueOf((long) value)); + } else if(value instanceof BigInteger) { + return new PlcLWORD((BigInteger) value); + } else if(value instanceof String) { + try { + return new PlcLWORD(new BigInteger((String) value)); + } catch (NumberFormatException e) { + throw new PlcRuntimeException("Value of " + value + " not parseable as BigInteger"); + } + } + throw new PlcRuntimeException("LWORD requires BigInteger"); + case REAL: + return PlcREAL.of(value); + case LREAL: + return PlcLREAL.of(value); + case CHAR: + return PlcCHAR.of(value); + case WCHAR: + return PlcWCHAR.of(value); + case STRING: + return PlcSTRING.of(value); + case WSTRING: + return PlcWSTRING.of(value); + case TIME: + return PlcTIME.of(value); + case DATE: + return PlcDATE.of(value); + case TIME_OF_DAY: + return PlcTIME_OF_DAY.of(value); + case DATE_AND_TIME: + return PlcDATE_AND_TIME.of(value); + default: + return customDataType(new Object[]{value}); + } + } else { + PlcList list = new PlcList(); + for (Object value : values) { + list.add(of(tag, new Object[]{value})); + } + return list; + } + } + + public static PlcValue customDataType(Object[] values) { + return of(values); + } +} diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcBINT.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcBINT.java deleted file mode 100644 index e3295121f89..00000000000 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcBINT.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * 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. - */ -package org.apache.plc4x.java.spi.values; - -import org.apache.plc4x.java.api.types.PlcValueType; -import org.apache.plc4x.java.spi.generation.SerializationException; -import org.apache.plc4x.java.spi.generation.WriteBuffer; - -import java.math.BigDecimal; -import java.math.BigInteger; - -public class PlcBINT extends PlcIECValue { - - public static PlcBINT of(Object value) { - if (value instanceof Boolean) { - return new PlcBINT((Boolean) value); - } else if (value instanceof Byte) { - return new PlcBINT((Byte) value); - } else if (value instanceof Short) { - return new PlcBINT((Short) value); - } else if (value instanceof Integer) { - return new PlcBINT((Integer) value); - } else if (value instanceof Long) { - return new PlcBINT((Long) value); - } else if (value instanceof Float) { - return new PlcBINT((Float) value); - } else if (value instanceof Double) { - return new PlcBINT((Double) value); - } else if (value instanceof BigInteger) { - return new PlcBINT((BigInteger) value); - } else if (value instanceof BigDecimal) { - return new PlcBINT((BigDecimal) value); - } else { - return new PlcBINT((String) value); - } - } - - public PlcBINT(Boolean value) { - this.value = value ? BigInteger.valueOf(1) : BigInteger.valueOf(0); - this.isNullable = false; - } - - public PlcBINT(Byte value) { - this.value = BigInteger.valueOf(value); - this.isNullable = false; - } - - public PlcBINT(Short value) { - this.value = BigInteger.valueOf(value); - this.isNullable = false; - } - - public PlcBINT(Integer value) { - this.value = BigInteger.valueOf(value); - this.isNullable = false; - } - - public PlcBINT(Long value) { - this.value = BigInteger.valueOf(value); - this.isNullable = false; - } - - public PlcBINT(Float value) { - this.value = BigDecimal.valueOf(value).toBigInteger(); - this.isNullable = false; - } - - public PlcBINT(Double value) { - this.value = BigDecimal.valueOf(value).toBigInteger(); - this.isNullable = false; - } - - public PlcBINT(BigInteger value) { - this.value = value; - this.isNullable = false; - } - - public PlcBINT(BigDecimal value) { - this.value = value.toBigInteger(); - this.isNullable = false; - } - - public PlcBINT(String value) { - this.value = new BigInteger(value.trim()); - this.isNullable = false; - } - - @Override - public PlcValueType getPlcValueType() { - return PlcValueType.ULINT; - } - - @Override - public boolean isBoolean() { - return true; - } - - @Override - public boolean getBoolean() { - return (value != null) && !value.equals(BigInteger.ZERO); - } - - @Override - public boolean isByte() { - return (value != null) && (value.compareTo(BigInteger.valueOf(Byte.MAX_VALUE)) <= 0) && (value.compareTo(BigInteger.valueOf(Byte.MIN_VALUE)) >= 0); - } - - @Override - public byte getByte() { - return value.byteValue(); - } - - @Override - public boolean isShort() { - return (value != null) && (value.compareTo(BigInteger.valueOf(Short.MAX_VALUE)) <= 0) && (value.compareTo(BigInteger.valueOf(Short.MIN_VALUE)) >= 0); - } - - @Override - public short getShort() { - return value.shortValue(); - } - - @Override - public boolean isInteger() { - return (value != null) && (value.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) <= 0) && (value.compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) >= 0); - } - - @Override - public int getInteger() { - return value.intValue(); - } - - @Override - public boolean isLong() { - return (value != null) && (value.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) <= 0) && (value.compareTo(BigInteger.valueOf(Long.MIN_VALUE)) >= 0); - } - - @Override - public long getLong() { - return value.longValue(); - } - - @Override - public boolean isBigInteger() { - return true; - } - - @Override - public BigInteger getBigInteger() { - return value; - } - - @Override - public boolean isFloat() { - return true; - } - - @Override - public float getFloat() { - return value.floatValue(); - } - - @Override - public boolean isDouble() { - return true; - } - - @Override - public double getDouble() { - return value.doubleValue(); - } - - @Override - public boolean isBigDecimal() { - return true; - } - - @Override - public BigDecimal getBigDecimal() { - return new BigDecimal(value); - } - - @Override - public boolean isString() { - return true; - } - - @Override - public String getString() { - return toString(); - } - - @Override - public String toString() { - return value.toString(); - } - - @Override - public byte[] getRaw() { - return getBytes(); - } - - public byte[] getBytes() { - byte[] tmp = value.toByteArray(); - byte[] bytes = new byte[8]; - for (int i = 0; i < bytes.length; i++) { - if (i >= (bytes.length - tmp.length)) { - bytes[i] = tmp[i - (bytes.length - tmp.length)]; - } else { - bytes[i] = 0x00; - } - } - return bytes; - } - - @Override - public void serialize(WriteBuffer writeBuffer) throws SerializationException { - writeBuffer.writeBigInteger(getClass().getSimpleName(), 64, value); - } - -} diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcBOOL.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcBOOL.java index 229c805de94..a6dbada59a1 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcBOOL.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcBOOL.java @@ -28,12 +28,12 @@ public class PlcBOOL extends PlcIECValue { - private static final String VALUE_OUT_OF_RANGE = "Value of type %s is out of range %d - %d for a %s Value"; - static final int minValue = 0; - static final int maxValue = 1; + private static final String VALUE_OUT_OF_RANGE = "Value of is required for a %s Value"; public static PlcBOOL of(Object value) { - if (value instanceof Boolean) { + if (value instanceof PlcBOOL) { + return (PlcBOOL) value; + } else if (value instanceof Boolean) { return new PlcBOOL((Boolean) value); } else if (value instanceof Byte) { return new PlcBOOL((Byte) value); @@ -52,7 +52,7 @@ public static PlcBOOL of(Object value) { } else if (value instanceof BigDecimal) { return new PlcBOOL((BigDecimal) value); } else { - return new PlcBOOL((String) value); + return new PlcBOOL(value.toString()); } } @@ -62,66 +62,66 @@ public PlcBOOL(Boolean value) { } public PlcBOOL(Byte value) { - if ((value == null) || (value < minValue || value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if (value == null) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, this.getClass().getSimpleName())); } - this.value = value >= 1; + this.value = value != 0; this.isNullable = true; } public PlcBOOL(Short value) { - if ((value == null) || (value < minValue || value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if (value == null) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, this.getClass().getSimpleName())); } - this.value = value >= 1; + this.value = value != 0; this.isNullable = true; } public PlcBOOL(Integer value) { - if ((value == null) || (value < minValue || value > maxValue)) { - throw new PlcInvalidTagException(String.format("Value of type %d is out of range %d - %d for a %s Value", value, minValue, maxValue, this.getClass().getSimpleName())); + if (value == null) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, this.getClass().getSimpleName())); } - this.value = value >= 1; + this.value = value != 0; this.isNullable = true; } public PlcBOOL(Long value) { - if ((value == null) || (value < minValue || value > maxValue)) { - throw new PlcInvalidTagException(String.format("Value of type %d is out of range %d - %d for a %s Value", value, minValue, maxValue, this.getClass().getSimpleName())); + if (value == null) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, this.getClass().getSimpleName())); } - this.value = value >= 1; + this.value = value != 0; this.isNullable = true; } public PlcBOOL(Float value) { - if ((value == null) || (value < minValue) || (value > maxValue) || (value % 1 != 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if (value == null) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, this.getClass().getSimpleName())); } - this.value = value >= 1; + this.value = value != 0.0; this.isNullable = true; } public PlcBOOL(Double value) { - if ((value == null) || (value < minValue) || (value > maxValue) || (value % 1 != 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if (value == null) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, this.getClass().getSimpleName())); } - this.value = value >= 1; + this.value = value != 0.0d; this.isNullable = true; } public PlcBOOL(BigInteger value) { - if ((value == null) || (value.compareTo(BigInteger.valueOf(minValue)) < 0) || (value.compareTo(BigInteger.valueOf(maxValue)) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if (value == null) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, this.getClass().getSimpleName())); } - this.value = value.compareTo(BigInteger.valueOf(maxValue)) >= 0; + this.value = value.compareTo(BigInteger.ZERO) != 0; this.isNullable = true; } public PlcBOOL(BigDecimal value) { - if ((value == null) || (value.compareTo(BigDecimal.valueOf(minValue)) < 0) || (value.compareTo(BigDecimal.valueOf(maxValue)) > 0) || (value.scale() > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if (value == null) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, this.getClass().getSimpleName())); } - this.value = value.compareTo(BigDecimal.valueOf(maxValue)) >= 0; + this.value = value.compareTo(BigDecimal.ZERO) != 0; this.isNullable = true; } @@ -130,7 +130,7 @@ public PlcBOOL(String value) { this.value = parseValue(value); this.isNullable = false; } catch (RuntimeException e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName()), e); + throw new PlcInvalidTagException(String.format("Value %s could not be parsed to %s Value", value, this.getClass().getSimpleName()), e); } } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcBREAL.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcBREAL.java deleted file mode 100644 index 6f73a709e6c..00000000000 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcBREAL.java +++ /dev/null @@ -1,238 +0,0 @@ -/* - * 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. - */ -package org.apache.plc4x.java.spi.values; - -import org.apache.plc4x.java.api.types.PlcValueType; -import org.apache.plc4x.java.spi.generation.SerializationException; -import org.apache.plc4x.java.spi.generation.WriteBuffer; - -import java.math.BigDecimal; -import java.math.BigInteger; - -public class PlcBREAL extends PlcIECValue { - - public static PlcBREAL of(Object value) { - if (value instanceof Boolean) { - return new PlcBREAL((Boolean) value); - } else if (value instanceof Byte) { - return new PlcBREAL((Byte) value); - } else if (value instanceof Short) { - return new PlcBREAL((Short) value); - } else if (value instanceof Integer) { - return new PlcBREAL((Integer) value); - } else if (value instanceof Long) { - return new PlcBREAL((Long) value); - } else if (value instanceof Float) { - return new PlcBREAL((Float) value); - } else if (value instanceof Double) { - return new PlcBREAL((Double) value); - } else if (value instanceof BigInteger) { - return new PlcBREAL((BigInteger) value); - } else if (value instanceof BigDecimal) { - return new PlcBREAL((BigDecimal) value); - } else { - return new PlcBREAL((String) value); - } - } - - public PlcBREAL(Boolean value) { - this.value = value ? BigDecimal.valueOf(1) : BigDecimal.valueOf(0); - this.isNullable = false; - } - - public PlcBREAL(Byte value) { - this.value = BigDecimal.valueOf(value); - this.isNullable = false; - } - - public PlcBREAL(Short value) { - this.value = BigDecimal.valueOf(value); - this.isNullable = false; - } - - public PlcBREAL(Integer value) { - this.value = BigDecimal.valueOf(value); - this.isNullable = false; - } - - public PlcBREAL(Long value) { - this.value = BigDecimal.valueOf(value); - this.isNullable = false; - } - - public PlcBREAL(Float value) { - this.value = BigDecimal.valueOf(value); - this.isNullable = false; - } - - public PlcBREAL(Double value) { - this.value = BigDecimal.valueOf(value); - this.isNullable = false; - } - - public PlcBREAL(BigInteger value) { - this.value = new BigDecimal(value); - this.isNullable = false; - } - - public PlcBREAL(BigDecimal value) { - this.value = value; - this.isNullable = false; - } - - public PlcBREAL(String value) { - this.value = new BigDecimal(value.trim()); - this.isNullable = false; - } - - @Override - public PlcValueType getPlcValueType() { - return PlcValueType.ULINT; - } - - @Override - public boolean isBoolean() { - return true; - } - - @Override - public boolean getBoolean() { - return (value != null) && !value.equals(BigDecimal.ZERO); - } - - @Override - public boolean isByte() { - return (value != null) && (value.compareTo(BigDecimal.valueOf(Byte.MAX_VALUE)) <= 0) && (value.compareTo(BigDecimal.valueOf(Byte.MIN_VALUE)) >= 0); - } - - @Override - public byte getByte() { - return value.byteValue(); - } - - @Override - public boolean isShort() { - return (value != null) && (value.compareTo(BigDecimal.valueOf(Short.MAX_VALUE)) <= 0) && (value.compareTo(BigDecimal.valueOf(Short.MIN_VALUE)) >= 0); - } - - @Override - public short getShort() { - return value.shortValue(); - } - - @Override - public boolean isInteger() { - return (value != null) && (value.compareTo(BigDecimal.valueOf(Integer.MAX_VALUE)) <= 0) && (value.compareTo(BigDecimal.valueOf(Integer.MIN_VALUE)) >= 0); - } - - @Override - public int getInteger() { - return value.intValue(); - } - - @Override - public boolean isLong() { - return (value != null) && (value.compareTo(BigDecimal.valueOf(Long.MAX_VALUE)) <= 0) && (value.compareTo(BigDecimal.valueOf(Long.MIN_VALUE)) >= 0); - } - - @Override - public long getLong() { - return value.longValue(); - } - - @Override - public boolean isBigInteger() { - return true; - } - - @Override - public BigInteger getBigInteger() { - return value.toBigInteger(); - } - - @Override - public boolean isFloat() { - return true; - } - - @Override - public float getFloat() { - return value.floatValue(); - } - - @Override - public boolean isDouble() { - return true; - } - - @Override - public double getDouble() { - return value.doubleValue(); - } - - @Override - public boolean isBigDecimal() { - return true; - } - - @Override - public BigDecimal getBigDecimal() { - return value; - } - - @Override - public boolean isString() { - return true; - } - - @Override - public String getString() { - return toString(); - } - - @Override - public String toString() { - return value.toString(); - } - - @Override - public byte[] getRaw() { - return getBytes(); - } - - public byte[] getBytes() { - // TODO: Not sure if this is correct ... - byte[] tmp = value.unscaledValue().toByteArray(); - byte[] bytes = new byte[8]; - for (int i = 0; i < bytes.length; i++) { - if (i >= (bytes.length - tmp.length)) { - bytes[i] = tmp[i - (bytes.length - tmp.length)]; - } else { - bytes[i] = 0x00; - } - } - return bytes; - } - - @Override - public void serialize(WriteBuffer writeBuffer) throws SerializationException { - writeBuffer.writeBigDecimal(getClass().getSimpleName(), 64, value); - } - -} diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcBYTE.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcBYTE.java index 72370dee5a0..e481c560eea 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcBYTE.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcBYTE.java @@ -30,11 +30,13 @@ public class PlcBYTE extends PlcIECValue { private static final String VALUE_OUT_OF_RANGE = "Value of type %s is out of range %d - %d for a %s Value"; - static final Short minValue = 0; - static final Short maxValue = (short) Byte.MAX_VALUE * 2 + 1; + public static final Short MIN_VALUE = 0; + public static final Short MAX_VALUE = (short) Byte.MAX_VALUE * 2 + 1; public static PlcBYTE of(Object value) { - if (value instanceof Boolean) { + if (value instanceof PlcBYTE) { + return (PlcBYTE) value; + } else if (value instanceof Boolean) { return new PlcBYTE((Boolean) value); } else if (value instanceof Byte) { return new PlcBYTE((Byte) value); @@ -53,7 +55,7 @@ public static PlcBYTE of(Object value) { } else if (value instanceof BigDecimal) { return new PlcBYTE((BigDecimal) value); } else { - return new PlcBYTE((String) value); + return new PlcBYTE(value.toString()); } } @@ -64,64 +66,64 @@ public PlcBYTE(Boolean value) { } public PlcBYTE(Byte value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.shortValue(); this.isNullable = false; } public PlcBYTE(Short value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value; this.isNullable = false; } public PlcBYTE(Integer value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.shortValue(); this.isNullable = false; } public PlcBYTE(Long value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.shortValue(); this.isNullable = false; } public PlcBYTE(Float value) { - if ((value < minValue) || (value > maxValue) || (value % 1 != 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.shortValue(); this.isNullable = false; } public PlcBYTE(Double value) { - if ((value < minValue) || (value > maxValue) || (value % 1 != 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.shortValue(); this.isNullable = false; } public PlcBYTE(BigInteger value) { - if ((value.compareTo(BigInteger.valueOf(minValue)) < 0) || (value.compareTo(BigInteger.valueOf(maxValue)) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value.compareTo(BigInteger.valueOf(MIN_VALUE)) < 0) || (value.compareTo(BigInteger.valueOf(MAX_VALUE)) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.shortValue(); this.isNullable = true; } public PlcBYTE(BigDecimal value) { - if ((value.compareTo(BigDecimal.valueOf(minValue)) < 0) || (value.compareTo(BigDecimal.valueOf(maxValue)) > 0) || (value.scale() > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value.compareTo(BigDecimal.valueOf(MIN_VALUE)) < 0) || (value.compareTo(BigDecimal.valueOf(MAX_VALUE)) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.shortValue(); this.isNullable = true; @@ -130,19 +132,19 @@ public PlcBYTE(BigDecimal value) { public PlcBYTE(String value) { try { short val = Short.parseShort(value.trim()); - if ((val < minValue) || (val > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((val < MIN_VALUE) || (val > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = val; this.isNullable = false; } catch (Exception e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } } public PlcBYTE(short value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value; this.isNullable = false; diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcCHAR.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcCHAR.java index f6e7389215a..d32e8f8f84e 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcCHAR.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcCHAR.java @@ -31,11 +31,13 @@ public class PlcCHAR extends PlcIECValue { private static final String VALUE_OUT_OF_RANGE = "Value of type %s is out of range %d - %d for a %s Value"; - static final Short minValue = 0; - static final Short maxValue = (short) Byte.MAX_VALUE * 2 + 1; + public static final Short MIN_VALUE = 0; + public static final Short MAX_VALUE = (short) Byte.MAX_VALUE * 2 + 1; public static PlcCHAR of(Object value) { - if (value instanceof Boolean) { + if (value instanceof PlcCHAR) { + return (PlcCHAR) value; + } else if (value instanceof Boolean) { return new PlcCHAR((Boolean) value); } else if (value instanceof Byte) { return new PlcCHAR((Byte) value); @@ -56,104 +58,104 @@ public static PlcCHAR of(Object value) { } else if(value instanceof Character){ return new PlcCHAR((Character) value); }else { - return new PlcCHAR((String) value); + return new PlcCHAR(value.toString()); } } public PlcCHAR(Boolean value) { super(); - this.value = value ? Short.valueOf((short) 1) : Short.valueOf((short) 0); + this.value = value ? (short) 'T' : (short) 'F'; this.isNullable = false; } public PlcCHAR(Character value) { super(); Integer val = (int) value; - if ((val >= minValue) && (val <= maxValue)) { + if ((val >= MIN_VALUE) && (val <= MAX_VALUE)) { this.value = val.shortValue(); this.isNullable = false; } else { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } } public PlcCHAR(Byte value) { super(); - if ((value >= minValue) && (value <= maxValue)) { + if ((value >= MIN_VALUE) && (value <= MAX_VALUE)) { this.value = value.shortValue(); this.isNullable = false; } else { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } } public PlcCHAR(Short value) { super(); - if ((value >= minValue) && (value <= maxValue)) { + if ((value >= MIN_VALUE) && (value <= MAX_VALUE)) { this.value = value; this.isNullable = false; } else { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } } public PlcCHAR(Integer value) { super(); - if ((value >= minValue) && (value <= maxValue)) { + if ((value >= MIN_VALUE) && (value <= MAX_VALUE)) { this.value = value.shortValue(); this.isNullable = false; } else { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } } public PlcCHAR(Long value) { super(); - if ((value >= minValue) && (value <= maxValue)) { + if ((value >= MIN_VALUE) && (value <= MAX_VALUE)) { this.value = value.shortValue(); this.isNullable = false; } else { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } } public PlcCHAR(Float value) { super(); - if ((value >= minValue) && (value <= maxValue) && (value % 1 == 0)) { + if ((value >= MIN_VALUE) && (value <= MAX_VALUE)) { this.value = value.shortValue(); this.isNullable = false; } else { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } } public PlcCHAR(Double value) { super(); - if ((value >= minValue) && (value <= maxValue) && (value % 1 == 0)) { + if ((value >= MIN_VALUE) && (value <= MAX_VALUE)) { this.value = value.shortValue(); this.isNullable = false; } else { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } } public PlcCHAR(BigInteger value) { super(); - if ((value.compareTo(BigInteger.valueOf(minValue)) >= 0) && (value.compareTo(BigInteger.valueOf(maxValue)) <= 0)) { + if ((value.compareTo(BigInteger.valueOf(MIN_VALUE)) >= 0) && (value.compareTo(BigInteger.valueOf(MAX_VALUE)) <= 0)) { this.value = value.shortValue(); this.isNullable = true; } else { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } } public PlcCHAR(BigDecimal value) { super(); - if ((value.compareTo(BigDecimal.valueOf(minValue)) >= 0) && (value.compareTo(BigDecimal.valueOf(maxValue)) <= 0) && (value.scale() <= 0)) { + if ((value.compareTo(BigDecimal.valueOf(MIN_VALUE)) >= 0) && (value.compareTo(BigDecimal.valueOf(MAX_VALUE)) <= 0) && (value.scale() <= 0)) { this.value = value.shortValue(); this.isNullable = true; } else { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } } @@ -166,24 +168,24 @@ public PlcCHAR(String value) { s = " "; } short val = (short) s.charAt(0); - if ((val >= minValue) && (val <= maxValue)) { + if ((val >= MIN_VALUE) && (val <= MAX_VALUE)) { this.value = val; this.isNullable = false; } else { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } } catch (Exception e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } } public PlcCHAR(short value) { super(); - if ((value >= minValue) && (value <= maxValue)) { + if ((value >= MIN_VALUE) && (value <= MAX_VALUE)) { this.value = value; this.isNullable = false; } else { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcDATE.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcDATE.java index 4b691db3750..50904a35553 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcDATE.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcDATE.java @@ -18,25 +18,46 @@ */ package org.apache.plc4x.java.spi.values; -import org.apache.plc4x.java.api.exceptions.PlcRuntimeException; import org.apache.plc4x.java.api.types.PlcValueType; import org.apache.plc4x.java.spi.codegen.WithOption; import org.apache.plc4x.java.spi.generation.SerializationException; import org.apache.plc4x.java.spi.generation.WriteBuffer; +import java.math.BigDecimal; +import java.math.BigInteger; import java.nio.charset.StandardCharsets; -import java.time.*; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; -public class PlcDATE extends PlcSimpleValue { +public class PlcDATE extends PlcIECValue { public static PlcDATE of(Object value) { - if (value instanceof LocalDate) { + if (value instanceof PlcDATE) { + return (PlcDATE) value; + } else if (value instanceof LocalDate) { return new PlcDATE((LocalDate) value); + } else if (value instanceof Byte) { + return new PlcDATE((Byte) value); + } else if (value instanceof Short) { + return new PlcDATE((Short) value); + } else if (value instanceof Integer) { + return new PlcDATE((Integer) value); } else if (value instanceof Long) { - return new PlcDATE(LocalDateTime.ofInstant( - Instant.ofEpochSecond((long) value), ZoneOffset.UTC).toLocalDate()); + return new PlcDATE((Long) value); + } else if (value instanceof Float) { + return new PlcDATE((Float) value); + } else if (value instanceof Double) { + return new PlcDATE((Double) value); + } else if (value instanceof BigInteger) { + return new PlcDATE((BigInteger) value); + } else if (value instanceof BigDecimal) { + return new PlcDATE((BigDecimal) value); + } else { + return new PlcDATE(LocalDate.parse(value.toString())); } - throw new PlcRuntimeException("Invalid value type"); } public static PlcDATE ofSecondsSinceEpoch(long secondsSinceEpoch) { @@ -51,19 +72,62 @@ public static PlcDATE ofDaysSinceEpoch(int daysSinceEpoch) { } public PlcDATE(LocalDate value) { - super(value, true); + this.value = value; + this.isNullable = false; } - public PlcDATE(int daysSinceEpoch) { + public PlcDATE(Byte daysSinceEpoch) { // REMARK: Yes, I'm using LocalDataTime.ofInstant as LocalDate.ofInstant is marked "JDK 1.9" - super(LocalDateTime.ofInstant( - Instant.ofEpochSecond(((long) daysSinceEpoch) * 86400), ZoneOffset.UTC).toLocalDate(), true); + this.value = LocalDateTime.ofInstant( + Instant.ofEpochSecond(((long) daysSinceEpoch) * 86400), ZoneOffset.UTC).toLocalDate(); + this.isNullable = false; } - public PlcDATE(long secondsSinceEpoch) { + public PlcDATE(Short daysSinceEpoch) { // REMARK: Yes, I'm using LocalDataTime.ofInstant as LocalDate.ofInstant is marked "JDK 1.9" - super(LocalDateTime.ofInstant( - Instant.ofEpochSecond(secondsSinceEpoch), ZoneOffset.UTC).toLocalDate(), true); + this.value = LocalDateTime.ofInstant( + Instant.ofEpochSecond(((long) daysSinceEpoch) * 86400), ZoneOffset.UTC).toLocalDate(); + this.isNullable = false; + } + + public PlcDATE(Integer daysSinceEpoch) { + // REMARK: Yes, I'm using LocalDataTime.ofInstant as LocalDate.ofInstant is marked "JDK 1.9" + this.value = LocalDateTime.ofInstant( + Instant.ofEpochSecond(((long) daysSinceEpoch) * 86400), ZoneOffset.UTC).toLocalDate(); + this.isNullable = false; + } + + public PlcDATE(Long daysSinceEpoch) { + // REMARK: Yes, I'm using LocalDataTime.ofInstant as LocalDate.ofInstant is marked "JDK 1.9" + this.value = LocalDateTime.ofInstant( + Instant.ofEpochSecond((daysSinceEpoch) * 86400), ZoneOffset.UTC).toLocalDate(); + this.isNullable = false; + } + + public PlcDATE(Float daysSinceEpoch) { + // REMARK: Yes, I'm using LocalDataTime.ofInstant as LocalDate.ofInstant is marked "JDK 1.9" + this.value = LocalDateTime.ofInstant( + Instant.ofEpochSecond(daysSinceEpoch.longValue() * 86400), ZoneOffset.UTC).toLocalDate(); + this.isNullable = false; + } + + public PlcDATE(Double daysSinceEpoch) { + // REMARK: Yes, I'm using LocalDataTime.ofInstant as LocalDate.ofInstant is marked "JDK 1.9" + this.value = LocalDateTime.ofInstant( + Instant.ofEpochSecond(daysSinceEpoch.longValue() * 86400), ZoneOffset.UTC).toLocalDate(); + this.isNullable = false; + } + + public PlcDATE(BigInteger daysSinceEpoch) { + this.value = LocalDateTime.ofInstant( + Instant.ofEpochSecond(daysSinceEpoch.longValue() * 86400), ZoneOffset.UTC).toLocalDate(); + this.isNullable = false; + } + + public PlcDATE(BigDecimal daysSinceEpoch) { + this.value = LocalDateTime.ofInstant( + Instant.ofEpochSecond(daysSinceEpoch.longValue() * 86400), ZoneOffset.UTC).toLocalDate(); + this.isNullable = false; } @Override diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcDATE_AND_LTIME.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcDATE_AND_LTIME.java index 433438baaf0..6c88b2b409d 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcDATE_AND_LTIME.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcDATE_AND_LTIME.java @@ -18,46 +18,120 @@ */ package org.apache.plc4x.java.spi.values; -import org.apache.plc4x.java.api.exceptions.PlcRuntimeException; import org.apache.plc4x.java.api.types.PlcValueType; import org.apache.plc4x.java.spi.codegen.WithOption; import org.apache.plc4x.java.spi.generation.SerializationException; import org.apache.plc4x.java.spi.generation.WriteBuffer; +import java.math.BigDecimal; import java.math.BigInteger; import java.nio.charset.StandardCharsets; -import java.time.*; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneOffset; -public class PlcDATE_AND_LTIME extends PlcSimpleValue { +public class PlcDATE_AND_LTIME extends PlcIECValue { public static PlcDATE_AND_LTIME of(Object value) { - if (value instanceof LocalDateTime) { + if (value instanceof PlcDATE_AND_LTIME) { + return (PlcDATE_AND_LTIME) value; + } else if (value instanceof LocalDateTime) { return new PlcDATE_AND_LTIME((LocalDateTime) value); + } else if (value instanceof Byte) { + return new PlcDATE_AND_LTIME((Byte) value); + } else if (value instanceof Short) { + return new PlcDATE_AND_LTIME((Short) value); + } else if (value instanceof Integer) { + return new PlcDATE_AND_LTIME((Integer) value); } else if (value instanceof Long) { - return new PlcDATE_AND_LTIME(LocalDateTime.ofInstant( - Instant.ofEpochSecond((long) value), ZoneOffset.UTC)); + return new PlcDATE_AND_LTIME((Long) value); + } else if (value instanceof Float) { + return new PlcDATE_AND_LTIME((Float) value); + } else if (value instanceof Double) { + return new PlcDATE_AND_LTIME((Double) value); } else if (value instanceof BigInteger) { - return new PlcDATE_AND_LTIME(LocalDateTime.ofInstant( - Instant.ofEpochSecond(((BigInteger) value).longValue()), ZoneOffset.UTC)); + return new PlcDATE_AND_LTIME((BigInteger) value); + } else if (value instanceof BigDecimal) { + return new PlcDATE_AND_LTIME((BigDecimal) value); + } else { + return new PlcDATE_AND_LTIME(LocalDateTime.parse(value.toString())); } - throw new PlcRuntimeException("Invalid value type"); } - public static PlcDATE_AND_LTIME ofNanosecondsSinceEpoch(BigInteger nanosecondsSinceEpoch) { - return new PlcDATE_AND_LTIME(nanosecondsSinceEpoch); + public PlcDATE_AND_LTIME(Byte nanosecondsSinceEpoch) { + long secondsSinceEpoch = 0; + long nannoSecondsOfSecond = nanosecondsSinceEpoch % 1000000000; + this.value = LocalDateTime.ofEpochSecond(secondsSinceEpoch, (int) nannoSecondsOfSecond, + ZoneOffset.UTC); + this.isNullable = false; } - public PlcDATE_AND_LTIME(LocalDateTime value) { - super(value, true); + public PlcDATE_AND_LTIME(Short nanosecondsSinceEpoch) { + long secondsSinceEpoch = 0; + long nannoSecondsOfSecond = nanosecondsSinceEpoch % 1000000000; + this.value = LocalDateTime.ofEpochSecond(secondsSinceEpoch, (int) nannoSecondsOfSecond, + ZoneOffset.UTC); + this.isNullable = false; + } + + public PlcDATE_AND_LTIME(Integer nanosecondsSinceEpoch) { + long secondsSinceEpoch = nanosecondsSinceEpoch.longValue() / 1000000000; + long nannoSecondsOfSecond = nanosecondsSinceEpoch % 1000000000; + this.value = LocalDateTime.ofEpochSecond(secondsSinceEpoch, (int) nannoSecondsOfSecond, + ZoneOffset.UTC); + this.isNullable = false; + } + + public PlcDATE_AND_LTIME(Long nanosecondsSinceEpoch) { + long secondsSinceEpoch = nanosecondsSinceEpoch / 1000000000; + long nannoSecondsOfSecond = nanosecondsSinceEpoch % 1000000000; + this.value = LocalDateTime.ofEpochSecond(secondsSinceEpoch, (int) nannoSecondsOfSecond, + ZoneOffset.UTC); + this.isNullable = false; + } + + public PlcDATE_AND_LTIME(Float nanosecondsSinceEpoch) { + long secondsSinceEpoch = nanosecondsSinceEpoch.longValue() / 1000000000; + long nannoSecondsOfSecond = nanosecondsSinceEpoch.longValue() % 1000000000; + this.value = LocalDateTime.ofEpochSecond(secondsSinceEpoch, (int) nannoSecondsOfSecond, + ZoneOffset.UTC); + this.isNullable = false; + } + + public PlcDATE_AND_LTIME(Double nanosecondsSinceEpoch) { + long secondsSinceEpoch = nanosecondsSinceEpoch.longValue() / 1000000000; + long nannoSecondsOfSecond = nanosecondsSinceEpoch.longValue() % 1000000000; + this.value = LocalDateTime.ofEpochSecond(secondsSinceEpoch, (int) nannoSecondsOfSecond, + ZoneOffset.UTC); + this.isNullable = false; } public PlcDATE_AND_LTIME(BigInteger nanosecondsSinceEpoch) { - super( - LocalDateTime.ofEpochSecond( - nanosecondsSinceEpoch.divide(BigInteger.valueOf(1000000000L)).longValue(), - nanosecondsSinceEpoch.mod(BigInteger.valueOf(1000000000L)).intValue(), - ZoneOffset.UTC), - true); + long secondsSinceEpoch = nanosecondsSinceEpoch.longValue() / 1000000000; + long nannoSecondsOfSecond = nanosecondsSinceEpoch.longValue() % 1000000000; + this.value = LocalDateTime.ofEpochSecond(secondsSinceEpoch, (int) nannoSecondsOfSecond, + ZoneOffset.UTC); + this.isNullable = false; + } + + public PlcDATE_AND_LTIME(BigDecimal nanosecondsSinceEpoch) { + long secondsSinceEpoch = nanosecondsSinceEpoch.longValue() / 1000000000; + long nannoSecondsOfSecond = nanosecondsSinceEpoch.longValue() % 1000000000; + this.value = LocalDateTime.ofEpochSecond(secondsSinceEpoch, (int) nannoSecondsOfSecond, + ZoneOffset.UTC); + this.isNullable = false; + } + + public PlcDATE_AND_LTIME(LocalDateTime value) { + this.value = value; + this.isNullable = false; + } + + + public static PlcDATE_AND_LTIME ofNanosecondsSinceEpoch(BigInteger nanosecondsSinceEpoch) { + return new PlcDATE_AND_LTIME(nanosecondsSinceEpoch.longValue()); } public static PlcDATE_AND_LTIME ofSegments(int year, int month, int day, int hour, int minutes, int seconds, long nannosecondsOfSecond) { diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcDATE_AND_TIME.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcDATE_AND_TIME.java index 71ebb499cc7..60b4416bf81 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcDATE_AND_TIME.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcDATE_AND_TIME.java @@ -18,25 +18,46 @@ */ package org.apache.plc4x.java.spi.values; -import org.apache.plc4x.java.api.exceptions.PlcRuntimeException; import org.apache.plc4x.java.api.types.PlcValueType; import org.apache.plc4x.java.spi.codegen.WithOption; import org.apache.plc4x.java.spi.generation.SerializationException; import org.apache.plc4x.java.spi.generation.WriteBuffer; +import java.math.BigDecimal; +import java.math.BigInteger; import java.nio.charset.StandardCharsets; -import java.time.*; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneOffset; -public class PlcDATE_AND_TIME extends PlcSimpleValue { +public class PlcDATE_AND_TIME extends PlcIECValue { public static PlcDATE_AND_TIME of(Object value) { - if (value instanceof LocalDateTime) { + if (value instanceof PlcDATE_AND_TIME) { + return (PlcDATE_AND_TIME) value; + } else if (value instanceof LocalDateTime) { return new PlcDATE_AND_TIME((LocalDateTime) value); + } else if (value instanceof Byte) { + return new PlcDATE_AND_TIME((Byte) value); + } else if (value instanceof Short) { + return new PlcDATE_AND_TIME((Short) value); + } else if (value instanceof Integer) { + return new PlcDATE_AND_TIME((Integer) value); } else if (value instanceof Long) { - return new PlcDATE_AND_TIME(LocalDateTime.ofInstant( - Instant.ofEpochSecond((long) value), ZoneOffset.UTC)); + return new PlcDATE_AND_TIME((Long) value); + } else if (value instanceof Float) { + return new PlcDATE_AND_TIME((Float) value); + } else if (value instanceof Double) { + return new PlcDATE_AND_TIME((Double) value); + } else if (value instanceof BigInteger) { + return new PlcDATE_AND_TIME((BigInteger) value); + } else if (value instanceof BigDecimal) { + return new PlcDATE_AND_TIME((BigDecimal) value); + } else { + return new PlcDATE_AND_TIME(LocalDateTime.parse(value.toString())); } - throw new PlcRuntimeException("Invalid value type"); } public static PlcDATE_AND_TIME ofSecondsSinceEpoch(long secondsSinceEpoch) { @@ -48,17 +69,62 @@ public static PlcDATE_AND_TIME ofSegments(int year, int month, int day, int hour return new PlcDATE_AND_TIME(LocalDateTime.of(year, month, day, hour, minutes, seconds, nanoseconds)); } - public PlcDATE_AND_TIME(LocalDateTime value) { - super(value, true); + public PlcDATE_AND_TIME(Byte secondsSinceEpoch) { + this.value = LocalDateTime.ofEpochSecond(secondsSinceEpoch, 0, + ZoneOffset.UTC); + this.isNullable = false; + } + + public PlcDATE_AND_TIME(Short secondsSinceEpoch) { + this.value = LocalDateTime.ofEpochSecond(secondsSinceEpoch, 0, + ZoneOffset.UTC); + this.isNullable = false; + } + + public PlcDATE_AND_TIME(Integer secondsSinceEpoch) { + this.value = LocalDateTime.ofEpochSecond(secondsSinceEpoch, 0, + ZoneOffset.UTC); + this.isNullable = false; + } + + public PlcDATE_AND_TIME(Long secondsSinceEpoch) { + this.value = LocalDateTime.ofEpochSecond(secondsSinceEpoch, 0, + ZoneOffset.UTC); + this.isNullable = false; + } + + public PlcDATE_AND_TIME(Float secondsSinceEpoch) { + this.value = LocalDateTime.ofEpochSecond(secondsSinceEpoch.longValue(), 0, + ZoneOffset.UTC); + this.isNullable = false; + } + + public PlcDATE_AND_TIME(Double secondsSinceEpoch) { + this.value = LocalDateTime.ofEpochSecond(secondsSinceEpoch.longValue(), 0, + ZoneOffset.UTC); + this.isNullable = false; + } + + public PlcDATE_AND_TIME(BigInteger secondsSinceEpoch) { + this.value = LocalDateTime.ofEpochSecond(secondsSinceEpoch.longValue(), 0, + ZoneOffset.UTC); + this.isNullable = false; + } + + public PlcDATE_AND_TIME(BigDecimal secondsSinceEpoch) { + this.value = LocalDateTime.ofEpochSecond(secondsSinceEpoch.longValue(), 0, + ZoneOffset.UTC); + this.isNullable = false; } - public PlcDATE_AND_TIME(long secondsSinceEpoch) { - super(LocalDateTime.ofEpochSecond(secondsSinceEpoch, 0, - ZoneOffset.UTC), true); + public PlcDATE_AND_TIME(LocalDateTime value) { + this.value = value; + this.isNullable = false; } public PlcDATE_AND_TIME(int year, int month, int day, int hour, int minutes, int seconds, int nanoseconds) { - super(LocalDateTime.of(year, month, day, hour, minutes, seconds, nanoseconds), true); + this.value = LocalDateTime.of(year, month, day, hour, minutes, seconds, nanoseconds); + this.isNullable = false; } @Override @@ -67,7 +133,7 @@ public PlcValueType getPlcValueType() { } public long getSecondsSinceEpoch() { - Instant instant = getDateTime().toInstant(ZoneOffset.of(ZoneOffset.UTC.getId())); + Instant instant = getDateTime().toInstant(ZoneOffset.UTC); return instant.getEpochSecond(); } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcDINT.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcDINT.java index dc587043a94..f747e285d33 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcDINT.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcDINT.java @@ -29,11 +29,13 @@ public class PlcDINT extends PlcIECValue { private static final String VALUE_OUT_OF_RANGE = "Value of type %s is out of range %d - %d for a %s Value"; - static final Integer minValue = Integer.MIN_VALUE; - static final Integer maxValue = Integer.MAX_VALUE; + public static final Integer MIN_VALUE = Integer.MIN_VALUE; + public static final Integer MAX_VALUE = Integer.MAX_VALUE; public static PlcDINT of(Object value) { - if (value instanceof Boolean) { + if (value instanceof PlcDINT) { + return (PlcDINT) value; + } else if (value instanceof Boolean) { return new PlcDINT((Boolean) value); } else if (value instanceof Byte) { return new PlcDINT((Byte) value); @@ -52,7 +54,7 @@ public static PlcDINT of(Object value) { } else if (value instanceof BigDecimal) { return new PlcDINT((BigDecimal) value); } else { - return new PlcDINT((String) value); + return new PlcDINT(value.toString()); } } @@ -77,40 +79,40 @@ public PlcDINT(Integer value) { } public PlcDINT(Long value) { - if (value < minValue || value > maxValue) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if (value < MIN_VALUE || value > MAX_VALUE) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.intValue(); this.isNullable = false; } public PlcDINT(Float value) { - if ((value < minValue) || (value > maxValue) || (value % 1 != 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.intValue(); this.isNullable = false; } public PlcDINT(Double value) { - if ((value < minValue) || (value > maxValue) || (value % 1 != 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.intValue(); this.isNullable = false; } public PlcDINT(BigInteger value) { - if ((value.compareTo(BigInteger.valueOf(minValue)) < 0) || (value.compareTo(BigInteger.valueOf(maxValue)) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value.compareTo(BigInteger.valueOf(MIN_VALUE)) < 0) || (value.compareTo(BigInteger.valueOf(MAX_VALUE)) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.intValue(); this.isNullable = true; } public PlcDINT(BigDecimal value) { - if ((value.compareTo(BigDecimal.valueOf(minValue)) < 0) || (value.compareTo(BigDecimal.valueOf(maxValue)) > 0) || (value.scale() > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value.compareTo(BigDecimal.valueOf(MIN_VALUE)) < 0) || (value.compareTo(BigDecimal.valueOf(MAX_VALUE)) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.intValue(); this.isNullable = true; @@ -121,7 +123,7 @@ public PlcDINT(String value) { this.value = Integer.parseInt(value.trim()); this.isNullable = false; } catch (Exception e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName()), e); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName()), e); } } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcDWORD.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcDWORD.java index e33a6f9f25a..2ab06b560d8 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcDWORD.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcDWORD.java @@ -30,11 +30,13 @@ public class PlcDWORD extends PlcIECValue { private static final String VALUE_OUT_OF_RANGE = "Value of type %s is out of range %d - %d for a %s Value"; - static final Long minValue = (long) 0; - static final Long maxValue = (long) Integer.MAX_VALUE * 2 + 1; + public static final Long MIN_VALUE = (long) 0; + public static final Long MAX_VALUE = (long) Integer.MAX_VALUE * 2 + 1; public static PlcDWORD of(Object value) { - if (value instanceof Boolean) { + if (value instanceof PlcDWORD) { + return (PlcDWORD) value; + } else if (value instanceof Boolean) { return new PlcDWORD((Boolean) value); } else if (value instanceof Byte) { return new PlcDWORD((Byte) value); @@ -53,7 +55,7 @@ public static PlcDWORD of(Object value) { } else if (value instanceof BigDecimal) { return new PlcDWORD((BigDecimal) value); } else { - return new PlcDWORD((String) value); + return new PlcDWORD(value.toString()); } } @@ -64,64 +66,64 @@ public PlcDWORD(Boolean value) { } public PlcDWORD(Byte value) { - if (value < minValue || value > maxValue) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if (value < MIN_VALUE || value > MAX_VALUE) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.longValue(); this.isNullable = false; } public PlcDWORD(Short value) { - if (value < minValue || value > maxValue) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if (value < MIN_VALUE || value > MAX_VALUE) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.longValue(); this.isNullable = false; } public PlcDWORD(Integer value) { - if (value < minValue || value > maxValue) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if (value < MIN_VALUE || value > MAX_VALUE) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.longValue(); this.isNullable = false; } public PlcDWORD(Long value) { - if (value < minValue || value > maxValue) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if (value < MIN_VALUE || value > MAX_VALUE) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.longValue(); this.isNullable = false; } public PlcDWORD(Float value) { - if ((value < minValue) || (value > maxValue) || (value % 1 != 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.longValue(); this.isNullable = false; } public PlcDWORD(Double value) { - if ((value < minValue) || (value > maxValue) || (value % 1 != 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.longValue(); this.isNullable = false; } public PlcDWORD(BigInteger value) { - if ((value.compareTo(BigInteger.valueOf(minValue)) < 0) || (value.compareTo(BigInteger.valueOf(maxValue)) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value.compareTo(BigInteger.valueOf(MIN_VALUE)) < 0) || (value.compareTo(BigInteger.valueOf(MAX_VALUE)) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.longValue(); this.isNullable = true; } public PlcDWORD(BigDecimal value) { - if ((value.compareTo(BigDecimal.valueOf(minValue)) < 0) || (value.compareTo(BigDecimal.valueOf(maxValue)) > 0) || (value.scale() > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value.compareTo(BigDecimal.valueOf(MIN_VALUE)) < 0) || (value.compareTo(BigDecimal.valueOf(MAX_VALUE)) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.longValue(); this.isNullable = true; @@ -130,19 +132,19 @@ public PlcDWORD(BigDecimal value) { public PlcDWORD(String value) { try { long val = Long.parseLong(value.trim()); - if (val < minValue || val > maxValue) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if (val < MIN_VALUE || val > MAX_VALUE) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = val; this.isNullable = false; } catch (Exception e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName()), e); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName()), e); } } public PlcDWORD(long value) { - if (value < minValue || value > maxValue) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if (value < MIN_VALUE || value > MAX_VALUE) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value; this.isNullable = false; diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcINT.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcINT.java index 93caa2ce753..656fbeedeea 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcINT.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcINT.java @@ -29,11 +29,13 @@ public class PlcINT extends PlcIECValue { private static final String VALUE_OUT_OF_RANGE = "Value of type %s is out of range %d - %d for a %s Value"; - static final Short minValue = Short.MIN_VALUE; - static final Short maxValue = Short.MAX_VALUE; + public static final Short MIN_VALUE = Short.MIN_VALUE; + public static final Short MAX_VALUE = Short.MAX_VALUE; public static PlcINT of(Object value) { - if (value instanceof Boolean) { + if (value instanceof PlcINT) { + return (PlcINT) value; + } else if (value instanceof Boolean) { return new PlcINT((Boolean) value); } else if (value instanceof Byte) { return new PlcINT((Byte) value); @@ -52,7 +54,7 @@ public static PlcINT of(Object value) { } else if (value instanceof BigDecimal) { return new PlcINT((BigDecimal) value); } else { - return new PlcINT((String) value); + return new PlcINT(value.toString()); } } @@ -72,8 +74,8 @@ public PlcINT(Short value) { } public PlcINT(Integer value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } else { this.value = value.shortValue(); this.isNullable = false; @@ -81,40 +83,40 @@ public PlcINT(Integer value) { } public PlcINT(Long value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.shortValue(); this.isNullable = false; } public PlcINT(Float value) { - if ((value < minValue) || (value > maxValue) || (value % 1 != 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.shortValue(); this.isNullable = false; } public PlcINT(Double value) { - if ((value < minValue) || (value > maxValue) || (value % 1 != 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.shortValue(); this.isNullable = false; } public PlcINT(BigInteger value) { - if ((value.compareTo(BigInteger.valueOf(minValue)) < 0) || (value.compareTo(BigInteger.valueOf(maxValue)) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value.compareTo(BigInteger.valueOf(MIN_VALUE)) < 0) || (value.compareTo(BigInteger.valueOf(MAX_VALUE)) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.shortValue(); this.isNullable = true; } public PlcINT(BigDecimal value) { - if ((value.compareTo(BigDecimal.valueOf(minValue)) < 0) || (value.compareTo(BigDecimal.valueOf(maxValue)) > 0) || (value.scale() > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value.compareTo(BigDecimal.valueOf(MIN_VALUE)) < 0) || (value.compareTo(BigDecimal.valueOf(MAX_VALUE)) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.shortValue(); this.isNullable = true; @@ -125,7 +127,7 @@ public PlcINT(String value) { this.value = Short.valueOf(value.trim()); this.isNullable = false; } catch (Exception e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLDATE.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLDATE.java index d9730b44017..79cbc77b239 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLDATE.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLDATE.java @@ -18,43 +18,113 @@ */ package org.apache.plc4x.java.spi.values; -import org.apache.plc4x.java.api.exceptions.PlcRuntimeException; import org.apache.plc4x.java.api.types.PlcValueType; import org.apache.plc4x.java.spi.codegen.WithOption; import org.apache.plc4x.java.spi.generation.SerializationException; import org.apache.plc4x.java.spi.generation.WriteBuffer; +import java.math.BigDecimal; import java.math.BigInteger; import java.nio.charset.StandardCharsets; -import java.time.*; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneOffset; -public class PlcLDATE extends PlcSimpleValue { +public class PlcLDATE extends PlcIECValue { public static PlcLDATE of(Object value) { - if (value instanceof LocalDate) { + if (value instanceof PlcLDATE) { + return (PlcLDATE) value; + } else if (value instanceof LocalDate) { return new PlcLDATE((LocalDate) value); + } else if (value instanceof Byte) { + return new PlcLDATE((Byte) value); + } else if (value instanceof Short) { + return new PlcLDATE((Short) value); + } else if (value instanceof Integer) { + return new PlcLDATE((Integer) value); } else if (value instanceof Long) { - return new PlcLDATE(LocalDateTime.ofInstant( - Instant.ofEpochSecond((long) value), ZoneOffset.UTC).toLocalDate()); + return new PlcLDATE((Long) value); + } else if (value instanceof Float) { + return new PlcLDATE((Float) value); + } else if (value instanceof Double) { + return new PlcLDATE((Double) value); + } else if (value instanceof BigInteger) { + return new PlcLDATE((BigInteger) value); + } else if (value instanceof BigDecimal) { + return new PlcLDATE((BigDecimal) value); + } else { + return new PlcLDATE(LocalDate.parse(value.toString())); } - throw new PlcRuntimeException("Invalid value type"); } public static PlcLDATE ofNanosecondsSinceEpoch(BigInteger nanosecondsSinceEpoch) { BigInteger epochSecond = nanosecondsSinceEpoch.divide(BigInteger.valueOf(1000_000)); BigInteger nanoOfSecond = nanosecondsSinceEpoch.mod(BigInteger.valueOf(1000_000)); return new PlcLDATE(LocalDateTime.ofEpochSecond(epochSecond.longValue(), nanoOfSecond.intValue(), - ZoneOffset.of(ZoneOffset.systemDefault().getId())).toLocalDate()); + ZoneOffset.UTC).toLocalDate()); } public PlcLDATE(LocalDate value) { - super(value, true); + this.value = value; + this.isNullable = false; } - public PlcLDATE(BigInteger nanosecondsSinceEpoch) { - super(LocalDateTime.ofEpochSecond(nanosecondsSinceEpoch.longValue() / 1000000, - (int) (nanosecondsSinceEpoch.longValue() % 1000000), - ZoneOffset.of(ZoneOffset.systemDefault().getId())).toLocalDate(), true); + public PlcLDATE(Byte secondsSinceEpoch) { + // REMARK: Yes, I'm using LocalDataTime.ofInstant as LocalDate.ofInstant is marked "JDK 1.9" + this.value = LocalDateTime.ofEpochSecond((long) secondsSinceEpoch, 0, + ZoneOffset.UTC).toLocalDate(); + this.isNullable = false; + } + + public PlcLDATE(Short secondsSinceEpoch) { + // REMARK: Yes, I'm using LocalDataTime.ofInstant as LocalDate.ofInstant is marked "JDK 1.9" + this.value = LocalDateTime.ofEpochSecond((long) secondsSinceEpoch, 0, + ZoneOffset.UTC).toLocalDate(); + this.isNullable = false; + } + + public PlcLDATE(Integer secondsSinceEpoch) { + // REMARK: Yes, I'm using LocalDataTime.ofInstant as LocalDate.ofInstant is marked "JDK 1.9" + this.value = LocalDateTime.ofEpochSecond((long) secondsSinceEpoch, 0, + ZoneOffset.UTC).toLocalDate(); + this.isNullable = false; + } + + public PlcLDATE(Long secondsSinceEpoch) { + // REMARK: Yes, I'm using LocalDataTime.ofInstant as LocalDate.ofInstant is marked "JDK 1.9" + this.value = LocalDateTime.ofEpochSecond((long) secondsSinceEpoch, 0, + ZoneOffset.UTC).toLocalDate(); + this.isNullable = false; + } + + public PlcLDATE(Float secondsSinceEpoch) { + // REMARK: Yes, I'm using LocalDataTime.ofInstant as LocalDate.ofInstant is marked "JDK 1.9" + this.value = LocalDateTime.ofEpochSecond(secondsSinceEpoch.longValue(), 0, + ZoneOffset.UTC).toLocalDate(); + this.isNullable = false; + } + + public PlcLDATE(Double secondsSinceEpoch) { + // REMARK: Yes, I'm using LocalDataTime.ofInstant as LocalDate.ofInstant is marked "JDK 1.9" + this.value = LocalDateTime.ofEpochSecond(secondsSinceEpoch.longValue(), 0, + ZoneOffset.UTC).toLocalDate(); + this.isNullable = false; + } + + public PlcLDATE(BigInteger secondsSinceEpoch) { + // REMARK: Yes, I'm using LocalDataTime.ofInstant as LocalDate.ofInstant is marked "JDK 1.9" + this.value = LocalDateTime.ofEpochSecond(secondsSinceEpoch.longValue(), 0, + ZoneOffset.UTC).toLocalDate(); + this.isNullable = false; + } + + public PlcLDATE(BigDecimal secondsSinceEpoch) { + // REMARK: Yes, I'm using LocalDataTime.ofInstant as LocalDate.ofInstant is marked "JDK 1.9" + this.value = LocalDateTime.ofEpochSecond(secondsSinceEpoch.longValue(), 0, + ZoneOffset.UTC).toLocalDate(); + this.isNullable = false; } @Override @@ -63,7 +133,7 @@ public PlcValueType getPlcValueType() { } public BigInteger getNanosecondsSinceEpoch() { - Instant instant = getDateTime().toInstant(ZoneOffset.of(ZoneOffset.systemDefault().getId())); + Instant instant = getDateTime().toInstant(ZoneOffset.UTC); return BigInteger.valueOf(instant.getEpochSecond()).multiply(BigInteger.valueOf(1000_000_000)).add(BigInteger.valueOf(instant.getNano())); } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLDATE_AND_TIME.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLDATE_AND_TIME.java index bc6dbbfa069..6d620ac7318 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLDATE_AND_TIME.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLDATE_AND_TIME.java @@ -18,43 +18,114 @@ */ package org.apache.plc4x.java.spi.values; -import org.apache.plc4x.java.api.exceptions.PlcRuntimeException; import org.apache.plc4x.java.api.types.PlcValueType; import org.apache.plc4x.java.spi.codegen.WithOption; import org.apache.plc4x.java.spi.generation.SerializationException; import org.apache.plc4x.java.spi.generation.WriteBuffer; +import java.math.BigDecimal; import java.math.BigInteger; import java.nio.charset.StandardCharsets; -import java.time.*; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneOffset; -public class PlcLDATE_AND_TIME extends PlcSimpleValue { +public class PlcLDATE_AND_TIME extends PlcIECValue { public static PlcLDATE_AND_TIME of(Object value) { - if (value instanceof LocalDateTime) { + if (value instanceof PlcLDATE_AND_TIME) { + return (PlcLDATE_AND_TIME) value; + } else if (value instanceof LocalDateTime) { return new PlcLDATE_AND_TIME((LocalDateTime) value); + } else if (value instanceof Byte) { + return new PlcLDATE_AND_TIME((Byte) value); + } else if (value instanceof Short) { + return new PlcLDATE_AND_TIME((Short) value); + } else if (value instanceof Integer) { + return new PlcLDATE_AND_TIME((Integer) value); } else if (value instanceof Long) { - return new PlcLDATE_AND_TIME(LocalDateTime.ofInstant( - Instant.ofEpochSecond((long) value), ZoneOffset.UTC)); + return new PlcLDATE_AND_TIME((Long) value); + } else if (value instanceof Float) { + return new PlcLDATE_AND_TIME((Float) value); + } else if (value instanceof Double) { + return new PlcLDATE_AND_TIME((Double) value); + } else if (value instanceof BigInteger) { + return new PlcLDATE_AND_TIME((BigInteger) value); + } else if (value instanceof BigDecimal) { + return new PlcLDATE_AND_TIME((BigDecimal) value); + } else { + return new PlcLDATE_AND_TIME(LocalDateTime.parse(value.toString())); } - throw new PlcRuntimeException("Invalid value type"); } public static PlcLDATE_AND_TIME ofNanosecondsSinceEpoch(BigInteger nanosecondsSinceEpoch) { BigInteger epochSecond = nanosecondsSinceEpoch.divide(BigInteger.valueOf(1000_000)); BigInteger nanoOfSecond = nanosecondsSinceEpoch.mod(BigInteger.valueOf(1000_000)); return new PlcLDATE_AND_TIME(LocalDateTime.ofEpochSecond(epochSecond.longValue(), nanoOfSecond.intValue(), - ZoneOffset.of(ZoneOffset.systemDefault().getId()))); + ZoneOffset.UTC)); } - public PlcLDATE_AND_TIME(LocalDateTime value) { - super(value, true); + public PlcLDATE_AND_TIME(Byte millisecondsSinceEpoch) { + long daysSinceEpoch = 0; + long millisecondsOfDay = millisecondsSinceEpoch.longValue(); + this.value = LocalDateTime.of(LocalDate.ofEpochDay(daysSinceEpoch), LocalTime.ofNanoOfDay(millisecondsOfDay * 1000000)); + this.isNullable = false; + } + + public PlcLDATE_AND_TIME(Short millisecondsSinceEpoch) { + long daysSinceEpoch = 0; + long millisecondsOfDay = millisecondsSinceEpoch.longValue(); + this.value = LocalDateTime.of(LocalDate.ofEpochDay(daysSinceEpoch), LocalTime.ofNanoOfDay(millisecondsOfDay * 1000000)); + this.isNullable = false; + } + + public PlcLDATE_AND_TIME(Integer millisecondsSinceEpoch) { + long daysSinceEpoch = millisecondsSinceEpoch.longValue() / 86400000; + long millisecondsOfDay = millisecondsSinceEpoch.longValue() % 86400000; + this.value = LocalDateTime.of(LocalDate.ofEpochDay(daysSinceEpoch), LocalTime.ofNanoOfDay(millisecondsOfDay * 1000000)); + this.isNullable = false; + } + + public PlcLDATE_AND_TIME(Long millisecondsSinceEpoch) { + long daysSinceEpoch = millisecondsSinceEpoch / 86400000; + long millisecondsOfDay = millisecondsSinceEpoch % 86400000; + this.value = LocalDateTime.of(LocalDate.ofEpochDay(daysSinceEpoch), LocalTime.ofNanoOfDay(millisecondsOfDay * 1000000)); + this.isNullable = false; + } + + public PlcLDATE_AND_TIME(Float millisecondsSinceEpoch) { + long daysSinceEpoch = millisecondsSinceEpoch.longValue() / 86400000; + long millisecondsOfDay = millisecondsSinceEpoch.longValue() % 86400000; + this.value = LocalDateTime.of(LocalDate.ofEpochDay(daysSinceEpoch), LocalTime.ofNanoOfDay(millisecondsOfDay * 1000000)); + this.isNullable = false; + } + + public PlcLDATE_AND_TIME(Double millisecondsSinceEpoch) { + long daysSinceEpoch = millisecondsSinceEpoch.longValue() / 86400000; + long millisecondsOfDay = millisecondsSinceEpoch.longValue() % 86400000; + this.value = LocalDateTime.of(LocalDate.ofEpochDay(daysSinceEpoch), LocalTime.ofNanoOfDay(millisecondsOfDay * 1000000)); + this.isNullable = false; + } + + public PlcLDATE_AND_TIME(BigInteger millisecondsSinceEpoch) { + long daysSinceEpoch = millisecondsSinceEpoch.longValue() / 86400000; + long millisecondsOfDay = millisecondsSinceEpoch.longValue() % 86400000; + this.value = LocalDateTime.of(LocalDate.ofEpochDay(daysSinceEpoch), LocalTime.ofNanoOfDay(millisecondsOfDay * 1000000)); + this.isNullable = false; + } + + public PlcLDATE_AND_TIME(BigDecimal millisecondsSinceEpoch) { + long daysSinceEpoch = millisecondsSinceEpoch.longValue() / 86400000; + long millisecondsOfDay = millisecondsSinceEpoch.longValue() % 86400000; + this.value = LocalDateTime.of(LocalDate.ofEpochDay(daysSinceEpoch), LocalTime.ofNanoOfDay(millisecondsOfDay * 1000000)); + this.isNullable = false; } - public PlcLDATE_AND_TIME(BigInteger nanosecondsSinceEpoch) { - super(LocalDateTime.ofEpochSecond(nanosecondsSinceEpoch.divide(BigInteger.valueOf(1000_000)).longValue(), - nanosecondsSinceEpoch.mod(BigInteger.valueOf(1000_000)).intValue(), - ZoneOffset.of(ZoneOffset.systemDefault().getId())), true); + public PlcLDATE_AND_TIME(LocalDateTime value) { + this.value = value; + this.isNullable = false; } @Override @@ -63,7 +134,7 @@ public PlcValueType getPlcValueType() { } public BigInteger getNanosecondsSinceEpoch() { - Instant instant = getDateTime().toInstant(ZoneOffset.of(ZoneOffset.systemDefault().getId())); + Instant instant = getDateTime().toInstant(ZoneOffset.UTC); return BigInteger.valueOf(instant.getEpochSecond()).multiply(BigInteger.valueOf(1000_000_000)).add(BigInteger.valueOf(instant.getNano())); } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLINT.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLINT.java index 1e1ecfac0f9..db1ff3fbd28 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLINT.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLINT.java @@ -29,11 +29,13 @@ public class PlcLINT extends PlcIECValue { private static final String VALUE_OUT_OF_RANGE = "Value of type %s is out of range %d - %d for a %s Value"; - static final Long minValue = Long.MIN_VALUE; - static final Long maxValue = Long.MAX_VALUE; + public static final Long MIN_VALUE = Long.MIN_VALUE; + public static final Long MAX_VALUE = Long.MAX_VALUE; public static PlcLINT of(Object value) { - if (value instanceof Boolean) { + if (value instanceof PlcLINT) { + return (PlcLINT) value; + } else if (value instanceof Boolean) { return new PlcLINT((Boolean) value); } else if (value instanceof Byte) { return new PlcLINT((Byte) value); @@ -52,7 +54,7 @@ public static PlcLINT of(Object value) { } else if (value instanceof BigDecimal) { return new PlcLINT((BigDecimal) value); } else { - return new PlcLINT((String) value); + return new PlcLINT(value.toString()); } } @@ -82,32 +84,32 @@ public PlcLINT(Long value) { } public PlcLINT(Float value) { - if ((value < minValue) || (value > maxValue) || (value % 1 != 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.longValue(); this.isNullable = false; } public PlcLINT(Double value) { - if ((value < minValue) || (value > maxValue) || (value % 1 != 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.longValue(); this.isNullable = false; } public PlcLINT(BigInteger value) { - if ((value.compareTo(BigInteger.valueOf(minValue)) < 0) || (value.compareTo(BigInteger.valueOf(maxValue)) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value.compareTo(BigInteger.valueOf(MIN_VALUE)) < 0) || (value.compareTo(BigInteger.valueOf(MAX_VALUE)) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.longValue(); this.isNullable = true; } public PlcLINT(BigDecimal value) { - if ((value.compareTo(BigDecimal.valueOf(minValue)) < 0) || (value.compareTo(BigDecimal.valueOf(maxValue)) > 0) || (value.scale() > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value.compareTo(BigDecimal.valueOf(MIN_VALUE)) < 0) || (value.compareTo(BigDecimal.valueOf(MAX_VALUE)) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.longValue(); this.isNullable = true; @@ -118,7 +120,7 @@ public PlcLINT(String value) { this.value = Long.parseLong(value.trim()); this.isNullable = false; } catch (Exception e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLREAL.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLREAL.java index 2d440d847ba..b5c8222e41c 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLREAL.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLREAL.java @@ -28,12 +28,14 @@ public class PlcLREAL extends PlcIECValue { - private static final String VALUE_OUT_OF_RANGE = "Value of type %s is out of range %d - %d for a %s Value"; - static final Double minValue = -Double.MAX_VALUE; - static final Double maxValue = Double.MAX_VALUE; + private static final String VALUE_OUT_OF_RANGE = "Value of type %s is out of range %f - %f for a %s Value"; + public static final Double MIN_VALUE = -Double.MAX_VALUE; + public static final Double MAX_VALUE = Double.MAX_VALUE; public static PlcLREAL of(Object value) { - if (value instanceof Boolean) { + if (value instanceof PlcLREAL) { + return (PlcLREAL) value; + } else if (value instanceof Boolean) { return new PlcLREAL((Boolean) value); } else if (value instanceof Byte) { return new PlcLREAL((Byte) value); @@ -52,7 +54,7 @@ public static PlcLREAL of(Object value) { } else if (value instanceof BigDecimal) { return new PlcLREAL((BigDecimal) value); } else { - return new PlcLREAL((String) value); + return new PlcLREAL(value.toString()); } } @@ -76,6 +78,11 @@ public PlcLREAL(Integer value) { this.isNullable = false; } + public PlcLREAL(Long value) { + this.value = value.doubleValue(); + this.isNullable = false; + } + public PlcLREAL(Float value) { this.value = value.doubleValue(); this.isNullable = false; @@ -88,16 +95,16 @@ public PlcLREAL(Double value) { public PlcLREAL(BigInteger value) { BigDecimal val = new BigDecimal(value); - if ((val.compareTo(BigDecimal.valueOf(minValue)) < 0) || (val.compareTo(BigDecimal.valueOf(maxValue)) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((val.compareTo(BigDecimal.valueOf(MIN_VALUE)) < 0) || (val.compareTo(BigDecimal.valueOf(MAX_VALUE)) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = val.doubleValue(); this.isNullable = true; } public PlcLREAL(BigDecimal value) { - if ((value.compareTo(BigDecimal.valueOf(minValue)) < 0) || (value.compareTo(BigDecimal.valueOf(maxValue)) > 0) || (value.scale() > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value.compareTo(BigDecimal.valueOf(MIN_VALUE)) < 0) || (value.compareTo(BigDecimal.valueOf(MAX_VALUE)) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.doubleValue(); this.isNullable = true; @@ -108,7 +115,7 @@ public PlcLREAL(String value) { this.value = Double.parseDouble(value.trim()); this.isNullable = false; } catch (Exception e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLTIME.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLTIME.java index 27620f61860..4e2c2a7491e 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLTIME.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLTIME.java @@ -18,31 +18,44 @@ */ package org.apache.plc4x.java.spi.values; -import org.apache.plc4x.java.api.exceptions.PlcRuntimeException; import org.apache.plc4x.java.api.types.PlcValueType; import org.apache.plc4x.java.spi.codegen.WithOption; import org.apache.plc4x.java.spi.generation.SerializationException; import org.apache.plc4x.java.spi.generation.WriteBuffer; +import java.math.BigDecimal; import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.time.Duration; import java.time.temporal.ChronoUnit; -public class PlcLTIME extends PlcSimpleValue { +public class PlcLTIME extends PlcIECValue { public static PlcLTIME of(Object value) { - if (value instanceof Duration) { + if (value instanceof PlcLTIME) { + return (PlcLTIME) value; + } else if (value instanceof Duration) { return new PlcLTIME((Duration) value); - } else if(value instanceof Integer) { - return new PlcLTIME(Duration.of((long) value, ChronoUnit.MILLIS)); - } else if(value instanceof Long) { - return new PlcLTIME(Duration.of((long) value, ChronoUnit.NANOS)); - } else if(value instanceof BigInteger) { - // TODO: Not 100% correct, we're loosing precision here - return new PlcLTIME(Duration.of(((BigInteger) value).longValue(), ChronoUnit.NANOS)); + } else if (value instanceof Byte) { + return new PlcLTIME((Byte) value); + } else if (value instanceof Short) { + return new PlcLTIME((Short) value); + } else if (value instanceof Integer) { + return new PlcLTIME((Integer) value); + } else if (value instanceof Long) { + return new PlcLTIME((Long) value); + } else if (value instanceof Float) { + return new PlcLTIME((Float) value); + } else if (value instanceof Double) { + return new PlcLTIME((Double) value); + } else if (value instanceof BigInteger) { + return new PlcLTIME((BigInteger) value); + } else if (value instanceof BigDecimal) { + return new PlcLTIME((BigDecimal) value); + } else { + return new PlcLTIME(Duration.parse(value.toString())); } - throw new PlcRuntimeException("Invalid value type"); + //throw new PlcRuntimeException("Invalid value type"); } public static PlcLTIME ofNanoseconds(long nanoseconds) { @@ -54,17 +67,49 @@ public static PlcLTIME ofNanoseconds(BigInteger nanoseconds) { return new PlcLTIME(Duration.ofNanos(nanoseconds.longValue())); } - public PlcLTIME(Duration value) { - super(value, true); + public PlcLTIME(Byte nanoseconds) { + this.value = Duration.ofNanos(nanoseconds); + this.isNullable = false; + } + + public PlcLTIME(Short nanoseconds) { + this.value = Duration.ofNanos(nanoseconds); + this.isNullable = false; + } + + public PlcLTIME(Integer nanoseconds) { + this.value = Duration.ofNanos(nanoseconds); + this.isNullable = false; + } + + public PlcLTIME(Long nanoseconds) { + this.value = Duration.ofNanos(nanoseconds); + this.isNullable = false; } - public PlcLTIME(long nanoseconds) { - super(Duration.ofNanos(nanoseconds), true); + public PlcLTIME(Float nanoseconds) { + this.value = Duration.ofNanos(nanoseconds.longValue()); + this.isNullable = false; + } + + public PlcLTIME(Double nanoseconds) { + this.value = Duration.ofNanos(nanoseconds.longValue()); + this.isNullable = false; } public PlcLTIME(BigInteger nanoseconds) { - // TODO: Not 100% correct, we're loosing precision here - super(Duration.ofNanos(nanoseconds.longValue()), true); + this.value = Duration.ofNanos(nanoseconds.longValue()); + this.isNullable = false; + } + + public PlcLTIME(BigDecimal nanoseconds) { + this.value = Duration.ofNanos(nanoseconds.longValue()); + this.isNullable = false; + } + + public PlcLTIME(Duration value) { + this.value = value; + this.isNullable = false; } @Override diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLTIME_OF_DAY.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLTIME_OF_DAY.java index 3d482e8617f..4d3242161a7 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLTIME_OF_DAY.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLTIME_OF_DAY.java @@ -18,28 +18,42 @@ */ package org.apache.plc4x.java.spi.values; -import org.apache.plc4x.java.api.exceptions.PlcRuntimeException; import org.apache.plc4x.java.api.types.PlcValueType; import org.apache.plc4x.java.spi.codegen.WithOption; import org.apache.plc4x.java.spi.generation.SerializationException; import org.apache.plc4x.java.spi.generation.WriteBuffer; +import java.math.BigDecimal; import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.time.LocalTime; -public class PlcLTIME_OF_DAY extends PlcSimpleValue { +public class PlcLTIME_OF_DAY extends PlcIECValue { public static PlcLTIME_OF_DAY of(Object value) { - if (value instanceof LocalTime) { + if (value instanceof PlcLTIME_OF_DAY) { + return (PlcLTIME_OF_DAY) value; + } else if (value instanceof LocalTime) { return new PlcLTIME_OF_DAY((LocalTime) value); + } else if (value instanceof Byte) { + return new PlcLTIME_OF_DAY((Byte) value); + } else if (value instanceof Short) { + return new PlcLTIME_OF_DAY((Short) value); + } else if (value instanceof Integer) { + return new PlcLTIME_OF_DAY((Integer) value); } else if (value instanceof Long) { - return new PlcLTIME_OF_DAY(LocalTime.ofSecondOfDay(((Long) value) / 1000)); + return new PlcLTIME_OF_DAY((Long) value); + } else if (value instanceof Float) { + return new PlcLTIME_OF_DAY((Float) value); + } else if (value instanceof Double) { + return new PlcLTIME_OF_DAY((Double) value); } else if (value instanceof BigInteger) { - // TODO: Not 100% correct, we're loosing precision here - return new PlcLTIME_OF_DAY(LocalTime.ofSecondOfDay(((BigInteger) value).longValue() / 1000)); + return new PlcLTIME_OF_DAY((BigInteger) value); + } else if (value instanceof BigDecimal) { + return new PlcLTIME_OF_DAY((BigDecimal) value); + } else { + return new PlcLTIME_OF_DAY(LocalTime.parse(value.toString())); } - throw new PlcRuntimeException("Invalid value type"); } public static PlcLTIME_OF_DAY ofNanosecondsSinceMidnight(BigInteger nanosecondsSinceMidnight) { @@ -47,17 +61,49 @@ public static PlcLTIME_OF_DAY ofNanosecondsSinceMidnight(BigInteger nanosecondsS return new PlcLTIME_OF_DAY(LocalTime.ofNanoOfDay(nanosecondsSinceMidnight.longValue())); } - public PlcLTIME_OF_DAY(LocalTime value) { - super(value, true); + public PlcLTIME_OF_DAY(Byte millisecondsSinceMidnight) { + this.value = LocalTime.ofNanoOfDay((long) millisecondsSinceMidnight * 1000000); + this.isNullable = false; } - public PlcLTIME_OF_DAY(Long nanosecondsSinceMidnight) { - super(LocalTime.ofNanoOfDay(nanosecondsSinceMidnight), true); + public PlcLTIME_OF_DAY(Short millisecondsSinceMidnight) { + this.value = LocalTime.ofNanoOfDay((long) millisecondsSinceMidnight * 1000000); + this.isNullable = false; } - public PlcLTIME_OF_DAY(BigInteger nanosecondsSinceMidnight) { - // TODO: Not 100% correct, we're loosing precision here - super(LocalTime.ofNanoOfDay(nanosecondsSinceMidnight.longValue()), true); + public PlcLTIME_OF_DAY(Integer millisecondsSinceMidnight) { + this.value = LocalTime.ofNanoOfDay((long) millisecondsSinceMidnight * 1000000); + this.isNullable = false; + } + + public PlcLTIME_OF_DAY(Long millisecondsSinceMidnight) { + this.value = LocalTime.ofNanoOfDay(millisecondsSinceMidnight * 1000000); + this.isNullable = false; + } + + public PlcLTIME_OF_DAY(Float millisecondsSinceMidnight) { + this.value = LocalTime.ofNanoOfDay(millisecondsSinceMidnight.longValue() * 1000000); + this.isNullable = false; + } + + public PlcLTIME_OF_DAY(Double millisecondsSinceMidnight) { + this.value = LocalTime.ofNanoOfDay(millisecondsSinceMidnight.longValue() * 1000000); + this.isNullable = false; + } + + public PlcLTIME_OF_DAY(BigInteger millisecondsSinceMidnight) { + this.value = LocalTime.ofNanoOfDay(millisecondsSinceMidnight.longValue() * 1000000); + this.isNullable = false; + } + + public PlcLTIME_OF_DAY(BigDecimal millisecondsSinceMidnight) { + this.value = LocalTime.ofNanoOfDay(millisecondsSinceMidnight.longValue() * 1000000); + this.isNullable = false; + } + + public PlcLTIME_OF_DAY(LocalTime value) { + this.value = value; + this.isNullable = false; } @Override diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLWORD.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLWORD.java index c0b055a6a05..bceed5dcd8e 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLWORD.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLWORD.java @@ -30,11 +30,13 @@ public class PlcLWORD extends PlcIECValue { private static final String VALUE_OUT_OF_RANGE = "Value of type %s is out of range %d - %d for a %s Value"; - static final BigInteger minValue = BigInteger.valueOf(0); - static final BigInteger maxValue = BigInteger.valueOf(Long.MAX_VALUE).multiply(BigInteger.valueOf(2)).add(BigInteger.valueOf(1)); + public static final BigInteger MIN_VALUE = BigInteger.valueOf(0); + public static final BigInteger MAX_VALUE = BigInteger.valueOf(Long.MAX_VALUE).multiply(BigInteger.valueOf(2)).add(BigInteger.valueOf(1)); public static PlcLWORD of(Object value) { - if (value instanceof Boolean) { + if (value instanceof PlcLWORD) { + return (PlcLWORD) value; + } else if (value instanceof Boolean) { return new PlcLWORD((Boolean) value); } else if (value instanceof Byte) { return new PlcLWORD((Byte) value); @@ -53,7 +55,7 @@ public static PlcLWORD of(Object value) { } else if (value instanceof BigDecimal) { return new PlcLWORD((BigDecimal) value); } else { - return new PlcLWORD((String) value); + return new PlcLWORD(value.toString()); } } @@ -64,8 +66,8 @@ public PlcLWORD(Boolean value) { public PlcLWORD(Byte value) { BigInteger val = BigInteger.valueOf(value); - if ((val.compareTo(minValue) < 0) || (val.compareTo(maxValue) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((val.compareTo(MIN_VALUE) < 0) || (val.compareTo(MAX_VALUE) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = val; this.isNullable = false; @@ -73,8 +75,8 @@ public PlcLWORD(Byte value) { public PlcLWORD(Short value) { BigInteger val = BigInteger.valueOf(value); - if ((val.compareTo(minValue) < 0) || (val.compareTo(maxValue) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((val.compareTo(MIN_VALUE) < 0) || (val.compareTo(MAX_VALUE) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = val; this.isNullable = false; @@ -82,8 +84,8 @@ public PlcLWORD(Short value) { public PlcLWORD(Integer value) { BigInteger val = BigInteger.valueOf(value); - if ((val.compareTo(minValue) < 0) || (val.compareTo(maxValue) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((val.compareTo(MIN_VALUE) < 0) || (val.compareTo(MAX_VALUE) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = val; this.isNullable = false; @@ -91,8 +93,8 @@ public PlcLWORD(Integer value) { public PlcLWORD(Long value) { BigInteger val = BigInteger.valueOf(value); - if ((val.compareTo(minValue) < 0) || (val.compareTo(maxValue) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((val.compareTo(MIN_VALUE) < 0) || (val.compareTo(MAX_VALUE) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = val; this.isNullable = false; @@ -101,32 +103,32 @@ public PlcLWORD(Long value) { public PlcLWORD(Float value) { try { BigInteger val = BigDecimal.valueOf(value).toBigInteger(); - if ((val.compareTo(minValue) < 0) || (val.compareTo(maxValue) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((val.compareTo(MIN_VALUE) < 0) || (val.compareTo(MAX_VALUE) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = val; this.isNullable = false; } catch (Exception e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName()), e); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName()), e); } } public PlcLWORD(Double value) { try { BigInteger val = BigDecimal.valueOf(value).toBigInteger(); - if ((val.compareTo(minValue) < 0) || (val.compareTo(maxValue) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((val.compareTo(MIN_VALUE) < 0) || (val.compareTo(MAX_VALUE) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = val; this.isNullable = false; } catch (Exception e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName()), e); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName()), e); } } public PlcLWORD(BigInteger value) { - if ((value.compareTo(minValue) < 0) || (value.compareTo(maxValue) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value.compareTo(MIN_VALUE) < 0) || (value.compareTo(MAX_VALUE) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value; this.isNullable = false; @@ -135,26 +137,26 @@ public PlcLWORD(BigInteger value) { public PlcLWORD(BigDecimal value) { try { BigInteger val = value.toBigInteger(); - if ((val.compareTo(minValue) < 0) || (val.compareTo(maxValue) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((val.compareTo(MIN_VALUE) < 0) || (val.compareTo(MAX_VALUE) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = val; this.isNullable = false; } catch (Exception e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName()), e); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName()), e); } } public PlcLWORD(String value) { try { BigInteger val = new BigInteger(value.trim()); - if ((val.compareTo(minValue) < 0) || (val.compareTo(maxValue) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((val.compareTo(MIN_VALUE) < 0) || (val.compareTo(MAX_VALUE) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = val; this.isNullable = false; } catch (Exception e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName()), e); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName()), e); } } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcList.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcList.java index 4f1fb5f5b01..998280e5782 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcList.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcList.java @@ -26,7 +26,6 @@ import org.apache.plc4x.java.spi.utils.Serializable; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.stream.Collectors; diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcREAL.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcREAL.java index f919cacecb0..3e1df5abf15 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcREAL.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcREAL.java @@ -29,11 +29,13 @@ public class PlcREAL extends PlcIECValue { private static final String VALUE_OUT_OF_RANGE = "Value of type %s is out of range %f - %f for a %s Value"; - static final Float minValue = -Float.MAX_VALUE; - static final Float maxValue = Float.MAX_VALUE; + public static final Float MIN_VALUE = -Float.MAX_VALUE; + public static final Float MAX_VALUE = Float.MAX_VALUE; public static PlcREAL of(Object value) { - if (value instanceof Boolean) { + if (value instanceof PlcREAL) { + return (PlcREAL) value; + } else if (value instanceof Boolean) { return new PlcREAL((Boolean) value); } else if (value instanceof Byte) { return new PlcREAL((Byte) value); @@ -52,7 +54,7 @@ public static PlcREAL of(Object value) { } else if (value instanceof BigDecimal) { return new PlcREAL((BigDecimal) value); } else { - return new PlcREAL((String) value); + return new PlcREAL(value.toString()); } } @@ -76,14 +78,19 @@ public PlcREAL(Integer value) { this.isNullable = false; } + public PlcREAL(Long value) { + this.value = value.floatValue(); + this.isNullable = false; + } + public PlcREAL(Float value) { this.value = value; this.isNullable = false; } public PlcREAL(Double value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.floatValue(); this.isNullable = false; @@ -91,16 +98,16 @@ public PlcREAL(Double value) { public PlcREAL(BigInteger value) { BigDecimal val = new BigDecimal(value); - if ((val.compareTo(BigDecimal.valueOf(minValue)) < 0) || (val.compareTo(BigDecimal.valueOf(maxValue)) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((val.compareTo(BigDecimal.valueOf(MIN_VALUE)) < 0) || (val.compareTo(BigDecimal.valueOf(MAX_VALUE)) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = val.floatValue(); this.isNullable = true; } public PlcREAL(BigDecimal value) { - if ((value.compareTo(BigDecimal.valueOf(minValue)) < 0) || (value.compareTo(BigDecimal.valueOf(maxValue)) > 0) || (value.scale() > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value.compareTo(BigDecimal.valueOf(MIN_VALUE)) < 0) || (value.compareTo(BigDecimal.valueOf(MAX_VALUE)) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.floatValue(); this.isNullable = true; @@ -111,7 +118,7 @@ public PlcREAL(String value) { this.value = Float.parseFloat(value.trim()); this.isNullable = false; } catch (Exception e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName()), e); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName()), e); } } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcRawByteArray.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcRawByteArray.java index 691f4e2edde..9cf8fd096d9 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcRawByteArray.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcRawByteArray.java @@ -26,7 +26,9 @@ public class PlcRawByteArray extends PlcIECValue { public static PlcRawByteArray of(Object value) { - if (value instanceof byte[]) { + if (value instanceof PlcRawByteArray) { + return (PlcRawByteArray) value; + } else if (value instanceof byte[]) { return new PlcRawByteArray((byte[]) value); } throw new IllegalArgumentException("Only byte[] supported here"); diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcSINT.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcSINT.java index 162f430caaf..27c4da0abbf 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcSINT.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcSINT.java @@ -29,11 +29,13 @@ public class PlcSINT extends PlcIECValue { private static final String VALUE_OUT_OF_RANGE = "Value of type %s is out of range %d - %d for a %s Value"; - static final Byte minValue = Byte.MIN_VALUE; - static final Byte maxValue = Byte.MAX_VALUE; + public static final Byte MIN_VALUE = Byte.MIN_VALUE; + public static final Byte MAX_VALUE = Byte.MAX_VALUE; public static PlcSINT of(Object value) { - if (value instanceof Boolean) { + if (value instanceof PlcSINT) { + return (PlcSINT) value; + } else if (value instanceof Boolean) { return new PlcSINT((Boolean) value); } else if (value instanceof Byte) { return new PlcSINT((Byte) value); @@ -52,7 +54,7 @@ public static PlcSINT of(Object value) { } else if (value instanceof BigDecimal) { return new PlcSINT((BigDecimal) value); } else { - return new PlcSINT((String) value); + return new PlcSINT(value.toString()); } } @@ -67,56 +69,56 @@ public PlcSINT(Byte value) { } public PlcSINT(Short value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.byteValue(); this.isNullable = false; } public PlcSINT(Integer value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.byteValue(); this.isNullable = false; } public PlcSINT(Long value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.byteValue(); this.isNullable = false; } public PlcSINT(Float value) { - if ((value < minValue) || (value > maxValue) || (value % 1 != 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.byteValue(); this.isNullable = false; } public PlcSINT(Double value) { - if ((value < minValue) || (value > maxValue) || (value % 1 != 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.byteValue(); this.isNullable = false; } public PlcSINT(BigInteger value) { - if ((value.compareTo(BigInteger.valueOf(minValue)) < 0) || (value.compareTo(BigInteger.valueOf(maxValue)) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value.compareTo(BigInteger.valueOf(MIN_VALUE)) < 0) || (value.compareTo(BigInteger.valueOf(MAX_VALUE)) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.byteValue(); this.isNullable = true; } public PlcSINT(BigDecimal value) { - if ((value.compareTo(BigDecimal.valueOf(minValue)) < 0) || (value.compareTo(BigDecimal.valueOf(maxValue)) > 0) || (value.scale() > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value.compareTo(BigDecimal.valueOf(MIN_VALUE)) < 0) || (value.compareTo(BigDecimal.valueOf(MAX_VALUE)) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.byteValue(); this.isNullable = true; @@ -127,7 +129,7 @@ public PlcSINT(String value) { this.value = Byte.valueOf(value.trim()); this.isNullable = false; } catch (Exception e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName()), e); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName()), e); } } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcSTRING.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcSTRING.java index ba84b08d92a..279bc88849e 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcSTRING.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcSTRING.java @@ -27,17 +27,20 @@ import java.math.BigInteger; import java.nio.charset.StandardCharsets; -public class PlcSTRING extends PlcSimpleValue { +public class PlcSTRING extends PlcIECValue { public static PlcSTRING of(Object value) { - if (value instanceof String) { + if (value instanceof PlcSTRING) { + return (PlcSTRING) value; + } else if (value instanceof String) { return new PlcSTRING((String) value); } return new PlcSTRING(String.valueOf(value)); } public PlcSTRING(String value) { - super(value, true); + this.value = value; + this.isNullable = false; } @Override @@ -200,7 +203,7 @@ public int getLength() { @Override public String toString() { - return "\"" + value + "\""; + return value; } @Override diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcSimpleValue.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcSimpleValue.java deleted file mode 100644 index 5746a8d27d2..00000000000 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcSimpleValue.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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. - */ -package org.apache.plc4x.java.spi.values; - -import org.apache.plc4x.java.api.value.PlcValue; - -public abstract class PlcSimpleValue extends PlcValueAdapter { - - final T value; - final boolean isNullable; - - PlcSimpleValue(T value, boolean isNullable) { - this.value = value; - this.isNullable = isNullable; - } - - @Override - public Object getObject() { - return value; - } - - @Override - public int getLength() { - return 1; - } - - @Override - public boolean isSimple() { - return true; - } - - @Override - public boolean isNullable() { - return isNullable; - } - - @Override - public boolean isNull() { - return isNullable && value == null; - } - - /** - * Convenience method to simplify accessing items with a list syntax. - * @param i item number - * @return if i == 0 returns itself, otherwise throws an exception. - */ - @Override - public PlcValue getIndex(int i) { - if(i == 0) { - return this; - } - return super.getIndex(i); - } - -} diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcTIME.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcTIME.java index 40876e4f880..730ce80e8e1 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcTIME.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcTIME.java @@ -18,40 +18,91 @@ */ package org.apache.plc4x.java.spi.values; -import org.apache.plc4x.java.api.exceptions.PlcRuntimeException; import org.apache.plc4x.java.api.types.PlcValueType; -import org.apache.plc4x.java.spi.codegen.WithOption; import org.apache.plc4x.java.spi.generation.SerializationException; import org.apache.plc4x.java.spi.generation.WriteBuffer; -import java.nio.charset.StandardCharsets; +import java.math.BigDecimal; +import java.math.BigInteger; import java.time.Duration; import java.time.temporal.ChronoUnit; -import java.time.temporal.TemporalUnit; -public class PlcTIME extends PlcSimpleValue { +public class PlcTIME extends PlcIECValue { public static PlcTIME of(Object value) { - if (value instanceof Duration) { + if (value instanceof PlcTIME) { + return (PlcTIME) value; + } else if (value instanceof Duration) { return new PlcTIME((Duration) value); + } else if (value instanceof Byte) { + return new PlcTIME((Byte) value); + } else if (value instanceof Short) { + return new PlcTIME((Short) value); } else if (value instanceof Integer) { - return new PlcTIME(Duration.of((long) value, ChronoUnit.MILLIS)); + return new PlcTIME((Integer) value); } else if (value instanceof Long) { - return new PlcTIME(Duration.of((long) value, ChronoUnit.MILLIS)); + return new PlcTIME((Long) value); + } else if (value instanceof Float) { + return new PlcTIME((Float) value); + } else if (value instanceof Double) { + return new PlcTIME((Double) value); + } else if (value instanceof BigInteger) { + return new PlcTIME((BigInteger) value); + } else if (value instanceof BigDecimal) { + return new PlcTIME((BigDecimal) value); + } else { + return new PlcTIME(Duration.parse(value.toString())); } - throw new PlcRuntimeException("Invalid value type"); + //throw new PlcRuntimeException("Invalid value type"); } public static PlcTIME ofMilliseconds(long milliseconds) { return new PlcTIME(Duration.ofMillis(milliseconds)); } - public PlcTIME(Duration value) { - super(value, true); + public PlcTIME(Byte milliseconds) { + this.value = Duration.ofMillis(milliseconds); + this.isNullable = false; + } + + public PlcTIME(Short milliseconds) { + this.value = Duration.ofMillis(milliseconds); + this.isNullable = false; + } + + public PlcTIME(Integer milliseconds) { + this.value = Duration.ofMillis(milliseconds); + this.isNullable = false; + } + + public PlcTIME(Long milliseconds) { + this.value = Duration.ofMillis(milliseconds); + this.isNullable = false; + } + + public PlcTIME(Float milliseconds) { + this.value = Duration.ofMillis(milliseconds.longValue()); + this.isNullable = false; + } + + public PlcTIME(Double milliseconds) { + this.value = Duration.ofMillis(milliseconds.longValue()); + this.isNullable = false; + } + + public PlcTIME(BigInteger milliseconds) { + this.value = Duration.ofMillis(milliseconds.longValue()); + this.isNullable = false; + } + + public PlcTIME(BigDecimal milliseconds) { + this.value = Duration.ofMillis(milliseconds.longValue()); + this.isNullable = false; } - public PlcTIME(long milliseconds) { - super(Duration.ofMillis(milliseconds), true); + public PlcTIME(Duration value) { + this.value = value; + this.isNullable = false; } @Override diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcTIME_OF_DAY.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcTIME_OF_DAY.java index da75f58d6f8..76f3854b3f6 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcTIME_OF_DAY.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcTIME_OF_DAY.java @@ -18,36 +18,91 @@ */ package org.apache.plc4x.java.spi.values; -import org.apache.plc4x.java.api.exceptions.PlcRuntimeException; import org.apache.plc4x.java.api.types.PlcValueType; import org.apache.plc4x.java.spi.codegen.WithOption; import org.apache.plc4x.java.spi.generation.SerializationException; import org.apache.plc4x.java.spi.generation.WriteBuffer; +import java.math.BigDecimal; +import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.time.LocalTime; -public class PlcTIME_OF_DAY extends PlcSimpleValue { +public class PlcTIME_OF_DAY extends PlcIECValue { public static PlcTIME_OF_DAY of(Object value) { - if (value instanceof LocalTime) { + if (value instanceof PlcTIME_OF_DAY) { + return (PlcTIME_OF_DAY) value; + } else if (value instanceof LocalTime) { return new PlcTIME_OF_DAY((LocalTime) value); - } else if(value instanceof Long) { + } else if (value instanceof Byte) { + return new PlcTIME_OF_DAY((Byte) value); + } else if (value instanceof Short) { + return new PlcTIME_OF_DAY((Short) value); + } else if (value instanceof Integer) { + return new PlcTIME_OF_DAY((Integer) value); + } else if (value instanceof Long) { return new PlcTIME_OF_DAY((Long) value); + } else if (value instanceof Float) { + return new PlcTIME_OF_DAY((Float) value); + } else if (value instanceof Double) { + return new PlcTIME_OF_DAY((Double) value); + } else if (value instanceof BigInteger) { + return new PlcTIME_OF_DAY((BigInteger) value); + } else if (value instanceof BigDecimal) { + return new PlcTIME_OF_DAY((BigDecimal) value); + } else { + return new PlcTIME_OF_DAY(LocalTime.parse(value.toString())); } - throw new PlcRuntimeException("Invalid value type"); } public static PlcTIME_OF_DAY ofMillisecondsSinceMidnight(long millisecondsSinceMidnight) { return new PlcTIME_OF_DAY(LocalTime.ofNanoOfDay(millisecondsSinceMidnight * 1000_000)); } - public PlcTIME_OF_DAY(LocalTime value) { - super(value, true); + public PlcTIME_OF_DAY(Byte secondsSinceMidnight) { + this.value = LocalTime.ofSecondOfDay(secondsSinceMidnight); + this.isNullable = false; + } + + public PlcTIME_OF_DAY(Short secondsSinceMidnight) { + this.value = LocalTime.ofSecondOfDay(secondsSinceMidnight); + this.isNullable = false; + } + + public PlcTIME_OF_DAY(Integer secondsSinceMidnight) { + this.value = LocalTime.ofSecondOfDay(secondsSinceMidnight); + this.isNullable = false; + } + + public PlcTIME_OF_DAY(Long secondsSinceMidnight) { + this.value = LocalTime.ofSecondOfDay(secondsSinceMidnight); + this.isNullable = false; + } + + public PlcTIME_OF_DAY(Float secondsSinceMidnight) { + this.value = LocalTime.ofSecondOfDay(secondsSinceMidnight.longValue()); + this.isNullable = false; + } + + public PlcTIME_OF_DAY(Double secondsSinceMidnight) { + this.value = LocalTime.ofSecondOfDay(secondsSinceMidnight.longValue()); + this.isNullable = false; + } + + public PlcTIME_OF_DAY(BigInteger secondsSinceMidnight) { + this.value = LocalTime.ofSecondOfDay(secondsSinceMidnight.longValue()); + this.isNullable = false; + } + + public PlcTIME_OF_DAY(BigDecimal secondsSinceMidnight) { + this.value = LocalTime.ofSecondOfDay(secondsSinceMidnight.longValue()); + this.isNullable = false; } - public PlcTIME_OF_DAY(long millisecondsSinceMidnight) { - super(LocalTime.ofNanoOfDay(millisecondsSinceMidnight * 1000_000), true); + public PlcTIME_OF_DAY(LocalTime value) { + this.value = value; + this.isNullable = false; } @Override diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcUBINT.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcUBINT.java deleted file mode 100644 index e688f9075c2..00000000000 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcUBINT.java +++ /dev/null @@ -1,292 +0,0 @@ -/* - * 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. - */ -package org.apache.plc4x.java.spi.values; - -import org.apache.plc4x.java.api.exceptions.PlcInvalidTagException; -import org.apache.plc4x.java.api.types.PlcValueType; -import org.apache.plc4x.java.spi.generation.SerializationException; -import org.apache.plc4x.java.spi.generation.WriteBuffer; - -import java.math.BigDecimal; -import java.math.BigInteger; - -public class PlcUBINT extends PlcIECValue { - - private static final String VALUE_OUT_OF_RANGE = "Value of type %s is out of range %d - infinity for a %s Value"; - static final BigInteger minValue = BigInteger.valueOf(0); - - public static PlcUBINT of(Object value) { - if (value instanceof Boolean) { - return new PlcUBINT((Boolean) value); - } else if (value instanceof Byte) { - return new PlcUBINT((Byte) value); - } else if (value instanceof Short) { - return new PlcUBINT((Short) value); - } else if (value instanceof Integer) { - return new PlcUBINT((Integer) value); - } else if (value instanceof Long) { - return new PlcUBINT((Long) value); - } else if (value instanceof Float) { - return new PlcUBINT((Float) value); - } else if (value instanceof Double) { - return new PlcUBINT((Double) value); - } else if (value instanceof BigInteger) { - return new PlcUBINT((BigInteger) value); - } else if (value instanceof BigDecimal) { - return new PlcUBINT((BigDecimal) value); - } else { - return new PlcUBINT((String) value); - } - } - - public PlcUBINT(Boolean value) { - this.value = value ? BigInteger.valueOf(1) : BigInteger.valueOf(0); - this.isNullable = false; - } - - public PlcUBINT(Byte value) { - BigInteger val = BigInteger.valueOf(value); - if (val.compareTo(minValue) < 0) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, this.getClass().getSimpleName())); - } - this.value = val; - this.isNullable = false; - } - - public PlcUBINT(Short value) { - BigInteger val = BigInteger.valueOf(value); - if (val.compareTo(minValue) < 0) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, this.getClass().getSimpleName())); - } - this.value = val; - this.isNullable = false; - } - - public PlcUBINT(Integer value) { - BigInteger val = BigInteger.valueOf(value); - if (val.compareTo(minValue) < 0) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, this.getClass().getSimpleName())); - } - this.value = val; - this.isNullable = false; - } - - public PlcUBINT(Long value) { - BigInteger val = BigInteger.valueOf(value); - if (val.compareTo(minValue) < 0) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, this.getClass().getSimpleName())); - } - this.value = val; - this.isNullable = false; - } - - public PlcUBINT(Float value) { - try { - BigInteger val = BigDecimal.valueOf(value).toBigInteger(); - if (val.compareTo(minValue) < 0) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, this.getClass().getSimpleName())); - } - this.value = val; - this.isNullable = false; - } catch (Exception e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, this.getClass().getSimpleName()), e); - } - } - - public PlcUBINT(Double value) { - try { - BigInteger val = BigDecimal.valueOf(value).toBigInteger(); - if (val.compareTo(minValue) < 0) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, this.getClass().getSimpleName())); - } - this.value = val; - this.isNullable = false; - } catch (Exception e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, this.getClass().getSimpleName()), e); - } - } - - public PlcUBINT(BigInteger value) { - if (value.compareTo(minValue) < 0) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, this.getClass().getSimpleName())); - } - this.value = value; - this.isNullable = false; - } - - public PlcUBINT(BigDecimal value) { - try { - BigInteger val = value.toBigInteger(); - if (val.compareTo(minValue) < 0) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, this.getClass().getSimpleName())); - } - this.value = val; - this.isNullable = false; - } catch (Exception e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, this.getClass().getSimpleName()), e); - } - } - - public PlcUBINT(String value) { - try { - BigInteger val = new BigInteger(value.trim()); - if (val.compareTo(minValue) < 0) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, this.getClass().getSimpleName())); - } - this.value = val; - this.isNullable = false; - } catch (Exception e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, this.getClass().getSimpleName()), e); - } - } - - @Override - public PlcValueType getPlcValueType() { - return PlcValueType.ULINT; - } - - @Override - public boolean isBoolean() { - return true; - } - - @Override - public boolean getBoolean() { - return (value != null) && !value.equals(BigInteger.ZERO); - } - - @Override - public boolean isByte() { - return (value != null) && (value.compareTo(BigInteger.valueOf(Byte.MAX_VALUE)) <= 0) && (value.compareTo(BigInteger.valueOf(Byte.MIN_VALUE)) >= 0); - } - - @Override - public byte getByte() { - return value.byteValue(); - } - - @Override - public boolean isShort() { - return (value != null) && (value.compareTo(BigInteger.valueOf(Short.MAX_VALUE)) <= 0) && (value.compareTo(BigInteger.valueOf(Short.MIN_VALUE)) >= 0); - } - - @Override - public short getShort() { - return value.shortValue(); - } - - @Override - public boolean isInteger() { - return (value != null) && (value.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) <= 0) && (value.compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) >= 0); - } - - @Override - public int getInteger() { - return value.intValue(); - } - - @Override - public boolean isLong() { - return (value != null) && (value.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) <= 0) && (value.compareTo(BigInteger.valueOf(Long.MIN_VALUE)) >= 0); - } - - @Override - public long getLong() { - return value.longValue(); - } - - @Override - public boolean isBigInteger() { - return true; - } - - @Override - public BigInteger getBigInteger() { - return value; - } - - @Override - public boolean isFloat() { - return true; - } - - @Override - public float getFloat() { - return value.floatValue(); - } - - @Override - public boolean isDouble() { - return true; - } - - @Override - public double getDouble() { - return value.doubleValue(); - } - - @Override - public boolean isBigDecimal() { - return true; - } - - @Override - public BigDecimal getBigDecimal() { - return new BigDecimal(value); - } - - @Override - public boolean isString() { - return true; - } - - @Override - public String getString() { - return toString(); - } - - @Override - public String toString() { - return value.toString(); - } - - @Override - public byte[] getRaw() { - return getBytes(); - } - - public byte[] getBytes() { - byte[] tmp = value.toByteArray(); - byte[] bytes = new byte[8]; - for (int i = 0; i < bytes.length; i++) { - if (i >= (bytes.length - tmp.length)) { - bytes[i] = tmp[i - (bytes.length - tmp.length)]; - } else { - bytes[i] = 0x00; - } - } - return bytes; - } - - @Override - public void serialize(WriteBuffer writeBuffer) throws SerializationException { - writeBuffer.writeBigInteger(getClass().getSimpleName(), 64, value); - } - -} diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcUDINT.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcUDINT.java index ede2fa8a038..eea7f77b30f 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcUDINT.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcUDINT.java @@ -29,11 +29,13 @@ public class PlcUDINT extends PlcIECValue { private static final String VALUE_OUT_OF_RANGE = "Value of type %s is out of range %d - %d for a %s Value"; - static final Long minValue = (long) 0; - static final Long maxValue = (long) Integer.MAX_VALUE * 2 + 1; + public static final Long MIN_VALUE = (long) 0; + public static final Long MAX_VALUE = (long) Integer.MAX_VALUE * 2 + 1; public static PlcUDINT of(Object value) { - if (value instanceof Boolean) { + if (value instanceof PlcUDINT) { + return (PlcUDINT) value; + } else if (value instanceof Boolean) { return new PlcUDINT((Boolean) value); } else if (value instanceof Byte) { return new PlcUDINT((Byte) value); @@ -52,7 +54,7 @@ public static PlcUDINT of(Object value) { } else if (value instanceof BigDecimal) { return new PlcUDINT((BigDecimal) value); } else { - return new PlcUDINT((String) value); + return new PlcUDINT(value.toString()); } } @@ -62,57 +64,57 @@ public PlcUDINT(Boolean value) { } public PlcUDINT(Byte value) { - if (value < minValue || value > maxValue) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if (value < MIN_VALUE || value > MAX_VALUE) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.longValue(); this.isNullable = false; } public PlcUDINT(Short value) { - if (value < minValue || value > maxValue) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if (value < MIN_VALUE || value > MAX_VALUE) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.longValue(); this.isNullable = false; } public PlcUDINT(Integer value) { - if (value < minValue || value > maxValue) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if (value < MIN_VALUE || value > MAX_VALUE) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.longValue(); this.isNullable = false; } public PlcUDINT(Long value) { - if (value < minValue || value > maxValue) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if (value < MIN_VALUE || value > MAX_VALUE) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value; this.isNullable = false; } public PlcUDINT(Float value) { - if ((value < minValue) || (value > maxValue) || (value % 1 != 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.longValue(); this.isNullable = false; } public PlcUDINT(Double value) { - if ((value < minValue) || (value > maxValue) || (value % 1 != 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.longValue(); this.isNullable = false; } public PlcUDINT(BigInteger value) { - if ((value.compareTo(BigInteger.valueOf(minValue)) < 0) || (value.compareTo(BigInteger.valueOf(maxValue)) > 0)) { + if ((value.compareTo(BigInteger.valueOf(MIN_VALUE)) < 0) || (value.compareTo(BigInteger.valueOf(MAX_VALUE)) > 0)) { throw new PlcInvalidTagException("Value of type " + value + - " is out of range " + minValue + " - " + maxValue + " for a " + + " is out of range " + MIN_VALUE + " - " + MAX_VALUE + " for a " + this.getClass().getSimpleName() + " Value"); } this.value = value.longValue(); @@ -120,8 +122,8 @@ public PlcUDINT(BigInteger value) { } public PlcUDINT(BigDecimal value) { - if ((value.compareTo(BigDecimal.valueOf(minValue)) < 0) || (value.compareTo(BigDecimal.valueOf(maxValue)) > 0) || (value.scale() > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value.compareTo(BigDecimal.valueOf(MIN_VALUE)) < 0) || (value.compareTo(BigDecimal.valueOf(MAX_VALUE)) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.longValue(); this.isNullable = true; @@ -130,20 +132,20 @@ public PlcUDINT(BigDecimal value) { public PlcUDINT(String value) { try { long val = Long.parseLong(value.trim()); - if (val >= minValue && val <= maxValue) { + if (val >= MIN_VALUE && val <= MAX_VALUE) { this.value = val; this.isNullable = false; } else { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } } catch (Exception e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } } public PlcUDINT(long value) { - if (value < minValue || value > maxValue) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if (value < MIN_VALUE || value > MAX_VALUE) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value; this.isNullable = false; diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcUINT.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcUINT.java index ee7a66c4f5d..3615653d951 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcUINT.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcUINT.java @@ -29,11 +29,13 @@ public class PlcUINT extends PlcIECValue { private static final String VALUE_OUT_OF_RANGE = "Value of type %s is out of range %d - %d for a %s Value"; - static final Integer minValue = 0; - static final Integer maxValue = Short.MAX_VALUE * 2 + 1; + public static final Integer MIN_VALUE = 0; + public static final Integer MAX_VALUE = Short.MAX_VALUE * 2 + 1; public static PlcUINT of(Object value) { - if (value instanceof Boolean) { + if (value instanceof PlcUINT) { + return (PlcUINT) value; + } else if (value instanceof Boolean) { return new PlcUINT((Boolean) value); } else if (value instanceof Byte) { return new PlcUINT((Byte) value); @@ -52,7 +54,7 @@ public static PlcUINT of(Object value) { } else if (value instanceof BigDecimal) { return new PlcUINT((BigDecimal) value); } else { - return new PlcUINT((String) value); + return new PlcUINT(value.toString()); } } @@ -67,56 +69,56 @@ public PlcUINT(Byte value) { } public PlcUINT(Short value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.intValue(); this.isNullable = false; } public PlcUINT(Integer value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value; this.isNullable = false; } public PlcUINT(Long value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.intValue(); this.isNullable = false; } public PlcUINT(Float value) { - if ((value < minValue) || (value > maxValue) || (value % 1 != 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.intValue(); this.isNullable = false; } public PlcUINT(Double value) { - if ((value < minValue) || (value > maxValue) || (value % 1 != 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.intValue(); this.isNullable = false; } public PlcUINT(BigInteger value) { - if ((value.compareTo(BigInteger.valueOf(minValue)) < 0) || (value.compareTo(BigInteger.valueOf(maxValue)) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value.compareTo(BigInteger.valueOf(MIN_VALUE)) < 0) || (value.compareTo(BigInteger.valueOf(MAX_VALUE)) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.intValue(); this.isNullable = true; } public PlcUINT(BigDecimal value) { - if ((value.compareTo(BigDecimal.valueOf(minValue)) < 0) || (value.compareTo(BigDecimal.valueOf(maxValue)) > 0) || (value.scale() > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value.compareTo(BigDecimal.valueOf(MIN_VALUE)) < 0) || (value.compareTo(BigDecimal.valueOf(MAX_VALUE)) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.intValue(); this.isNullable = true; @@ -125,19 +127,19 @@ public PlcUINT(BigDecimal value) { public PlcUINT(String value) { try { int val = Integer.parseInt(value.trim()); - if ((val < minValue) || (val > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((val < MIN_VALUE) || (val > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = val; this.isNullable = false; } catch (Exception e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } } public PlcUINT(int value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value; this.isNullable = false; diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcULINT.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcULINT.java index f9107815ae7..479fa04316f 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcULINT.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcULINT.java @@ -29,11 +29,13 @@ public class PlcULINT extends PlcIECValue { private static final String VALUE_OUT_OF_RANGE = "Value of type %s is out of range %d - %d for a %s Value"; - static final BigInteger minValue = BigInteger.valueOf(0); - static final BigInteger maxValue = BigInteger.valueOf(Long.MAX_VALUE).multiply(BigInteger.valueOf(2)).add(BigInteger.valueOf(1)); + public static final BigInteger MIN_VALUE = BigInteger.valueOf(0); + public static final BigInteger MAX_VALUE = BigInteger.valueOf(Long.MAX_VALUE).multiply(BigInteger.valueOf(2)).add(BigInteger.valueOf(1)); public static PlcULINT of(Object value) { - if (value instanceof Boolean) { + if (value instanceof PlcULINT) { + return (PlcULINT) value; + } else if (value instanceof Boolean) { return new PlcULINT((Boolean) value); } else if (value instanceof Byte) { return new PlcULINT((Byte) value); @@ -52,7 +54,7 @@ public static PlcULINT of(Object value) { } else if (value instanceof BigDecimal) { return new PlcULINT((BigDecimal) value); } else { - return new PlcULINT((String) value); + return new PlcULINT(value.toString()); } } @@ -63,8 +65,8 @@ public PlcULINT(Boolean value) { public PlcULINT(Byte value) { BigInteger val = BigInteger.valueOf(value); - if ((val.compareTo(minValue) < 0) || (val.compareTo(maxValue) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((val.compareTo(MIN_VALUE) < 0) || (val.compareTo(MAX_VALUE) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = val; this.isNullable = false; @@ -72,8 +74,8 @@ public PlcULINT(Byte value) { public PlcULINT(Short value) { BigInteger val = BigInteger.valueOf(value); - if ((val.compareTo(minValue) < 0) || (val.compareTo(maxValue) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((val.compareTo(MIN_VALUE) < 0) || (val.compareTo(MAX_VALUE) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = val; this.isNullable = false; @@ -81,8 +83,8 @@ public PlcULINT(Short value) { public PlcULINT(Integer value) { BigInteger val = BigInteger.valueOf(value); - if ((val.compareTo(minValue) < 0) || (val.compareTo(maxValue) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((val.compareTo(MIN_VALUE) < 0) || (val.compareTo(MAX_VALUE) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = val; this.isNullable = false; @@ -90,8 +92,8 @@ public PlcULINT(Integer value) { public PlcULINT(Long value) { BigInteger val = BigInteger.valueOf(value); - if ((val.compareTo(minValue) < 0) || (val.compareTo(maxValue) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((val.compareTo(MIN_VALUE) < 0) || (val.compareTo(MAX_VALUE) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = val; this.isNullable = false; @@ -100,32 +102,32 @@ public PlcULINT(Long value) { public PlcULINT(Float value) { try { BigInteger val = BigDecimal.valueOf(value).toBigInteger(); - if ((val.compareTo(minValue) < 0) || (val.compareTo(maxValue) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((val.compareTo(MIN_VALUE) < 0) || (val.compareTo(MAX_VALUE) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = val; this.isNullable = false; } catch (Exception e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName()), e); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName()), e); } } public PlcULINT(Double value) { try { BigInteger val = BigDecimal.valueOf(value).toBigInteger(); - if ((val.compareTo(minValue) < 0) || (val.compareTo(maxValue) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((val.compareTo(MIN_VALUE) < 0) || (val.compareTo(MAX_VALUE) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = val; this.isNullable = false; } catch (Exception e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName()), e); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName()), e); } } public PlcULINT(BigInteger value) { - if ((value.compareTo(minValue) < 0) || (value.compareTo(maxValue) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value.compareTo(MIN_VALUE) < 0) || (value.compareTo(MAX_VALUE) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value; this.isNullable = false; @@ -134,26 +136,26 @@ public PlcULINT(BigInteger value) { public PlcULINT(BigDecimal value) { try { BigInteger val = value.toBigInteger(); - if ((val.compareTo(minValue) < 0) || (val.compareTo(maxValue) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((val.compareTo(MIN_VALUE) < 0) || (val.compareTo(MAX_VALUE) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = val; this.isNullable = false; } catch (Exception e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName()), e); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName()), e); } } public PlcULINT(String value) { try { BigInteger val = new BigInteger(value.trim()); - if ((val.compareTo(minValue) < 0) || (val.compareTo(maxValue) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((val.compareTo(MIN_VALUE) < 0) || (val.compareTo(MAX_VALUE) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = val; this.isNullable = false; } catch (Exception e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName()), e); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName()), e); } } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcUSINT.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcUSINT.java index d6f16e8b2b7..c496ea832fc 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcUSINT.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcUSINT.java @@ -29,11 +29,13 @@ public class PlcUSINT extends PlcIECValue { private static final String VALUE_OUT_OF_RANGE = "Value of type %s is out of range %d - %d for a %s Value"; - static final Short minValue = 0; - static final Short maxValue = (short) Byte.MAX_VALUE * 2 + 1; + public static final Short MIN_VALUE = 0; + public static final Short MAX_VALUE = (short) Byte.MAX_VALUE * 2 + 1; public static PlcUSINT of(Object value) { - if (value instanceof Boolean) { + if (value instanceof PlcUSINT) { + return (PlcUSINT) value; + } else if (value instanceof Boolean) { return new PlcUSINT((Boolean) value); } else if (value instanceof Byte) { return new PlcUSINT((Byte) value); @@ -52,7 +54,7 @@ public static PlcUSINT of(Object value) { } else if (value instanceof BigDecimal) { return new PlcUSINT((BigDecimal) value); } else { - return new PlcUSINT((String) value); + return new PlcUSINT(value.toString()); } } @@ -62,64 +64,64 @@ public PlcUSINT(Boolean value) { } public PlcUSINT(Byte value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.shortValue(); this.isNullable = false; } public PlcUSINT(Short value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value; this.isNullable = false; } public PlcUSINT(Integer value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.shortValue(); this.isNullable = false; } public PlcUSINT(Long value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.shortValue(); this.isNullable = false; } public PlcUSINT(Float value) { - if ((value < minValue) || (value > maxValue) || (value % 1 != 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.shortValue(); this.isNullable = false; } public PlcUSINT(Double value) { - if ((value < minValue) || (value > maxValue) || (value % 1 != 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.shortValue(); this.isNullable = false; } public PlcUSINT(BigInteger value) { - if ((value.compareTo(BigInteger.valueOf(minValue)) < 0) || (value.compareTo(BigInteger.valueOf(maxValue)) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value.compareTo(BigInteger.valueOf(MIN_VALUE)) < 0) || (value.compareTo(BigInteger.valueOf(MAX_VALUE)) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.shortValue(); this.isNullable = true; } public PlcUSINT(BigDecimal value) { - if ((value.compareTo(BigDecimal.valueOf(minValue)) < 0) || (value.compareTo(BigDecimal.valueOf(maxValue)) > 0) || (value.scale() > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value.compareTo(BigDecimal.valueOf(MIN_VALUE)) < 0) || (value.compareTo(BigDecimal.valueOf(MAX_VALUE)) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.shortValue(); this.isNullable = true; @@ -128,19 +130,19 @@ public PlcUSINT(BigDecimal value) { public PlcUSINT(String value) { try { short val = Short.parseShort(value.trim()); - if ((val < minValue) || (val > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((val < MIN_VALUE) || (val > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = val; this.isNullable = false; } catch (Exception e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName()), e); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName()), e); } } public PlcUSINT(short value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value; this.isNullable = false; diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcValueAdapter.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcValueAdapter.java index 62ec4105e41..42a3dfe8c2d 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcValueAdapter.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcValueAdapter.java @@ -20,6 +20,7 @@ import org.apache.plc4x.java.api.exceptions.PlcIncompatibleDatatypeException; import org.apache.plc4x.java.api.value.PlcValue; +import org.apache.plc4x.java.spi.generation.WriteBufferXmlBased; import org.apache.plc4x.java.spi.utils.Serializable; import java.math.BigDecimal; @@ -28,7 +29,12 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; -import java.util.*; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; public abstract class PlcValueAdapter implements PlcValue, Serializable { @@ -290,4 +296,31 @@ public PlcValue getMetaData(String key) { return metaData.get(key); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + PlcValueAdapter that = (PlcValueAdapter) o; + try { + WriteBufferXmlBased thisWb = new WriteBufferXmlBased(); + thisWb.pushContext(getClass().getSimpleName()); + thisWb.writeSerializable(this); + thisWb.popContext(getClass().getSimpleName()); + + WriteBufferXmlBased thatWb = new WriteBufferXmlBased(); + thatWb.pushContext(o.getClass().getSimpleName()); + thatWb.writeSerializable(that); + thatWb.popContext(o.getClass().getSimpleName()); + + return thisWb.getXmlString().equals(thatWb.getXmlString()); + } catch (Exception e) { + return false; + } + } + + @Override + public int hashCode() { + return Objects.hashCode(metaData); + } + } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcValueHandler.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcValueHandler.java index 5ec85a89291..436979a833e 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcValueHandler.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcValueHandler.java @@ -7,7 +7,7 @@ * "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 + * 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 @@ -16,248 +16,14 @@ * specific language governing permissions and limitations * under the License. */ + package org.apache.plc4x.java.spi.values; -import org.apache.plc4x.java.api.exceptions.PlcRuntimeException; -import org.apache.plc4x.java.api.exceptions.PlcUnsupportedDataTypeException; import org.apache.plc4x.java.api.model.PlcTag; import org.apache.plc4x.java.api.value.PlcValue; -import java.math.BigInteger; -import java.time.Duration; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.util.List; - -public class PlcValueHandler implements org.apache.plc4x.java.api.value.PlcValueHandler { - - public PlcValue newPlcValue(Object value) { - return of(new Object[]{value}); - } - - public PlcValue newPlcValue(Object[] values) { - return of(values); - } - - public PlcValue newPlcValue(PlcTag tag, Object value) { - return of(tag, new Object[]{value}); - } - - public PlcValue newPlcValue(PlcTag tag, Object[] values) { - return of(tag, values); - } - - public static PlcValue of(Object value) { - return of(new Object[]{value}); - } - - public static PlcValue of(List value) { - return of(value.toArray()); - } - - public static PlcValue of(Object[] values) { - if (values.length != 1) { - PlcList list = new PlcList(); - for (Object value : values) { - list.add(of(new Object[]{value})); - } - return list; - } - Object value = values[0]; - if (value instanceof Boolean) { - return PlcBOOL.of(value); - } - if (value instanceof Byte) { - return PlcSINT.of(value); - } - if (value instanceof byte[]) { - return PlcRawByteArray.of(value); - } - if (value instanceof Short) { - return PlcINT.of(value); - } - if (value instanceof Integer) { - return PlcDINT.of(value); - } - if (value instanceof Long) { - return PlcLINT.of(value); - } - if (value instanceof BigInteger) { - return PlcLINT.of(value); - } - if (value instanceof Float) { - return PlcREAL.of(value); - } - if (value instanceof Double) { - return PlcLREAL.of(value); - } - if (value instanceof Duration) { - return new PlcTIME((Duration) value); - } - if (value instanceof LocalTime) { - return new PlcTIME_OF_DAY((LocalTime) value); - } - if (value instanceof LocalDate) { - return new PlcDATE((LocalDate) value); - } - if (value instanceof LocalDateTime) { - return new PlcDATE_AND_TIME((LocalDateTime) value); - } - if (value instanceof String) { - return new PlcSTRING((String) value); - } - if (value instanceof PlcValue) { - return (PlcValue) value; - } - throw new PlcUnsupportedDataTypeException("Data Type " + value.getClass() - + " Is not supported"); - } - - - public static PlcValue of(PlcTag tag, Object value) { - return of(tag, new Object[]{value}); - } - - - public static PlcValue of(PlcTag tag, Object[] values) { - if (values.length == 1) { - Object value = values[0]; - if(tag.getPlcValueType() == null) { - // TODO: This is a hacky shortcut .. - if(value instanceof PlcValue) { - return (PlcValue) value; - } - return new PlcNull(); - } - if (value instanceof PlcValue) { - PlcValue plcValue = (PlcValue) value; - if (plcValue.getPlcValueType() == tag.getPlcValueType()) { - return (PlcValue) value; - } else { - throw new PlcRuntimeException("Expected PlcValue of type " + tag.getPlcValueType().name() + " but got " + plcValue.getPlcValueType().name()); - } - } - switch (tag.getPlcValueType()) { - case BOOL: - return PlcBOOL.of(value); - case BYTE: - if(value instanceof Short) { - return new PlcBYTE((short) value); - } else if(value instanceof Integer) { - return new PlcBYTE(((Integer) value).shortValue()); - } else if(value instanceof Long) { - return new PlcBYTE(((Long) value).shortValue()); - } else if(value instanceof BigInteger) { - return new PlcBYTE(((BigInteger) value).shortValue()); - } else if(value instanceof String) { - try { - return new PlcBYTE(Short.valueOf((String) value)); - } catch (NumberFormatException e) { - throw new PlcRuntimeException("Value of " + value + " not parseable as Byte"); - } - } - throw new PlcRuntimeException("BYTE requires short"); - case SINT: - return PlcSINT.of(value); - case USINT: - return PlcUSINT.of(value); - case INT: - return PlcINT.of(value); - case UINT: - return PlcUINT.of(value); - case WORD: - if(value instanceof Short) { - return new PlcWORD((int) value); - } else if(value instanceof Integer) { - return new PlcWORD((int) value); - } else if(value instanceof Long) { - return new PlcWORD(((Long) value).intValue()); - } else if(value instanceof BigInteger) { - return new PlcWORD(((BigInteger) value).intValue()); - } else if(value instanceof String) { - try { - return new PlcWORD(Integer.valueOf((String) value)); - } catch (NumberFormatException e) { - throw new PlcRuntimeException("Value of " + value + " not parseable as Integer"); - } - } - throw new PlcRuntimeException("WORD requires int"); - case DINT: - return PlcDINT.of(value); - case UDINT: - return PlcUDINT.of(value); - case DWORD: - if(value instanceof Short) { - return new PlcDWORD((long) value); - } else if(value instanceof Integer) { - return new PlcDWORD((long) value); - } else if(value instanceof Long) { - return new PlcDWORD((long) value); - } else if(value instanceof BigInteger) { - return new PlcDWORD(((BigInteger) value).longValue()); - } else if(value instanceof String) { - try { - return new PlcDWORD(Long.valueOf((String) value)); - } catch (NumberFormatException e) { - throw new PlcRuntimeException("Value of " + value + " not parseable as Long"); - } - } - throw new PlcRuntimeException("DWORD requires long"); - case LINT: - return PlcLINT.of(value); - case ULINT: - return PlcULINT.of(value); - case LWORD: - if(value instanceof Short) { - return new PlcLWORD(BigInteger.valueOf((long) value)); - } else if(value instanceof Integer) { - return new PlcLWORD(BigInteger.valueOf((long) value)); - } else if(value instanceof Long) { - return new PlcLWORD(BigInteger.valueOf((long) value)); - } else if(value instanceof BigInteger) { - return new PlcLWORD((BigInteger) value); - } else if(value instanceof String) { - try { - return new PlcLWORD(new BigInteger((String) value)); - } catch (NumberFormatException e) { - throw new PlcRuntimeException("Value of " + value + " not parseable as BigInteger"); - } - } - throw new PlcRuntimeException("LWORD requires BigInteger"); - case REAL: - return PlcREAL.of(value); - case LREAL: - return PlcLREAL.of(value); - case CHAR: - return PlcCHAR.of(value); - case WCHAR: - return PlcWCHAR.of(value); - case STRING: - return PlcSTRING.of(value); - case WSTRING: - return PlcWSTRING.of(value); - case TIME: - return PlcTIME.of(value); - case DATE: - return PlcDATE.of(value); - case TIME_OF_DAY: - return PlcTIME_OF_DAY.of(value); - case DATE_AND_TIME: - return PlcDATE_AND_TIME.of(value); - default: - return customDataType(new Object[]{value}); - } - } else { - PlcList list = new PlcList(); - for (Object value : values) { - list.add(of(tag, new Object[]{value})); - } - return list; - } - } +public interface PlcValueHandler { + PlcValue newPlcValue(PlcTag tag, Object value); - public static PlcValue customDataType(Object[] values) { - return of(values); - } + PlcValue newPlcValue(PlcTag tag, Object[] values); } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcWCHAR.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcWCHAR.java index 5e787a3db53..f63eff5bd5d 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcWCHAR.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcWCHAR.java @@ -31,11 +31,13 @@ public class PlcWCHAR extends PlcIECValue { private static final String VALUE_OUT_OF_RANGE = "Value of type %s is out of range %d - %d for a %s Value"; - static final Integer minValue = 0; - static final Integer maxValue = Short.MAX_VALUE * 2 + 1; + public static final Integer MIN_VALUE = 0; + public static final Integer MAX_VALUE = Short.MAX_VALUE * 2 + 1; public static PlcWCHAR of(Object value) { - if (value instanceof Boolean) { + if (value instanceof PlcWCHAR) { + return (PlcWCHAR) value; + } else if (value instanceof Boolean) { return new PlcWCHAR((Boolean) value); } else if (value instanceof Byte) { return new PlcWCHAR((Byte) value); @@ -54,12 +56,12 @@ public static PlcWCHAR of(Object value) { } else if (value instanceof BigDecimal) { return new PlcWCHAR((BigDecimal) value); } else { - return new PlcWCHAR((String) value); + return new PlcWCHAR(value.toString()); } } public PlcWCHAR(Boolean value) { - this.value = value ? (Integer) 1 : (Integer) 0; + this.value = value ? (int) 'T' : (int) 'F'; this.isNullable = false; } @@ -70,32 +72,32 @@ public PlcWCHAR(Byte value) { public PlcWCHAR(Character value) { int val = (int) value; - if ((val < minValue) || (val > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((val < MIN_VALUE) || (val > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = val; this.isNullable = false; } public PlcWCHAR(Short value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.intValue(); this.isNullable = false; } public PlcWCHAR(Integer value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value; this.isNullable = false; } public PlcWCHAR(Long value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } else { this.value = value.intValue(); this.isNullable = false; @@ -103,32 +105,32 @@ public PlcWCHAR(Long value) { } public PlcWCHAR(Float value) { - if ((value < minValue) || (value > maxValue) || (value % 1 != 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.intValue(); this.isNullable = false; } public PlcWCHAR(Double value) { - if ((value < minValue) || (value > maxValue) || (value % 1 != 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.intValue(); this.isNullable = false; } public PlcWCHAR(BigInteger value) { - if ((value.compareTo(BigInteger.valueOf(minValue)) < 0) || (value.compareTo(BigInteger.valueOf(maxValue)) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value.compareTo(BigInteger.valueOf(MIN_VALUE)) < 0) || (value.compareTo(BigInteger.valueOf(MAX_VALUE)) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.intValue(); this.isNullable = true; } public PlcWCHAR(BigDecimal value) { - if ((value.compareTo(BigDecimal.valueOf(minValue)) < 0) || (value.compareTo(BigDecimal.valueOf(maxValue)) > 0) || (value.scale() > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value.compareTo(BigDecimal.valueOf(MIN_VALUE)) < 0) || (value.compareTo(BigDecimal.valueOf(MAX_VALUE)) > 0) || (value.scale() > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.intValue(); this.isNullable = true; @@ -138,23 +140,23 @@ public PlcWCHAR(String value) { try { //If there is a extra space around the character trim it, unless you are actually sending a space String s = value.trim(); - if (s.length() == 0) { + if (s.isEmpty()) { s = " "; } int val = (int) s.charAt(0); - if ((val < minValue) || (val > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((val < MIN_VALUE) || (val > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = val; this.isNullable = false; } catch (Exception e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName()), e); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName()), e); } } public PlcWCHAR(int value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value; this.isNullable = false; diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcWORD.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcWORD.java index 9003db77532..d47e302907d 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcWORD.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcWORD.java @@ -30,11 +30,13 @@ public class PlcWORD extends PlcIECValue { private static final String VALUE_OUT_OF_RANGE = "Value of type %s is out of range %d - %d for a %s Value"; - static final Integer minValue = 0; - static final Integer maxValue = Short.MAX_VALUE * 2 + 1; + public static final Integer MIN_VALUE = 0; + public static final Integer MAX_VALUE = Short.MAX_VALUE * 2 + 1; public static PlcWORD of(Object value) { - if (value instanceof Boolean) { + if (value instanceof PlcWORD) { + return (PlcWORD) value; + } else if (value instanceof Boolean) { return new PlcWORD((Boolean) value); } else if (value instanceof Byte) { return new PlcWORD((Byte) value); @@ -53,7 +55,7 @@ public static PlcWORD of(Object value) { } else if (value instanceof BigDecimal) { return new PlcWORD((BigDecimal) value); } else { - return new PlcWORD((String) value); + return new PlcWORD(value.toString()); } } @@ -68,56 +70,56 @@ public PlcWORD(Byte value) { } public PlcWORD(Short value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.intValue(); this.isNullable = false; } public PlcWORD(Integer value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value; this.isNullable = false; } public PlcWORD(Long value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.intValue(); this.isNullable = false; } public PlcWORD(Float value) { - if ((value < minValue) || (value > maxValue) || (value % 1 != 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.intValue(); this.isNullable = false; } public PlcWORD(Double value) { - if ((value < minValue) || (value > maxValue) || (value % 1 != 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.intValue(); this.isNullable = false; } public PlcWORD(BigInteger value) { - if ((value.compareTo(BigInteger.valueOf(minValue)) < 0) || (value.compareTo(BigInteger.valueOf(maxValue)) > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value.compareTo(BigInteger.valueOf(MIN_VALUE)) < 0) || (value.compareTo(BigInteger.valueOf(MAX_VALUE)) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.intValue(); this.isNullable = true; } public PlcWORD(BigDecimal value) { - if ((value.compareTo(BigDecimal.valueOf(minValue)) < 0) || (value.compareTo(BigDecimal.valueOf(maxValue)) > 0) || (value.scale() > 0)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value.compareTo(BigDecimal.valueOf(MIN_VALUE)) < 0) || (value.compareTo(BigDecimal.valueOf(MAX_VALUE)) > 0)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value.intValue(); this.isNullable = true; @@ -126,19 +128,19 @@ public PlcWORD(BigDecimal value) { public PlcWORD(String value) { try { int val = Integer.parseInt(value.trim()); - if ((val < minValue) || (val > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((val < MIN_VALUE) || (val > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = val; this.isNullable = false; } catch (Exception e) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName()), e); + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName()), e); } } public PlcWORD(int value) { - if ((value < minValue) || (value > maxValue)) { - throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, minValue, maxValue, this.getClass().getSimpleName())); + if ((value < MIN_VALUE) || (value > MAX_VALUE)) { + throw new PlcInvalidTagException(String.format(VALUE_OUT_OF_RANGE, value, MIN_VALUE, MAX_VALUE, this.getClass().getSimpleName())); } this.value = value; this.isNullable = false; diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcWSTRING.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcWSTRING.java index 6c66faa90a2..5cb769546d7 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcWSTRING.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcWSTRING.java @@ -27,17 +27,20 @@ import java.math.BigInteger; import java.nio.charset.StandardCharsets; -public class PlcWSTRING extends PlcSimpleValue { +public class PlcWSTRING extends PlcIECValue { public static PlcWSTRING of(Object value) { - if (value instanceof String) { + if (value instanceof PlcWSTRING) { + return (PlcWSTRING) value; + } else if (value instanceof String) { return new PlcWSTRING((String) value); } return new PlcWSTRING(String.valueOf(value)); } public PlcWSTRING(String value) { - super(value, true); + this.value = value; + this.isNullable = false; } @Override @@ -200,7 +203,7 @@ public int getLength() { @Override public String toString() { - return "\"" + value + "\""; + return value; } @Override diff --git a/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnectionTest.java b/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnectionTest.java index 8fea8da1b17..66d410ef032 100644 --- a/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnectionTest.java +++ b/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnectionTest.java @@ -161,6 +161,11 @@ public TestProtocolBase(GateKeeper discover, GateKeeper connect, GateKeeper disc this.disconnect = disconnect; } + @Override + public PlcTagHandler getTagHandler() { + return null; + } + @Override public void onDiscover(ConversationContext context) { logger.info("On Discover"); diff --git a/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/connection/PlcConnectionFactory.java b/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/connection/PlcConnectionFactory.java index 6af52531935..ff65f434790 100644 --- a/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/connection/PlcConnectionFactory.java +++ b/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/connection/PlcConnectionFactory.java @@ -41,7 +41,7 @@ PlcConnectionFactory doNotAwaitForDisconnect() { DefaultNettyPlcConnection create(ChannelFactory channelFactory, ProtocolStackConfigurer stackConfigurer) { return new DefaultNettyPlcConnection( true, true, true, true, true, - null, null, null, channelFactory, + null, null, channelFactory, fireDiscovery, // force discovery true, // await setup awaitDisconnect, // await disconnect diff --git a/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/connection/TestProtocol.java b/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/connection/TestProtocol.java index 59f4f94950b..ed2d7abc98b 100644 --- a/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/connection/TestProtocol.java +++ b/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/connection/TestProtocol.java @@ -25,6 +25,11 @@ public class TestProtocol extends Plc4xProtocolBase { + @Override + public PlcTagHandler getTagHandler() { + return null; + } + @Override public void onDiscover(ConversationContext context) { context.fireDiscovered(null); diff --git a/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/values/DefaultPlcValueHandlerTest.java b/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/values/DefaultPlcValueHandlerTest.java new file mode 100644 index 00000000000..014594129b8 --- /dev/null +++ b/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/values/DefaultPlcValueHandlerTest.java @@ -0,0 +1,573 @@ +/* + * 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 org.apache.plc4x.java.spi.values; + +import org.apache.plc4x.java.api.model.ArrayInfo; +import org.apache.plc4x.java.api.model.PlcTag; +import org.apache.plc4x.java.api.types.PlcValueType; +import org.apache.plc4x.java.api.value.PlcValue; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.lang.reflect.Field; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.time.Duration; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; +import java.util.Collections; +import java.util.List; +import java.util.StringJoiner; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.*; + +class DefaultPlcValueHandlerTest { + + private static Stream getSingleElementPlcValues() { + return Stream.of( + // BOOL values + Arguments.of(new MockTag("mock", PlcValueType.BOOL), true, new PlcBOOL(true)), + Arguments.of(new MockTag("mock", PlcValueType.BOOL), false, new PlcBOOL(false)), + Arguments.of(new MockTag("mock", PlcValueType.BOOL), (byte) 42, new PlcBOOL(true)), + Arguments.of(new MockTag("mock", PlcValueType.BOOL), (byte) 0, new PlcBOOL(false)), + Arguments.of(new MockTag("mock", PlcValueType.BOOL), (short) 42, new PlcBOOL(true)), + Arguments.of(new MockTag("mock", PlcValueType.BOOL), (short) 0, new PlcBOOL(false)), + Arguments.of(new MockTag("mock", PlcValueType.BOOL), 42, new PlcBOOL(true)), + Arguments.of(new MockTag("mock", PlcValueType.BOOL), 0, new PlcBOOL(false)), + Arguments.of(new MockTag("mock", PlcValueType.BOOL), (long) 42, new PlcBOOL(true)), + Arguments.of(new MockTag("mock", PlcValueType.BOOL), (long) 0, new PlcBOOL(false)), + Arguments.of(new MockTag("mock", PlcValueType.BOOL), (float) 4.2, new PlcBOOL(true)), + Arguments.of(new MockTag("mock", PlcValueType.BOOL), (float) 0.0, new PlcBOOL(false)), + Arguments.of(new MockTag("mock", PlcValueType.BOOL), (double) 4.2, new PlcBOOL(true)), + Arguments.of(new MockTag("mock", PlcValueType.BOOL), (double) 0.0, new PlcBOOL(false)), + Arguments.of(new MockTag("mock", PlcValueType.BOOL), BigInteger.ONE, new PlcBOOL(true)), + Arguments.of(new MockTag("mock", PlcValueType.BOOL), BigInteger.ZERO, new PlcBOOL(false)), + Arguments.of(new MockTag("mock", PlcValueType.BOOL), BigDecimal.ONE, new PlcBOOL(true)), + Arguments.of(new MockTag("mock", PlcValueType.BOOL), BigInteger.ZERO, new PlcBOOL(false)), + Arguments.of(new MockTag("mock", PlcValueType.BOOL), "true", new PlcBOOL(true)), + Arguments.of(new MockTag("mock", PlcValueType.BOOL), "false", new PlcBOOL(false)), + + // BYTE values + Arguments.of(new MockTag("mock", PlcValueType.BYTE), true, new PlcBYTE(1)), + Arguments.of(new MockTag("mock", PlcValueType.BYTE), false, new PlcBYTE(0)), + Arguments.of(new MockTag("mock", PlcValueType.BYTE), (byte) 42, new PlcBYTE(42)), + Arguments.of(new MockTag("mock", PlcValueType.BYTE), (short) 42, new PlcBYTE(42)), + Arguments.of(new MockTag("mock", PlcValueType.BYTE), 42, new PlcBYTE(42)), + Arguments.of(new MockTag("mock", PlcValueType.BYTE), (long) 42, new PlcBYTE(42)), + Arguments.of(new MockTag("mock", PlcValueType.BYTE), (float) 42.34, new PlcBYTE(42)), + Arguments.of(new MockTag("mock", PlcValueType.BYTE), (double) 42.34, new PlcBYTE(42)), + Arguments.of(new MockTag("mock", PlcValueType.BYTE), BigInteger.valueOf(42), new PlcBYTE(42)), + Arguments.of(new MockTag("mock", PlcValueType.BYTE), BigDecimal.valueOf(42.34), new PlcBYTE(42)), + Arguments.of(new MockTag("mock", PlcValueType.BYTE), "42", new PlcBYTE(42)), + // TODO: Add some range tests (values above the max and below the min value) + + // WORD values + Arguments.of(new MockTag("mock", PlcValueType.WORD), true, new PlcWORD(1)), + Arguments.of(new MockTag("mock", PlcValueType.WORD), false, new PlcWORD(0)), + Arguments.of(new MockTag("mock", PlcValueType.WORD), (byte) 42, new PlcWORD(42)), + Arguments.of(new MockTag("mock", PlcValueType.WORD), (short) 42, new PlcWORD(42)), + Arguments.of(new MockTag("mock", PlcValueType.WORD), 42, new PlcWORD(42)), + Arguments.of(new MockTag("mock", PlcValueType.WORD), (long) 42, new PlcWORD(42)), + Arguments.of(new MockTag("mock", PlcValueType.WORD), (float) 42.34, new PlcWORD(42)), + Arguments.of(new MockTag("mock", PlcValueType.WORD), (double) 42.34, new PlcWORD(42)), + Arguments.of(new MockTag("mock", PlcValueType.WORD), BigInteger.valueOf(42), new PlcWORD(42)), + Arguments.of(new MockTag("mock", PlcValueType.WORD), BigDecimal.valueOf(42.34), new PlcWORD(42)), + Arguments.of(new MockTag("mock", PlcValueType.WORD), "42", new PlcWORD(42)), + // TODO: Add some range tests (values above the max and below the min value) + + // DWORD values + Arguments.of(new MockTag("mock", PlcValueType.DWORD), true, new PlcDWORD(1)), + Arguments.of(new MockTag("mock", PlcValueType.DWORD), false, new PlcDWORD(0)), + Arguments.of(new MockTag("mock", PlcValueType.DWORD), (byte) 42, new PlcDWORD(42)), + Arguments.of(new MockTag("mock", PlcValueType.DWORD), (short) 42, new PlcDWORD(42)), + Arguments.of(new MockTag("mock", PlcValueType.DWORD), 42, new PlcDWORD(42)), + Arguments.of(new MockTag("mock", PlcValueType.DWORD), (long) 42, new PlcDWORD(42)), + Arguments.of(new MockTag("mock", PlcValueType.DWORD), (float) 42.34, new PlcDWORD(42)), + Arguments.of(new MockTag("mock", PlcValueType.DWORD), (double) 42.34, new PlcDWORD(42)), + Arguments.of(new MockTag("mock", PlcValueType.DWORD), BigInteger.valueOf(42), new PlcDWORD(42)), + Arguments.of(new MockTag("mock", PlcValueType.DWORD), BigDecimal.valueOf(42.34), new PlcDWORD(42)), + Arguments.of(new MockTag("mock", PlcValueType.DWORD), "42", new PlcDWORD(42)), + // TODO: Add some range tests (values above the max and below the min value) + + // LWORD values + Arguments.of(new MockTag("mock", PlcValueType.LWORD), true, new PlcLWORD(1)), + Arguments.of(new MockTag("mock", PlcValueType.LWORD), false, new PlcLWORD(0)), + Arguments.of(new MockTag("mock", PlcValueType.LWORD), (byte) 42, new PlcLWORD(42)), + Arguments.of(new MockTag("mock", PlcValueType.LWORD), (short) 42, new PlcLWORD(42)), + Arguments.of(new MockTag("mock", PlcValueType.LWORD), 42, new PlcLWORD(42)), + Arguments.of(new MockTag("mock", PlcValueType.LWORD), (long) 42, new PlcLWORD(42)), + Arguments.of(new MockTag("mock", PlcValueType.LWORD), (float) 42.34, new PlcLWORD(42)), + Arguments.of(new MockTag("mock", PlcValueType.LWORD), (double) 42.34, new PlcLWORD(42)), + Arguments.of(new MockTag("mock", PlcValueType.LWORD), BigInteger.valueOf(42), new PlcLWORD(42)), + Arguments.of(new MockTag("mock", PlcValueType.LWORD), BigDecimal.valueOf(42.34), new PlcLWORD(42)), + Arguments.of(new MockTag("mock", PlcValueType.LWORD), "42", new PlcLWORD(42)), + // TODO: Add some range tests (values above the max and below the min value) + + // USINT values + Arguments.of(new MockTag("mock", PlcValueType.USINT), true, new PlcUSINT(1)), + Arguments.of(new MockTag("mock", PlcValueType.USINT), false, new PlcUSINT(0)), + Arguments.of(new MockTag("mock", PlcValueType.USINT), (byte) 42, new PlcUSINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.USINT), (short) 42, new PlcUSINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.USINT), 42, new PlcUSINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.USINT), (long) 42, new PlcUSINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.USINT), (float) 42.34, new PlcUSINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.USINT), (double) 42.34, new PlcUSINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.USINT), BigInteger.valueOf(42), new PlcUSINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.USINT), BigDecimal.valueOf(42.34), new PlcUSINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.USINT), "42", new PlcUSINT(42)), + // TODO: Add some range tests (values above the max and below the min value) + + // UINT values + Arguments.of(new MockTag("mock", PlcValueType.UINT), true, new PlcUINT(1)), + Arguments.of(new MockTag("mock", PlcValueType.UINT), false, new PlcUINT(0)), + Arguments.of(new MockTag("mock", PlcValueType.UINT), (byte) 42, new PlcUINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.UINT), (short) 42, new PlcUINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.UINT), 42, new PlcUINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.UINT), (long) 42, new PlcUINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.UINT), (float) 42.34, new PlcUINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.UINT), (double) 42.34, new PlcUINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.UINT), BigInteger.valueOf(42), new PlcUINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.UINT), BigDecimal.valueOf(42.34), new PlcUINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.UINT), "42", new PlcUINT(42)), + // TODO: Add some range tests (values above the max and below the min value) + + // UDINT values + Arguments.of(new MockTag("mock", PlcValueType.UDINT), true, new PlcUDINT(1)), + Arguments.of(new MockTag("mock", PlcValueType.UDINT), false, new PlcUDINT(0)), + Arguments.of(new MockTag("mock", PlcValueType.UDINT), (byte) 42, new PlcUDINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.UDINT), (short) 42, new PlcUDINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.UDINT), 42, new PlcUDINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.UDINT), (long) 42, new PlcUDINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.UDINT), (float) 42.34, new PlcUDINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.UDINT), (double) 42.34, new PlcUDINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.UDINT), BigInteger.valueOf(42), new PlcUDINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.UDINT), BigDecimal.valueOf(42.34), new PlcUDINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.UDINT), "42", new PlcUDINT(42)), + // TODO: Add some range tests (values above the max and below the min value) + + // ULINT values + Arguments.of(new MockTag("mock", PlcValueType.ULINT), true, new PlcULINT(1)), + Arguments.of(new MockTag("mock", PlcValueType.ULINT), false, new PlcULINT(0)), + Arguments.of(new MockTag("mock", PlcValueType.ULINT), (byte) 42, new PlcULINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.ULINT), (short) 42, new PlcULINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.ULINT), 42, new PlcULINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.ULINT), (long) 42, new PlcULINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.ULINT), (float) 42.34, new PlcULINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.ULINT), (double) 42.34, new PlcULINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.ULINT), BigInteger.valueOf(42), new PlcULINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.ULINT), BigDecimal.valueOf(42.34), new PlcULINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.ULINT), "42", new PlcULINT(42)), + // TODO: Add some range tests (values above the max and below the min value) + + // SINT values + Arguments.of(new MockTag("mock", PlcValueType.SINT), true, new PlcSINT(1)), + Arguments.of(new MockTag("mock", PlcValueType.SINT), false, new PlcSINT(0)), + Arguments.of(new MockTag("mock", PlcValueType.SINT), (byte) 42, new PlcSINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.SINT), (short) 42, new PlcSINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.SINT), 42, new PlcSINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.SINT), (long) 42, new PlcSINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.SINT), (float) 42.34, new PlcSINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.SINT), (double) 42.34, new PlcSINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.SINT), BigInteger.valueOf(42), new PlcSINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.SINT), BigDecimal.valueOf(42.34), new PlcSINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.SINT), "42", new PlcSINT(42)), + // TODO: Add some range tests (values above the max and below the min value) + + // INT values + Arguments.of(new MockTag("mock", PlcValueType.INT), true, new PlcINT(1)), + Arguments.of(new MockTag("mock", PlcValueType.INT), false, new PlcINT(0)), + Arguments.of(new MockTag("mock", PlcValueType.INT), (byte) 42, new PlcINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.INT), (short) 42, new PlcINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.INT), 42, new PlcINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.INT), (long) 42, new PlcINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.INT), (float) 42.34, new PlcINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.INT), (double) 42.34, new PlcINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.INT), BigInteger.valueOf(42), new PlcINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.INT), BigDecimal.valueOf(42.34), new PlcINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.INT), "42", new PlcINT(42)), + // TODO: Add some range tests (values above the max and below the min value) + + // DINT values + Arguments.of(new MockTag("mock", PlcValueType.DINT), true, new PlcDINT(1)), + Arguments.of(new MockTag("mock", PlcValueType.DINT), false, new PlcDINT(0)), + Arguments.of(new MockTag("mock", PlcValueType.DINT), (byte) 42, new PlcDINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.DINT), (short) 42, new PlcDINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.DINT), 42, new PlcDINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.DINT), (long) 42, new PlcDINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.DINT), (float) 42.34, new PlcDINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.DINT), (double) 42.34, new PlcDINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.DINT), BigInteger.valueOf(42), new PlcDINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.DINT), BigDecimal.valueOf(42.34), new PlcDINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.DINT), "42", new PlcDINT(42)), + // TODO: Add some range tests (values above the max and below the min value) + + // LINT values + Arguments.of(new MockTag("mock", PlcValueType.LINT), true, new PlcLINT(1)), + Arguments.of(new MockTag("mock", PlcValueType.LINT), false, new PlcLINT(0)), + Arguments.of(new MockTag("mock", PlcValueType.LINT), (byte) 42, new PlcLINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.LINT), (short) 42, new PlcLINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.LINT), 42, new PlcLINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.LINT), (long) 42, new PlcLINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.LINT), (float) 42.34, new PlcLINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.LINT), (double) 42.34, new PlcLINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.LINT), BigInteger.valueOf(42), new PlcLINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.LINT), BigDecimal.valueOf(42.34), new PlcLINT(42)), + Arguments.of(new MockTag("mock", PlcValueType.LINT), "42", new PlcLINT(42)), + // TODO: Add some range tests (values above the max and below the min value) + + // REAL values + Arguments.of(new MockTag("mock", PlcValueType.REAL), true, new PlcREAL(1.0)), + Arguments.of(new MockTag("mock", PlcValueType.REAL), false, new PlcREAL(0.0)), + Arguments.of(new MockTag("mock", PlcValueType.REAL), (byte) 42, new PlcREAL(42.0)), + Arguments.of(new MockTag("mock", PlcValueType.REAL), (short) 42, new PlcREAL(42.0)), + Arguments.of(new MockTag("mock", PlcValueType.REAL), 42, new PlcREAL(42.0)), + Arguments.of(new MockTag("mock", PlcValueType.REAL), (long) 42, new PlcREAL(42.0)), + Arguments.of(new MockTag("mock", PlcValueType.REAL), (float) 42.34, new PlcREAL(42.34)), + Arguments.of(new MockTag("mock", PlcValueType.REAL), (double) 42.35, new PlcREAL(42.35)), + Arguments.of(new MockTag("mock", PlcValueType.REAL), BigInteger.valueOf(42), new PlcREAL(42.0)), + Arguments.of(new MockTag("mock", PlcValueType.REAL), BigDecimal.valueOf(42.34), new PlcREAL(42.34)), + Arguments.of(new MockTag("mock", PlcValueType.REAL), "42.1", new PlcREAL(42.1)), + // TODO: Add some range tests (values above the max and below the min value) + + // LREAL values + Arguments.of(new MockTag("mock", PlcValueType.LREAL), true, new PlcLREAL(1.0)), + Arguments.of(new MockTag("mock", PlcValueType.LREAL), false, new PlcLREAL(0.0)), + Arguments.of(new MockTag("mock", PlcValueType.LREAL), (byte) 42, new PlcLREAL(42.0)), + Arguments.of(new MockTag("mock", PlcValueType.LREAL), (short) 42, new PlcLREAL(42.0)), + Arguments.of(new MockTag("mock", PlcValueType.LREAL), 42, new PlcLREAL(42.0)), + Arguments.of(new MockTag("mock", PlcValueType.LREAL), (long) 42, new PlcLREAL(42.0)), + Arguments.of(new MockTag("mock", PlcValueType.LREAL), (float) 42.34, new PlcLREAL(42.34000015258789)), + Arguments.of(new MockTag("mock", PlcValueType.LREAL), (double) 42.35, new PlcLREAL(42.35)), + Arguments.of(new MockTag("mock", PlcValueType.LREAL), BigInteger.valueOf(42), new PlcLREAL(42.0)), + Arguments.of(new MockTag("mock", PlcValueType.LREAL), BigDecimal.valueOf(42.34), new PlcLREAL(42.34)), + Arguments.of(new MockTag("mock", PlcValueType.LREAL), "42.1", new PlcLREAL(42.1)), + // TODO: Add some range tests (values above the max and below the min value) + + // CHAR values + Arguments.of(new MockTag("mock", PlcValueType.CHAR), true, new PlcCHAR('T')), + Arguments.of(new MockTag("mock", PlcValueType.CHAR), false, new PlcCHAR('F')), + Arguments.of(new MockTag("mock", PlcValueType.CHAR), (byte) 65, new PlcCHAR('A')), + Arguments.of(new MockTag("mock", PlcValueType.CHAR), (short) 66, new PlcCHAR('B')), + Arguments.of(new MockTag("mock", PlcValueType.CHAR), 67, new PlcCHAR('C')), + Arguments.of(new MockTag("mock", PlcValueType.CHAR), (long) 68, new PlcCHAR('D')), + Arguments.of(new MockTag("mock", PlcValueType.CHAR), (float) 69.34, new PlcCHAR('E')), + Arguments.of(new MockTag("mock", PlcValueType.CHAR), (double) 70.35, new PlcCHAR('F')), + Arguments.of(new MockTag("mock", PlcValueType.CHAR), BigInteger.valueOf(71), new PlcCHAR('G')), + Arguments.of(new MockTag("mock", PlcValueType.CHAR), BigDecimal.valueOf(72), new PlcCHAR('H')), + Arguments.of(new MockTag("mock", PlcValueType.CHAR), 'I', new PlcCHAR('I')), + Arguments.of(new MockTag("mock", PlcValueType.CHAR), "J", new PlcCHAR('J')), + + // WCHAR values + Arguments.of(new MockTag("mock", PlcValueType.WCHAR), true, new PlcWCHAR('T')), + Arguments.of(new MockTag("mock", PlcValueType.WCHAR), false, new PlcWCHAR('F')), + Arguments.of(new MockTag("mock", PlcValueType.WCHAR), (byte) 65, new PlcWCHAR('A')), + Arguments.of(new MockTag("mock", PlcValueType.WCHAR), (short) 66, new PlcWCHAR('B')), + Arguments.of(new MockTag("mock", PlcValueType.WCHAR), 67, new PlcWCHAR('C')), + Arguments.of(new MockTag("mock", PlcValueType.WCHAR), (long) 68, new PlcWCHAR('D')), + Arguments.of(new MockTag("mock", PlcValueType.WCHAR), (float) 69.34, new PlcWCHAR('E')), + Arguments.of(new MockTag("mock", PlcValueType.WCHAR), (double) 70.35, new PlcWCHAR('F')), + Arguments.of(new MockTag("mock", PlcValueType.WCHAR), BigInteger.valueOf(71), new PlcWCHAR('G')), + Arguments.of(new MockTag("mock", PlcValueType.WCHAR), BigDecimal.valueOf(72), new PlcWCHAR('H')), + Arguments.of(new MockTag("mock", PlcValueType.WCHAR), 'I', new PlcWCHAR('I')), + Arguments.of(new MockTag("mock", PlcValueType.WCHAR), "J", new PlcWCHAR('J')), + + // STRING values + Arguments.of(new MockTag("mock", PlcValueType.STRING), true, new PlcSTRING("true")), + Arguments.of(new MockTag("mock", PlcValueType.STRING), false, new PlcSTRING("false")), + Arguments.of(new MockTag("mock", PlcValueType.STRING), (byte) 42, new PlcSTRING("42")), + Arguments.of(new MockTag("mock", PlcValueType.STRING), (short) 42, new PlcSTRING("42")), + Arguments.of(new MockTag("mock", PlcValueType.STRING), 42, new PlcSTRING("42")), + Arguments.of(new MockTag("mock", PlcValueType.STRING), (long) 42, new PlcSTRING("42")), + Arguments.of(new MockTag("mock", PlcValueType.STRING), (float) 42.34, new PlcSTRING("42.34")), + Arguments.of(new MockTag("mock", PlcValueType.STRING), (double) 42.35, new PlcSTRING("42.35")), + Arguments.of(new MockTag("mock", PlcValueType.STRING), BigInteger.valueOf(42), new PlcSTRING("42")), + Arguments.of(new MockTag("mock", PlcValueType.STRING), BigDecimal.valueOf(42.34), new PlcSTRING("42.34")), + Arguments.of(new MockTag("mock", PlcValueType.STRING), "Wolf", new PlcSTRING("Wolf")), + + // WSTRING values + Arguments.of(new MockTag("mock", PlcValueType.WSTRING), true, new PlcWSTRING("true")), + Arguments.of(new MockTag("mock", PlcValueType.WSTRING), false, new PlcWSTRING("false")), + Arguments.of(new MockTag("mock", PlcValueType.WSTRING), (byte) 42, new PlcWSTRING("42")), + Arguments.of(new MockTag("mock", PlcValueType.WSTRING), (short) 42, new PlcWSTRING("42")), + Arguments.of(new MockTag("mock", PlcValueType.WSTRING), 42, new PlcWSTRING("42")), + Arguments.of(new MockTag("mock", PlcValueType.WSTRING), (long) 42, new PlcWSTRING("42")), + Arguments.of(new MockTag("mock", PlcValueType.WSTRING), (float) 42.34, new PlcWSTRING("42.34")), + Arguments.of(new MockTag("mock", PlcValueType.WSTRING), (double) 42.35, new PlcWSTRING("42.35")), + Arguments.of(new MockTag("mock", PlcValueType.WSTRING), BigInteger.valueOf(42), new PlcWSTRING("42")), + Arguments.of(new MockTag("mock", PlcValueType.WSTRING), BigDecimal.valueOf(42.34), new PlcWSTRING("42.34")), + Arguments.of(new MockTag("mock", PlcValueType.WSTRING), "Lamm", new PlcWSTRING("Lamm")), + + // TIME values (Numeric values are interpreted as milliseconds) + Arguments.of(new MockTag("mock", PlcValueType.TIME), Duration.ofMillis(1234), new PlcTIME(Duration.parse("PT1.234S"))), + Arguments.of(new MockTag("mock", PlcValueType.TIME), (byte) 123, new PlcTIME(Duration.parse("PT0.123S"))), + Arguments.of(new MockTag("mock", PlcValueType.TIME), (short) 1234, new PlcTIME(Duration.parse("PT1.234S"))), + Arguments.of(new MockTag("mock", PlcValueType.TIME), 1234, new PlcTIME(Duration.parse("PT1.234S"))), + Arguments.of(new MockTag("mock", PlcValueType.TIME), 12345678901L, new PlcTIME(Duration.parse("PT3429H21M18.901S"))), + Arguments.of(new MockTag("mock", PlcValueType.TIME), (float) 1234.56, new PlcTIME(Duration.parse("PT1.234S"))), + Arguments.of(new MockTag("mock", PlcValueType.TIME), (double) 1234.56, new PlcTIME(Duration.parse("PT1.234S"))), + Arguments.of(new MockTag("mock", PlcValueType.TIME), BigInteger.valueOf(12345678901L), new PlcTIME(Duration.parse("PT3429H21M18.901S"))), + Arguments.of(new MockTag("mock", PlcValueType.TIME), BigDecimal.valueOf(12345678901L), new PlcTIME(Duration.parse("PT3429H21M18.901S"))), + Arguments.of(new MockTag("mock", PlcValueType.TIME), "PT3429H21M18.901S", new PlcTIME(Duration.parse("PT3429H21M18.901S"))), + + // LTIME values (Numeric values are interpreted as nanoseconds) + Arguments.of(new MockTag("mock", PlcValueType.LTIME), Duration.ofMillis(1234), new PlcLTIME(Duration.parse("PT1.234S"))), + Arguments.of(new MockTag("mock", PlcValueType.LTIME), (byte) 123, new PlcLTIME(Duration.parse("PT0.000000123S"))), + Arguments.of(new MockTag("mock", PlcValueType.LTIME), (short) 1234, new PlcLTIME(Duration.parse("PT0.000001234S"))), + Arguments.of(new MockTag("mock", PlcValueType.LTIME), 1234, new PlcLTIME(Duration.parse("PT0.000001234S"))), + Arguments.of(new MockTag("mock", PlcValueType.LTIME), 12345678901L, new PlcLTIME(Duration.parse("PT12.345678901S"))), + Arguments.of(new MockTag("mock", PlcValueType.LTIME), (float) 1234.56, new PlcLTIME(Duration.parse("PT0.000001234S"))), + Arguments.of(new MockTag("mock", PlcValueType.LTIME), (double) 1234.56, new PlcLTIME(Duration.parse("PT0.000001234S"))), + Arguments.of(new MockTag("mock", PlcValueType.LTIME), BigInteger.valueOf(12345678901L), new PlcLTIME(Duration.parse("PT12.345678901S"))), + Arguments.of(new MockTag("mock", PlcValueType.LTIME), BigDecimal.valueOf(12345678901L), new PlcLTIME(Duration.parse("PT12.345678901S"))), + Arguments.of(new MockTag("mock", PlcValueType.LTIME), "PT12.345678901S", new PlcLTIME(Duration.parse("PT12.345678901S"))), + + // DATE values (Numeric values are interpreted as days since epoch) + Arguments.of(new MockTag("mock", PlcValueType.DATE), LocalDate.ofEpochDay(1234), new PlcDATE(LocalDate.ofEpochDay(1234))), + Arguments.of(new MockTag("mock", PlcValueType.DATE), (byte) 123, new PlcDATE(LocalDate.ofEpochDay(123))), + Arguments.of(new MockTag("mock", PlcValueType.DATE), (short) 1234, new PlcDATE(LocalDate.ofEpochDay(1234))), + Arguments.of(new MockTag("mock", PlcValueType.DATE), 1234, new PlcDATE(LocalDate.ofEpochDay(1234))), + Arguments.of(new MockTag("mock", PlcValueType.DATE), 12345678901L, new PlcDATE(LocalDate.ofEpochDay(12345678901L))), + Arguments.of(new MockTag("mock", PlcValueType.DATE), (float) 1234.56, new PlcDATE(LocalDate.ofEpochDay(1234))), + Arguments.of(new MockTag("mock", PlcValueType.DATE), (double) 1234.56, new PlcDATE(LocalDate.ofEpochDay(1234))), + Arguments.of(new MockTag("mock", PlcValueType.DATE), BigInteger.valueOf(12345678901L), new PlcDATE(LocalDate.ofEpochDay(12345678901L))), + Arguments.of(new MockTag("mock", PlcValueType.DATE), BigDecimal.valueOf(12345678901L), new PlcDATE(LocalDate.ofEpochDay(12345678901L))), + Arguments.of(new MockTag("mock", PlcValueType.DATE), LocalDate.parse("+33803290-10-08"), new PlcDATE(LocalDate.ofEpochDay(12345678901L))), + + // LDATE values (Numeric values are interpreted as seconds since epoch) + Arguments.of(new MockTag("mock", PlcValueType.LDATE), LocalDate.ofEpochDay(1234), new PlcLDATE(LocalDate.ofEpochDay(1234))), + Arguments.of(new MockTag("mock", PlcValueType.LDATE), (byte) 123, new PlcLDATE(LocalDate.parse("1970-01-01"))), + Arguments.of(new MockTag("mock", PlcValueType.LDATE), (short) 12345, new PlcLDATE(LocalDate.parse("1970-01-01"))), + Arguments.of(new MockTag("mock", PlcValueType.LDATE), 1234567890, new PlcLDATE(LocalDate.parse("2009-02-13"))), + Arguments.of(new MockTag("mock", PlcValueType.LDATE), 12345678901L, new PlcLDATE(LocalDate.parse("2361-03-21"))), + Arguments.of(new MockTag("mock", PlcValueType.LDATE), (float) 123456.56, new PlcLDATE(LocalDate.parse("1970-01-02"))), + Arguments.of(new MockTag("mock", PlcValueType.LDATE), (double) 12345678.9, new PlcLDATE(LocalDate.parse("1970-05-23"))), + Arguments.of(new MockTag("mock", PlcValueType.LDATE), BigInteger.valueOf(12345678901L), new PlcLDATE(LocalDate.parse("2361-03-21"))), + Arguments.of(new MockTag("mock", PlcValueType.LDATE), BigDecimal.valueOf(12345678901L), new PlcLDATE(LocalDate.parse("2361-03-21"))), + Arguments.of(new MockTag("mock", PlcValueType.LDATE), "1978-03-28", new PlcLDATE(LocalDate.parse("1978-03-28"))), + + // TIME_OF_DAY values (Numeric values are interpreted as seconds since midnight) + Arguments.of(new MockTag("mock", PlcValueType.TIME_OF_DAY), LocalTime.ofSecondOfDay(1234), new PlcTIME_OF_DAY(LocalTime.parse("00:20:34"))), + Arguments.of(new MockTag("mock", PlcValueType.TIME_OF_DAY), (byte) 123, new PlcTIME_OF_DAY(LocalTime.parse("00:02:03"))), + Arguments.of(new MockTag("mock", PlcValueType.TIME_OF_DAY), (short) 12345, new PlcTIME_OF_DAY(LocalTime.parse("03:25:45"))), + Arguments.of(new MockTag("mock", PlcValueType.TIME_OF_DAY), 67890, new PlcTIME_OF_DAY(LocalTime.parse("18:51:30"))), + Arguments.of(new MockTag("mock", PlcValueType.TIME_OF_DAY), 67890L, new PlcTIME_OF_DAY(LocalTime.parse("18:51:30"))), + Arguments.of(new MockTag("mock", PlcValueType.TIME_OF_DAY), (float) 67890.56, new PlcTIME_OF_DAY(LocalTime.parse("18:51:30"))), + Arguments.of(new MockTag("mock", PlcValueType.TIME_OF_DAY), (double) 67890.9, new PlcTIME_OF_DAY(LocalTime.parse("18:51:30"))), + Arguments.of(new MockTag("mock", PlcValueType.TIME_OF_DAY), BigInteger.valueOf(67890L), new PlcTIME_OF_DAY(LocalTime.parse("18:51:30"))), + Arguments.of(new MockTag("mock", PlcValueType.TIME_OF_DAY), BigDecimal.valueOf(67890L), new PlcTIME_OF_DAY(LocalTime.parse("18:51:30"))), + Arguments.of(new MockTag("mock", PlcValueType.TIME_OF_DAY), "12:34:56", new PlcTIME_OF_DAY(LocalTime.parse("12:34:56"))), + + // LTIME_OF_DAY values (Numeric values are interpreted as milliseconds since midnight) + Arguments.of(new MockTag("mock", PlcValueType.LTIME_OF_DAY), LocalTime.ofSecondOfDay(1234), new PlcLTIME_OF_DAY(LocalTime.parse("00:20:34"))), + Arguments.of(new MockTag("mock", PlcValueType.LTIME_OF_DAY), (byte) 123, new PlcLTIME_OF_DAY(LocalTime.parse("00:00:00.123"))), + Arguments.of(new MockTag("mock", PlcValueType.LTIME_OF_DAY), (short) 12345, new PlcLTIME_OF_DAY(LocalTime.parse("00:00:12.345"))), + Arguments.of(new MockTag("mock", PlcValueType.LTIME_OF_DAY), 12345678, new PlcLTIME_OF_DAY(LocalTime.parse("03:25:45.678"))), + Arguments.of(new MockTag("mock", PlcValueType.LTIME_OF_DAY), 12345678L, new PlcLTIME_OF_DAY(LocalTime.parse("03:25:45.678"))), + Arguments.of(new MockTag("mock", PlcValueType.LTIME_OF_DAY), (float) 123456.56, new PlcLTIME_OF_DAY(LocalTime.parse("00:02:03.456"))), + Arguments.of(new MockTag("mock", PlcValueType.LTIME_OF_DAY), (double) 12345678.9, new PlcLTIME_OF_DAY(LocalTime.parse("03:25:45.678"))), + Arguments.of(new MockTag("mock", PlcValueType.LTIME_OF_DAY), BigInteger.valueOf(12345678L), new PlcLTIME_OF_DAY(LocalTime.parse("03:25:45.678"))), + Arguments.of(new MockTag("mock", PlcValueType.LTIME_OF_DAY), BigDecimal.valueOf(12345678L), new PlcLTIME_OF_DAY(LocalTime.parse("03:25:45.678"))), + Arguments.of(new MockTag("mock", PlcValueType.LTIME_OF_DAY), "12:34:56", new PlcLTIME_OF_DAY(LocalTime.parse("12:34:56"))), + + // DATE_AND_TIME values (Numeric values are interpreted as seconds since epoch) + Arguments.of(new MockTag("mock", PlcValueType.DATE_AND_TIME), LocalDateTime.ofEpochSecond(1234, 0, ZoneOffset.UTC), new PlcDATE_AND_TIME(LocalDateTime.parse("1970-01-01T00:20:34"))), + Arguments.of(new MockTag("mock", PlcValueType.DATE_AND_TIME), (byte) 123, new PlcDATE_AND_TIME(LocalDateTime.parse("1970-01-01T00:02:03"))), + Arguments.of(new MockTag("mock", PlcValueType.DATE_AND_TIME), (short) 12345, new PlcDATE_AND_TIME(LocalDateTime.parse("1970-01-01T03:25:45"))), + Arguments.of(new MockTag("mock", PlcValueType.DATE_AND_TIME), 12345678, new PlcDATE_AND_TIME(LocalDateTime.parse("1970-05-23T21:21:18"))), + Arguments.of(new MockTag("mock", PlcValueType.DATE_AND_TIME), 12345678L, new PlcDATE_AND_TIME(LocalDateTime.parse("1970-05-23T21:21:18"))), + Arguments.of(new MockTag("mock", PlcValueType.DATE_AND_TIME), (float) 123456.56, new PlcDATE_AND_TIME(LocalDateTime.parse("1970-01-02T10:17:36"))), + Arguments.of(new MockTag("mock", PlcValueType.DATE_AND_TIME), (double) 12345678.9, new PlcDATE_AND_TIME(LocalDateTime.parse("1970-05-23T21:21:18"))), + Arguments.of(new MockTag("mock", PlcValueType.DATE_AND_TIME), BigInteger.valueOf(12345678L), new PlcDATE_AND_TIME(LocalDateTime.parse("1970-05-23T21:21:18"))), + Arguments.of(new MockTag("mock", PlcValueType.DATE_AND_TIME), BigDecimal.valueOf(12345678L), new PlcDATE_AND_TIME(LocalDateTime.parse("1970-05-23T21:21:18"))), + Arguments.of(new MockTag("mock", PlcValueType.DATE_AND_TIME), "1978-03-28T12:34:56", new PlcDATE_AND_TIME(LocalDateTime.parse("1978-03-28T12:34:56"))), + + // DATE_AND_LTIME values (Numeric values are interpreted as milliseconds since epoch) + Arguments.of(new MockTag("mock", PlcValueType.DATE_AND_LTIME), LocalDateTime.ofEpochSecond(1234, 5678, ZoneOffset.UTC), new PlcDATE_AND_LTIME(LocalDateTime.parse("1970-01-01T00:20:34.000005678"))), + Arguments.of(new MockTag("mock", PlcValueType.DATE_AND_LTIME), (byte) 123, new PlcDATE_AND_LTIME(LocalDateTime.parse("1970-01-01T00:00:00.000000123"))), + Arguments.of(new MockTag("mock", PlcValueType.DATE_AND_LTIME), (short) 12345, new PlcDATE_AND_LTIME(LocalDateTime.parse("1970-01-01T00:00:00.000012345"))), + Arguments.of(new MockTag("mock", PlcValueType.DATE_AND_LTIME), 1234567890, new PlcDATE_AND_LTIME(LocalDateTime.parse("1970-01-01T00:00:01.234567890"))), + Arguments.of(new MockTag("mock", PlcValueType.DATE_AND_LTIME), 12345678901L, new PlcDATE_AND_LTIME(LocalDateTime.parse("1970-01-01T00:00:12.345678901"))), + Arguments.of(new MockTag("mock", PlcValueType.DATE_AND_LTIME), (float) 123456.56, new PlcDATE_AND_LTIME(LocalDateTime.parse("1970-01-01T00:00:00.000123456"))), + Arguments.of(new MockTag("mock", PlcValueType.DATE_AND_LTIME), (double) 12345678.9, new PlcDATE_AND_LTIME(LocalDateTime.parse("1970-01-01T00:00:00.012345678"))), + Arguments.of(new MockTag("mock", PlcValueType.DATE_AND_LTIME), BigInteger.valueOf(12345678901L), new PlcDATE_AND_LTIME(LocalDateTime.parse("1970-01-01T00:00:12.345678901"))), + Arguments.of(new MockTag("mock", PlcValueType.DATE_AND_LTIME), BigDecimal.valueOf(12345678901L), new PlcDATE_AND_LTIME(LocalDateTime.parse("1970-01-01T00:00:12.345678901"))), + Arguments.of(new MockTag("mock", PlcValueType.DATE_AND_LTIME), "1978-03-28T01:02:03", new PlcDATE_AND_LTIME(LocalDateTime.parse("1978-03-28T01:02:03"))), + + // LDATE_AND_TIME values + Arguments.of(new MockTag("mock", PlcValueType.LDATE_AND_TIME), LocalDateTime.ofEpochSecond(1234, 5678, ZoneOffset.UTC), new PlcLDATE_AND_TIME(LocalDateTime.parse("1970-01-01T00:20:34.000005678"))), + Arguments.of(new MockTag("mock", PlcValueType.LDATE_AND_TIME), (byte) 123, new PlcLDATE_AND_TIME(LocalDateTime.parse("1970-01-01T00:00:00.123"))), + Arguments.of(new MockTag("mock", PlcValueType.LDATE_AND_TIME), (short) 12345, new PlcLDATE_AND_TIME(LocalDateTime.parse("1970-01-01T00:00:12.345"))), + Arguments.of(new MockTag("mock", PlcValueType.LDATE_AND_TIME), 1234567890, new PlcLDATE_AND_TIME(LocalDateTime.parse("1970-01-15T06:56:07.890"))), + Arguments.of(new MockTag("mock", PlcValueType.LDATE_AND_TIME), 12345678901L, new PlcLDATE_AND_TIME(LocalDateTime.parse("1970-05-23T21:21:18.901"))), + Arguments.of(new MockTag("mock", PlcValueType.LDATE_AND_TIME), (float) 123456.56, new PlcLDATE_AND_TIME(LocalDateTime.parse("1970-01-01T00:02:03.456"))), + Arguments.of(new MockTag("mock", PlcValueType.LDATE_AND_TIME), (double) 12345678.9, new PlcLDATE_AND_TIME(LocalDateTime.parse("1970-01-01T03:25:45.678"))), + Arguments.of(new MockTag("mock", PlcValueType.LDATE_AND_TIME), BigInteger.valueOf(12345678901L), new PlcLDATE_AND_TIME(LocalDateTime.parse("1970-05-23T21:21:18.901"))), + Arguments.of(new MockTag("mock", PlcValueType.LDATE_AND_TIME), BigDecimal.valueOf(12345678901L), new PlcLDATE_AND_TIME(LocalDateTime.parse("1970-05-23T21:21:18.901"))), + Arguments.of(new MockTag("mock", PlcValueType.LDATE_AND_TIME), "1978-03-28T01:02:03", new PlcLDATE_AND_TIME(LocalDateTime.parse("1978-03-28T01:02:03"))), + + // RAW_BYTE_ARRAY values + Arguments.of(new MockTag("mock", PlcValueType.RAW_BYTE_ARRAY), new byte[]{(byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6}, new PlcRawByteArray(new byte[]{(byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6})) + ); + } + + @ParameterizedTest + @MethodSource("getSingleElementPlcValues") + void testSingleElementPlcValues(PlcTag plcTag, Object input, PlcValue expected) { + PlcValueHandler sut = new DefaultPlcValueHandler(); + + PlcValue plcValue = sut.newPlcValue(plcTag, input); + + assertNotNull(plcValue); + assertEquals(expected, plcValue); + } + + private static Stream getPlcValueTypesRanges() { + return Stream.of( + Arguments.of(PlcBYTE.class), + Arguments.of(PlcWORD.class), + Arguments.of(PlcDWORD.class), + // TODO: Need to find out how to test these ... + //Arguments.of(PlcLWORD.class), + Arguments.of(PlcUSINT.class), + Arguments.of(PlcUINT.class), + Arguments.of(PlcUDINT.class), + // TODO: Need to find out how to test these ... + //Arguments.of(PlcULINT.class), + Arguments.of(PlcSINT.class), + Arguments.of(PlcINT.class), + Arguments.of(PlcDINT.class), + // TODO: Need to find out how to test these ... + //Arguments.of(PlcLINT.class), + //Arguments.of(PlcREAL.class), + //Arguments.of(PlcLREAL.class), + Arguments.of(PlcCHAR.class), + Arguments.of(PlcWCHAR.class) + ); + } + + @ParameterizedTest + @MethodSource("getPlcValueTypesRanges") + void testPlcValueTypesRanges(Class plcValueType) throws Exception { + Field minValueField = plcValueType.getField("MIN_VALUE"); + Number minValue = (Number) minValueField.get(null); + Field maxValueField = plcValueType.getField("MAX_VALUE"); + Number maxValue = (Number) maxValueField.get(null); + + // Set value to one less than the lower bound (Should fail) + try { + plcValueType.getConstructor(Long.class).newInstance(minValue.longValue() - 1); + fail("Set value to one less than the lower bound should have failed"); + } catch (Exception e) { + // We want an exception here ... + } + + // Set value to exactly the lower bound (Should succeed) + try { + PlcValue plcValue = plcValueType.getConstructor(Long.class).newInstance(minValue.longValue()); + assertEquals(minValue.longValue(), plcValue.getLong()); + } catch (Exception e) { + fail("Set value to exactly the lower bound should have succeeded"); + } + + // Set value to one more than the lower bound (Should succeed) + try { + PlcValue plcValue = plcValueType.getConstructor(Long.class).newInstance(minValue.longValue() + 1); + assertEquals(minValue.longValue() + 1, plcValue.getLong()); + } catch (Exception e) { + fail("Set value to one more than the lower bound should have succeeded"); + } + + // Set value to one less than the upper bound (Should succeed) + try { + PlcValue plcValue = plcValueType.getConstructor(Long.class).newInstance(maxValue.longValue() - 1); + assertEquals(maxValue.longValue() - 1, plcValue.getLong()); + } catch (Exception e) { + fail("Set value to one less than the upper bound should have succeeded"); + } + + // Set value to exactly the upper bound (Should succeed) + try { + PlcValue plcValue = plcValueType.getConstructor(Long.class).newInstance(maxValue.longValue()); + assertEquals(maxValue.longValue(), plcValue.getLong()); + } catch (Exception e) { + fail("Set value to exactly the upper bound should have succeeded"); + } + + // Set value to one more than the upper bound (Should fail) + try { + plcValueType.getConstructor(Long.class).newInstance(maxValue.longValue() + 1); + fail("Set value to one more than the upper bound should have failed"); + } catch (Exception e) { + // We want an exception here ... + } + } + + + @Test + void newPlcValues() { + } + + public static class MockTag implements PlcTag { + private final String addressString; + private final PlcValueType plcValueType; + private final List arrayInfo; + + public MockTag(String addressString, PlcValueType plcValueType) { + this(addressString, plcValueType, Collections.emptyList()); + } + + public MockTag(String addressString, PlcValueType plcValueType, List arrayInfo) { + this.addressString = addressString; + this.plcValueType = plcValueType; + this.arrayInfo = arrayInfo; + } + + @Override + public String getAddressString() { + return addressString; + } + + @Override + public PlcValueType getPlcValueType() { + return plcValueType; + } + + @Override + public List getArrayInfo() { + return arrayInfo; + } + + @Override + public String toString() { + return new StringJoiner(", ", MockTag.class.getSimpleName() + "[", "]") + .add("addressString='" + addressString + "'") + .add("plcValueType=" + plcValueType) + .add("arrayInfo=" + arrayInfo) + .toString(); + } + } + +} \ No newline at end of file diff --git a/plc4j/tools/connection-cache/src/main/java/org/apache/plc4x/java/utils/cache/LeasedPlcConnection.java b/plc4j/tools/connection-cache/src/main/java/org/apache/plc4x/java/utils/cache/LeasedPlcConnection.java index 05dbf4e963e..ddcb70e2f9b 100644 --- a/plc4j/tools/connection-cache/src/main/java/org/apache/plc4x/java/utils/cache/LeasedPlcConnection.java +++ b/plc4j/tools/connection-cache/src/main/java/org/apache/plc4x/java/utils/cache/LeasedPlcConnection.java @@ -29,6 +29,7 @@ import org.apache.plc4x.java.api.model.PlcSubscriptionHandle; import org.apache.plc4x.java.api.model.PlcSubscriptionTag; import org.apache.plc4x.java.api.model.PlcTag; +import org.apache.plc4x.java.api.types.PlcResponseCode; import org.apache.plc4x.java.api.value.PlcValue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -102,6 +103,14 @@ public Optional parseTagAddress(String tagAddress) { return plcConnection.parseTagAddress(tagAddress); } + @Override + public Optional parseTagValue(PlcTag tag, Object... values) { + PlcConnection plcConnection = connection.get(); + if(plcConnection == null) { + throw new PlcRuntimeException("Error using leased connection after returning it to the cache."); + } + return plcConnection.parseTagValue(tag, values); + } @Override public void connect() throws PlcConnectionException { @@ -158,8 +167,7 @@ public CompletableFuture execute() { } else { // Mark the connection as invalid. invalidateConnection = true; - log.debug("ReadRequest execution completed exceptionally invalidateConnection={} t={}", - invalidateConnection, + log.debug("ReadRequest execution completed exceptionally invalidateConnection=true", throwable); responseFuture.completeExceptionally(throwable); } @@ -178,6 +186,11 @@ public LinkedHashSet getTagNames() { return innerPlcReadRequest.getTagNames(); } + @Override + public PlcResponseCode getTagResponseCode(String tagName) { + return innerPlcReadRequest.getTagResponseCode(tagName); + } + @Override public PlcTag getTag(String name) { return innerPlcReadRequest.getTag(name); @@ -251,6 +264,11 @@ public LinkedHashSet getTagNames() { return innerPlcWriteRequest.getTagNames(); } + @Override + public PlcResponseCode getTagResponseCode(String tagName) { + return innerPlcWriteRequest.getTagResponseCode(tagName); + } + @Override public PlcTag getTag(String name) { return innerPlcWriteRequest.getTag(name); diff --git a/plc4j/tools/opm/src/test/java/org/apache/plc4x/java/opm/ConnectedEntityTest.java b/plc4j/tools/opm/src/test/java/org/apache/plc4x/java/opm/ConnectedEntityTest.java index 3724a65bc01..f555b629a76 100644 --- a/plc4j/tools/opm/src/test/java/org/apache/plc4x/java/opm/ConnectedEntityTest.java +++ b/plc4j/tools/opm/src/test/java/org/apache/plc4x/java/opm/ConnectedEntityTest.java @@ -20,10 +20,10 @@ import org.apache.plc4x.java.DefaultPlcDriverManager; import org.apache.plc4x.java.api.types.PlcResponseCode; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; import org.apache.plc4x.java.spi.values.PlcSTRING; import org.apache.plc4x.java.mock.connection.MockConnection; import org.apache.plc4x.java.mock.connection.MockDevice; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -56,7 +56,7 @@ void setUp() throws Exception { driverManager = new DefaultPlcDriverManager(); connection = (MockConnection) driverManager.getConnection("mock:cached"); when(mockDevice.read(any())) - .thenReturn(new ResponseItem<>(PlcResponseCode.OK, new PlcSTRING("hallo"))); + .thenReturn(new DefaultPlcResponseItem<>(PlcResponseCode.OK, new PlcSTRING("hallo"))); connection.setDevice(mockDevice); entityManager = new PlcEntityManager(driverManager); } diff --git a/plc4j/tools/opm/src/test/java/org/apache/plc4x/java/opm/PlcEntityInterceptorTest.java b/plc4j/tools/opm/src/test/java/org/apache/plc4x/java/opm/PlcEntityInterceptorTest.java index 2d77e7a58a6..063686dbd46 100644 --- a/plc4j/tools/opm/src/test/java/org/apache/plc4x/java/opm/PlcEntityInterceptorTest.java +++ b/plc4j/tools/opm/src/test/java/org/apache/plc4x/java/opm/PlcEntityInterceptorTest.java @@ -26,7 +26,7 @@ import org.apache.plc4x.java.mock.connection.MockConnection; import org.apache.plc4x.java.mock.connection.MockDevice; import org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; import org.assertj.core.api.WithAssertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; @@ -118,7 +118,7 @@ public void getPlcReadResponse_timeoutOnGet_rethrows() { @Test public void getTyped_notOkResponse_throws() { DefaultPlcReadResponse response = new DefaultPlcReadResponse(null, - Collections.singletonMap("tag", new ResponseItem<>(PlcResponseCode.NOT_FOUND, null))); + Collections.singletonMap("tag", new DefaultPlcResponseItem<>(PlcResponseCode.NOT_FOUND, null))); assertThatThrownBy(() -> PlcEntityInterceptor.getTyped(Long.class, response, "tag")) .isInstanceOf(PlcRuntimeException.class) .hasMessage("Unable to read specified tag 'tag', response code was 'NOT_FOUND'"); diff --git a/plc4j/tools/opm/src/test/java/org/apache/plc4x/java/opm/PlcEntityManagerComplexTest.java b/plc4j/tools/opm/src/test/java/org/apache/plc4x/java/opm/PlcEntityManagerComplexTest.java index 0bd40ffd7bb..d26347f174b 100644 --- a/plc4j/tools/opm/src/test/java/org/apache/plc4x/java/opm/PlcEntityManagerComplexTest.java +++ b/plc4j/tools/opm/src/test/java/org/apache/plc4x/java/opm/PlcEntityManagerComplexTest.java @@ -29,6 +29,7 @@ import org.apache.plc4x.java.api.types.PlcResponseCode; import org.apache.plc4x.java.api.types.PlcValueType; import org.apache.plc4x.java.api.value.*; +import org.apache.plc4x.java.mock.tag.MockTag; import org.apache.plc4x.java.spi.connection.PlcTagHandler; import org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest; import org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse; @@ -36,10 +37,12 @@ import org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse; import org.apache.plc4x.java.spi.messages.PlcReader; import org.apache.plc4x.java.spi.messages.PlcWriter; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; -import org.apache.plc4x.java.spi.values.PlcValueHandler; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; +import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem; +import org.apache.plc4x.java.spi.values.DefaultPlcValueHandler; import org.apache.plc4x.java.spi.values.PlcDINT; import org.apache.plc4x.java.spi.values.PlcLINT; +import org.apache.plc4x.java.spi.values.PlcValueHandler; import org.assertj.core.api.WithAssertions; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -127,26 +130,27 @@ public void connect_callComplexMethod() throws PlcConnectionException, OPMExcept private PlcEntityManager getInitializedEntityManager() throws PlcConnectionException { Map map = new HashMap<>(); String prefix = ConnectedEntity.class.getName() + "."; - map.put(prefix + "boolVar", PlcValueHandler.of(true)); - map.put(prefix + "byteVar", PlcValueHandler.of((byte) 1)); - map.put(prefix + "shortVar", PlcValueHandler.of((short) 1)); - map.put(prefix + "intVar", PlcValueHandler.of(1)); - map.put(prefix + "longVar", PlcValueHandler.of(1L)); - map.put(prefix + "boxedBoolVar", PlcValueHandler.of(1L)); - map.put(prefix + "boxedByteVar", PlcValueHandler.of((byte) 1)); - map.put(prefix + "boxedShortVar", PlcValueHandler.of((short) 1)); - map.put(prefix + "boxedIntegerVar", PlcValueHandler.of(1)); - map.put(prefix + "boxedLongVar", PlcValueHandler.of(1L)); - map.put(prefix + "bigIntegerVar", PlcValueHandler.of(BigInteger.ONE)); - map.put(prefix + "floatVar", PlcValueHandler.of(1f)); - map.put(prefix + "doubleVar", PlcValueHandler.of(1d)); - map.put(prefix + "bigDecimalVar", PlcValueHandler.of(BigDecimal.ONE)); - map.put(prefix + "localTimeVar", PlcValueHandler.of(LocalTime.of(1, 1))); - map.put(prefix + "localDateVar", PlcValueHandler.of(LocalDate.of(1, 1, 1))); - map.put(prefix + "localDateTimeVar", PlcValueHandler.of(LocalDateTime.of(1, 1, 1, 1, 1))); - map.put(prefix + "byteArrayVar", PlcValueHandler.of(new Byte[]{0x0, 0x1})); - map.put(prefix + "bigByteArrayVar", PlcValueHandler.of(new Byte[]{0x0, 0x1})); - map.put(prefix + "stringVar", PlcValueHandler.of("Hallo")); + PlcValueHandler valueHandler = new DefaultPlcValueHandler(); + map.put(prefix + "boolVar", valueHandler.newPlcValue(new MockTag(prefix + "boolVar", PlcValueType.BOOL), true)); + map.put(prefix + "byteVar", valueHandler.newPlcValue(new MockTag(prefix + "byteVar", PlcValueType.SINT), (byte) 1)); + map.put(prefix + "shortVar", valueHandler.newPlcValue(new MockTag(prefix + "shortVar", PlcValueType.INT), (short) 1)); + map.put(prefix + "intVar", valueHandler.newPlcValue(new MockTag(prefix + "intVar", PlcValueType.DINT), 1)); + map.put(prefix + "longVar", valueHandler.newPlcValue(new MockTag(prefix + "longVar", PlcValueType.LINT), 1L)); + map.put(prefix + "boxedBoolVar", valueHandler.newPlcValue(new MockTag(prefix + "boxedBoolVar", PlcValueType.BOOL), 1L)); + map.put(prefix + "boxedByteVar", valueHandler.newPlcValue(new MockTag(prefix + "boxedByteVar", PlcValueType.SINT), (byte) 1)); + map.put(prefix + "boxedShortVar", valueHandler.newPlcValue(new MockTag(prefix + "boxedShortVar", PlcValueType.INT), (short) 1)); + map.put(prefix + "boxedIntegerVar", valueHandler.newPlcValue(new MockTag(prefix + "boxedIntegerVar", PlcValueType.DINT), 1)); + map.put(prefix + "boxedLongVar", valueHandler.newPlcValue(new MockTag(prefix + "boxedLongVar", PlcValueType.LINT), 1L)); + map.put(prefix + "bigIntegerVar", valueHandler.newPlcValue(new MockTag(prefix + "bigIntegerVar", PlcValueType.LINT), BigInteger.ONE)); + map.put(prefix + "floatVar", valueHandler.newPlcValue(new MockTag(prefix + "floatVar", PlcValueType.REAL), 1f)); + map.put(prefix + "doubleVar", valueHandler.newPlcValue(new MockTag(prefix + "doubleVar", PlcValueType.LREAL), 1d)); + map.put(prefix + "bigDecimalVar", valueHandler.newPlcValue(new MockTag(prefix + "bigDecimalVar", PlcValueType.LREAL), BigDecimal.ONE)); + map.put(prefix + "localTimeVar", valueHandler.newPlcValue(new MockTag(prefix + "localTimeVar", PlcValueType.TIME), LocalTime.of(1, 1))); + map.put(prefix + "localDateVar", valueHandler.newPlcValue(new MockTag(prefix + "localDateVar", PlcValueType.DATE), LocalDate.of(1, 1, 1))); + map.put(prefix + "localDateTimeVar", valueHandler.newPlcValue(new MockTag(prefix + "localDateTimeVar", PlcValueType.DATE_AND_TIME), LocalDateTime.of(1, 1, 1, 1, 1))); + map.put(prefix + "byteArrayVar", valueHandler.newPlcValue(new MockTag(prefix + "byteArrayVar", PlcValueType.RAW_BYTE_ARRAY), new Byte[]{0x0, 0x1})); + map.put(prefix + "bigByteArrayVar", valueHandler.newPlcValue(new MockTag(prefix + "bigByteArrayVar", PlcValueType.RAW_BYTE_ARRAY), new Byte[]{0x0, 0x1})); + map.put(prefix + "stringVar", valueHandler.newPlcValue(new MockTag(prefix + "stringVar", PlcValueType.STRING), "Hallo")); return getPlcEntityManager(map); } @@ -226,10 +230,10 @@ public boolean isBrowseSupported() { }); PlcReader reader = readRequest -> { - Map> map = readRequest.getTagNames().stream() + Map> map = readRequest.getTagNames().stream() .collect(Collectors.toMap( Function.identity(), - s -> new ResponseItem<>(PlcResponseCode.OK, Objects.requireNonNull(responses.get(s), s + " not found")) + s -> new DefaultPlcResponseItem<>(PlcResponseCode.OK, Objects.requireNonNull(responses.get(s), s + " not found")) )); return CompletableFuture.completedFuture(new DefaultPlcReadResponse(readRequest, map)); }; @@ -242,7 +246,7 @@ public boolean isBrowseSupported() { )); return CompletableFuture.completedFuture(new DefaultPlcWriteResponse(writeRequest, map)); }; - when(connection.writeRequestBuilder()).then(invocation -> new DefaultPlcWriteRequest.Builder(writer, getTagHandler(), getValueHandler())); + when(connection.writeRequestBuilder()).then(invocation -> new DefaultPlcWriteRequest.Builder(writer, getTagHandler(), new DefaultPlcValueHandler())); return new PlcEntityManager(mock); } @@ -251,10 +255,6 @@ private PlcTagHandler getTagHandler() { return new NoOpPlcTagHandler(); } - private org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() { - return new NoOpPlcValueHandler(); - } - private static class NoOpPlcTagHandler implements PlcTagHandler { @Override public org.apache.plc4x.java.api.model.PlcTag parseTag(String tagAddress) throws PlcInvalidTagException { @@ -282,28 +282,6 @@ public PlcQuery parseQuery(String query) { } } - private static class NoOpPlcValueHandler implements org.apache.plc4x.java.api.value.PlcValueHandler { - @Override - public PlcValue newPlcValue(Object value) { - throw new RuntimeException("Data Type " + value.getClass().getSimpleName() + "Is not supported"); - } - - @Override - public PlcValue newPlcValue(Object[] values) { - throw new RuntimeException("Data Type " + values.getClass().getSimpleName() + "Is not supported"); - } - - @Override - public PlcValue newPlcValue(org.apache.plc4x.java.api.model.PlcTag tag, Object value) { - throw new RuntimeException("Data Type " + value.getClass().getSimpleName() + "Is not supported"); - } - - @Override - public PlcValue newPlcValue(org.apache.plc4x.java.api.model.PlcTag tag, Object[] values) { - throw new RuntimeException("Data Type " + values.getClass().getSimpleName() + "Is not supported"); - } - } - private static class NoEntity { } diff --git a/plc4j/tools/opm/src/test/java/org/apache/plc4x/java/opm/PlcEntityManagerTest.java b/plc4j/tools/opm/src/test/java/org/apache/plc4x/java/opm/PlcEntityManagerTest.java index 389f58335fd..efa9d210977 100644 --- a/plc4j/tools/opm/src/test/java/org/apache/plc4x/java/opm/PlcEntityManagerTest.java +++ b/plc4j/tools/opm/src/test/java/org/apache/plc4x/java/opm/PlcEntityManagerTest.java @@ -23,10 +23,10 @@ import org.apache.plc4x.java.api.exceptions.PlcConnectionException; import org.apache.plc4x.java.api.exceptions.PlcInvalidTagException; import org.apache.plc4x.java.api.types.PlcResponseCode; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; import org.apache.plc4x.java.spi.values.PlcSTRING; import org.apache.plc4x.java.mock.connection.MockConnection; import org.apache.plc4x.java.mock.connection.MockDevice; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; import org.assertj.core.api.WithAssertions; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -119,7 +119,7 @@ public void resolveAlias_works() throws OPMException, PlcConnectionException { DefaultPlcDriverManager driverManager = new DefaultPlcDriverManager(); MockConnection connection = (MockConnection) driverManager.getConnection("mock:test"); MockDevice mockDevice = Mockito.mock(MockDevice.class); - when(mockDevice.read(any())).thenReturn(new ResponseItem<>(PlcResponseCode.OK, new PlcSTRING("value"))); + when(mockDevice.read(any())).thenReturn(new DefaultPlcResponseItem<>(PlcResponseCode.OK, new PlcSTRING("value"))); connection.setDevice(mockDevice); PlcEntityManager entityManager = new PlcEntityManager(driverManager, registry); @@ -169,7 +169,7 @@ void simpleWrite() throws Exception { MockConnection connection = (MockConnection) driverManager.getConnection("mock:test"); MockDevice mockDevice = Mockito.mock(MockDevice.class); when(mockDevice.write(anyString(), any())).thenReturn(PlcResponseCode.OK); - when(mockDevice.read(any())).thenReturn(new ResponseItem<>(PlcResponseCode.OK, new PlcSTRING("value"))); + when(mockDevice.read(any())).thenReturn(new DefaultPlcResponseItem<>(PlcResponseCode.OK, new PlcSTRING("value"))); connection.setDevice(mockDevice); PlcEntityManager entityManager = new PlcEntityManager(driverManager, registry); @@ -198,7 +198,7 @@ void simpleWrite_uses_getter() throws Exception { DefaultPlcDriverManager driverManager = new DefaultPlcDriverManager(); MockConnection connection = (MockConnection) driverManager.getConnection("mock:test"); MockDevice mockDevice = Mockito.mock(MockDevice.class); - when(mockDevice.read(any())).thenReturn(new ResponseItem<>(PlcResponseCode.OK, new PlcSTRING("value"))); + when(mockDevice.read(any())).thenReturn(new DefaultPlcResponseItem<>(PlcResponseCode.OK, new PlcSTRING("value"))); connection.setDevice(mockDevice); PlcEntityManager entityManager = new PlcEntityManager(driverManager); @@ -231,7 +231,7 @@ public void connect_resolveAlias_works() throws PlcConnectionException, OPMExcep DefaultPlcDriverManager driverManager = new DefaultPlcDriverManager(); MockConnection connection = (MockConnection) driverManager.getConnection("mock:test"); MockDevice mockDevice = Mockito.mock(MockDevice.class); - when(mockDevice.read(any())).thenReturn(new ResponseItem<>(PlcResponseCode.OK, new PlcSTRING("value"))); + when(mockDevice.read(any())).thenReturn(new DefaultPlcResponseItem<>(PlcResponseCode.OK, new PlcSTRING("value"))); connection.setDevice(mockDevice); PlcEntityManager entityManager = new PlcEntityManager(driverManager, registry); diff --git a/plc4j/tools/scraper/src/test/java/org/apache/plc4x/java/scraper/ScraperTaskTest.java b/plc4j/tools/scraper/src/test/java/org/apache/plc4x/java/scraper/ScraperTaskTest.java index aebf65e16b6..c0b2289c687 100644 --- a/plc4j/tools/scraper/src/test/java/org/apache/plc4x/java/scraper/ScraperTaskTest.java +++ b/plc4j/tools/scraper/src/test/java/org/apache/plc4x/java/scraper/ScraperTaskTest.java @@ -25,7 +25,7 @@ import org.apache.plc4x.java.spi.values.PlcSTRING; import org.apache.plc4x.java.mock.connection.MockConnection; import org.apache.plc4x.java.mock.connection.MockDevice; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; import org.assertj.core.api.WithAssertions; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -54,7 +54,7 @@ public void scrape() throws PlcConnectionException { DefaultPlcDriverManager driverManager = new DefaultPlcDriverManager(); MockConnection connection = (MockConnection) driverManager.getConnection("mock:scraper"); connection.setDevice(mockDevice); - when(mockDevice.read(any())).thenReturn(new ResponseItem<>(PlcResponseCode.OK, new PlcSTRING("hallo"))); + when(mockDevice.read(any())).thenReturn(new DefaultPlcResponseItem<>(PlcResponseCode.OK, new PlcSTRING("hallo"))); ScraperTask scraperTask = new ScraperTaskImpl(driverManager, "job1", "m1", "mock:scraper", Collections.singletonMap("a", "b"), 1_000, ForkJoinPool.commonPool(), (j,a,m) -> {}); @@ -71,7 +71,7 @@ public void badResponseCode_shouldHandleException() throws PlcConnectionExceptio DefaultPlcDriverManager driverManager = new DefaultPlcDriverManager(); MockConnection connection = (MockConnection) driverManager.getConnection("mock:scraper"); connection.setDevice(mockDevice); - when(mockDevice.read(any())).thenReturn(new ResponseItem<>(PlcResponseCode.NOT_FOUND, new PlcSTRING("hallo"))); + when(mockDevice.read(any())).thenReturn(new DefaultPlcResponseItem<>(PlcResponseCode.NOT_FOUND, new PlcSTRING("hallo"))); ScraperTask scraperTask = new ScraperTaskImpl(driverManager, "job1", "m1", "mock:scraper", Collections.singletonMap("a", "b"), 1_000, ForkJoinPool.commonPool(), (j,a,m) -> {}); diff --git a/plc4j/tools/scraper/src/test/java/org/apache/plc4x/java/scraper/ScraperTest.java b/plc4j/tools/scraper/src/test/java/org/apache/plc4x/java/scraper/ScraperTest.java index c329d8a95ff..3c4ccafa4cb 100644 --- a/plc4j/tools/scraper/src/test/java/org/apache/plc4x/java/scraper/ScraperTest.java +++ b/plc4j/tools/scraper/src/test/java/org/apache/plc4x/java/scraper/ScraperTest.java @@ -25,7 +25,7 @@ import org.apache.plc4x.java.spi.values.PlcDINT; import org.apache.plc4x.java.mock.connection.MockConnection; import org.apache.plc4x.java.mock.connection.MockDevice; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; import org.apache.plc4x.java.utils.cache.CachedPlcConnectionManager; import org.assertj.core.api.WithAssertions; import org.junit.jupiter.api.Disabled; @@ -83,7 +83,7 @@ void scraper_schedulesJob() throws InterruptedException, PlcConnectionException MockConnection connection = (MockConnection) driverManager.getConnection("mock:m1"); connection.setDevice(mockDevice); - when(mockDevice.read(any())).thenReturn(new ResponseItem<>(PlcResponseCode.OK, new PlcDINT(1))); + when(mockDevice.read(any())).thenReturn(new DefaultPlcResponseItem<>(PlcResponseCode.OK, new PlcDINT(1))); ScraperImpl scraper = new ScraperImpl((j, a, m) -> {}, driverManager, Collections.singletonList( new ScrapeJobImpl("job1", @@ -134,7 +134,7 @@ void restart_works() throws PlcConnectionException { MockConnection connection = (MockConnection) driverManager.getConnection("mock:m1"); connection.setDevice(mockDevice); - when(mockDevice.read(any())).thenReturn(new ResponseItem<>(PlcResponseCode.OK, new PlcDINT(1))); + when(mockDevice.read(any())).thenReturn(new DefaultPlcResponseItem<>(PlcResponseCode.OK, new PlcDINT(1))); Scraper scraper = new ScraperImpl((j, a, m) -> {}, driverManager, Collections.singletonList( new ScrapeJobImpl("job1", diff --git a/plc4j/tools/scraper/src/test/java/org/apache/plc4x/java/scraper/triggeredscraper/TriggeredScraperImplTest.java b/plc4j/tools/scraper/src/test/java/org/apache/plc4x/java/scraper/triggeredscraper/TriggeredScraperImplTest.java index e109009e821..db7ebfad3b6 100644 --- a/plc4j/tools/scraper/src/test/java/org/apache/plc4x/java/scraper/triggeredscraper/TriggeredScraperImplTest.java +++ b/plc4j/tools/scraper/src/test/java/org/apache/plc4x/java/scraper/triggeredscraper/TriggeredScraperImplTest.java @@ -27,7 +27,7 @@ import org.apache.plc4x.java.scraper.exception.ScraperException; import org.apache.plc4x.java.scraper.triggeredscraper.triggerhandler.collector.TriggerCollector; import org.apache.plc4x.java.scraper.triggeredscraper.triggerhandler.collector.TriggerCollectorImpl; -import org.apache.plc4x.java.spi.messages.utils.ResponseItem; +import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem; import org.apache.plc4x.java.spi.values.PlcBOOL; import org.apache.plc4x.java.spi.values.PlcLINT; import org.junit.jupiter.api.BeforeEach; @@ -69,24 +69,24 @@ public void setUp() throws Exception { void scrapeMultipleTargets() throws ScraperException, IOException, InterruptedException { // Prepare the Mocking // Scrate Jobs 1 and 2 - when(mockDevice1.read("%DB810:DBB0:USINT")).thenReturn(new ResponseItem<>(PlcResponseCode.OK, new PlcLINT(1L))); - when(mockDevice2.read("%DB810:DBB0:USINT")).thenReturn(new ResponseItem<>(PlcResponseCode.OK, new PlcLINT(2L))); + when(mockDevice1.read("%DB810:DBB0:USINT")).thenReturn(new DefaultPlcResponseItem<>(PlcResponseCode.OK, new PlcLINT(1L))); + when(mockDevice2.read("%DB810:DBB0:USINT")).thenReturn(new DefaultPlcResponseItem<>(PlcResponseCode.OK, new PlcLINT(2L))); // Trigger Jobs // Trigger var Random rand = new Random(); when(mockDevice1.read(("%M0.3:BOOL"))).thenAnswer(invocationOnMock -> { boolean trigger = rand.nextBoolean(); System.out.println(trigger); - return new ResponseItem<>(PlcResponseCode.OK, new PlcBOOL(trigger)); + return new DefaultPlcResponseItem<>(PlcResponseCode.OK, new PlcBOOL(trigger)); }); when(mockDevice2.read(("%M0.3:BOOL"))).thenAnswer(invocationOnMock -> { boolean trigger = rand.nextBoolean(); System.out.println("\t\t" + trigger); - return new ResponseItem<>(PlcResponseCode.OK, new PlcBOOL(trigger)); + return new DefaultPlcResponseItem<>(PlcResponseCode.OK, new PlcBOOL(trigger)); }); // Read var - when(mockDevice1.read("%DB810:DBW0:INT")).thenReturn(new ResponseItem<>(PlcResponseCode.OK, new PlcLINT(3L))); - when(mockDevice2.read("%DB810:DBW0:INT")).thenReturn(new ResponseItem<>(PlcResponseCode.OK, new PlcLINT(4L))); + when(mockDevice1.read("%DB810:DBW0:INT")).thenReturn(new DefaultPlcResponseItem<>(PlcResponseCode.OK, new PlcLINT(3L))); + when(mockDevice2.read("%DB810:DBW0:INT")).thenReturn(new DefaultPlcResponseItem<>(PlcResponseCode.OK, new PlcLINT(4L))); ScraperConfiguration configuration = ScraperConfiguration.fromFile("src/test/resources/mock-scraper-config.yml", ScraperConfigurationClassicImpl.class); TriggerCollector triggerCollector = new TriggerCollectorImpl(driverManager); diff --git a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/manual/ManualTest.java b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/manual/ManualTest.java index 88f88dbbf12..d0ece31aca0 100644 --- a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/manual/ManualTest.java +++ b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/manual/ManualTest.java @@ -29,7 +29,6 @@ import org.apache.plc4x.java.spi.values.PlcList; import org.apache.plc4x.java.spi.values.PlcRawByteArray; import org.apache.plc4x.java.spi.values.PlcStruct; -import org.apache.plc4x.java.spi.values.PlcValues; import org.junit.jupiter.api.Assertions; import java.util.ArrayList; @@ -61,7 +60,17 @@ public ManualTest(String connectionString, boolean testRead, boolean testWrite, } public ManualTest addTestCase(String address, PlcValue expectedReadValue) { - testCases.add(new TestCase(address, expectedReadValue, null)); + testCases.add(new TestCase(address, PlcResponseCode.OK, expectedReadValue)); + return this; + } + + public ManualTest addTestCase(String address, PlcResponseCode expectedResponseCode) { + testCases.add(new TestCase(address, expectedResponseCode, null)); + return this; + } + + public ManualTest addTestCase(String address, PlcResponseCode expectedResponseCode, PlcValue expectedReadValue) { + testCases.add(new TestCase(address, expectedResponseCode, expectedReadValue)); return this; } @@ -78,7 +87,8 @@ public void run() throws Exception { if (testRead) { System.out.println(" - Reading: " + tagName); // Prepare the read-request - final PlcReadRequest readRequest = plcConnection.readRequestBuilder().addTagAddress(tagName, testCase.address).build(); + final PlcReadRequest readRequest = plcConnection.readRequestBuilder().addTagAddress( + tagName, testCase.address).build(); // Execute the read request long startTime = System.currentTimeMillis(); @@ -88,7 +98,7 @@ public void run() throws Exception { // Check the result Assertions.assertEquals(1, readResponse.getTagNames().size(), tagName); Assertions.assertEquals(tagName, readResponse.getTagNames().iterator().next(), tagName); - Assertions.assertEquals(PlcResponseCode.OK, readResponse.getResponseCode(tagName), tagName); + Assertions.assertEquals(testCase.responseCode, readResponse.getResponseCode(tagName), tagName); Assertions.assertNotNull(readResponse.getPlcValue(tagName), tagName); if (readResponse.getPlcValue(tagName) instanceof PlcList) { PlcList plcList = (PlcList) readResponse.getPlcValue(tagName); @@ -104,24 +114,29 @@ public void run() throws Exception { } for (int j = 0; j < expectedValues.size(); j++) { if (expectedValues.get(j) instanceof PlcValue) { - Assertions.assertEquals(((PlcValue) expectedValues.get(j)).getObject(), plcList.getIndex(j).getObject(), tagName + "[" + j + "]"); + Assertions.assertEquals(((PlcValue) expectedValues.get(j)).getObject(), + plcList.getIndex(j).getObject(), tagName + "[" + j + "]"); } else { - Assertions.assertEquals(expectedValues.get(j), plcList.getIndex(j).getObject(), tagName + "[" + j + "]"); + Assertions.assertEquals(expectedValues.get(j), plcList.getIndex(j).getObject(), + tagName + "[" + j + "]"); } } } else { if (testCase.expectedReadValue instanceof PlcStruct) { - Assertions.assertEquals(testCase.expectedReadValue.toString(), readResponse.getPlcValue(tagName).toString(), tagName); + Assertions.assertEquals(testCase.expectedReadValue.toString(), + readResponse.getPlcValue(tagName).toString(), tagName); } else if (testCase.expectedReadValue instanceof PlcRawByteArray) { byte[] expectedRawByteArray = ((PlcRawByteArray) testCase.expectedReadValue).getRaw(); byte[] readRawByteArray = ((PlcRawByteArray) readResponse.getPlcValue(tagName)).getRaw(); Assertions.assertArrayEquals(expectedRawByteArray, readRawByteArray); } else if (testCase.expectedReadValue instanceof PlcValue) { Assertions.assertEquals( - ((PlcValue) testCase.expectedReadValue).getObject(), readResponse.getPlcValue(tagName).getObject(), tagName); + ((PlcValue) testCase.expectedReadValue).getObject(), + readResponse.getPlcValue(tagName).getObject(), tagName); } else { Assertions.assertEquals( - testCase.expectedReadValue.toString(), readResponse.getPlcValue(tagName).getObject().toString(), tagName); + testCase.expectedReadValue.toString(), + readResponse.getPlcValue(tagName).getObject().toString(), tagName); } } } @@ -129,15 +144,10 @@ public void run() throws Exception { // Try writing the value to the PLC. if (testWrite) { System.out.println(" - Writing: " + tagName); - PlcValue plcValue; - if (testCase.expectedReadValue instanceof PlcValue) { - plcValue = ((PlcValue) testCase.expectedReadValue); - } else { - plcValue = PlcValues.of(testCase.expectedReadValue); - } // Prepare the write request - PlcWriteRequest writeRequest = plcConnection.writeRequestBuilder().addTagAddress(tagName, testCase.address, plcValue).build(); + PlcWriteRequest writeRequest = plcConnection.writeRequestBuilder().addTagAddress( + tagName, testCase.address, testCase.expectedReadValue).build(); // Execute the write request long startTime = System.currentTimeMillis(); @@ -145,7 +155,9 @@ public void run() throws Exception { long endTime = System.currentTimeMillis(); // Check the result - Assertions.assertEquals(PlcResponseCode.OK, writeResponse.getResponseCode(tagName), String.format("Got status %s for %s", writeResponse.getResponseCode(tagName).name(), testCase.address)); + Assertions.assertEquals(testCase.responseCode, writeResponse.getResponseCode(tagName), + String.format("Got status %s for %s", + writeResponse.getResponseCode(tagName).name(), testCase.address)); } } System.out.println("Success"); @@ -234,25 +246,25 @@ public void run() throws Exception { public static class TestCase { private final String address; + private final PlcResponseCode responseCode; private final Object expectedReadValue; - private final Object writeValue; - public TestCase(String address, Object expectedReadValue, Object writeValue) { + public TestCase(String address, PlcResponseCode responseCode, Object expectedReadValue) { this.address = address; + this.responseCode = responseCode; this.expectedReadValue = expectedReadValue; - this.writeValue = writeValue; } public String getAddress() { return address; } - public Object getExpectedReadValue() { - return expectedReadValue; + public PlcResponseCode getResponseCode() { + return responseCode; } - public Object getWriteValue() { - return writeValue; + public Object getExpectedReadValue() { + return expectedReadValue; } } diff --git a/protocols/ads/src/test/resources/protocols/ads/DriverTestsuite.xml b/protocols/ads/src/test/resources/protocols/ads/DriverTestsuite.xml index 73ddc897851..3770e9d267e 100644 --- a/protocols/ads/src/test/resources/protocols/ads/DriverTestsuite.xml +++ b/protocols/ads/src/test/resources/protocols/ads/DriverTestsuite.xml @@ -1150,9 +1150,13 @@ - - MAIN.hurz_Struct - + + + + MAIN.hurz_Struct + + + @@ -1160,7 +1164,7 @@ - + OK @@ -1232,7 +1236,7 @@ - + @@ -1580,12 +1584,12 @@ - + OK true - + @@ -1754,20 +1758,20 @@ - + OK true - + - + OK true - + @@ -2040,12 +2044,12 @@ - + OK false - + @@ -2319,12 +2323,12 @@ - + OK false - + @@ -2474,12 +2478,12 @@ - + OK false - + diff --git a/protocols/canopen/src/test/resources/protocols/canopen/CANOpenDriverSDOIT.xml b/protocols/canopen/src/test/resources/protocols/canopen/CANOpenDriverSDOIT.xml index 0dda4803357..af0bbb47a14 100644 --- a/protocols/canopen/src/test/resources/protocols/canopen/CANOpenDriverSDOIT.xml +++ b/protocols/canopen/src/test/resources/protocols/canopen/CANOpenDriverSDOIT.xml @@ -199,12 +199,12 @@ - + OK 1717859169 - + @@ -328,12 +328,12 @@ - + OK 97 - + @@ -504,12 +504,12 @@ - + OK 1717859169 - + @@ -835,7 +835,7 @@ - + OK @@ -849,7 +849,7 @@ 0x66 - + @@ -965,12 +965,12 @@ - + REMOTE_ERROR 84082688 - + diff --git a/protocols/eip/src/test/resources/protocols/eip/DriverTestsuite.xml b/protocols/eip/src/test/resources/protocols/eip/DriverTestsuite.xml index b18faac99d3..b6eca5cd50c 100644 --- a/protocols/eip/src/test/resources/protocols/eip/DriverTestsuite.xml +++ b/protocols/eip/src/test/resources/protocols/eip/DriverTestsuite.xml @@ -398,11 +398,15 @@ - - %rate - DINT - 1 - + + + + %rate + DINT + 1 + + + @@ -410,12 +414,12 @@ - + OK 369229824 - + diff --git a/protocols/iec-60870/src/test/resources/logback-test.xml b/protocols/iec-60870/src/test/resources/logback-test.xml index 2b9cea25dc8..941f1546f84 100644 --- a/protocols/iec-60870/src/test/resources/logback-test.xml +++ b/protocols/iec-60870/src/test/resources/logback-test.xml @@ -29,7 +29,7 @@ - + diff --git a/protocols/modbus/src/test/resources/protocols/modbus/tcp/DriverTestsuite.xml b/protocols/modbus/src/test/resources/protocols/modbus/tcp/DriverTestsuite.xml index cad5d8eb6f7..b88fd463e35 100644 --- a/protocols/modbus/src/test/resources/protocols/modbus/tcp/DriverTestsuite.xml +++ b/protocols/modbus/src/test/resources/protocols/modbus/tcp/DriverTestsuite.xml @@ -109,12 +109,12 @@ - + OK 3.1415927410125732 - + @@ -202,7 +202,7 @@ - + OK @@ -210,7 +210,7 @@ 3.1415927410125732 - + @@ -357,20 +357,20 @@ - + OK 3.1415927410125732 - + - + OK 3.1415927410125732 - + diff --git a/protocols/modbus/src/test/resources/protocols/modbus/tcp/DriverTestsuiteOptimized.xml b/protocols/modbus/src/test/resources/protocols/modbus/tcp/DriverTestsuiteOptimized.xml index ebd8db39865..ac935f38bee 100644 --- a/protocols/modbus/src/test/resources/protocols/modbus/tcp/DriverTestsuiteOptimized.xml +++ b/protocols/modbus/src/test/resources/protocols/modbus/tcp/DriverTestsuiteOptimized.xml @@ -97,11 +97,15 @@ - -

0
- 1 - REAL - + + + +
0
+ 1 + REAL +
+
+
@@ -109,12 +113,12 @@ - + OK 3.1415927410125732 - +
@@ -190,11 +194,15 @@ - -
0
- 2 - REAL -
+ + + +
0
+ 2 + REAL +
+
+
@@ -202,7 +210,7 @@ - + OK @@ -210,7 +218,7 @@ 3.1415927410125732 - +
@@ -290,18 +298,26 @@ - -
0
- 1 - REAL -
+ + + +
0
+ 1 + REAL +
+
+
- -
2
- 1 - REAL -
+ + + +
2
+ 1 + REAL +
+
+
@@ -309,20 +325,20 @@ - + OK 3.1415927410125732 - + - + OK 3.1415927410125732 - + @@ -401,19 +417,21 @@ - -
0
- 1 - REAL -
+ + + +
0
+ 1 + REAL +
+
+ + 3.1415927410125732 + +
- - - 3.1415927410125732 - - @@ -498,22 +516,24 @@ - -
0
- 2 - REAL -
+ + + +
0
+ 2 + REAL +
+
+ + + 3.1415927410125732 + 3.1415927410125732 + + +
- - - - 3.1415927410125732 - 3.1415927410125732 - - - diff --git a/protocols/modbus/src/test/resources/protocols/modbus/tcp/Modbus-all-datatypes-little-endian.xml b/protocols/modbus/src/test/resources/protocols/modbus/tcp/Modbus-all-datatypes-little-endian.xml index 1c01f468725..7e46dc7933f 100644 --- a/protocols/modbus/src/test/resources/protocols/modbus/tcp/Modbus-all-datatypes-little-endian.xml +++ b/protocols/modbus/src/test/resources/protocols/modbus/tcp/Modbus-all-datatypes-little-endian.xml @@ -101,11 +101,15 @@ - -
0
- 1 - BOOL -
+ + + +
0
+ 1 + BOOL +
+
+
@@ -113,12 +117,12 @@ - + OK true - + @@ -197,19 +201,21 @@ - -
0
- 1 - BOOL -
+ + + +
0
+ 1 + BOOL +
+
+ + true + +
- - - true - - @@ -290,11 +296,15 @@ - -
1
- 1 - BYTE -
+ + + +
1
+ 1 + BYTE +
+
+
@@ -302,12 +312,12 @@ - + OK 42 - + @@ -386,19 +396,21 @@ - -
1
- 1 - BYTE -
+ + + +
1
+ 1 + BYTE +
+
+ + 42 + +
- - - 42 - - @@ -479,11 +491,15 @@ - -
2
- 1 - WORD -
+ + + +
2
+ 1 + WORD +
+
+
@@ -491,12 +507,12 @@ - + OK 42424 - + @@ -575,19 +591,21 @@ - -
2
- 1 - WORD -
+ + + +
2
+ 1 + WORD +
+
+ + 42424 + +
- - - 42424 - - @@ -668,11 +686,15 @@ - -
3
- 1 - DWORD -
+ + + +
3
+ 1 + DWORD +
+
+
@@ -680,12 +702,12 @@ - + OK 4242442424 - + @@ -764,19 +786,21 @@ - -
3
- 1 - DWORD -
+ + + +
3
+ 1 + DWORD +
+
+ + 4242442424 + +
- - - 4242442424 - - @@ -857,11 +881,15 @@ - -
9
- 1 - SINT -
+ + + +
9
+ 1 + SINT +
+
+
@@ -869,12 +897,12 @@ - + OK -42 - + @@ -953,19 +981,21 @@ - -
9
- 1 - SINT -
+ + + +
9
+ 1 + SINT +
+
+ + -42 + +
- - - -42 - - @@ -1046,11 +1076,15 @@ - -
10
- 1 - USINT -
+ + + +
10
+ 1 + USINT +
+
+
@@ -1058,12 +1092,12 @@ - + OK 42 - + @@ -1142,19 +1176,21 @@ - -
10
- 1 - USINT -
+ + + +
10
+ 1 + USINT +
+
+ + 42 + +
- - - 42 - - @@ -1235,11 +1271,15 @@ - -
11
- 1 - INT -
+ + + +
11
+ 1 + INT +
+
+
@@ -1247,12 +1287,12 @@ - + OK -2424 - + @@ -1331,19 +1371,21 @@ - -
11
- 1 - INT -
+ + + +
11
+ 1 + INT +
+
+ + -2424 + +
- - - -2424 - - @@ -1424,11 +1466,15 @@ - -
12
- 1 - UINT -
+ + + +
12
+ 1 + UINT +
+
+
@@ -1436,12 +1482,12 @@ - + OK 42424 - + @@ -1520,19 +1566,21 @@ - -
12
- 1 - UINT -
+ + + +
12
+ 1 + UINT +
+
+ + 42424 + +
- - - 42424 - - @@ -1613,11 +1661,15 @@ - -
13
- 1 - DINT -
+ + + +
13
+ 1 + DINT +
+
+
@@ -1625,12 +1677,12 @@ - + OK -242442424 - + @@ -1709,19 +1761,21 @@ - -
13
- 1 - DINT -
+ + + +
13
+ 1 + DINT +
+
+ + -242442424 + +
- - - -242442424 - - @@ -1802,11 +1856,15 @@ - -
15
- 1 - UDINT -
+ + + +
15
+ 1 + UDINT +
+
+
@@ -1814,12 +1872,12 @@ - + OK 4242442424 - + @@ -1898,19 +1956,21 @@ - -
15
- 1 - UDINT -
+ + + +
15
+ 1 + UDINT +
+
+ + 4242442424 + +
- - - 4242442424 - - @@ -1991,11 +2051,15 @@ - -
17
- 1 - LINT -
+ + + +
17
+ 1 + LINT +
+
+
@@ -2003,12 +2067,12 @@ - + OK -4242442424242424242 - + @@ -2087,19 +2151,21 @@ - -
17
- 1 - LINT -
+ + + +
17
+ 1 + LINT +
+
+ + -4242442424242424242 + +
- - - -4242442424242424242 - - @@ -2180,11 +2246,15 @@ - -
21
- 1 - ULINT -
+ + + +
21
+ 1 + ULINT +
+
+
@@ -2192,12 +2262,12 @@ - + OK 4242442424242424242 - + @@ -2276,19 +2346,21 @@ - -
21
- 1 - ULINT -
+ + + +
21
+ 1 + ULINT +
+
+ + 4242442424242424242 + +
- - - 4242442424242424242 - - @@ -2369,11 +2441,15 @@ - -
25
- 1 - REAL -
+ + + +
25
+ 1 + REAL +
+
+
@@ -2381,12 +2457,12 @@ - + OK 3.1415929794311523 - + @@ -2465,19 +2541,21 @@ - -
25
- 1 - REAL -
+ + + +
25
+ 1 + REAL +
+
+ + 3.1415929794311523 + +
- - - 3.1415929794311523 - - @@ -2558,11 +2636,15 @@ - -
27
- 1 - LREAL -
+ + + +
27
+ 1 + LREAL +
+
+
@@ -2570,12 +2652,12 @@ - + OK 2.71828182846 - + @@ -2654,19 +2736,21 @@ - -
27
- 1 - LREAL -
+ + + +
27
+ 1 + LREAL +
+
+ + 2.71828182846 + +
- - - 2.71828182846 - - diff --git a/protocols/modbus/src/test/resources/protocols/modbus/tcp/Modbus-all-datatypes.xml b/protocols/modbus/src/test/resources/protocols/modbus/tcp/Modbus-all-datatypes.xml index b3c7d9050c3..938027aff6f 100644 --- a/protocols/modbus/src/test/resources/protocols/modbus/tcp/Modbus-all-datatypes.xml +++ b/protocols/modbus/src/test/resources/protocols/modbus/tcp/Modbus-all-datatypes.xml @@ -95,11 +95,15 @@ - -
0
- 1 - BOOL -
+ + + +
0
+ 1 + BOOL +
+
+
@@ -107,12 +111,12 @@ - + OK true - + @@ -191,19 +195,21 @@ - -
0
- 1 - BOOL -
+ + + +
0
+ 1 + BOOL +
+
+ + true + +
- - - true - - @@ -284,11 +290,15 @@ - -
1
- 1 - BYTE -
+ + + +
1
+ 1 + BYTE +
+
+
@@ -296,12 +306,12 @@ - + OK 42 - + @@ -380,19 +390,21 @@ - -
1
- 1 - BYTE -
+ + + +
1
+ 1 + BYTE +
+
+ + 42 + +
- - - 42 - - @@ -473,11 +485,15 @@ - -
2
- 1 - WORD -
+ + + +
2
+ 1 + WORD +
+
+
@@ -485,12 +501,12 @@ - + OK 42424 - + @@ -569,19 +585,21 @@ - -
2
- 1 - WORD -
+ + + +
2
+ 1 + WORD +
+
+ + 42424 + +
- - - 42424 - - @@ -662,11 +680,15 @@ - -
3
- 1 - DWORD -
+ + + +
3
+ 1 + DWORD +
+
+
@@ -674,12 +696,12 @@ - + OK 4242442424 - + @@ -758,19 +780,21 @@ - -
3
- 1 - DWORD -
+ + + +
3
+ 1 + DWORD +
+
+ + 4242442424 + +
- - - 4242442424 - - @@ -851,11 +875,15 @@ - -
9
- 1 - SINT -
+ + + +
9
+ 1 + SINT +
+
+
@@ -863,12 +891,12 @@ - + OK -42 - + @@ -947,19 +975,21 @@ - -
9
- 1 - SINT -
+ + + +
9
+ 1 + SINT +
+
+ + -42 + +
- - - -42 - - @@ -1040,11 +1070,15 @@ - -
10
- 1 - USINT -
+ + + +
10
+ 1 + USINT +
+
+
@@ -1052,12 +1086,12 @@ - + OK 42 - + @@ -1136,19 +1170,21 @@ - -
10
- 1 - USINT -
+ + + +
10
+ 1 + USINT +
+
+ + 42 + +
- - - 42 - - @@ -1229,11 +1265,15 @@ - -
11
- 1 - INT -
+ + + +
11
+ 1 + INT +
+
+
@@ -1241,12 +1281,12 @@ - + OK -2424 - + @@ -1325,19 +1365,21 @@ - -
11
- 1 - INT -
+ + + +
11
+ 1 + INT +
+
+ + -2424 + +
- - - -2424 - - @@ -1418,11 +1460,15 @@ - -
12
- 1 - UINT -
+ + + +
12
+ 1 + UINT +
+
+
@@ -1430,12 +1476,12 @@ - + OK 42424 - + @@ -1514,19 +1560,21 @@ - -
12
- 1 - UINT -
+ + + +
12
+ 1 + UINT +
+
+ + 42424 + +
- - - 42424 - - @@ -1607,11 +1655,15 @@ - -
13
- 1 - DINT -
+ + + +
13
+ 1 + DINT +
+
+
@@ -1619,12 +1671,12 @@ - + OK -242442424 - + @@ -1703,19 +1755,21 @@ - -
13
- 1 - DINT -
+ + + +
13
+ 1 + DINT +
+
+ + -242442424 + +
- - - -242442424 - - @@ -1796,11 +1850,15 @@ - -
15
- 1 - UDINT -
+ + + +
15
+ 1 + UDINT +
+
+
@@ -1808,12 +1866,12 @@ - + OK 4242442424 - + @@ -1892,19 +1950,21 @@ - -
15
- 1 - UDINT -
+ + + +
15
+ 1 + UDINT +
+
+ + 4242442424 + +
- - - 4242442424 - - @@ -1985,11 +2045,15 @@ - -
17
- 1 - LINT -
+ + + +
17
+ 1 + LINT +
+
+
@@ -1997,12 +2061,12 @@ - + OK -4242442424242424242 - + @@ -2081,19 +2145,21 @@ - -
17
- 1 - LINT -
+ + + +
17
+ 1 + LINT +
+
+ + -4242442424242424242 + +
- - - -4242442424242424242 - - @@ -2174,11 +2240,15 @@ - -
21
- 1 - ULINT -
+ + + +
21
+ 1 + ULINT +
+
+
@@ -2186,12 +2256,12 @@ - + OK 4242442424242424242 - + @@ -2270,19 +2340,21 @@ - -
21
- 1 - ULINT -
+ + + +
21
+ 1 + ULINT +
+
+ + 4242442424242424242 + +
- - - 4242442424242424242 - - @@ -2363,11 +2435,15 @@ - -
25
- 1 - REAL -
+ + + +
25
+ 1 + REAL +
+
+
@@ -2375,12 +2451,12 @@ - + OK 3.1415929794311523 - + @@ -2459,19 +2535,21 @@ - -
25
- 1 - REAL -
+ + + +
25
+ 1 + REAL +
+
+ + 3.1415929794311523 + +
- - - 3.1415929794311523 - - @@ -2552,11 +2630,15 @@ - -
27
- 1 - LREAL -
+ + + +
27
+ 1 + LREAL +
+
+
@@ -2564,12 +2646,12 @@ - + OK 2.71828182846 - + @@ -2648,19 +2730,21 @@ - -
27
- 1 - LREAL -
+ + + +
27
+ 1 + LREAL +
+
+ + 2.71828182846 + +
- - - 2.71828182846 - - diff --git a/protocols/s7/src/test/resources/protocols/s7/DriverTestsuite.xml b/protocols/s7/src/test/resources/protocols/s7/DriverTestsuite.xml index d870c8b0caa..a62da145862 100644 --- a/protocols/s7/src/test/resources/protocols/s7/DriverTestsuite.xml +++ b/protocols/s7/src/test/resources/protocols/s7/DriverTestsuite.xml @@ -582,12 +582,12 @@ - + OK true - + @@ -730,12 +730,12 @@ - + ACCESS_DENIED - +