diff --git a/nbproject/build-impl.xml b/nbproject/build-impl.xml index ba9568a..c683433 100644 --- a/nbproject/build-impl.xml +++ b/nbproject/build-impl.xml @@ -1092,6 +1092,15 @@ is divided into following sections: + + + + + + + + + @@ -1762,6 +1771,15 @@ is divided into following sections: + + + + + + + + + diff --git a/nbproject/genfiles.properties b/nbproject/genfiles.properties index 1b14c9d..719dd4d 100644 --- a/nbproject/genfiles.properties +++ b/nbproject/genfiles.properties @@ -3,6 +3,6 @@ build.xml.script.CRC32=da12c040 build.xml.stylesheet.CRC32=f85dc8f2@1.94.0.48 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. -nbproject/build-impl.xml.data.CRC32=390183ca -nbproject/build-impl.xml.script.CRC32=64165c0f +nbproject/build-impl.xml.data.CRC32=97e0c359 +nbproject/build-impl.xml.script.CRC32=a31f424b nbproject/build-impl.xml.stylesheet.CRC32=f89f7d21@1.94.0.48 diff --git a/nbproject/project.properties b/nbproject/project.properties index 4655c91..d3f5276 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -41,7 +41,8 @@ includes=** jar.compress=false javac.classpath=\ ${file.reference.jlibmodbus-1.2.9.7.jar}:\ - ${file.reference.etherip.jar} + ${file.reference.etherip.jar}:\ + ${reference.EIPGetAttr.jar} # Space-separated list of extra javac options javac.compilerargs= javac.deprecation=false @@ -82,7 +83,9 @@ manifest.file=manifest.mf meta.inf.dir=${src.dir}/META-INF mkdist.disabled=false platform.active=default_platform +project.EIPGetAttr=../MinimalCIPJ project.license=apache20 +reference.EIPGetAttr.jar=${project.EIPGetAttr}/dist/MinimalCIPJ.jar run.classpath=\ ${javac.classpath}:\ ${build.classes.dir} diff --git a/nbproject/project.xml b/nbproject/project.xml index 285c269..1781714 100644 --- a/nbproject/project.xml +++ b/nbproject/project.xml @@ -14,6 +14,15 @@ .\lib\nblibraries.properties - + + + EIPGetAttr + jar + + jar + clean + jar + + diff --git a/src/protocolwhisperer/BridgeManager.java b/src/protocolwhisperer/BridgeManager.java index 8772d6a..d79d958 100644 --- a/src/protocolwhisperer/BridgeManager.java +++ b/src/protocolwhisperer/BridgeManager.java @@ -56,6 +56,7 @@ public BridgeManager(boolean aHeadless, String fileName) headless = aHeadless; driverList.add(new ModbusProtocolDriver()); driverList.add(new CIPProtocolDriver()); + driverList.add(new DriveParameterProtocolDriver()); driverList.add(new StaticTagProtocolDriver()); loadDrivers(); loadDatalogDrivers(); diff --git a/src/protocolwhisperer/drivers/DriveParameterConfigFrame.form b/src/protocolwhisperer/drivers/DriveParameterConfigFrame.form new file mode 100644 index 0000000..bf9226b --- /dev/null +++ b/src/protocolwhisperer/drivers/DriveParameterConfigFrame.form @@ -0,0 +1,168 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/protocolwhisperer/drivers/DriveParameterConfigFrame.java b/src/protocolwhisperer/drivers/DriveParameterConfigFrame.java new file mode 100644 index 0000000..72604d7 --- /dev/null +++ b/src/protocolwhisperer/drivers/DriveParameterConfigFrame.java @@ -0,0 +1,250 @@ +/* + * Copyright 2021 Matt Jamesson . + * + * Licensed 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 protocolwhisperer.drivers; + +import javax.swing.*; +import java.util.*; +import java.awt.event.*; +import static protocolwhisperer.drivers.ModbusConfigFrame.dataTypeMenuNames; +import protocolwhisperer.*; + +/** + * + * @author Matt Jamesson + */ +public class DriveParameterConfigFrame extends javax.swing.JFrame { + + /** + * Creates new form CIPConfigFrame + */ + DriveParameterProtocolRecord currentRecord = null; + ArrayList tagGuiRecords = new ArrayList(); + BridgeManager manager = null; + public DriveParameterConfigFrame(DriveParameterProtocolRecord aCurrentRecord, BridgeManager aManager) { + initComponents(); + currentRecord = aCurrentRecord; + manager = aManager; + if (currentRecord.configured) + { + cipHostField.setText(currentRecord.host); + buildTagRecords(currentRecord.tagRecords); + } + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + topPane = new javax.swing.JPanel(); + configPane = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + cipHostField = new javax.swing.JTextField(); + addTagPane = new javax.swing.JPanel(); + addTagButton = new javax.swing.JButton(); + headerPane = new javax.swing.JPanel(); + jLabel2 = new javax.swing.JLabel(); + filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(70, 0), new java.awt.Dimension(70, 0), new java.awt.Dimension(70, 32767)); + jLabel4 = new javax.swing.JLabel(); + filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(70, 0), new java.awt.Dimension(70, 0), new java.awt.Dimension(70, 32767)); + jScrollPane1 = new javax.swing.JScrollPane(); + tagRecordParent = new javax.swing.JPanel(); + tagRecordPane = new javax.swing.JPanel(); + okPane = new javax.swing.JPanel(); + okButton = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + + topPane.setLayout(new javax.swing.BoxLayout(topPane, javax.swing.BoxLayout.Y_AXIS)); + + jLabel1.setText("Drive IP:"); + configPane.add(jLabel1); + + cipHostField.setColumns(10); + configPane.add(cipHostField); + + topPane.add(configPane); + + addTagButton.setText("Add tag"); + addTagButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + addTagButtonActionPerformed(evt); + } + }); + addTagPane.add(addTagButton); + + topPane.add(addTagPane); + + jLabel2.setText("Tag"); + headerPane.add(jLabel2); + headerPane.add(filler1); + + jLabel4.setText("Parameter"); + headerPane.add(jLabel4); + headerPane.add(filler2); + + topPane.add(headerPane); + + getContentPane().add(topPane, java.awt.BorderLayout.NORTH); + + tagRecordParent.setLayout(new java.awt.BorderLayout()); + + tagRecordPane.setLayout(new javax.swing.BoxLayout(tagRecordPane, javax.swing.BoxLayout.Y_AXIS)); + tagRecordParent.add(tagRecordPane, java.awt.BorderLayout.NORTH); + + jScrollPane1.setViewportView(tagRecordParent); + + getContentPane().add(jScrollPane1, java.awt.BorderLayout.CENTER); + + okButton.setText("OK"); + okButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + okButtonActionPerformed(evt); + } + }); + okPane.add(okButton); + + getContentPane().add(okPane, java.awt.BorderLayout.SOUTH); + + setBounds(0, 0, 332, 268); + }// //GEN-END:initComponents + + private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed + currentRecord.host = cipHostField.getText(); + currentRecord.configured = true; + mapTagRecords(); + dispose(); + }//GEN-LAST:event_okButtonActionPerformed + + private void addTagButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addTagButtonActionPerformed + DriveParameterTagRecord tagRecord = new DriveParameterTagRecord(); + currentRecord.tagRecords.add(tagRecord); + buildTagRecord(tagRecord); + revalidate(); + repaint(); + }//GEN-LAST:event_addTagButtonActionPerformed + + public void mapTagRecords() + { + currentRecord.tagRecords.clear(); + for (int i = 0; i < tagGuiRecords.size(); i++) + { + currentRecord.tagRecords.add(tagGuiRecords.get(i).mapTagRecord()); + } + } + public void buildTagRecords(ArrayList tagRecords) + { + for (int i = 0; i < tagRecords.size(); i++) + { + DriveParameterTagRecord currentRecord = (DriveParameterTagRecord)tagRecords.get(i); + buildTagRecord(currentRecord); + } + } + public void buildTagRecord(DriveParameterTagRecord currentTagRecord) + { + JPanel currentTagPane = new JPanel(); + java.awt.Component tagField; + if (currentRecord.type == ProtocolRecord.RECORD_TYPE_INCOMING) + { + tagField = new JTextField(10); + if (currentTagRecord.configured) + { + ((JTextField)tagField).setText(currentTagRecord.tag); + } + } + else + { + if (currentTagRecord.configured) + { + tagField = manager.getOutgoingRecordTags(currentTagRecord.tag); + } + else + { + tagField = manager.getOutgoingRecordTags(""); + } + } + JTextField parameterField = new JTextField(3); + currentTagPane.add(tagField); + currentTagPane.add(parameterField); + JButton deleteButton = new JButton("Delete"); + currentTagPane.add(deleteButton); + if (currentTagRecord.configured) + { + parameterField.setText(currentTagRecord.parameter + ""); + } + tagRecordPane.add(currentTagPane); + TagMapper tm = new TagMapper() + { + public DriveParameterTagRecord mapTagRecord() + { + DriveParameterTagRecord outputRecord = new DriveParameterTagRecord(); + if (currentRecord.type == ProtocolRecord.RECORD_TYPE_INCOMING) + { + outputRecord.tag = ((JTextField)tagField).getText(); + } + else + { + outputRecord.tag = ((JComboBox)tagField).getSelectedItem().toString(); + } + outputRecord.parameter = Integer.parseInt(parameterField.getText()); + outputRecord.configured = true; + return outputRecord; + } + }; + tagGuiRecords.add(tm); + deleteButton.addActionListener(new ActionListener(){ + public void actionPerformed(ActionEvent e) + { + tagGuiRecords.remove(tm); + tagRecordPane.remove(currentTagPane); + revalidate(); + repaint(); + + }}); + } + + /** + * @param args the command line arguments + */ + + public interface TagMapper + { + public DriveParameterTagRecord mapTagRecord(); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton addTagButton; + private javax.swing.JPanel addTagPane; + private javax.swing.JTextField cipHostField; + private javax.swing.JPanel configPane; + private javax.swing.Box.Filler filler1; + private javax.swing.Box.Filler filler2; + private javax.swing.JPanel headerPane; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel4; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JButton okButton; + private javax.swing.JPanel okPane; + private javax.swing.JPanel tagRecordPane; + private javax.swing.JPanel tagRecordParent; + private javax.swing.JPanel topPane; + // End of variables declaration//GEN-END:variables +} diff --git a/src/protocolwhisperer/drivers/DriveParameterProtocolDriver.java b/src/protocolwhisperer/drivers/DriveParameterProtocolDriver.java new file mode 100644 index 0000000..86ec8cb --- /dev/null +++ b/src/protocolwhisperer/drivers/DriveParameterProtocolDriver.java @@ -0,0 +1,117 @@ +/* + * Copyright 2020 Matt Jamesson . + * + * Licensed 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 protocolwhisperer.drivers; + +import minimalcipj.DPIOnlineReadFullResponse; +import minimalcipj.CIPResponse; +import minimalcipj.CIPDataFormatter; +import minimalcipj.CIPClient; +import etherip.EtherNetIP; +import etherip.types.CIPData; +import java.util.ArrayList; +import java.util.Arrays; +import protocolwhisperer.*; + +/** + * + * @author Matt Jamesson + */ +public class DriveParameterProtocolDriver extends ProtocolDriver{ + boolean enabled = true; + + public void setEnabled(boolean aEnabled) + { + enabled = aEnabled; + } + public boolean getEnabled() + { + return enabled; + } + + public void ParameterRead(DriveParameterProtocolRecord currentRecord) + { + CIPClient client = null; + try + { + client = new CIPClient(currentRecord.host); + client.connect(); + for (int i = 0; i < currentRecord.tagRecords.size(); i++) + { + DriveParameterTagRecord currentTagRecord = ((DriveParameterTagRecord)currentRecord.tagRecords.get(i)); + double oldValue = currentTagRecord.getValue(); + CIPResponse response = client.getAttribute(0x93, currentTagRecord.parameter, 0x07); + if (response instanceof DPIOnlineReadFullResponse) + { + CIPDataFormatter formatter = ((DPIOnlineReadFullResponse)(response)).getCIPDataFormatter(); + currentTagRecord.setValue(formatter.getDisplayVal(((DPIOnlineReadFullResponse)(response)).getParamValue())); + } + if (oldValue != currentTagRecord.getValue()) + { + currentTagRecord.lastChangedTime = System.currentTimeMillis(); + } + } + } + catch (Exception e) + { + if (ProtocolWhisperer.debug) + { + e.printStackTrace(); + } + } + try + { + client.disconnect(); + } + catch (java.io.IOException e) + { + if (ProtocolWhisperer.debug) + { + e.printStackTrace(); + } + } + } + public void storeProtocolRecord(ProtocolRecord pr) + { + recordList.add(pr); + } + public void getIncomingRecords() + { + for (int i = 0; i < recordList.size(); i++) + { + DriveParameterProtocolRecord currentRecord = (DriveParameterProtocolRecord)recordList.get(i); + if (currentRecord.getType() == ProtocolRecord.RECORD_TYPE_INCOMING) + { + ParameterRead(currentRecord); + } + } + } + public void mapIncomingValues() + { + } + + public void sendOutgoingRecords() + { + + } + public Class getProtocolHandlerClass() + { + return DriveParameterProtocolHandler.class; + } + public Class getProtocolRecordClass() + { + return DriveParameterProtocolRecord.class; + } +} diff --git a/src/protocolwhisperer/drivers/DriveParameterProtocolHandler.java b/src/protocolwhisperer/drivers/DriveParameterProtocolHandler.java new file mode 100644 index 0000000..d8b55e7 --- /dev/null +++ b/src/protocolwhisperer/drivers/DriveParameterProtocolHandler.java @@ -0,0 +1,46 @@ +/* + * Copyright 2020 Matt Jamesson . + * + * Licensed 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 protocolwhisperer.drivers; +import protocolwhisperer.*; +import javax.swing.*; +import java.awt.event.*; +import java.util.ArrayList; + +/** + * + * @author Matt Jamesson + */ +public class DriveParameterProtocolHandler implements ProtocolHandler{ + String[] incomingMenuNames = new String[] {"CIP Read Drive Parameter"}; + String[] outgoingMenuNames = new String[] {}; + + public ProtocolRecord getNewProtocolRecord(int type, String calledMenuItem) + { + return new DriveParameterProtocolRecord(type, calledMenuItem); + } + public String[] getIncomingMenuNames() + { + return incomingMenuNames; + } + public String[] getOutgoingMenuNames() + { + return outgoingMenuNames; + } + public void configure(ProtocolRecord currentRecord, BridgeManager manager) + { + new DriveParameterConfigFrame((DriveParameterProtocolRecord)currentRecord, manager).setVisible(true); + } +} diff --git a/src/protocolwhisperer/drivers/DriveParameterProtocolRecord.java b/src/protocolwhisperer/drivers/DriveParameterProtocolRecord.java new file mode 100644 index 0000000..e326d04 --- /dev/null +++ b/src/protocolwhisperer/drivers/DriveParameterProtocolRecord.java @@ -0,0 +1,41 @@ +/* + * Copyright 2020 Matt Jamesson . + * + * Licensed 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 protocolwhisperer.drivers; + +/** + * + * @author Matt Jamesson + */ +public class DriveParameterProtocolRecord extends ProtocolRecord { + public static int PROTOCOL_TYPE_GETATTR = 1; + public static int PROTOCOL_TYPE_SETATTR = 2; + public String host = null; + public Class protocolHandler = DriveParameterProtocolHandler.class; + public DriveParameterProtocolRecord() + { + + } + public Class getProtocolHandlerClass() + { + return protocolHandler; + } + public DriveParameterProtocolRecord(int aType, String calledMenuItem) + { + selectedItem = calledMenuItem; + type = aType; + } + +} diff --git a/src/protocolwhisperer/drivers/DriveParameterTagRecord.java b/src/protocolwhisperer/drivers/DriveParameterTagRecord.java new file mode 100644 index 0000000..333b6eb --- /dev/null +++ b/src/protocolwhisperer/drivers/DriveParameterTagRecord.java @@ -0,0 +1,33 @@ +/* + * Copyright 2021 Matt Jamesson . + * + * Licensed 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 protocolwhisperer.drivers; + +/** + * + * @author Matt Jamesson + */ +public class DriveParameterTagRecord extends TagRecord { + public int parameter = 0; + double value = 0; + public void setValue(double aValue) + { + value = aValue; + } + public double getValue() + { + return value; + } +}