From fd4bf09485d6d6849adf0b7bf644ef2a2dc88076 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Garc=C3=ADa?= Date: Sat, 11 Mar 2023 13:41:46 -0400 Subject: [PATCH] Integration with Hop V2.X.X in progress. Action and Transform Read, Write and Events are working, Subscription is missing due to S7 driver problems. The resources for modification are added to the portal. --- .gitignore | 1 + .../bacnetip/readwrite/BACnetVendorId.java | 2 - .../hop/actions/ActionSampleMetaData.java | 4 +- .../hop/actions/Plc4xCheckConnections.java | 72 +++- .../hop/actions/Plc4xCheckDisConnections.java | 271 +++++++++++++ .../Plc4xCheckDisConnectionsDialog.java | 371 ++++++++++++++++++ .../messages/messages_en_US.properties | 13 +- .../src/assembly/assembly.xml | 33 +- .../src/assembly/assembly.xml | 49 +++ .../apache-hop/plc4x-hop-metadata/pom.xml | 18 +- .../apache-hop/plc4x-hop-transformer/pom.xml | 16 + .../hop/transforms/plc4xevent/Plc4xEvent.java | 165 +++++--- .../plc4xevent/Plc4xEventDialog.java | 17 +- .../transforms/plc4xevent/Plc4xEventMeta.java | 22 +- .../hop/transforms/plc4xinput/Plc4xRead.java | 28 +- .../plc4xinput/Plc4xReadDialog.java | 2 +- .../transforms/plc4xinput/Plc4xReadMeta.java | 36 +- .../transforms/plc4xoutput/Plc4xWrite.java | 22 +- .../plc4xoutput/Plc4xWriteMeta.java | 36 +- .../hop/transforms/plc4xsubs/Plc4xSubs.java | 88 +++-- .../transforms/plc4xsubs/Plc4xSubsMeta.java | 34 +- .../util/Plc4xPlcSubscriptionTag.java | 160 ++++++++ .../{Plc4xPlcField.java => Plc4xPlcTag.java} | 20 +- .../messages/messages_en_US.properties | 14 +- pom.xml | 2 + src/site/asciidoc/index.adoc | 14 + src/site/asciidoc/users/index.adoc | 14 + .../users/integrations/apache-hop.adoc | 41 ++ src/site/resources/images/icons/s7_alert.png | Bin 0 -> 19948 bytes .../resources/images/icons/s7_caution.png | Bin 0 -> 18944 bytes src/site/resources/images/icons/s7_danger.png | Bin 0 -> 20452 bytes src/site/resources/images/icons/s7_dont.png | Bin 0 -> 20067 bytes src/site/resources/images/icons/s7_ex.png | Bin 0 -> 20057 bytes .../resources/images/icons/s7_important.png | Bin 0 -> 19667 bytes src/site/resources/images/icons/s7_note.png | Bin 0 -> 19486 bytes src/site/resources/images/icons/s7_tip.png | Bin 0 -> 20231 bytes src/site/resources/images/icons/s7_toddy.png | Bin 0 -> 20356 bytes .../resources/images/icons/s7_warning.png | Bin 0 -> 19172 bytes .../images/integrations/apache_hop_logo.png | Bin 0 -> 14041 bytes .../images/integrations/plc4x_hop_banner.jpg | Bin 0 -> 81373 bytes src/site/site.xml | 1 + 41 files changed, 1355 insertions(+), 211 deletions(-) create mode 100644 plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/Plc4xCheckDisConnections.java create mode 100644 plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/Plc4xCheckDisConnectionsDialog.java create mode 100644 plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/util/Plc4xPlcSubscriptionTag.java rename plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/util/{Plc4xPlcField.java => Plc4xPlcTag.java} (85%) create mode 100644 src/site/asciidoc/users/integrations/apache-hop.adoc create mode 100644 src/site/resources/images/icons/s7_alert.png create mode 100644 src/site/resources/images/icons/s7_caution.png create mode 100644 src/site/resources/images/icons/s7_danger.png create mode 100644 src/site/resources/images/icons/s7_dont.png create mode 100644 src/site/resources/images/icons/s7_ex.png create mode 100644 src/site/resources/images/icons/s7_important.png create mode 100644 src/site/resources/images/icons/s7_note.png create mode 100644 src/site/resources/images/icons/s7_tip.png create mode 100644 src/site/resources/images/icons/s7_toddy.png create mode 100644 src/site/resources/images/icons/s7_warning.png create mode 100644 src/site/resources/images/integrations/apache_hop_logo.png create mode 100644 src/site/resources/images/integrations/plc4x_hop_banner.jpg diff --git a/.gitignore b/.gitignore index 39a55e142e7..d86ce58836f 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,7 @@ atlassian-ide-plugin.xml *.tar.gz *.rar + # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* diff --git a/plc4j/drivers/bacnet/src/main/generated/org/apache/plc4x/java/bacnetip/readwrite/BACnetVendorId.java b/plc4j/drivers/bacnet/src/main/generated/org/apache/plc4x/java/bacnetip/readwrite/BACnetVendorId.java index 8f5d0a26fcd..a5f60c30a41 100644 --- a/plc4j/drivers/bacnet/src/main/generated/org/apache/plc4x/java/bacnetip/readwrite/BACnetVendorId.java +++ b/plc4j/drivers/bacnet/src/main/generated/org/apache/plc4x/java/bacnetip/readwrite/BACnetVendorId.java @@ -1615,8 +1615,6 @@ public enum BACnetVendorId { THING_WAREHOUSELLC((int) 1404, (int) 1404, (String) "Thing Warehouse LLC"), INNOFRIENDS_GMBH((int) 1405, (int) 1405, (String) "Innofriends GmbH"), METRONICAKP_SPJ((int) 1406, (int) 1406, (String) "Metronic AKP Sp. J."), -<<<<<<< HEAD - TECHKNAVE((int) 1407, (int) 1407, (String) "Techknave"), ELSNER_ELEKTRONIK((int) 1408, (int) 1408, (String) "Elsner Elektronik"), LEFOO_INDUSTRIAL_HANGZHOU_CO_LTD( diff --git a/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/ActionSampleMetaData.java b/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/ActionSampleMetaData.java index ecaaf6efdf7..67145901ab6 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/ActionSampleMetaData.java +++ b/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/ActionSampleMetaData.java @@ -25,8 +25,8 @@ * @author cgarcia */ @HopMetadata( - key = "Xplc4xconnection", - name = "PLC4x Connection", + key = "Xplc4xaction", + name = "PLC4x Action", description = "A shared PLC4x connection to a PLC", image = "plc4x_toddy.svg", documentationUrl = "/metadata-types/neo4j/neo4j-connection.html") diff --git a/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/Plc4xCheckConnections.java b/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/Plc4xCheckConnections.java index 752890f7f23..c2aac428f52 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/Plc4xCheckConnections.java +++ b/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/Plc4xCheckConnections.java @@ -31,25 +31,32 @@ import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; import org.apache.hop.core.Const; import org.apache.hop.core.exception.HopException; import org.apache.plc4x.hop.metadata.Plc4xConnection; +import org.apache.plc4x.java.DefaultPlcDriverManager; +import org.apache.plc4x.java.api.PlcConnection; +import org.apache.plc4x.java.api.exceptions.PlcConnectionException; import org.w3c.dom.Node; @Action( id = "CHECK_PLC4X_CONNECTIONS", - name = "i18n::Plc4xAction.Name", - description = "i18n::Plc4xAction.Description", + name = "i18n::Plc4xActionConnections.Name", + description = "i18n::Plc4xActionConnections.Description", image = "plc4x_toddy.svg", categoryDescription = "i18n:org.apache.hop.workflow:ActionCategory.Category.Conditions", - keywords = "i18n::Plc4xAction.keyword", - documentationUrl = "/workflow/actions/checkdbconnection.html") + keywords = "i18n::Plc4xActionConnections.keyword", + documentationUrl = "/workflow/actions/plc4x.html") public class Plc4xCheckConnections extends ActionBase implements Cloneable, IAction { private static final Class PKG = Plc4xCheckConnections.class; // Needed by Translator private Plc4xConnection[] connections; + private boolean connected = false; + private PlcConnection plcconn = null; protected static final String[] unitTimeDesc = new String[] { @@ -241,17 +248,41 @@ public void loadXml( Node entrynode, IHopMetadataProvider metadataProvider, IVar } /** - * Execute this action and return the result. In this case it means, just set the result boolean in the Result + * Execute this action and return the result. + * In this case it means, just set the result boolean in the Result * class. - * - * @param result The result of the previous execution + * Check all conections metadata from the dialog. + * @param prevResult The result of the previous execution * @return The Result of the execution. */ @Override - public Result execute( Result result, int nr ) { - result.setResult(true); - System.out.println("NR: " + nr); - + public Result execute( Result prevResult, int nr ) { + Result result = prevResult; + result.setNrErrors(0); + connected = true; + for (Plc4xConnection connmeta:connections) { + try { + plcconn = new DefaultPlcDriverManager().getConnection(connmeta.getUrl()); //(01) + if (!plcconn.isConnected()) { + logBasic("Cant connect to: " + connmeta.getUrl()); + connected = false; + plcconn = null; + //break; + } + plcconn.close(); + plcconn = null; + } catch (Exception ex) { + Logger.getLogger(Plc4xCheckConnections.class.getName()).log(Level.SEVERE, null, ex); + connected = false; + plcconn = null; + //break; + } finally { + + } + + } + + result.setResult(connected); return result; } @@ -268,4 +299,23 @@ public Result execute( Result result, int nr ) { public void check( List remarks, WorkflowMeta workflowMeta, IVariables variables, IHopMetadataProvider metadataProvider ) { } + + @Override + public boolean resetErrorsBeforeExecution() { + return false; + } + + @Override + public boolean isEvaluation() { + return true; + } + + @Override + public boolean isUnconditional() { + return false; + } + + + + } diff --git a/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/Plc4xCheckDisConnections.java b/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/Plc4xCheckDisConnections.java new file mode 100644 index 00000000000..d4f3f5e2538 --- /dev/null +++ b/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/Plc4xCheckDisConnections.java @@ -0,0 +1,271 @@ +/* + * 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.hop.actions; + +import org.apache.hop.core.ICheckResult; +import org.apache.hop.core.Result; +import org.apache.hop.core.annotations.Action; +import org.apache.hop.core.exception.HopXmlException; +import org.apache.hop.core.variables.IVariables; +import org.apache.hop.core.xml.XmlHandler; +import org.apache.hop.i18n.BaseMessages; +import org.apache.hop.metadata.api.IHopMetadataProvider; +import org.apache.hop.workflow.WorkflowMeta; +import org.apache.hop.workflow.action.ActionBase; +import org.apache.hop.workflow.action.IAction; + + +import java.util.List; +import org.apache.hop.core.Const; +import org.apache.hop.core.exception.HopException; +import org.apache.plc4x.hop.metadata.Plc4xConnection; +import org.w3c.dom.Node; + + +@Action( + id = "CHECK_PLC4X_DISCONNECTIONS", + name = "i18n::Plc4xActionDisConnections.Name", + description = "i18n::Plc4xActionDisConnections.Description", + image = "plc4x_toddy.svg", + categoryDescription = "i18n:org.apache.hop.workflow:ActionCategory.Category.Conditions", + keywords = "i18n::Plc4xActionDisConnections.keyword", + documentationUrl = "/workflow/actions/checkdbconnection.html") +public class Plc4xCheckDisConnections extends ActionBase implements Cloneable, IAction { + private static final Class PKG = Plc4xCheckDisConnections.class; // Needed by Translator + + + private Plc4xConnection[] connections; + + protected static final String[] unitTimeDesc = + new String[] { + BaseMessages.getString(PKG, "Plc4xCheckConnections.UnitTimeMilliSecond.Label"), + BaseMessages.getString(PKG, "Plc4xCheckConnections.UnitTimeSecond.Label"), + BaseMessages.getString(PKG, "Plc4xCheckConnections.UnitTimeMinute.Label"), + BaseMessages.getString(PKG, "Plc4xCheckConnections.UnitTimeHour.Label"), + }; + protected static final String[] unitTimeCode = + new String[] {"millisecond", "second", "minute", "hour"}; + + public static final int UNIT_TIME_MILLI_SECOND = 0; + public static final int UNIT_TIME_SECOND = 1; + public static final int UNIT_TIME_MINUTE = 2; + public static final int UNIT_TIME_HOUR = 3; + + private String[] waitfors; + private int[] waittimes; + + private long timeStart; + private long now; + + public Plc4xCheckDisConnections( String name) { + super(name, ""); + //connections = null; + waitfors = null; + waittimes = null; + } + + public Plc4xCheckDisConnections() { + this( ""); + } + + public Object clone() { + Plc4xCheckDisConnections c = (Plc4xCheckDisConnections) super.clone(); + return c; + } + + + public Plc4xConnection[] getConnections() { + return connections; + } + + public void setConnections(Plc4xConnection[] connections) { + this.connections = connections; + } + + public String[] getWaitfors() { + return waitfors; + } + + public void setWaitfors(String[] waitfors) { + this.waitfors = waitfors; + } + + public int[] getWaittimes() { + return waittimes; + } + + public void setWaittimes(int[] waittimes) { + this.waittimes = waittimes; + } + + public long getTimeStart() { + return timeStart; + } + + public long getNow() { + return now; + } + + private static String getWaitTimeCode(int i) { + if (i < 0 || i >= unitTimeCode.length) { + return unitTimeCode[0]; + } + return unitTimeCode[i]; + } + + public static String getWaitTimeDesc(int i) { + if (i < 0 || i >= unitTimeDesc.length) { + return unitTimeDesc[0]; + } + return unitTimeDesc[i]; + } + + public static int getWaitTimeByDesc(String tt) { + if (tt == null) { + return 0; + } + + for (int i = 0; i < unitTimeDesc.length; i++) { + if (unitTimeDesc[i].equalsIgnoreCase(tt)) { + return i; + } + } + + // If this fails, try to match using the code. + return getWaitTimeByCode(tt); + } + + private static int getWaitTimeByCode(String tt) { + if (tt == null) { + return 0; + } + + for (int i = 0; i < unitTimeCode.length; i++) { + if (unitTimeCode[i].equalsIgnoreCase(tt)) { + return i; + } + } + return 0; + } + + + + /** + * + * Save values to XML + * + * @return + */ + @Override + public String getXml() { + StringBuilder xml = new StringBuilder(120); + xml.append(super.getXml()); + xml.append(" ").append(Const.CR); + if (connections != null) { + for (int i = 0; i < connections.length; i++) { + xml.append(" ").append(Const.CR); + xml.append(" ") + .append( + XmlHandler.addTagValue( + "name", connections[i] == null ? null : connections[i].getName())); + xml.append(" ").append(XmlHandler.addTagValue("waitfor", waitfors[i])); + xml.append(" ") + .append(XmlHandler.addTagValue("waittime", getWaitTimeCode(waittimes[i]))); + xml.append(" ").append(Const.CR); + } + } + xml.append(" ").append(Const.CR); + + return xml.toString(); + } + + /** + * + * Read the XML and get the values needed for the acton + * + * @param entrynode + * @param metadataProvider + * @throws HopXmlException + */ + @Override + public void loadXml( Node entrynode, IHopMetadataProvider metadataProvider, IVariables variables ) throws HopXmlException { + try { + super.loadXml(entrynode); + Node fields = XmlHandler.getSubNode(entrynode, "connections"); + + // How many hosts? + int nrFields = XmlHandler.countNodes(fields, "connection"); + connections = new Plc4xConnection[nrFields]; + waitfors = new String[nrFields]; + waittimes = new int[nrFields]; + // Read them all... + for (int i = 0; i < nrFields; i++) { + Node fnode = XmlHandler.getSubNodeByNr(fields, "connection", i); + String dbname = XmlHandler.getTagValue(fnode, "name"); + + //connections[i] = Plc4xConnection.loadDatabase(metadataProvider, dbname); + if (dbname != null) { + connections[i] = metadataProvider.getSerializer(Plc4xConnection.class).load(dbname); + waitfors[i] = XmlHandler.getTagValue(fnode, "waitfor"); + waittimes[i] = getWaitTimeByCode(Const.NVL(XmlHandler.getTagValue(fnode, "waittime"), "")); + }; + } + } catch (HopXmlException xe) { + throw new HopXmlException( + BaseMessages.getString( + PKG, + "Plc4xCheckConnections.ERROR_0001_Cannot_Load_Job_Entry_From_Xml_Node", + xe.getMessage())); + } catch (HopException ex) { + throw new HopXmlException( + BaseMessages.getString( + PKG, + "Plc4xCheckConnections.ERROR_0001_Cannot_Load_Job_Entry_From_Xml_Node", + ex.getMessage())); + } + } + + /** + * Execute this action and return the result. In this case it means, just set the result boolean in the Result + * class. + * + * @param result The result of the previous execution + * @return The Result of the execution. + */ + @Override + public Result execute( Result result, int nr ) { + result.setResult(true); + System.out.println("NR: " + nr); + + return result; + } + + /** + * + * Add checks to report warnings + * + * @param remarks + * @param workflowMeta + * @param variables + * @param metadataProvider + */ + @Override + public void check( List remarks, WorkflowMeta workflowMeta, IVariables variables, + IHopMetadataProvider metadataProvider ) { + } +} diff --git a/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/Plc4xCheckDisConnectionsDialog.java b/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/Plc4xCheckDisConnectionsDialog.java new file mode 100644 index 00000000000..75336387996 --- /dev/null +++ b/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/java/org/apache/plc4x/hop/actions/Plc4xCheckDisConnectionsDialog.java @@ -0,0 +1,371 @@ +/* + * 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.hop.actions; + +import java.util.ArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.apache.hop.core.Const; +import org.apache.hop.core.exception.HopException; +import org.apache.hop.core.util.Utils; +import org.apache.hop.core.variables.IVariables; +import org.apache.hop.i18n.BaseMessages; +import org.apache.hop.ui.core.dialog.BaseDialog; +import org.apache.hop.ui.core.gui.WindowProperty; +import org.apache.hop.ui.core.widget.ColumnInfo; +import org.apache.hop.ui.core.widget.TableView; +import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; +import org.apache.hop.ui.workflow.action.ActionDialog; +import org.apache.hop.ui.workflow.dialog.WorkflowDialog; +import org.apache.hop.workflow.WorkflowMeta; +import org.apache.hop.workflow.action.IAction; +import org.apache.hop.workflow.action.IActionDialog; +import org.apache.plc4x.hop.metadata.Plc4xConnection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.*; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.widgets.*; + +import org.apache.hop.metadata.api.IHopMetadata; +import org.apache.hop.ui.core.dialog.ErrorDialog; +import org.apache.hop.ui.core.metadata.MetadataManager; +import org.apache.hop.ui.core.widget.MetaSelectionLine; + + +public class Plc4xCheckDisConnectionsDialog extends ActionDialog implements IActionDialog { + private static final Class PKG = Plc4xCheckDisConnectionsDialog.class; // Needed by Translator + + private Shell shell; + + private Text wName; + + private Plc4xCheckDisConnections action; + + private boolean changed; + + private TableView wFields; + + private MetaSelectionLine wConnection; + + public Plc4xCheckDisConnectionsDialog(Shell parent, IAction action, WorkflowMeta workflowMeta, IVariables variables) { + super( parent, workflowMeta, variables ); + this.action = (Plc4xCheckDisConnections) action; + if ( this.action.getName() == null ) { + this.action.setName( BaseMessages.getString( PKG, "Plc4xCheckConnections.Label" ) ); + } + } + + @Override + public IAction open() { + Shell parent = getParent(); + + shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.MIN | SWT.MAX | SWT.RESIZE); + props.setLook(shell); + WorkflowDialog.setShellImage(shell, action); + + ModifyListener lsMod = (ModifyEvent e) -> action.setChanged(); + changed = action.hasChanged(); + + FormLayout formLayout = new FormLayout(); + formLayout.marginWidth = Const.FORM_MARGIN; + formLayout.marginHeight = Const.FORM_MARGIN; + + shell.setLayout(formLayout); + shell.setText(BaseMessages.getString(PKG, "Plc4xCheckonnections.Title")); + + int middle = props.getMiddlePct(); + int margin = Const.MARGIN; + + // Buttons at the bottom + // + Button wOk = new Button(shell, SWT.PUSH); + wOk.setText(BaseMessages.getString(PKG, "System.Button.OK")); + wOk.addListener(SWT.Selection, (Event e) -> ok()); + Button wCancel = new Button(shell, SWT.PUSH); + wCancel.setText(BaseMessages.getString(PKG, "System.Button.Cancel")); + wCancel.addListener(SWT.Selection, (Event e) -> cancel()); + BaseTransformDialog.positionBottomButtons(shell, new Button[] {wOk, wCancel}, margin, null); + + // Filename line + Label wlName = new Label(shell, SWT.RIGHT); + wlName.setText(BaseMessages.getString(PKG, "Plc4xCheckConnections.Name.Label")); + props.setLook(wlName); + FormData fdlName = new FormData(); + fdlName.left = new FormAttachment(0, 0); + fdlName.right = new FormAttachment(middle, -margin); + fdlName.top = new FormAttachment(0, margin); + wlName.setLayoutData(fdlName); + wName = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER); + props.setLook(wName); + wName.addModifyListener(lsMod); + FormData fdName = new FormData(); + fdName.left = new FormAttachment(middle, 0); + fdName.top = new FormAttachment(0, margin); + fdName.right = new FormAttachment(100, 0); + wName.setLayoutData(fdName); + + Label wlFields = new Label(shell, SWT.NONE); + wlFields.setText(BaseMessages.getString(PKG, "Plc4xCheckConnections.Fields.Label")); + props.setLook(wlFields); + FormData fdlFields = new FormData(); + fdlFields.left = new FormAttachment(0, 0); + // fdlFields.right= new FormAttachment(middle, -margin); + fdlFields.top = new FormAttachment(wName, 2 * margin); + wlFields.setLayoutData(fdlFields); + + + wConnection = + new MetaSelectionLine<>( + variables, + metadataProvider, + Plc4xConnection.class, + shell, + SWT.NONE, + BaseMessages.getString(PKG, "Plc4xCheckConnections.Connection.Label"), + BaseMessages.getString(PKG, "Plc4xCheckConnections.Connection.Tooltip")); + props.setLook(wConnection); + FormData fdConnection = new FormData(); + fdConnection.left = new FormAttachment(0, 0); + fdConnection.right = new FormAttachment(100, 0); + //fdConnection.top = new FormAttachment(wTransformName, margin); + wConnection.setLayoutData(fdConnection); + + try { + wConnection.fillItems(); + } catch (Exception e) { + new ErrorDialog(shell, "Error", "Error listing Cassandra connection metadata objects", e); + } + + + // Buttons to the right of the screen... + Button wbGetConnections = new Button(shell, SWT.PUSH | SWT.CENTER); + props.setLook(wbGetConnections); + wbGetConnections.setText( + BaseMessages.getString(PKG, "Plc4xCheckConnections.GetConnections")); + wbGetConnections.setToolTipText( + BaseMessages.getString(PKG, "Plc4xCheckConnections.GetConnections.Tooltip")); + FormData fdbGetConnections = new FormData(); + fdbGetConnections.right = new FormAttachment(100, -margin); + fdbGetConnections.top = new FormAttachment(wlFields, margin); + wbGetConnections.setLayoutData(fdbGetConnections); + + // Buttons to the right of the screen... + Button wbdSourceFileFolder = new Button(shell, SWT.PUSH | SWT.CENTER); + props.setLook(wbdSourceFileFolder); + wbdSourceFileFolder.setText( + BaseMessages.getString(PKG, "Plc4xCheckConnections.DeleteEntry")); + wbdSourceFileFolder.setToolTipText( + BaseMessages.getString(PKG, "Plc4xCheckConnections.DeleteSourceFileButton.Label")); + FormData fdbdSourceFileFolder = new FormData(); + fdbdSourceFileFolder.right = new FormAttachment(100, -margin); + fdbdSourceFileFolder.top = new FormAttachment(wbGetConnections, margin); + wbdSourceFileFolder.setLayoutData(fdbdSourceFileFolder); + + int rows = + action.getConnections() == null + ? 1 + : (action.getConnections().length == 0 ? 0 : action.getConnections().length); + + final int FieldsRows = rows; + + ColumnInfo[] colinf = + new ColumnInfo[] { + new ColumnInfo( + BaseMessages.getString(PKG, "Plc4xCheckConnections.Fields.Argument.Label"), + ColumnInfo.COLUMN_TYPE_CCOMBO, + this.getWorkflowMeta().getDatabaseNames(), + false), + new ColumnInfo( + BaseMessages.getString(PKG, "Plc4xCheckConnections.Fields.WaitFor.Label"), + ColumnInfo.COLUMN_TYPE_TEXT, + false), + new ColumnInfo( + BaseMessages.getString(PKG, "Plc4xCheckConnections.Fields.WaitForTime.Label"), + ColumnInfo.COLUMN_TYPE_CCOMBO, + Plc4xCheckConnections.unitTimeDesc, + false), + }; + + colinf[0].setToolTip(BaseMessages.getString(PKG, "Plc4xCheckConnections.Fields.Column")); + colinf[1].setUsingVariables(true); + colinf[1].setToolTip(BaseMessages.getString(PKG, "Plc4xCheckConnections.WaitFor.ToolTip")); + + wFields = + new TableView( + variables, + shell, + SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI, + colinf, + FieldsRows, + lsMod, + props); + + FormData fdFields = new FormData(); + fdFields.left = new FormAttachment(0, 0); + fdFields.top = new FormAttachment(wlFields, margin); + fdFields.right = new FormAttachment(wbGetConnections, -margin); + fdFields.bottom = new FormAttachment(wOk, -2 * margin); + wFields.setLayoutData(fdFields); + + // Delete files from the list of files... + wbdSourceFileFolder.addListener( + SWT.Selection, + e -> { + int[] idx = wFields.getSelectionIndices(); + wFields.remove(idx); + wFields.removeEmptyRows(); + wFields.setRowNums(); + }); + + // get connections... + wbGetConnections.addListener(SWT.Selection, e -> getConnections()); + + getData(); + + BaseDialog.defaultShellHandling(shell, c -> ok(), c -> cancel()); + + return action; + } + + // public void addDatabases() { + // connections = workflowMeta.getDatabaseNames(); + // } + + public void getConnections() { + /* + this.workflowMeta.getMetadataProvider().getMetadataClasses().forEach( + (c) -> { + System.out.println("Name: " + c.getName()); + }); + IHopMetadataProvider hmdp = this.workflowMeta.getMetadataProvider(); + */ + Class metadataClass = null; + + java.util.List databases = new ArrayList<>(); //this.workflowMeta.getMetadataProvider(). + try { + metadataClass = metadataProvider.getMetadataClassForKey("plc4x-connection"); + MetadataManager manager = new MetadataManager<>(variables, metadataProvider, metadataClass, null); + manager.getNames().forEach((s)->{ + try { + databases.add((Plc4xConnection) manager.loadElement(s)); + } catch (HopException ex) { + Logger.getLogger(Plc4xCheckDisConnectionsDialog.class.getName()).log(Level.SEVERE, null, ex); + } + }); + + } catch (Exception ex) { + Logger.getLogger(Plc4xCheckDisConnectionsDialog.class.getName()).log(Level.SEVERE, null, ex); + } + + + wFields.removeAll(); + + for (Plc4xConnection ci : databases) { + if (ci != null) { + wFields.add(new String[] {ci.getName(), "0", Plc4xCheckDisConnections.unitTimeDesc[0]}); + } + } + wFields.removeEmptyRows(); + wFields.setRowNums(); + wFields.optWidth(true); + } + + public void dispose() { + WindowProperty winprop = new WindowProperty(shell); + props.setScreen(winprop); + shell.dispose(); + } + + /** Copy information from the meta-data input to the dialog fields. */ + public void getData() { + if (action.getName() != null) { + wName.setText(action.getName()); + } + + if (action.getConnections() != null) { + for (int i = 0; i < action.getConnections().length; i++) { + TableItem ti = wFields.table.getItem(i); + if (action.getConnections()[i] != null) { + ti.setText(1, action.getConnections()[i].getName()); + ti.setText(2, "" + Const.toInt(action.getWaitfors()[i], 0)); + ti.setText(3, Plc4xCheckDisConnections.getWaitTimeDesc(action.getWaittimes()[i])); + } + } + wFields.setRowNums(); + wFields.optWidth(true); + } + wName.selectAll(); + wName.setFocus(); + } + + private void cancel() { + action.setChanged(changed); + action = null; + dispose(); + } + + private void ok() { + if (Utils.isEmpty(wName.getText())) { + MessageBox mb = new MessageBox(shell, SWT.OK | SWT.ICON_ERROR); + mb.setText(BaseMessages.getString(PKG, "System.TransformActionNameMissing.Title")); + mb.setMessage(BaseMessages.getString(PKG, "System.ActionNameMissing.Msg")); + mb.open(); + return; + } + Class metadataClass = null; + action.setName(wName.getText()); + + int nrItems = wFields.nrNonEmpty(); + System.out.println("Numero de items: " + nrItems); + + Plc4xConnection[] connections = new Plc4xConnection[nrItems]; + String[] waitfors = new String[nrItems]; + int[] waittimes = new int[nrItems]; + + + try { + metadataClass = metadataProvider.getMetadataClassForKey("plc4x-connection"); + } catch (HopException ex) { + Logger.getLogger(Plc4xCheckDisConnectionsDialog.class.getName()).log(Level.SEVERE, null, ex); + } + MetadataManager manager = new MetadataManager<>(variables, metadataProvider, metadataClass, null); + + for (int i = 0; i < nrItems; i++) { + String arg = wFields.getNonEmpty(i).getText(1); + Plc4xConnection conn; + try { + conn = (Plc4xConnection) manager.loadElement(arg); + if (conn != null) { + connections[i] = conn; + waitfors[i] = "" + Const.toInt(wFields.getNonEmpty(i).getText(2), 0); + waittimes[i] = + Plc4xCheckDisConnections.getWaitTimeByDesc(wFields.getNonEmpty(i).getText(3)); + } + } catch (HopException ex) { + Logger.getLogger(Plc4xCheckDisConnectionsDialog.class.getName()).log(Level.SEVERE, null, ex); + } + + } + action.setConnections(connections); + action.setWaitfors(waitfors); + action.setWaittimes(waittimes); + + dispose(); + } +} diff --git a/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/resources/org/apache/plc4x/hop/actions/messages/messages_en_US.properties b/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/resources/org/apache/plc4x/hop/actions/messages/messages_en_US.properties index f13f6255eb2..ae7eb85d961 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/resources/org/apache/plc4x/hop/actions/messages/messages_en_US.properties +++ b/plc4j/integrations/apache-hop/plc4x-hop-actions/src/main/resources/org/apache/plc4x/hop/actions/messages/messages_en_US.properties @@ -17,6 +17,15 @@ # # # +Plc4xActionConnections.Name=Plc4x Action Connections +Plc4xActionConnections.Description=Check Plc4x connections +Plc4xActionConnections.keyword=Plc4x Connections + +Plc4xActionDisConnections.Name=Plc4x Action Disconnections +Plc4xActionDisConnections.Description=Check Plc4x disconnections +Plc4xActionDisConnections.keyword=Plc4x Disconnections + + Plc4xCheckConnections.Name=Check PLC connections Plc4xCheckConnections.Description=Check if we can connect to one or several databases. Plc4xCheckConnections.ConnectionOK=We can successfully connect to database [{0}] (connection [{1}]) @@ -45,5 +54,5 @@ Plc4xCheckConnections.DeleteEntry=Delete Plc4xCheckConnections.GetConnections=Get connections Plc4xCheckConnections.GetConnections.Tooltip=Get available connections Plc4xCheckConnections.keyword=check,plc,database,connection -Plc4xCheckConnections.Connection.Label -Plc4xCheckConnections.Connection.Tooltip \ No newline at end of file +Plc4xCheckConnections.Connection.Label= +Plc4xCheckConnections.Connection.Tooltip= \ No newline at end of file diff --git a/plc4j/integrations/apache-hop/plc4x-hop-assemblies/plc4x-hop-assemblies-metadata/src/assembly/assembly.xml b/plc4j/integrations/apache-hop/plc4x-hop-assemblies/plc4x-hop-assemblies-metadata/src/assembly/assembly.xml index c79e5135186..984455a9bcb 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-assemblies/plc4x-hop-assemblies-metadata/src/assembly/assembly.xml +++ b/plc4j/integrations/apache-hop/plc4x-hop-assemblies/plc4x-hop-assemblies-metadata/src/assembly/assembly.xml @@ -57,11 +57,42 @@ com.github.jinahya:bit-io:jar ch.qos.logback:logback-core + io.netty:netty-buffer io.netty:netty-codec:jar + io.netty:netty-codec-dns:jar + io.netty:netty-codec-haproxy:jar + io.netty:netty-codec-http:jar + io.netty:netty-codec-http2:jar + io.netty:netty-codec-memcache:jar + io.netty:netty-codec-mqtt:jar + io.netty:netty-codec-redis:jar + io.netty:netty-codec-smtp:jar + io.netty:netty-codec-socks:jar + io.netty:netty-codec-stomp:jar + io.netty:netty-codec-xml:jar io.netty:netty-common:jar + io.netty:netty-handler:jar + io.netty:netty-handler-proxy:jar + io.netty:netty-ssl-ocsp:jar io.netty:netty-resolver:jar - io.netty:netty-transport + io.netty:netty-resolver-dns:jar + io.netty:netty-resolver-dns-classes-macos:jar + io.netty:netty-transport:jar + io.netty:netty-transport-classes-kqueue:jar + io.netty:netty-transport-native-unix-common:jar + io.netty:netty-transport-rxtx:jar + io.netty:netty-transport-sctp:jar + io.netty:netty-transport-udt:jar + + io.vavr:vavr:jar + io.vavr:vavr-match:jar + + org.apache.plc4x:plc4j-api:jar + org.apache.plc4x:plc4j-spi:jar + org.apache.plc4x:plc4j-spi:jar + org.apache.plc4x:plc4j-transport-tcp:jar + org.apache.plc4x:plc4j-driver-s7:jar diff --git a/plc4j/integrations/apache-hop/plc4x-hop-assemblies/plc4x-hop-assemblies-transform/src/assembly/assembly.xml b/plc4j/integrations/apache-hop/plc4x-hop-assemblies/plc4x-hop-assemblies-transform/src/assembly/assembly.xml index 3321a4ce6fe..bff52ed295f 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-assemblies/plc4x-hop-assemblies-transform/src/assembly/assembly.xml +++ b/plc4j/integrations/apache-hop/plc4x-hop-assemblies/plc4x-hop-assemblies-transform/src/assembly/assembly.xml @@ -48,5 +48,54 @@ org.apache.plc4x:plc4x-hop-transform:jar + + + + lib + false + true + runtime + + com.github.jinahya:bit-io:jar + ch.qos.logback:logback-core + + io.netty:netty-buffer + io.netty:netty-codec:jar + io.netty:netty-codec-dns:jar + io.netty:netty-codec-haproxy:jar + io.netty:netty-codec-http:jar + io.netty:netty-codec-http2:jar + io.netty:netty-codec-memcache:jar + io.netty:netty-codec-mqtt:jar + io.netty:netty-codec-redis:jar + io.netty:netty-codec-smtp:jar + io.netty:netty-codec-socks:jar + io.netty:netty-codec-stomp:jar + io.netty:netty-codec-xml:jar + io.netty:netty-common:jar + io.netty:netty-handler:jar + io.netty:netty-handler-proxy:jar + io.netty:netty-ssl-ocsp:jar + io.netty:netty-resolver:jar + io.netty:netty-resolver-dns:jar + io.netty:netty-resolver-dns-classes-macos:jar + io.netty:netty-transport:jar + io.netty:netty-transport-classes-kqueue:jar + io.netty:netty-transport-native-unix-common:jar + io.netty:netty-transport-rxtx:jar + io.netty:netty-transport-sctp:jar + io.netty:netty-transport-udt:jar + + io.vavr:vavr:jar + io.vavr:vavr-match:jar + + org.apache.plc4x:plc4j-api:jar + org.apache.plc4x:plc4j-spi:jar + org.apache.plc4x:plc4j-spi:jar + org.apache.plc4x:plc4j-transport-tcp:jar + org.apache.plc4x:plc4j-driver-s7:jar + + + \ No newline at end of file diff --git a/plc4j/integrations/apache-hop/plc4x-hop-metadata/pom.xml b/plc4j/integrations/apache-hop/plc4x-hop-metadata/pom.xml index 22eccd03ab7..84000a4fbe5 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-metadata/pom.xml +++ b/plc4j/integrations/apache-hop/plc4x-hop-metadata/pom.xml @@ -68,7 +68,23 @@ javax.annotation:javax.annotation-api:jar:1.2 - + + + + org.apache.maven.plugins + maven-jar-plugin + + + + + true + lib/ + + + + + + diff --git a/plc4j/integrations/apache-hop/plc4x-hop-transformer/pom.xml b/plc4j/integrations/apache-hop/plc4x-hop-transformer/pom.xml index e707e0d2069..3bd9600ebe6 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-transformer/pom.xml +++ b/plc4j/integrations/apache-hop/plc4x-hop-transformer/pom.xml @@ -67,6 +67,7 @@ xml-apis:xml-apis:jar:1.4.01 org.apache.plc4x:plc4j-spi:jar:${project.version} com.fasterxml.jackson.core:jackson-annotations:jar:2.14.2 + com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.14.2 @@ -139,5 +140,20 @@ commons-lang3 3.12.0 + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.version} + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + 2.14.2 + \ No newline at end of file diff --git a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xevent/Plc4xEvent.java b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xevent/Plc4xEvent.java index e87262ec01e..243aa0120b7 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xevent/Plc4xEvent.java +++ b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xevent/Plc4xEvent.java @@ -17,11 +17,17 @@ package org.apache.plc4x.hop.transforms.plc4xevent; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.locks.ReentrantLock; +import java.util.logging.Level; +import java.util.logging.Logger; import org.apache.hop.core.CheckResult; import org.apache.hop.core.Const; import org.apache.hop.core.ICheckResult; @@ -30,8 +36,11 @@ import org.apache.hop.core.exception.HopPluginException; import org.apache.hop.core.logging.LogLevel; import org.apache.hop.core.row.IRowMeta; +import org.apache.hop.core.row.IValueMeta; import org.apache.hop.core.row.RowDataUtil; import org.apache.hop.core.row.RowMeta; +import org.apache.hop.core.row.value.ValueMetaFactory; +import org.apache.hop.core.util.StringUtil; import org.apache.hop.i18n.BaseMessages; import org.apache.hop.metadata.api.IHopMetadataProvider; import org.apache.hop.pipeline.Pipeline; @@ -40,6 +49,7 @@ import org.apache.hop.pipeline.transform.ITransform; import org.apache.hop.pipeline.transform.TransformMeta; import org.apache.plc4x.hop.metadata.Plc4xConnection; +import org.apache.plc4x.hop.transforms.util.Plc4xGeneratorField; import org.apache.plc4x.hop.transforms.util.Plc4xWrapperConnection; import org.apache.plc4x.java.DefaultPlcDriverManager; import org.apache.plc4x.java.api.PlcConnection; @@ -48,14 +58,20 @@ import org.apache.plc4x.java.api.messages.PlcSubscriptionResponse; import org.apache.plc4x.java.api.model.PlcConsumerRegistration; import org.apache.plc4x.java.api.types.PlcResponseCode; +import org.apache.plc4x.java.s7.events.S7AlarmEvent; +import org.apache.plc4x.java.s7.events.S7Event; import org.apache.plc4x.java.s7.events.S7ModeEvent; +import org.apache.plc4x.java.s7.events.S7ModeEvent.Fields; +import org.apache.plc4x.java.s7.events.S7SysEvent; +import org.apache.plc4x.java.s7.events.S7UserEvent; import org.apache.plc4x.java.s7.readwrite.ModeTransitionType; /** - * Transform That contains the basic skeleton needed to create your own plugin + * This transform receives an event from the S7 driver, of type MODE, SYS, + * USR or ALM. Only one type can be processed at a time. * */ -public class Plc4xEvent extends BaseTransform implements ITransform { +public class Plc4xEvent extends BaseTransform { public static String FIELD_MODE_EVENT = "MODE"; public static String FIELD_USER_EVENT = "USR"; @@ -75,6 +91,17 @@ public class Plc4xEvent extends BaseTransform im private PlcSubscriptionRequest subsbuild = null; private PlcSubscriptionResponse subresponse = null; + private List remarks = new ArrayList<>(); // stores the errors... + + /* + * The transfer of events is done from the driver tasks. A delay can be added + * for the execution of this transformer. + */ + private ObjectMapper mapper = new ObjectMapper(); + private ConcurrentLinkedQueue events = new ConcurrentLinkedQueue(); + private boolean stopBundle = false; + private int index = 0; + private static final ReentrantLock lock = new ReentrantLock(); private static final String dummy = "dummy"; @@ -91,12 +118,41 @@ public Plc4xEvent(TransformMeta transformMeta, Plc4xEventMeta meta, Plc4xEventDa * @param remarks Error registers * @param origin transform instance name */ - public static final RowMetaAndData buildRow( - Plc4xEventMeta meta, List remarks, String origin) throws HopPluginException { + public static final RowMetaAndData buildRow(Plc4xEventMeta meta, + List remarks, + String origin) throws HopPluginException { IRowMeta rowMeta = new RowMeta(); Object[] rowData = RowDataUtil.allocateRowData(2); int index = 0; - + + ArrayList fields = new ArrayList(); + + if (meta.isModeEvent()) { + for (S7ModeEvent.Fields field:S7ModeEvent.Fields.values()) { + fields.add(field.name()); + } + } else if (meta.isSysEvent()) { + for (S7SysEvent.Fields field:S7SysEvent.Fields.values()) { + fields.add(field.name()); + } + } else if (meta.isUserEvent()) { + for (S7UserEvent.Fields field:S7UserEvent.Fields.values()) { + fields.add(field.name()); + } + } else if (meta.isAlarmEvent()) { + fields.add("ALARM"); + } + + for (String field : fields) { + IValueMeta valueMeta = + ValueMetaFactory.createValueMeta(field, IValueMeta.TYPE_STRING); // build a + rowData[index] = StringUtil.EMPTY_STRING; + // Now add value to the row! + // This is in fact a copy from the fields row, but now with data. + rowMeta.addValueMeta(valueMeta); + index++; + } + return new RowMetaAndData(rowMeta, rowData); } @@ -174,15 +230,7 @@ public boolean processRow() throws HopException { subresponse .getSubscriptionHandle(FIELD_MODE_EVENT) .register(msg -> { - System.out.println("******** S7ModeEvent ********"); - Map map = ((S7ModeEvent) msg).getMap(); - map.forEach((x, y) -> { - System.out.println(x + " : " + y); - }); - short currentmode = (short) - map.get(S7ModeEvent.Fields.CURRENT_MODE.name()); - System.out.println("CURRENT_MODE MSG: " + ModeTransitionType.enumForValue(currentmode).name()); - System.out.println("****************************"); + events.add((S7Event) msg); }); } @@ -191,15 +239,7 @@ public boolean processRow() throws HopException { subresponse .getSubscriptionHandle(FIELD_USER_EVENT) .register(msg -> { - System.out.println("******** S7ModeEvent ********"); - Map map = ((S7ModeEvent) msg).getMap(); - map.forEach((x, y) -> { - System.out.println(x + " : " + y); - }); - short currentmode = (short) - map.get(S7ModeEvent.Fields.CURRENT_MODE.name()); - System.out.println("CURRENT_MODE MSG: " + ModeTransitionType.enumForValue(currentmode).name()); - System.out.println("****************************"); + events.add((S7Event) msg); }); } @@ -208,15 +248,7 @@ public boolean processRow() throws HopException { subresponse .getSubscriptionHandle(FIELD_SYS_EVENT) .register(msg -> { - System.out.println("******** S7ModeEvent ********"); - Map map = ((S7ModeEvent) msg).getMap(); - map.forEach((x, y) -> { - System.out.println(x + " : " + y); - }); - short currentmode = (short) - map.get(S7ModeEvent.Fields.CURRENT_MODE.name()); - System.out.println("CURRENT_MODE MSG: " + ModeTransitionType.enumForValue(currentmode).name()); - System.out.println("****************************"); + events.add((S7Event) msg); }); } @@ -225,15 +257,7 @@ public boolean processRow() throws HopException { subresponse .getSubscriptionHandle(FIELD_ALARM_EVENT) .register(msg -> { - System.out.println("******** S7ModeEvent ********"); - Map map = ((S7ModeEvent) msg).getMap(); - map.forEach((x, y) -> { - System.out.println(x + " : " + y); - }); - short currentmode = (short) - map.get(S7ModeEvent.Fields.CURRENT_MODE.name()); - System.out.println("CURRENT_MODE MSG: " + ModeTransitionType.enumForValue(currentmode).name()); - System.out.println("****************************"); + events.add((S7Event) msg); }); } @@ -256,13 +280,39 @@ public boolean processRow() throws HopException { return false; } + while (events.size() == 0) { + try { + Thread.sleep(100); + if (stopBundle) { + setOutputDone(); // signal end to receiver(s) + return false; + } + } catch (InterruptedException ex) { + break; + } + } + + S7Event s7event = events.poll(); + index = 0; + r = data.outputRowMeta.cloneRow(data.outputRowData); + for (String name:data.outputRowMeta.getFieldNames()) { + System.out.println(name + ": " + s7event.getMap().get(name)); + if (null != s7event.getMap().get(name)) { + r[index++] = s7event.getMap().get(name).toString(); + } else { + try { + r[index++] = mapper.writer() + .writeValueAsString(s7event.getMap()); + } catch (Exception ex) { + Logger.getLogger(Plc4xEvent.class.getName()).log(Level.SEVERE, null, ex); + } + } + } - r = data.outputRowMeta.cloneRow(data.outputRowData); - logBasic("Tamano de los datos: " + r.length); + data.prevDate = data.rowDate; data.rowDate = new Date(); - putRow(data.outputRowMeta, r ); // return your data data.rowsWritten++; return true; @@ -293,7 +343,9 @@ public boolean init() { } data.outputRowData = outputRow.getData(); - data.outputRowMeta = outputRow.getRowMeta(); + data.outputRowMeta = outputRow.getRowMeta(); + + mapper.findAndRegisterModules(); return true; } @@ -313,8 +365,13 @@ public boolean init() { public void cleanup() { super.cleanup(); logBasic("Cleanup. Release connection."); - if (connwrapper != null) - connwrapper.release(); + if (null != connwrapper) { + if (null != registerMode ) registerMode.unregister(); + if (null != registerUser) registerUser.unregister(); + if (null != registerSys) registerSys.unregister(); + if (null != registerAlarm) registerAlarm.unregister(); + connwrapper.release(); + } } @@ -334,11 +391,21 @@ public void dispose() { if (!connwrapper.getConnection().isConnected()){ getPipeline().getExtensionDataMap().remove(meta.getConnection()); } - connwrapper = null; - readRequest = null; + connwrapper = null; + readRequest = null; + registerMode = null; + registerUser = null; + registerSys = null; + registerAlarm = null; } } + + @Override + public void stopRunning() throws HopException { + super.stopRunning(); + stopBundle = true; + } diff --git a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xevent/Plc4xEventDialog.java b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xevent/Plc4xEventDialog.java index ea369b5cb74..3d246028774 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xevent/Plc4xEventDialog.java +++ b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xevent/Plc4xEventDialog.java @@ -204,7 +204,7 @@ public void widgetSelected(SelectionEvent e) { * Mode Events ********************/ Label wlModeEvent = new Label(shell, SWT.RIGHT); - wlModeEvent.setText(BaseMessages.getString(PKG, "Plc4x.Read.Meta.Dialog.NeverEnding.Label")); + wlModeEvent.setText(BaseMessages.getString(PKG, "Plc4x.Read.Meta.Dialog.ModeEvent.Label")); props.setLook(wlModeEvent); FormData fdlModeEvent = new FormData(); fdlModeEvent.left = new FormAttachment(0, 0); @@ -233,7 +233,7 @@ public void widgetSelected(SelectionEvent e) { * User Events ********************/ Label wlUserEvent = new Label(shell, SWT.RIGHT); - wlUserEvent.setText(BaseMessages.getString(PKG, "Plc4x.Read.Meta.Dialog.NeverEnding.Label")); + wlUserEvent.setText(BaseMessages.getString(PKG, "Plc4x.Read.Meta.Dialog.UserEvent.Label")); props.setLook(wlUserEvent); FormData fdlUserEvent = new FormData(); fdlUserEvent.left = new FormAttachment(0, 0); @@ -262,7 +262,7 @@ public void widgetSelected(SelectionEvent e) { * Sys Events ********************/ Label wlSysEvent = new Label(shell, SWT.RIGHT); - wlSysEvent.setText(BaseMessages.getString(PKG, "Plc4x.Read.Meta.Dialog.NeverEnding.Label")); + wlSysEvent.setText(BaseMessages.getString(PKG, "Plc4x.Read.Meta.Dialog.SysEvent.Label")); props.setLook(wlSysEvent); FormData fdlSysEvent = new FormData(); fdlSysEvent.left = new FormAttachment(0, 0); @@ -291,7 +291,7 @@ public void widgetSelected(SelectionEvent e) { * Alarm Events ********************/ Label wlAlarmEvent = new Label(shell, SWT.RIGHT); - wlAlarmEvent.setText(BaseMessages.getString(PKG, "Plc4x.Read.Meta.Dialog.NeverEnding.Label")); + wlAlarmEvent.setText(BaseMessages.getString(PKG, "Plc4x.Read.Meta.Dialog.AlarmEvent.Label")); props.setLook(wlAlarmEvent); FormData fdlAlarmEvent = new FormData(); fdlAlarmEvent.left = new FormAttachment(0, 0); @@ -544,6 +544,10 @@ public void getData() { wLimit.setText(input.getRowLimit()); wNeverEnding.setSelection(input.isNeverEnding()); + wModeEvent.setSelection(input.isModeEvent()); + wUserEvent.setSelection(input.isUserEvent()); + wSysEvent.setSelection(input.isSysEvent()); + wAlarmEvent.setSelection(input.isAlarmEvent()); setActive(); @@ -560,6 +564,11 @@ private void getInfo( Plc4xEventMeta meta) throws HopException { meta.setConnection(wConnection.getText()); meta.setRowLimit(wLimit.getText()); meta.setNeverEnding(wNeverEnding.getSelection()); + + meta.setModeEvent(wModeEvent.getSelection()); + meta.setUserEvent(wUserEvent.getSelection()); + meta.setSysEvent(wSysEvent.getSelection()); + meta.setAlarmEvent(wAlarmEvent.getSelection()); } diff --git a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xevent/Plc4xEventMeta.java b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xevent/Plc4xEventMeta.java index 207adb78245..10de092241d 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xevent/Plc4xEventMeta.java +++ b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xevent/Plc4xEventMeta.java @@ -49,7 +49,7 @@ categoryDescription = "i18n:org.apache.plc4x.hop.transforms.plc4xevent:Plc4x.Category.plc4x", documentationUrl = "https://plc4x.apache.org/users/integrations/apache-hop.html" ) -public class Plc4xEventMeta extends BaseTransformMeta implements ITransformMeta { +public class Plc4xEventMeta extends BaseTransformMeta { private static final Class PKG = Plc4xEventMeta.class; // Needed by Translator @@ -70,23 +70,23 @@ public class Plc4xEventMeta extends BaseTransformMeta implements ITransformMeta private boolean neverEnding; @HopMetadataProperty( - key = "never_ending", - injectionKeyDescription = "Plc4x.Read.Meta.Injection.NeverEnding") + key = "mode_event", + injectionKeyDescription = "Plc4x.Read.Meta.Injection.ModeEvent") private boolean modeEvent; @HopMetadataProperty( - key = "never_ending", - injectionKeyDescription = "Plc4x.Read.Meta.Injection.NeverEnding") + key = "user_event", + injectionKeyDescription = "Plc4x.Read.Meta.Injection.UserEvent") private boolean userEvent; @HopMetadataProperty( - key = "never_ending", - injectionKeyDescription = "Plc4x.Read.Meta.Injection.NeverEnding") + key = "sys_event", + injectionKeyDescription = "Plc4x.Read.Meta.Injection.SysEvent") private boolean sysEvent; @HopMetadataProperty( - key = "never_ending", - injectionKeyDescription = "Plc4x.Read.Meta.Injection.NeverEnding") + key = "alarm_event", + injectionKeyDescription = "Plc4x.Read.Meta.Injection.AlarmEvent") private boolean alarmEvent; @@ -205,7 +205,7 @@ public void setNeverEnding(boolean neverEnding) { } public boolean isModeEvent() { - return neverEnding; + return modeEvent; } public void setModeEvent(boolean modeEvent) { @@ -213,7 +213,7 @@ public void setModeEvent(boolean modeEvent) { } public boolean isUserEvent() { - return neverEnding; + return userEvent; } public void setUserEvent(boolean userEvent) { diff --git a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xinput/Plc4xRead.java b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xinput/Plc4xRead.java index 7b1832c16d1..5e9302da020 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xinput/Plc4xRead.java +++ b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xinput/Plc4xRead.java @@ -50,7 +50,7 @@ import org.apache.hop.pipeline.transform.TransformMeta; import org.apache.plc4x.hop.metadata.Plc4xConnection; import org.apache.plc4x.hop.transforms.util.Plc4xGeneratorField; -import org.apache.plc4x.hop.transforms.util.Plc4xPlcField; +import org.apache.plc4x.hop.transforms.util.Plc4xPlcTag; import org.apache.plc4x.hop.transforms.util.Plc4xWrapperConnection; import org.apache.plc4x.java.DefaultPlcDriverManager; import org.apache.plc4x.java.api.PlcConnection; @@ -61,7 +61,7 @@ * Transform That contains the basic skeleton needed to create your own plugin * */ -public class Plc4xRead extends BaseTransform implements ITransform { +public class Plc4xRead extends BaseTransform { private static final Class PKG = Plc4xRead.class; // Needed by Translator @@ -75,7 +75,7 @@ public class Plc4xRead extends BaseTransform imple private static final String dummy = "dummy"; private Map index = new HashMap(); - private Map plcfields = new HashMap(); + private Map plcfields = new HashMap(); public Plc4xRead(TransformMeta transformMeta, Plc4xReadMeta meta, Plc4xReadData data, int copyNr, PipelineMeta pipelineMeta, Pipeline pipeline ) { @@ -89,8 +89,10 @@ public Plc4xRead(TransformMeta transformMeta, Plc4xReadMeta meta, Plc4xReadData * @param remarks Error registers * @param origin transform instance name */ - public static final RowMetaAndData buildRow( - Plc4xReadMeta meta, List remarks, String origin) throws HopPluginException { + public static final RowMetaAndData buildRow(Plc4xReadMeta meta, + List remarks, + String origin) throws HopPluginException { + IRowMeta rowMeta = new RowMeta(); Object[] rowData = RowDataUtil.allocateRowData(meta.getFields().size() + 2); int index = 0; @@ -108,7 +110,7 @@ public static final RowMetaAndData buildRow( for (Plc4xGeneratorField field : meta.getFields()) { int typeString = ValueMetaFactory.getIdForValueMeta(field.getType()); if (StringUtils.isNotEmpty(field.getType())) { - System.out.println("typeString: " + typeString); + IValueMeta valueMeta = ValueMetaFactory.createValueMeta(field.getName(), typeString); // build a // value! @@ -146,7 +148,7 @@ public static final RowMetaAndData buildRow( // try { System.out.println("stringValue: " + stringValue); - rowData[index] = valueMeta.convertData(stringMeta, stringValue); + rowData[index] = valueMeta.convertData(stringMeta, stringValue); } catch (HopValueException e) { switch (valueMeta.getType()) { case IValueMeta.TYPE_NUMBER: @@ -226,7 +228,6 @@ public static final RowMetaAndData buildRow( index++; } } - return new RowMetaAndData(rowMeta, rowData); } @@ -238,17 +239,18 @@ public static final RowMetaAndData buildRow( * 4. Register the connection wrapper for global access. * 5. If the connection to the PLC is made, then it creates the query * and executes it. - * + * TODO: Field validation. */ @Override public boolean processRow() throws HopException { + Object[] r = getRow(); // Get row from input rowset & set row busy! setLogLevel(LogLevel.DEBUG); if ((!meta.isNeverEnding() && data.rowsWritten >= data.rowLimit) && !isStopped()) { setOutputDone(); // signal end to receiver(s) return false; - } + } if (first) { index.clear(); @@ -256,7 +258,7 @@ public boolean processRow() throws HopException { //This performs a minimal check on the user item. //It guarantees that the rates are within those managed by Plc4x. meta.getFields().forEach((f) ->{ - plcfields.put(f.getName(),Plc4xPlcField.of(f.getItem())); + plcfields.put(f.getName(),Plc4xPlcTag.of(f.getItem())); }); first = false; } @@ -282,10 +284,12 @@ public boolean processRow() throws HopException { readRequest = null; try{ PlcConnection conn = new DefaultPlcDriverManager().getConnection(connmeta.getUrl()); //(03) + if (conn.isConnected()) { connwrapper = new Plc4xWrapperConnection(conn); getPipeline().getExtensionDataMap().put(meta.getConnection(), connwrapper); //(04) } + } catch (Exception ex){ setErrors(1L); logError("Unable to create connection to PLC. " + ex.getMessage()); @@ -342,7 +346,7 @@ public boolean processRow() throws HopException { } r = data.outputRowMeta.cloneRow(data.outputRowData); - logBasic("Tamano de los datos: " + r.length); + data.prevDate = data.rowDate; data.rowDate = new Date(); int index = 0; diff --git a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xinput/Plc4xReadDialog.java b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xinput/Plc4xReadDialog.java index a736e418da0..96a47e5f166 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xinput/Plc4xReadDialog.java +++ b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xinput/Plc4xReadDialog.java @@ -148,7 +148,7 @@ public String open() { try { wConnection.fillItems(); } catch (Exception e) { - new ErrorDialog(shell, "Error", "Error listing Cassandra connection metadata objects", e); + new ErrorDialog(shell, "Error", "Error listing Plc4x connection metadata objects", e); } Control lastControl = wConnection; diff --git a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xinput/Plc4xReadMeta.java b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xinput/Plc4xReadMeta.java index 3946c9a310b..c43178958ac 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xinput/Plc4xReadMeta.java +++ b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xinput/Plc4xReadMeta.java @@ -50,7 +50,7 @@ categoryDescription = "i18n:org.apache.plc4x.hop.transforms.plc4xinput:Plc4x.Category.plc4x", documentationUrl = "https://plc4x.apache.org/users/integrations/apache-calcite.html" ) -public class Plc4xReadMeta extends BaseTransformMeta implements ITransformMeta { +public class Plc4xReadMeta extends BaseTransformMeta { private static final Class PKG = Plc4xReadMeta.class; // Needed by Translator @@ -121,39 +121,33 @@ public Plc4xReadMeta(Plc4xReadMeta m) { } } - @Override public Plc4xReadMeta clone() { return new Plc4xReadMeta(this); } - @Override public void getFields( IRowMeta inputRowMeta, String name, IRowMeta[] info, TransformMeta nextTransform, IVariables variables, IHopMetadataProvider metadataProvider ) throws HopTransformException { try { - logBasic("PASO 1"); List remarks = new ArrayList<>(); RowMetaAndData rowMetaAndData = Plc4xRead.buildRow(this, remarks, name); - logBasic("PASO 2"); - if (!remarks.isEmpty()) { - logBasic("PASO 3"); - StringBuilder stringRemarks = new StringBuilder(); - for (ICheckResult remark : remarks) { - logBasic("PASO 3x: " + remark.toString()); - stringRemarks.append(remark.toString()).append(Const.CR); + + if (!remarks.isEmpty()) { + StringBuilder stringRemarks = new StringBuilder(); + for (ICheckResult remark : remarks) { + stringRemarks.append(remark.toString()).append(Const.CR); + } + throw new HopTransformException(stringRemarks.toString()); } - logBasic("PASO 3.1"); - throw new HopTransformException(stringRemarks.toString()); - } - logBasic("PASO 4"); - for (IValueMeta valueMeta : rowMetaAndData.getRowMeta().getValueMetaList()) { - valueMeta.setOrigin(name); - } - logBasic("PASO 5"); - inputRowMeta.mergeRowMeta(rowMetaAndData.getRowMeta()); + + for (IValueMeta valueMeta : rowMetaAndData.getRowMeta().getValueMetaList()) { + valueMeta.setOrigin(name); + } + + inputRowMeta.mergeRowMeta(rowMetaAndData.getRowMeta()); } catch (Exception e) { - throw new HopTransformException(e); + throw new HopTransformException(e); } } diff --git a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xoutput/Plc4xWrite.java b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xoutput/Plc4xWrite.java index 2381564a755..508831b0a5a 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xoutput/Plc4xWrite.java +++ b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xoutput/Plc4xWrite.java @@ -49,7 +49,7 @@ import org.apache.hop.pipeline.transform.TransformMeta; import org.apache.plc4x.hop.metadata.Plc4xConnection; import org.apache.plc4x.hop.transforms.util.Plc4xGeneratorField; -import org.apache.plc4x.hop.transforms.util.Plc4xPlcField; +import org.apache.plc4x.hop.transforms.util.Plc4xPlcTag; import org.apache.plc4x.hop.transforms.util.Plc4xWrapperConnection; import org.apache.plc4x.java.DefaultPlcDriverManager; import org.apache.plc4x.java.api.PlcConnection; @@ -60,7 +60,7 @@ * Transform That contains the basic skeleton needed to create your own plugin * */ -public class Plc4xWrite extends BaseTransform implements ITransform { +public class Plc4xWrite extends BaseTransform { private static final Class PKG = Plc4xWrite.class; // Needed by Translator @@ -75,7 +75,7 @@ public class Plc4xWrite extends BaseTransform im private static final String dummy = "dummy"; private Map index = new HashMap(); - private Map plcfields = new HashMap(); + private Map plcfields = new HashMap(); public Plc4xWrite(TransformMeta transformMeta, Plc4xWriteMeta meta, Plc4xWriteData data, int copyNr, PipelineMeta pipelineMeta, Pipeline pipeline ) { @@ -108,7 +108,6 @@ public static final RowMetaAndData buildRow( for (Plc4xGeneratorField field : meta.getFields()) { int typeString = ValueMetaFactory.getIdForValueMeta(field.getType()); if (StringUtils.isNotEmpty(field.getType())) { - System.out.println("typeString: " + typeString); IValueMeta valueMeta = ValueMetaFactory.createValueMeta(field.getName(), typeString); // build a // value! @@ -145,7 +144,6 @@ public static final RowMetaAndData buildRow( // Convert the data from String to the specified type ... // try { - System.out.println("stringValue: " + stringValue); rowData[index] = valueMeta.convertData(stringMeta, stringValue); } catch (HopValueException e) { switch (valueMeta.getType()) { @@ -261,7 +259,7 @@ public boolean processRow() throws HopException { Integer i = getInputRowMeta().indexOfValue(f.getName()); //(01) if (i>=0) { index.put(f.getName(), i); - plcfields.put(f.getName(),Plc4xPlcField.of(f.getItem())); + plcfields.put(f.getName(),Plc4xPlcTag.of(f.getItem())); } }); first = false; @@ -309,14 +307,15 @@ public boolean processRow() throws HopException { } finally { lock.unlock(); } - + if ((connmeta != null) && (connwrapper != null)){ if (connwrapper.getConnection().isConnected()){ - + builder = null; builder = connwrapper.getConnection().writeRequestBuilder(); //(05) Integer i; for (Plc4xGeneratorField field: meta.getFields()){ + i = index.get(field.getName()); if (i != null) { //From Input Type @@ -329,7 +328,7 @@ public boolean processRow() throws HopException { case IValueMeta.TYPE_BIGNUMBER: builder.addTagAddress(field.getName(), field.getItem(), - r[i]); + r[i]); break; case IValueMeta.TYPE_DATE: builder.addTagAddress(field.getName(), @@ -369,13 +368,14 @@ public boolean processRow() throws HopException { maxwait = (maxwait<100)?100:maxwait; writeResponse = writeRequest.execute().get(maxwait, TimeUnit.MILLISECONDS); + if (isDebug()) index.forEach((n,y)->{ - System.out.println("Resultado: " + writeResponse.getResponseCode(n)); + logDebug("Result: " + writeResponse.getResponseCode(n)); }); } catch (Exception ex) { setErrors(1L); - logError("Unable read from PLC. " + ex.getMessage()); + logError("Unable write to PLC. " + ex.getMessage()); } } else { diff --git a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xoutput/Plc4xWriteMeta.java b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xoutput/Plc4xWriteMeta.java index d3996ad4a93..d9461f6d07c 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xoutput/Plc4xWriteMeta.java +++ b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xoutput/Plc4xWriteMeta.java @@ -54,7 +54,7 @@ categoryDescription = "i18n:org.apache.plc4x.hop.transforms.plc4xoutput:Plc4x.Category.plc4x", documentationUrl = "https://plc4x.apache.org/users/integrations/apache-calcite.html" ) -public class Plc4xWriteMeta extends BaseTransformMeta implements ITransformMeta { +public class Plc4xWriteMeta extends BaseTransformMeta { private static final Class PKG = Plc4xWriteMeta.class; // Needed by Translator @@ -130,34 +130,28 @@ public Plc4xWriteMeta clone() { return new Plc4xWriteMeta(this); } - - + @Override public void getFields( IRowMeta inputRowMeta, String name, IRowMeta[] info, TransformMeta nextTransform, IVariables variables, IHopMetadataProvider metadataProvider ) throws HopTransformException { try { - logBasic("PASO 1"); List remarks = new ArrayList<>(); RowMetaAndData rowMetaAndData = Plc4xWrite.buildRow(this, remarks, name); - logBasic("PASO 2"); - if (!remarks.isEmpty()) { - logBasic("PASO 3"); - StringBuilder stringRemarks = new StringBuilder(); - for (ICheckResult remark : remarks) { - logBasic("PASO 3x: " + remark.toString()); - stringRemarks.append(remark.toString()).append(Const.CR); + + if (!remarks.isEmpty()) { + StringBuilder stringRemarks = new StringBuilder(); + for (ICheckResult remark : remarks) { + stringRemarks.append(remark.toString()).append(Const.CR); + } + throw new HopTransformException(stringRemarks.toString()); + } + for (IValueMeta valueMeta : rowMetaAndData.getRowMeta().getValueMetaList()) { + valueMeta.setOrigin(name); } - logBasic("PASO 3.1"); - throw new HopTransformException(stringRemarks.toString()); - } - logBasic("PASO 4"); - for (IValueMeta valueMeta : rowMetaAndData.getRowMeta().getValueMetaList()) { - valueMeta.setOrigin(name); - } - logBasic("PASO 5"); - inputRowMeta.mergeRowMeta(rowMetaAndData.getRowMeta()); + + inputRowMeta.mergeRowMeta(rowMetaAndData.getRowMeta()); } catch (Exception e) { - throw new HopTransformException(e); + throw new HopTransformException(e); } } diff --git a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xsubs/Plc4xSubs.java b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xsubs/Plc4xSubs.java index 51c6c9d5366..67003bf3b5e 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xsubs/Plc4xSubs.java +++ b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xsubs/Plc4xSubs.java @@ -17,13 +17,16 @@ package org.apache.plc4x.hop.transforms.plc4xsubs; +import java.time.Duration; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; +import java.util.function.Consumer; import org.apache.commons.lang3.StringUtils; import org.apache.hop.core.CheckResult; import org.apache.hop.core.Const; @@ -50,32 +53,40 @@ import org.apache.hop.pipeline.transform.TransformMeta; import org.apache.plc4x.hop.metadata.Plc4xConnection; import org.apache.plc4x.hop.transforms.util.Plc4xGeneratorField; -import org.apache.plc4x.hop.transforms.util.Plc4xPlcField; +import org.apache.plc4x.hop.transforms.util.Plc4xPlcTag; +import org.apache.plc4x.hop.transforms.util.Plc4xPlcSubscriptionTag; import org.apache.plc4x.hop.transforms.util.Plc4xWrapperConnection; import org.apache.plc4x.java.DefaultPlcDriverManager; import org.apache.plc4x.java.api.PlcConnection; import org.apache.plc4x.java.api.messages.PlcReadRequest; import org.apache.plc4x.java.api.messages.PlcReadResponse; +import org.apache.plc4x.java.api.messages.PlcSubscriptionEvent; +import org.apache.plc4x.java.api.messages.PlcSubscriptionRequest; +import org.apache.plc4x.java.api.messages.PlcSubscriptionResponse; +import org.apache.plc4x.java.s7.events.S7Event; /** * Transform That contains the basic skeleton needed to create your own plugin * */ -public class Plc4xSubs extends BaseTransform implements ITransform { +public class Plc4xSubs extends BaseTransform { private static final Class PKG = Plc4xSubs.class; // Needed by Translator private Plc4xConnection connmeta = null; private Plc4xWrapperConnection connwrapper = null; - private PlcReadRequest readRequest = null; - private PlcReadResponse readResponse = null; + private PlcSubscriptionRequest subsRequest = null; + private PlcSubscriptionResponse subsResponse = null; private int maxwait = 0; private static final ReentrantLock lock = new ReentrantLock(); + private ConcurrentLinkedQueue events = new ConcurrentLinkedQueue(); + private boolean stopBundle = false; + private static final String dummy = "dummy"; private Map index = new HashMap(); - private Map plcfields = new HashMap(); + private Map plctags = new HashMap(); public Plc4xSubs(TransformMeta transformMeta, Plc4xSubsMeta meta, Plc4xSubsData data, int copyNr, PipelineMeta pipelineMeta, Pipeline pipeline ) { @@ -108,7 +119,7 @@ public static final RowMetaAndData buildRow( for (Plc4xGeneratorField field : meta.getFields()) { int typeString = ValueMetaFactory.getIdForValueMeta(field.getType()); if (StringUtils.isNotEmpty(field.getType())) { - System.out.println("typeString: " + typeString); + IValueMeta valueMeta = ValueMetaFactory.createValueMeta(field.getName(), typeString); // build a // value! @@ -145,7 +156,7 @@ public static final RowMetaAndData buildRow( // Convert the data from String to the specified type ... // try { - System.out.println("stringValue: " + stringValue); + rowData[index] = valueMeta.convertData(stringMeta, stringValue); } catch (HopValueException e) { switch (valueMeta.getType()) { @@ -252,11 +263,11 @@ public boolean processRow() throws HopException { if (first) { index.clear(); - plcfields.clear(); + plctags.clear(); //This performs a minimal check on the user item. //It guarantees that the rates are within those managed by Plc4x. meta.getFields().forEach((f) ->{ - plcfields.put(f.getName(),Plc4xPlcField.of(f.getItem())); + plctags.put(f.getName(),Plc4xPlcSubscriptionTag.of(f.getItem())); }); first = false; } @@ -266,6 +277,7 @@ public boolean processRow() throws HopException { IHopMetadataProvider metaprovider = getMetadataProvider(); connmeta = metaprovider.getSerializer(Plc4xConnection.class).load(meta.getConnection()); if (connwrapper == null) { + System.out.println("PASO 02"); connwrapper = (Plc4xWrapperConnection) getPipeline().getExtensionDataMap().get(meta.getConnection()); //(02) if (connwrapper != null) connwrapper.retain(); }; @@ -279,7 +291,7 @@ public boolean processRow() throws HopException { } if ((connmeta != null) && (connwrapper == null)){ - readRequest = null; + subsRequest = null; try{ PlcConnection conn = new DefaultPlcDriverManager().getConnection(connmeta.getUrl()); //(03) if (conn.isConnected()) { @@ -297,24 +309,28 @@ public boolean processRow() throws HopException { if ((connmeta != null) && (connwrapper != null)){ if (connwrapper.getConnection().isConnected()){ - if (readRequest == null){ - PlcReadRequest.Builder builder = connwrapper.getConnection().readRequestBuilder(); //(05) + if (subsRequest == null){ + PlcSubscriptionRequest.Builder builder = connwrapper.getConnection().subscriptionRequestBuilder(); //(05) for (Plc4xGeneratorField field: meta.getFields()){ - builder.addTagAddress(field.getName(), field.getItem()); + System.out.println(field.getName() + " : " + field.getItem().toString()); + builder.addCyclicTagAddress(field.getName(), field.getItem().toString(), Duration.ofMillis(1000)); } - readRequest = builder.build(); + System.out.println("PASO: 05"); + subsRequest = builder.build(); } try { maxwait = Integer.parseInt(meta.getMaxwaitInMs()); - maxwait = (maxwait<100)?100:maxwait; - readResponse = readRequest.execute().get(maxwait, TimeUnit.MILLISECONDS); - - for (Plc4xGeneratorField field: meta.getFields()){ - field.setValue(readResponse.getString(field.getName())); - } + maxwait = (maxwait<1000)?1000:maxwait; + System.out.println("PASO: 06"); + subsResponse = subsRequest.execute().get(); + System.out.println("PASO: 07"); + //Only for Siemens S7 + subsResponse.getSubscriptionHandles().forEach(a -> a.register(e -> events.add(e))); + System.out.println("PASO: 08"); } catch (Exception ex) { setErrors(1L); logError("Unable read from PLC. " + ex.getMessage()); + ex.printStackTrace(); } } else { @@ -332,17 +348,23 @@ public boolean processRow() throws HopException { } // - int interval = Integer.parseInt(meta.getIntervalInMs()); + while (events.size() == 0) { + try { + Thread.sleep(100); + if (stopBundle) { + setOutputDone(); // signal end to receiver(s) + return false; + } + } catch (InterruptedException ex) { + break; + } + } - try { - Thread.sleep(interval); - } catch (InterruptedException ex) { - setErrors(1L); - logError(ex.getMessage()); - } + PlcSubscriptionEvent s7event = events.poll(); + System.out.println("Ejecuto el consumidor en el cliente..." + s7event.getTagNames()); r = data.outputRowMeta.cloneRow(data.outputRowData); - logBasic("Tamano de los datos: " + r.length); + data.prevDate = data.rowDate; data.rowDate = new Date(); int index = 0; @@ -435,12 +457,16 @@ public void dispose() { getPipeline().getExtensionDataMap().remove(meta.getConnection()); } connwrapper = null; - readRequest = null; - + subsRequest = null; } } - + + @Override + public void stopRunning() throws HopException { + super.stopRunning(); + stopBundle = true; + } } diff --git a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xsubs/Plc4xSubsMeta.java b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xsubs/Plc4xSubsMeta.java index 35f15665bdb..12943301d71 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xsubs/Plc4xSubsMeta.java +++ b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/plc4xsubs/Plc4xSubsMeta.java @@ -54,7 +54,7 @@ categoryDescription = "i18n:org.apache.plc4x.hop.transforms.plc4xinput:Plc4x.Category.plc4x", documentationUrl = "https://plc4x.apache.org/users/integrations/apache-calcite.html" ) -public class Plc4xSubsMeta extends BaseTransformMeta implements ITransformMeta { +public class Plc4xSubsMeta extends BaseTransformMeta{ private static final Class PKG = Plc4xSubsMeta.class; // Needed by Translator @@ -136,28 +136,24 @@ public Plc4xSubsMeta clone() { public void getFields( IRowMeta inputRowMeta, String name, IRowMeta[] info, TransformMeta nextTransform, IVariables variables, IHopMetadataProvider metadataProvider ) throws HopTransformException { try { - logBasic("PASO 1"); List remarks = new ArrayList<>(); RowMetaAndData rowMetaAndData = Plc4xSubs.buildRow(this, remarks, name); - logBasic("PASO 2"); - if (!remarks.isEmpty()) { - logBasic("PASO 3"); - StringBuilder stringRemarks = new StringBuilder(); - for (ICheckResult remark : remarks) { - logBasic("PASO 3x: " + remark.toString()); - stringRemarks.append(remark.toString()).append(Const.CR); + + if (!remarks.isEmpty()) { + StringBuilder stringRemarks = new StringBuilder(); + for (ICheckResult remark : remarks) { + stringRemarks.append(remark.toString()).append(Const.CR); + } + throw new HopTransformException(stringRemarks.toString()); + } + + for (IValueMeta valueMeta : rowMetaAndData.getRowMeta().getValueMetaList()) { + valueMeta.setOrigin(name); } - logBasic("PASO 3.1"); - throw new HopTransformException(stringRemarks.toString()); - } - logBasic("PASO 4"); - for (IValueMeta valueMeta : rowMetaAndData.getRowMeta().getValueMetaList()) { - valueMeta.setOrigin(name); - } - logBasic("PASO 5"); - inputRowMeta.mergeRowMeta(rowMetaAndData.getRowMeta()); + + inputRowMeta.mergeRowMeta(rowMetaAndData.getRowMeta()); } catch (Exception e) { - throw new HopTransformException(e); + throw new HopTransformException(e); } } diff --git a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/util/Plc4xPlcSubscriptionTag.java b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/util/Plc4xPlcSubscriptionTag.java new file mode 100644 index 00000000000..2a261a39062 --- /dev/null +++ b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/util/Plc4xPlcSubscriptionTag.java @@ -0,0 +1,160 @@ +/* + * 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.hop.transforms.util; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import java.time.Duration; +import org.apache.plc4x.java.api.exceptions.PlcInvalidTagException; +import org.apache.plc4x.java.api.model.PlcSubscriptionTag; +import org.apache.plc4x.java.spi.generation.SerializationException; +import org.apache.plc4x.java.spi.generation.WriteBuffer; +import org.apache.plc4x.java.spi.utils.Serializable; + +import java.util.Objects; +import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.apache.plc4x.java.api.model.PlcTag; +import org.apache.plc4x.java.api.types.PlcSubscriptionType; + +/* +* Code taken from the Modbus driver implementation. +* This allows me to make the correct interpretation of the "Hop" values +* towards the writing fields. +* +* TODO: The HOP interpreter generates an error when processing +* the "Integer" fields. +*/ + +public class Plc4xPlcSubscriptionTag implements PlcTag, Serializable { + + public static final Pattern ADDRESS_PATTERN = Pattern.compile("(?
[\\%a-zA-Z_\\.0-9]+)(:(?[a-zA-Z_]+))?(\\[(?\\d+)])?"); + + protected static final int PROTOCOL_ADDRESS_OFFSET = 1; + + private final String address; + + private final int quantity; + + private final Plc4xDataType dataType; + + public static Plc4xPlcSubscriptionTag of(String addressString) { + if (Plc4xPlcSubscriptionTag.matches(addressString)) { + Matcher matcher = ADDRESS_PATTERN.matcher(addressString); + + matcher.matches(); + + String address = matcher.group("address"); + + String quantityString = matcher.group("quantity"); + int quantity = quantityString != null ? Integer.parseInt(quantityString) : 1; + + Plc4xDataType dataType = (matcher.group("datatype") != null) ? Plc4xDataType.valueOf(matcher.group("datatype")) : Plc4xDataType.BOOL; + + + return new Plc4xPlcSubscriptionTag(address, quantity, dataType); + } + + throw new PlcInvalidTagException("Unable to parse address: " + addressString); + } + + protected Plc4xPlcSubscriptionTag(String address, Integer quantity, Plc4xDataType dataType) { + this.address = address; + + this.quantity = quantity != null ? quantity : 1; + + this.dataType = dataType != null ? dataType : Plc4xDataType.INT; + } + + public static boolean matches(String addressString) { + return ADDRESS_PATTERN.matcher(addressString).matches(); + } + + public String getAddress() { + return address; + } + + public int getNumberOfElements() { + return quantity; + } + + public int getLengthBytes() { + return quantity * dataType.getDataTypeSize(); + } + + @JsonIgnore + public int getLengthWords() { + return (int) ((quantity * (float) dataType.getDataTypeSize()) / 2.0f); + } + + public Plc4xDataType getDataType() { + return dataType; + } + + public String getPlcDataType() { + return dataType.name(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Plc4xPlcSubscriptionTag)) { + return false; + } + Plc4xPlcSubscriptionTag that = (Plc4xPlcSubscriptionTag) o; + return address == that.address; + } + + @Override + public int hashCode() { + return Objects.hash(address); + } + + @Override + public String toString() { + return "Plc4xPlcSubscriptionField{" + + " address=" + address + + " datatype=" + dataType + + " quantity=" + quantity + + " }"; + } + + @Override + public void serialize(WriteBuffer wb) throws SerializationException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String getAddressString() { + throw new UnsupportedOperationException("Not supported yet."); + } + +// @Override +// public PlcSubscriptionType getPlcSubscriptionType() { +// throw new UnsupportedOperationException("Not supported yet."); +// } +// +// @Override +// public Optional getDuration() { +// throw new UnsupportedOperationException("Not supported yet."); +// } + +} diff --git a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/util/Plc4xPlcField.java b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/util/Plc4xPlcTag.java similarity index 85% rename from plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/util/Plc4xPlcField.java rename to plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/util/Plc4xPlcTag.java index 295dc9f1765..d89cbfabc73 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/util/Plc4xPlcField.java +++ b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/java/org/apache/plc4x/hop/transforms/util/Plc4xPlcTag.java @@ -21,12 +21,10 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import org.apache.plc4x.java.api.exceptions.PlcInvalidTagException; import org.apache.plc4x.java.api.model.PlcTag; -import org.apache.plc4x.java.spi.generation.ParseException; import org.apache.plc4x.java.spi.generation.SerializationException; import org.apache.plc4x.java.spi.generation.WriteBuffer; import org.apache.plc4x.java.spi.utils.Serializable; -import java.nio.charset.StandardCharsets; import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -40,7 +38,7 @@ * the "Integer" fields. */ -public class Plc4xPlcField implements PlcTag, Serializable { +public class Plc4xPlcTag implements PlcTag, Serializable { public static final Pattern ADDRESS_PATTERN = Pattern.compile("(?
[\\%a-zA-Z_\\.0-9]+)(:(?[a-zA-Z_]+))?(\\[(?\\d+)])?"); @@ -52,8 +50,8 @@ public class Plc4xPlcField implements PlcTag, Serializable { private final Plc4xDataType dataType; - public static Plc4xPlcField of(String addressString) { - if (Plc4xPlcField.matches(addressString)) { + public static Plc4xPlcTag of(String addressString) { + if (Plc4xPlcTag.matches(addressString)) { Matcher matcher = ADDRESS_PATTERN.matcher(addressString); matcher.matches(); @@ -66,13 +64,13 @@ public static Plc4xPlcField of(String addressString) { Plc4xDataType dataType = (matcher.group("datatype") != null) ? Plc4xDataType.valueOf(matcher.group("datatype")) : Plc4xDataType.BOOL; - return new Plc4xPlcField(address, quantity, dataType); + return new Plc4xPlcTag(address, quantity, dataType); } throw new PlcInvalidTagException("Unable to parse address: " + addressString); } - protected Plc4xPlcField(String address, Integer quantity, Plc4xDataType dataType) { + protected Plc4xPlcTag(String address, Integer quantity, Plc4xDataType dataType) { this.address = address; this.quantity = quantity != null ? quantity : 1; @@ -114,10 +112,10 @@ public boolean equals(Object o) { if (this == o) { return true; } - if (!(o instanceof Plc4xPlcField)) { + if (!(o instanceof Plc4xPlcTag)) { return false; } - Plc4xPlcField that = (Plc4xPlcField) o; + Plc4xPlcTag that = (Plc4xPlcTag) o; return address == that.address; } @@ -137,12 +135,12 @@ public String toString() { @Override public void serialize(WriteBuffer wb) throws SerializationException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + throw new UnsupportedOperationException("Not supported yet."); } @Override public String getAddressString() { - throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody + throw new UnsupportedOperationException("Not supported yet."); } } diff --git a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/resources/org/apache/plc4x/hop/transforms/plc4xevent/messages/messages_en_US.properties b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/resources/org/apache/plc4x/hop/transforms/plc4xevent/messages/messages_en_US.properties index b6bc8d9f8d5..70a5e66f92e 100644 --- a/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/resources/org/apache/plc4x/hop/transforms/plc4xevent/messages/messages_en_US.properties +++ b/plc4j/integrations/apache-hop/plc4x-hop-transformer/src/main/resources/org/apache/plc4x/hop/transforms/plc4xevent/messages/messages_en_US.properties @@ -21,7 +21,7 @@ Plc4x.Read.Description=Plc4x Event Transform Description Plc4x.Read.Shell.Title=Plc4x Event Transform Title Plc4x.Read.TransformName.Label=Plc4x Event Sample Name -Plc4x.Read.Meta.Injection.NeverEnding=Connection +Plc4x.Read.Meta.Injection.Connection=Connection Plc4x.Read.Meta.Injection.NeverEnding=Nerverending Plc4x.Read.Meta.Injection.MaxwaitInMs=MaxwaitIn Plc4x.Read.Meta.Injection.IntervalInMs=IntervalIn @@ -30,6 +30,11 @@ Plc4x.Read.Meta.Injection.LastTimeField=LastTimeField Plc4x.Read.Meta.Injection.RowLimit=RowLimit Plc4x.Read.Meta.Injection.Fields=Fields +Plc4x.Read.Meta.Injection.ModeEvent=ModeEvent +Plc4x.Read.Meta.Injection.UserEvent=UserEvent +Plc4x.Read.Meta.Injection.SysEvent=SysEvent +Plc4x.Read.Meta.Injection.AlarmEvent=AlarmEvent + Plc4x.Read.Meta.Injection.Field.Name=Name Plc4x.Read.Meta.Injection.Field.Item=Item Plc4x.Read.Meta.Injection.Field.Type=Type @@ -47,6 +52,13 @@ Plc4x.Read.Meta.Dialog.Settings.Title=Dialog Plc4x.Read.Meta.Dialog.DialogTitle=Plc4x Read transformer Plc4x.Read.Meta.Dialog.Limit.Label=Limit Plc4x.Read.Meta.Dialog.NeverEnding.Label=Never ending + +Plc4x.Read.Meta.Dialog.ModeEvent.Label=Mode event +Plc4x.Read.Meta.Dialog.UserEvent.Label=User event +Plc4x.Read.Meta.Dialog.SysEvent.Label=Sys event +Plc4x.Read.Meta.Dialog.UserEvent.Label=User event +Plc4x.Read.Meta.Dialog.AlarmEvent.Label=Alarm event + Plc4x.Read.Meta.Dialog.Maxwait.Label=Max waiting Plc4x.Read.Meta.Dialog.Interval.Label=Interval Plc4x.Read.Meta.Dialog.RowTimeField.Label=Time diff --git a/pom.xml b/pom.xml index 4e114e4089c..324c0f7ded2 100644 --- a/pom.xml +++ b/pom.xml @@ -818,6 +818,8 @@ **/hs_err_pid* **/replay_pid* + + **/*.svg diff --git a/src/site/asciidoc/index.adoc b/src/site/asciidoc/index.adoc index 5ecb4db6614..cbed626f264 100644 --- a/src/site/asciidoc/index.adoc +++ b/src/site/asciidoc/index.adoc @@ -165,6 +165,20 @@ +