This is an automated email from the ASF dual-hosted git repository.
cgarcia pushed a commit to branch feature/merlot
in repository https://gitbox.apache.org/repos/asf/plc4x-extras.git
The following commit(s) were added to refs/heads/feature/merlot by this push:
new 23eda3a Working on s7 PlcModel.
23eda3a is described below
commit 23eda3adf8eeaa109a5788d6c472bd152de09740
Author: César García <[email protected]>
AuthorDate: Mon May 5 07:44:44 2025 -0400
Working on s7 PlcModel.
---
.../java/org/apache/plc4x/merlot/api/PlcModel.java | 57 +++++++
.../plc4x/merlot/db/impl/DBRPCSecurityImpl.java | 5 +-
.../merlot/org.apache.plc4x.merlot.drv.s7/pom.xml | 4 +-
.../plc4x/merlot/drv/s7/impl/S7PlcModelImpl.java | 185 +++++++++++++++++++++
.../plc4x/merlot/drv/s7/core/S7PlcModelTests.java | 110 ++++++++++++
.../plc4x/merlot/drv/s7/core/S7TagDistances.java | 61 +++++++
6 files changed, 418 insertions(+), 4 deletions(-)
diff --git
a/plc4j/tools/merlot/org.apache.plc4x.merlot.das.api/src/main/java/org/apache/plc4x/merlot/api/PlcModel.java
b/plc4j/tools/merlot/org.apache.plc4x.merlot.das.api/src/main/java/org/apache/plc4x/merlot/api/PlcModel.java
index e91c02d..7d18fdd 100644
---
a/plc4j/tools/merlot/org.apache.plc4x.merlot.das.api/src/main/java/org/apache/plc4x/merlot/api/PlcModel.java
+++
b/plc4j/tools/merlot/org.apache.plc4x.merlot.das.api/src/main/java/org/apache/plc4x/merlot/api/PlcModel.java
@@ -16,10 +16,67 @@
*/
package org.apache.plc4x.merlot.api;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+import org.apache.plc4x.java.api.model.PlcTag;
+
/*
* PlcModel represents the internal data structure associated with a PLC,
* RTU, etc. Exception or time-based subscriptions go against this model.
*/
public interface PlcModel {
+
+ /*
+ * Lists the different memory areas of this model.
+ * They are usually defined in the driver.
+ */
+ Set<String> ListMemoryAreas();
+
+ /*
+ * Retrieves the ID assigned to a memory area.
+ */
+ Integer MemoryAreaId(String strMemoryArea);
+
+ /*
+ * This procedure is responsible for creating the memory areas
+ * associated with a particular PLC or Device model.
+ */
+ void CreateMemoryArea(PlcTag tag);
+
+ /*
+ * Add a listener to a specific memory area within the model.
+ */
+ void AddMemoryAreaListener(String strMemmoryArea, Integer index,
PlcItemListener listener);
+
+ /*
+ * Remove a listener.
+ */
+ void RemoveMemoryAreaListener(String strMemmoryArea, Integer index,
PlcItemListener listener);
+ /*
+ * Returns the number of segments comprising this memory area.
+ * For example, for MODBUS, it will always return 1 for
+ * any type of memory area. For the S7 driver, specifically for DBs,
+ * it will return the number of DB instances required.
+ */
+ Integer MemoryAreaSegment(String strMemoryArea);
+
+ /*
+ * Returns the indices associated with each memory area.
+ */
+ List<Integer> MemoryAreaSegmentId(String strMemoryArea);
+
+
+ /*
+ * Each "model" must create its own scan PlcGroups.
+ */
+ List<UUID> ModelPlcGroupsUuid(String strMemoryArea);
+
+ /*
+ * Returns the PlcItems created for the model update.
+ */
+ List<UUID> ModelPlcItemsUuid(String strMemoryArea);
+
+
}
diff --git
a/plc4j/tools/merlot/org.apache.plc4x.merlot.db/src/main/java/org/apache/plc4x/merlot/db/impl/DBRPCSecurityImpl.java
b/plc4j/tools/merlot/org.apache.plc4x.merlot.db/src/main/java/org/apache/plc4x/merlot/db/impl/DBRPCSecurityImpl.java
index d50a674..c67f3cf 100644
---
a/plc4j/tools/merlot/org.apache.plc4x.merlot.db/src/main/java/org/apache/plc4x/merlot/db/impl/DBRPCSecurityImpl.java
+++
b/plc4j/tools/merlot/org.apache.plc4x.merlot.db/src/main/java/org/apache/plc4x/merlot/db/impl/DBRPCSecurityImpl.java
@@ -1,4 +1,4 @@
-/*
+ /*
* 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
@@ -234,12 +234,13 @@ public class DBRPCSecurityImpl extends PVRecord
implements RPCService, Job {
return result;
}
+ //TODO: The time must be parameterizable by individual user
@Override
public void execute(JobContext context) {
userSessions.forEach((k, u) -> u.timeout++);
Set<String> keys = userSessions.keySet();
for (String key:keys) {
- if (userSessions.get(key).timeout > 60){
+ if (userSessions.get(key).timeout > 300){
LOGGER.info("User [{}] session timeout.", key);
userSessions.remove(key);
}
diff --git a/plc4j/tools/merlot/org.apache.plc4x.merlot.drv.s7/pom.xml
b/plc4j/tools/merlot/org.apache.plc4x.merlot.drv.s7/pom.xml
index 48cdafa..b6d1b0f 100644
--- a/plc4j/tools/merlot/org.apache.plc4x.merlot.drv.s7/pom.xml
+++ b/plc4j/tools/merlot/org.apache.plc4x.merlot.drv.s7/pom.xml
@@ -55,8 +55,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
- <source>1.8</source>
- <target>1.8</target>
+ <source>11</source>
+ <target>11</target>
<maxmem>256M</maxmem>
</configuration>
</plugin>
diff --git
a/plc4j/tools/merlot/org.apache.plc4x.merlot.drv.s7/src/main/java/org/apache/plc4x/merlot/drv/s7/impl/S7PlcModelImpl.java
b/plc4j/tools/merlot/org.apache.plc4x.merlot.drv.s7/src/main/java/org/apache/plc4x/merlot/drv/s7/impl/S7PlcModelImpl.java
new file mode 100644
index 0000000..d671ac8
--- /dev/null
+++
b/plc4j/tools/merlot/org.apache.plc4x.merlot.drv.s7/src/main/java/org/apache/plc4x/merlot/drv/s7/impl/S7PlcModelImpl.java
@@ -0,0 +1,185 @@
+/*
+ * 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.merlot.drv.s7.impl;
+
+import io.netty.buffer.ByteBuf;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import org.apache.plc4x.java.api.model.PlcTag;
+import org.apache.plc4x.java.s7.readwrite.MemoryArea;
+import org.apache.plc4x.java.s7.readwrite.tag.S7Tag;
+import org.apache.plc4x.merlot.api.PlcItem;
+import org.apache.plc4x.merlot.api.PlcItemListener;
+import org.apache.plc4x.merlot.api.PlcModel;
+import org.apache.plc4x.merlot.api.impl.PlcItemImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author cgarcia
+ */
+public class S7PlcModelImpl implements PlcModel{
+ private static final Logger logger =
LoggerFactory.getLogger(S7PlcModelImpl.class);
+
+ private Map<String, Map<Integer,PlcItem>> memoryAreas;
+
+ public S7PlcModelImpl() {
+ memoryAreas = new HashMap();
+ memoryAreas.put(MemoryArea.COUNTERS.getShortName(), null);
+ memoryAreas.put(MemoryArea.TIMERS.getShortName(), null);
+ memoryAreas.put(MemoryArea.DIRECT_PERIPHERAL_ACCESS.getShortName(),
null);
+ memoryAreas.put(MemoryArea.INPUTS.getShortName(), null);
+ memoryAreas.put(MemoryArea.OUTPUTS.getShortName(), null);
+ memoryAreas.put(MemoryArea.FLAGS_MARKERS.getShortName(), null);
+ memoryAreas.put(MemoryArea.DATA_BLOCKS.getShortName(), null);
+ memoryAreas.put(MemoryArea.INSTANCE_DATA_BLOCKS.getShortName(), null);
+ memoryAreas.put(MemoryArea.LOCAL_DATA.getShortName(), null);
+ }
+
+ @Override
+ public Set<String> ListMemoryAreas() {
+ return memoryAreas.keySet();
+ }
+
+ @Override
+ public Integer MemoryAreaId(String strMemoryArea) {
+ return
Integer.valueOf(MemoryArea.firstEnumForFieldShortName((strMemoryArea)).getValue());
+ }
+
+ @Override
+ public void CreateMemoryArea(PlcTag tag) {
+
+ final S7Tag s7tag = (S7Tag) tag;
+ checkByteBufInstance(s7tag);
+
+// switch(s7tag.getMemoryArea().getValue()) {
+// case 0x1C: {
+// if (null == memoryAreas.get("C"))
createCounterArea(s7tag);
+// final Map<Integer, PlcItem> CBytes =
memoryAreas.get("C");
+// };
+// break;
+// case 0x1D: {
+// if (null == memoryAreas.get("T")) createTimerArea(s7tag);
+// final Map<Integer, PlcItem> TBytes =
memoryAreas.get("T");
+// };
+// break;
+// case 0x80: {
+// if (null == memoryAreas.get("D"))
createDirectPeripheralAccessArea(s7tag);
+// final Map<Integer, PlcItem> DBytes =
memoryAreas.get("D");
+// };
+// break;
+// case 0x81:{
+// if (null == memoryAreas.get("I")) createInputArea(s7tag);
+// final Map<Integer, PlcItem> inputBytes =
memoryAreas.get("I");
+// };
+// break;
+// case 0x82: {
+// if (null == memoryAreas.get("Q"))
createOutputArea(s7tag);
+// final Map<Integer, PlcItem> QBytes =
memoryAreas.get("Q");
+// };
+// break;
+// case 0x83: {
+// if (null == memoryAreas.get("M"))
createFlagMarkerArea(s7tag);
+// final Map<Integer, PlcItem> MBytes =
memoryAreas.get("M");
+// };
+// break;
+// case 0x84: {
+// if (null == memoryAreas.get("DB"))
createDataBlocksArea(s7tag);
+// final Map<Integer, PlcItem> DBBytes =
memoryAreas.get("DB");
+//
+// };
+// break;
+// case 0x85: {
+// if (null == memoryAreas.get("DBI"))
createDataBlocksInstanceArea(s7tag);
+// final Map<Integer, PlcItem> DBIBytes =
memoryAreas.get("DBI");
+// };
+// break;
+// case 0x86: {
+// if (null == memoryAreas.get("LD"))
createFlagMarkerArea(s7tag);
+// final Map<Integer, PlcItem> LDBytes =
memoryAreas.get("LD");
+// };
+// break;
+//
+// }
+ }
+
+
+
+ @Override
+ public Integer MemoryAreaSegment(String strMemoryArea) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public List<Integer> MemoryAreaSegmentId(String strMemoryArea) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public List<UUID> ModelPlcGroupsUuid(String strMemoryArea) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public List<UUID> ModelPlcItemsUuid(String strMemoryArea) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+
+ private void checkByteBufInstance(S7Tag tag) {
+ if (null == memoryAreas.get(tag.getMemoryArea().getShortName())) {
+ PlcItem internalPlcItem = new PlcItemImpl.PlcItemBuilder("s7" +
tag.getMemoryArea().getShortName() + "["+tag.getBlockNumber() +"]").
+ setItemDescription("Flag markes from PLC in byte order.").
+ setItemId("").
+ setItemEnable(true).
+ build();
+ Map<Integer, PlcItem> inputBytes = new HashMap();
+ inputBytes.put(tag.getBlockNumber(), internalPlcItem);
+ memoryAreas.put(tag.getMemoryArea().getShortName(), inputBytes);
+ logger.info("Creted memmory area with PlcItem: " + "s7" +
tag.getMemoryArea().getShortName() + "["+tag.getBlockNumber() +"]");
+ }
+
+ final Map<Integer, PlcItem> memoryBytes =
memoryAreas.get(tag.getMemoryArea().getShortName());
+
+ if (null == memoryBytes.get(tag.getBlockNumber())) {
+ PlcItem plcItem = new PlcItemImpl.PlcItemBuilder("s7" +
tag.getMemoryArea().getShortName() + "["+tag.getBlockNumber() +"]").
+ setItemDescription("Flag markes from PLC in byte order.").
+ setItemId("").
+ setItemEnable(true).
+ build();
+ memoryBytes.put(tag.getBlockNumber(), plcItem);
+ }
+
+ final PlcItem internalPlcItem = memoryBytes.get(tag.getBlockNumber());
+ final ByteBuf byteBuf = internalPlcItem.getItemByteBuf();
+
+ int minSize = tag.getByteOffset() +
+ tag.getDataType().getSizeInBytes() *
tag.getNumberOfElements();
+
+ if (byteBuf.capacity() < minSize) {
+ if (byteBuf.ensureWritable(minSize, true) != 0) {
+ logger.info("The buffer capacity was expanded to {}.",
minSize);
+ }
+ }
+
+ }
+
+}
diff --git
a/plc4j/tools/merlot/org.apache.plc4x.merlot.drv.s7/src/test/java/org/apache/plc4x/merlot/drv/s7/core/S7PlcModelTests.java
b/plc4j/tools/merlot/org.apache.plc4x.merlot.drv.s7/src/test/java/org/apache/plc4x/merlot/drv/s7/core/S7PlcModelTests.java
new file mode 100644
index 0000000..a81eb83
--- /dev/null
+++
b/plc4j/tools/merlot/org.apache.plc4x.merlot.drv.s7/src/test/java/org/apache/plc4x/merlot/drv/s7/core/S7PlcModelTests.java
@@ -0,0 +1,110 @@
+/*
+ * 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.merlot.drv.s7.core;
+
+import java.util.Set;
+import org.apache.plc4x.java.s7.readwrite.MemoryArea;
+import org.apache.plc4x.java.s7.readwrite.tag.S7Tag;
+import org.apache.plc4x.merlot.drv.s7.impl.S7PlcModelImpl;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.AfterAll;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+/**
+ *
+ * @author cgarcia
+ */
+public class S7PlcModelTests {
+
+ private static S7PlcModelImpl model;
+
+ public S7PlcModelTests() {
+ }
+
+ @BeforeAll
+ public static void setUpClass() {
+ model = new S7PlcModelImpl();
+ }
+
+ @AfterAll
+ public static void tearDownClass() {
+ }
+
+ @BeforeEach
+ public void setUp() {
+ }
+
+ @AfterEach
+ public void tearDown() {
+ }
+
+ @Test
+ public void testAreaModels() {
+ Set<String> areas = model.ListMemoryAreas();
+ assertTrue(areas.contains(MemoryArea.COUNTERS.getShortName()));
+ assertTrue(areas.contains(MemoryArea.TIMERS.getShortName()));
+
assertTrue(areas.contains(MemoryArea.DIRECT_PERIPHERAL_ACCESS.getShortName()));
+ assertTrue(areas.contains(MemoryArea.INPUTS.getShortName()));
+ assertTrue(areas.contains(MemoryArea.OUTPUTS.getShortName()));
+ assertTrue(areas.contains(MemoryArea.FLAGS_MARKERS.getShortName()));
+ assertTrue(areas.contains(MemoryArea.DATA_BLOCKS.getShortName()));
+
assertTrue(areas.contains(MemoryArea.INSTANCE_DATA_BLOCKS.getShortName()));
+ assertTrue(areas.contains(MemoryArea.LOCAL_DATA.getShortName()));
+
+ }
+
+ @Test
+ public void testAreaModelsId() {
+ assertEquals(model.MemoryAreaId("C"), 0x1C);
+ assertEquals(model.MemoryAreaId("T"), 0x1D);
+ assertEquals(model.MemoryAreaId("D"), 0x80);
+ assertEquals(model.MemoryAreaId("I"), 0x81);
+ assertEquals(model.MemoryAreaId("Q"), 0x82);
+ assertEquals(model.MemoryAreaId("M"), 0x83);
+ assertEquals(model.MemoryAreaId("DB"), 0x84);
+ assertEquals(model.MemoryAreaId("DBI"), 0x85);
+ assertEquals(model.MemoryAreaId("LD"), 0x86);
+ }
+
+ @Test
+ public void testCreateMemoryAreas() {
+ S7Tag s7TagC = null;
+ S7Tag s7TagT = null;
+ S7Tag s7TagD = null;
+ S7Tag s7TagI = S7Tag.of("%I2500:BYTE[100]");
+ S7Tag s7TagQ = S7Tag.of("%Q1900:BYTE[100]");
+ S7Tag s7TagM = S7Tag.of("%M3000:BYTE[100]");
+ S7Tag s7TagDB = S7Tag.of("%DB100:10:BYTE[100]");
+ S7Tag s7TagDBI = null;
+ S7Tag s7TagLD = null;
+
+ model.CreateMemoryArea(s7TagI);
+ model.CreateMemoryArea(s7TagQ);
+ model.CreateMemoryArea(s7TagM);
+ model.CreateMemoryArea(s7TagDB);
+
+
+
+
+ }
+
+
+}
diff --git
a/plc4j/tools/merlot/org.apache.plc4x.merlot.drv.s7/src/test/java/org/apache/plc4x/merlot/drv/s7/core/S7TagDistances.java
b/plc4j/tools/merlot/org.apache.plc4x.merlot.drv.s7/src/test/java/org/apache/plc4x/merlot/drv/s7/core/S7TagDistances.java
new file mode 100644
index 0000000..8c00b56
--- /dev/null
+++
b/plc4j/tools/merlot/org.apache.plc4x.merlot.drv.s7/src/test/java/org/apache/plc4x/merlot/drv/s7/core/S7TagDistances.java
@@ -0,0 +1,61 @@
+/*
+ * 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.merlot.drv.s7.core;
+
+import org.apache.plc4x.java.api.model.PlcTag;
+import org.apache.plc4x.java.s7.readwrite.tag.S7Tag;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ *
+ * @author cgarcia
+ */
+public class S7TagDistances {
+
+ public S7TagDistances() {
+ }
+
+ @BeforeAll
+ public static void setUpClass() {
+ }
+
+ @AfterAll
+ public static void tearDownClass() {
+ }
+
+ @BeforeEach
+ public void setUp() {
+ }
+
+ @AfterEach
+ public void tearDown() {
+ }
+
+ @Test
+ public void testDB() {
+ System.out.println("Distance...");
+ PlcTag tag = S7Tag.of("%DB42:0:BYTE");
+ System.out.println(tag.toString());
+ PlcTag tag2 = S7Tag.of("%DB42:50:BYTE[10]");
+ System.out.println(tag2.toString());
+ }
+}