This is an automated email from the ASF dual-hosted git repository. tmitsch pushed a commit to branch feature/improve-scraper-tim in repository https://gitbox.apache.org/repos/asf/plc4x.git
commit 3bf49bc674d3cd516715ee6e7c61cf652b7cf292 Author: Tim Mitsch <[email protected]> AuthorDate: Sun Aug 11 20:54:30 2019 +0200 fixed some bugs --- .../java/org/apache/plc4x/Plc4XBaseTableTest.java | 6 +- .../org/apache/plc4x/java/s7/model/S7Field.java | 11 ++ .../plc4x/java/s7/netty/Plc4XNettyException.java | 37 ++++ .../plc4x/java/s7/netty/Plc4XS7Protocol.java | 202 +++++++++++---------- .../triggeredscraper/TriggeredScraperTask.java | 2 +- .../plc4x/java/scraper/TriggeredScraperRunner.java | 1 + .../test/resources/example_triggered_scraper.yml | 22 ++- 7 files changed, 176 insertions(+), 105 deletions(-) diff --git a/plc4j/integrations/apache-calcite/src/test/java/org/apache/plc4x/Plc4XBaseTableTest.java b/plc4j/integrations/apache-calcite/src/test/java/org/apache/plc4x/Plc4XBaseTableTest.java index d80cc6b..b031393 100644 --- a/plc4j/integrations/apache-calcite/src/test/java/org/apache/plc4x/Plc4XBaseTableTest.java +++ b/plc4j/integrations/apache-calcite/src/test/java/org/apache/plc4x/Plc4XBaseTableTest.java @@ -20,6 +20,7 @@ package org.apache.plc4x; import org.apache.calcite.linq4j.Enumerator; import org.apache.plc4x.java.scraper.config.JobConfigurationClassicImpl; +import org.apache.plc4x.java.scraper.config.JobConfigurationImpl; import org.assertj.core.api.WithAssertions; import org.junit.jupiter.api.Test; @@ -33,7 +34,10 @@ class Plc4XBaseTableTest implements WithAssertions { @Test void testOnBlockingQueue() { ArrayBlockingQueue<Plc4xSchema.Record> queue = new ArrayBlockingQueue<>(100); - Plc4xStreamTable table = new Plc4xStreamTable(queue, new JobConfigurationClassicImpl("job1", 100, + Plc4xStreamTable table = new Plc4xStreamTable(queue, new JobConfigurationImpl( + "job1", + null, + 100, Collections.emptyList(), Collections.singletonMap("key", "address"))); diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/model/S7Field.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/model/S7Field.java index 5629a3a..7f93a1e 100644 --- a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/model/S7Field.java +++ b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/model/S7Field.java @@ -232,4 +232,15 @@ public class S7Field implements PlcField { } + @Override + public String toString() { + return "S7Field{" + + "dataType=" + dataType + + ", memoryArea=" + memoryArea + + ", blockNumber=" + blockNumber + + ", byteOffset=" + byteOffset + + ", bitOffset=" + bitOffset + + ", numElements=" + numElements + + '}'; + } } diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XNettyException.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XNettyException.java new file mode 100644 index 0000000..4b370d3 --- /dev/null +++ b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XNettyException.java @@ -0,0 +1,37 @@ +/* +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.s7.netty; + +/** + * when exceptions within netty-implementations are thrown this class will be used + */ +public class Plc4XNettyException extends RuntimeException{ + + /** + * Constructs a new runtime exception with the specified detail message. + * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. + */ + public Plc4XNettyException(String message) { + super(message); + } +} diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java index 6d734aa..6c789dd 100644 --- a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java +++ b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java @@ -45,6 +45,8 @@ import org.apache.plc4x.java.s7.netty.model.params.items.VarParameterItem; import org.apache.plc4x.java.s7.netty.model.payloads.VarPayload; import org.apache.plc4x.java.s7.netty.model.payloads.items.VarPayloadItem; import org.apache.plc4x.java.s7.netty.model.types.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.IOException; import java.lang.reflect.Array; @@ -72,6 +74,7 @@ import java.util.stream.IntStream; * the {@link PlcRequestContainer}s future with the {@link PlcResponse}. */ public class Plc4XS7Protocol extends PlcMessageToMessageCodec<S7Message, PlcRequestContainer> { + private static final Logger logger = LoggerFactory.getLogger( Plc4XS7Protocol.class ); private static final AtomicInteger tpduGenerator = new AtomicInteger(10); @@ -450,99 +453,105 @@ public class Plc4XS7Protocol extends PlcMessageToMessageCodec<S7Message, PlcRequ BaseDefaultFieldItem fieldItem = null; ByteBuf data = Unpooled.wrappedBuffer(payloadItem.getData()); if (responseCode == PlcResponseCode.OK) { - // TODO 2018-09-27 jf: array returning only implemented for BOOL, BYTE, INTEGERS, FP - // not for CHARS & STRINGS and not for all other bit-strings except for BYTE - switch (field.getDataType()) { - // ----------------------------------------- - // Bit - // ----------------------------------------- - case BOOL: - fieldItem = decodeReadResponseBitField(field, data); - break; - // ----------------------------------------- - // Bit-strings - // ----------------------------------------- - case BYTE: // 1 byte - fieldItem = decodeReadResponseByteBitStringField(field, data); - break; - case WORD: // 2 byte (16 bit) - fieldItem = decodeReadResponseShortBitStringField(field, data); - break; - case DWORD: // 4 byte (32 bit) - fieldItem = decodeReadResponseIntegerBitStringField(field, data); - break; - case LWORD: // 8 byte (64 bit) - fieldItem = decodeReadResponseLongBitStringField(field, data); - break; - // ----------------------------------------- - // Integers - // ----------------------------------------- - // 8 bit: - case SINT: - fieldItem = decodeReadResponseSignedByteField(field, data); - break; - case USINT: - fieldItem = decodeReadResponseUnsignedByteField(field, data); - break; - // 16 bit: - case INT: - fieldItem = decodeReadResponseSignedShortField(field, data); - break; - case UINT: - fieldItem = decodeReadResponseUnsignedShortField(field, data); - break; - // 32 bit: - case DINT: - fieldItem = decodeReadResponseSignedIntegerField(field, data); - break; - case UDINT: - fieldItem = decodeReadResponseUnsignedIntegerField(field, data); - break; - // 64 bit: - case LINT: - fieldItem = decodeReadResponseSignedLongField(field, data); - break; - case ULINT: - fieldItem = decodeReadResponseUnsignedLongField(field, data); - break; - // ----------------------------------------- - // Floating point values - // ----------------------------------------- - case REAL: - fieldItem = decodeReadResponseFloatField(field, data); - break; - case LREAL: - fieldItem = decodeReadResponseDoubleField(field, data); - break; - // ----------------------------------------- - // Characters & Strings - // ----------------------------------------- - case CHAR: // 1 byte (8 bit) - fieldItem = decodeReadResponseFixedLengthStringField(1, false, data); - break; - case WCHAR: // 2 byte - fieldItem = decodeReadResponseFixedLengthStringField(1, true, data); - break; - case STRING: - fieldItem = decodeReadResponseVarLengthStringField(false, data); - break; - case WSTRING: - fieldItem = decodeReadResponseVarLengthStringField(true, data); - break; - // ----------------------------------------- - // TIA Date-Formats - // ----------------------------------------- - case DATE_AND_TIME: - fieldItem = decodeReadResponseDateAndTime(field,data); - break; - case TIME_OF_DAY: - fieldItem = decodeReadResponseTimeOfDay(field,data); - break; - case DATE: - fieldItem = decodeReadResponseDate(field,data); - break; - default: - throw new PlcProtocolException("Unsupported type " + field.getDataType()); + try { + switch (field.getDataType()) { + // ----------------------------------------- + // Bit + // ----------------------------------------- + case BOOL: + fieldItem = decodeReadResponseBitField(field, data); + break; + // ----------------------------------------- + // Bit-strings + // ----------------------------------------- + case BYTE: // 1 byte + fieldItem = decodeReadResponseByteBitStringField(field, data); + break; + case WORD: // 2 byte (16 bit) + fieldItem = decodeReadResponseShortBitStringField(field, data); + break; + case DWORD: // 4 byte (32 bit) + fieldItem = decodeReadResponseIntegerBitStringField(field, data); + break; + case LWORD: // 8 byte (64 bit) + fieldItem = decodeReadResponseLongBitStringField(field, data); + break; + // ----------------------------------------- + // Integers + // ----------------------------------------- + // 8 bit: + case SINT: + fieldItem = decodeReadResponseSignedByteField(field, data); + break; + case USINT: + fieldItem = decodeReadResponseUnsignedByteField(field, data); + break; + // 16 bit: + case INT: + fieldItem = decodeReadResponseSignedShortField(field, data); + break; + case UINT: + fieldItem = decodeReadResponseUnsignedShortField(field, data); + break; + // 32 bit: + case DINT: + fieldItem = decodeReadResponseSignedIntegerField(field, data); + break; + case UDINT: + fieldItem = decodeReadResponseUnsignedIntegerField(field, data); + break; + // 64 bit: + case LINT: + fieldItem = decodeReadResponseSignedLongField(field, data); + break; + case ULINT: + fieldItem = decodeReadResponseUnsignedLongField(field, data); + break; + // ----------------------------------------- + // Floating point values + // ----------------------------------------- + case REAL: + fieldItem = decodeReadResponseFloatField(field, data); + break; + case LREAL: + fieldItem = decodeReadResponseDoubleField(field, data); + break; + // ----------------------------------------- + // Characters & Strings + // ----------------------------------------- + case CHAR: // 1 byte (8 bit) + fieldItem = decodeReadResponseFixedLengthStringField(1, false, data); + break; + case WCHAR: // 2 byte + fieldItem = decodeReadResponseFixedLengthStringField(1, true, data); + break; + case STRING: + fieldItem = decodeReadResponseVarLengthStringField(false, data); + break; + case WSTRING: + fieldItem = decodeReadResponseVarLengthStringField(true, data); + break; + // ----------------------------------------- + // TIA Date-Formats + // ----------------------------------------- + case DATE_AND_TIME: + fieldItem = decodeReadResponseDateAndTime(field, data); + break; + case TIME_OF_DAY: + fieldItem = decodeReadResponseTimeOfDay(field, data); + break; + case DATE: + fieldItem = decodeReadResponseDate(field, data); + break; + default: + throw new PlcProtocolException("Unsupported type " + field.getDataType()); + } + } + catch (Plc4XNettyException e){ + logger.warn("Problem during casting of field {}: Exception: {}; FieldInformation: {}",fieldName,e.getMessage(),field); + } + catch (Exception e){ + logger.warn("Some other error occurred casting field {}, FieldInformation: {}",fieldName, field,e); } } Pair<PlcResponseCode, BaseDefaultFieldItem> result = new ImmutablePair<>(responseCode, fieldItem); @@ -653,8 +662,11 @@ public class Plc4XS7Protocol extends PlcMessageToMessageCodec<S7Message, PlcRequ BaseDefaultFieldItem decodeReadResponseVarLengthStringField(boolean isUtf16, ByteBuf data) { // Max length ... ignored. data.skipBytes(1); - byte actualLength = data.readByte(); - return decodeReadResponseFixedLengthStringField(actualLength, isUtf16, data); + + //reading out byte and transforming that to an unsigned byte within an integer, otherwise longer strings are failing + byte currentLengthByte = data.readByte(); + int currentLength = currentLengthByte & 0xFF; + return decodeReadResponseFixedLengthStringField(currentLength, isUtf16, data); } BaseDefaultFieldItem decodeReadResponseDateAndTime(S7Field field,ByteBuf data) { diff --git a/plc4j/utils/scraper/src/main/java/org/apache/plc4x/java/scraper/triggeredscraper/TriggeredScraperTask.java b/plc4j/utils/scraper/src/main/java/org/apache/plc4x/java/scraper/triggeredscraper/TriggeredScraperTask.java index ca18021..6465790 100644 --- a/plc4j/utils/scraper/src/main/java/org/apache/plc4x/java/scraper/triggeredscraper/TriggeredScraperTask.java +++ b/plc4j/utils/scraper/src/main/java/org/apache/plc4x/java/scraper/triggeredscraper/TriggeredScraperTask.java @@ -146,7 +146,7 @@ public class TriggeredScraperTask implements ScraperTask, TriggeredScraperTaskMB // Handle response (Async) CompletableFuture.runAsync(() -> resultHandler.handle(jobName, connectionAlias, TriggeredScraperImpl.convertPlcResponseToMap(plcReadResponse)), executorService); } catch (Exception e) { - LOGGER.warn("Exception during scraping of Job {}, Connection-Alias {}: Error-message: {} - for stack-trace change logging to DEBUG", jobName,connectionAlias,e.getMessage()); + LOGGER.warn("Exception during scraping of Job {}, Connection-Alias {}: Error-message: {} - for stack-trace change logging to DEBUG", jobName,connectionAlias,e.getCause()); handleException(e); } finally { if (connection != null) { diff --git a/plc4j/utils/scraper/src/test/java/org/apache/plc4x/java/scraper/TriggeredScraperRunner.java b/plc4j/utils/scraper/src/test/java/org/apache/plc4x/java/scraper/TriggeredScraperRunner.java index 545b4aa..381df5a 100644 --- a/plc4j/utils/scraper/src/test/java/org/apache/plc4x/java/scraper/TriggeredScraperRunner.java +++ b/plc4j/utils/scraper/src/test/java/org/apache/plc4x/java/scraper/TriggeredScraperRunner.java @@ -42,6 +42,7 @@ public class TriggeredScraperRunner { * testing of TriggeredScraper vs real device */ public static void main(String[] args) throws IOException, ScraperException { + ScraperConfiguration configuration = ScraperConfiguration.fromFile("plc4j/utils/scraper/src/test/resources/example_triggered_scraper.yml", ScraperConfigurationTriggeredImpl.class); PlcDriverManager plcDriverManager = new PooledPlcDriverManager(); diff --git a/plc4j/utils/scraper/src/test/resources/example_triggered_scraper.yml b/plc4j/utils/scraper/src/test/resources/example_triggered_scraper.yml index 99ad571..ec79e17 100644 --- a/plc4j/utils/scraper/src/test/resources/example_triggered_scraper.yml +++ b/plc4j/utils/scraper/src/test/resources/example_triggered_scraper.yml @@ -18,7 +18,7 @@ # ---------------------------------------------------------------------------- --- sources: - S7_PI: s7://192.168.167.210/0/1 + S7_PI: s7://192.168.167.210/1/1 jobs: - name: scheduled-demo-job1 @@ -36,7 +36,7 @@ jobs: test1: '%DB810:DBW0:INT' - name: triggered-demo-job2 - triggerConfig: (S7_TRIGGER_VAR,250,(%M0.7:BOOL)==(true)) + triggerConfig: (S7_TRIGGER_VAR,1000,(%M0.7:BOOL)==(true)) sources: - S7_PI fields: @@ -45,13 +45,19 @@ jobs: test3: '%DB810:DBX266:STRING' test4: '%DB810:DBX526:STRING' test5: '%DB810:DBX786:STRING' - test6: '%DB810:DBX46806:STRING' test7: '%DB810:DBD2:REAL' - test8: '%DB811:DBX12:STRING' - test9: '%DB811:DBX280:STRING' - test10: '%DB811:DBB1000:BYTE[8]' - test11: '%DB811:DBX268.3:BOOL' - test12: '%DB811:DBB270:BYTE[8]' + test8: '%DB811:DBB1000:BYTE[8]' + test9: '%DB811:DBX268.3:BOOL' + test10: '%DB811:DBB270:BYTE[8]' + + - name: scheduled-string-job3 + triggerConfig: (SCHEDULED,2000) + sources: + - S7_PI + fields: + test3_8: '%DB811:DBX14:STRING' + test3_9: '%DB811:DBX282:STRING' + - name: triggered-demo-job3-prev_value triggerConfig: (S7_TRIGGER_VAR,500,(%M0:USINT)>=(PREV))
