From 4297afdc51acf0b4cadb225b237be48851976965 Mon Sep 17 00:00:00 2001 From: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com> Date: Thu, 14 Dec 2023 12:42:41 +0000 Subject: [PATCH 1/4] Fix user input bug in viewer which created exponential copies of user comments! --- src/UserInput/UserInputLogger.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/UserInput/UserInputLogger.java b/src/UserInput/UserInputLogger.java index a3b5f57c..31eb53a8 100644 --- a/src/UserInput/UserInputLogger.java +++ b/src/UserInput/UserInputLogger.java @@ -136,7 +136,9 @@ public class UserInputLogger extends SQLLogging { if (dataUnit != null && dataUnit.getDatabaseIndex() != databaseIndex) { dataUnit.setDatabaseIndex(databaseIndex); dataUnit.setUserString(dataUnit.getUserString() + " " + txt); - getPamDataBlock().updatePamData(dataUnit, timeMilliseconds); + // don't call this next line, it causes the unit to get relogged. +// getPamDataBlock().updatePamData(dataUnit, timeMilliseconds); + dataUnit.clearUpdateCount(); } else { dataUnit = new UserInputDataUnit(timeMilliseconds, txt); From f55311ea36523828d1f04fc5723fae5a01ba1873 Mon Sep 17 00:00:00 2001 From: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com> Date: Thu, 14 Dec 2023 18:51:42 +0000 Subject: [PATCH 2/4] Adding TAST trigger alarm action To be competed when GW provide correct string for interface --- src/alarm/AlarmControl.java | 2 ++ src/alarm/actions/tast/TastAction.java | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 src/alarm/actions/tast/TastAction.java diff --git a/src/alarm/AlarmControl.java b/src/alarm/AlarmControl.java index 9e211671..83f2dd8c 100644 --- a/src/alarm/AlarmControl.java +++ b/src/alarm/AlarmControl.java @@ -17,6 +17,7 @@ import alarm.actions.AlarmAction; import alarm.actions.email.SendEmailAction; import alarm.actions.serial.AlarmSerialAction; import alarm.actions.sound.PlaySound; +import alarm.actions.tast.TastAction; import alarm.actions.udp.AlarmUDPAction; import userDisplay.UserDisplayComponent; import userDisplay.UserDisplayControl; @@ -54,6 +55,7 @@ public class AlarmControl extends PamControlledUnit implements PamSettings { alarmActions.add(new AlarmSerialAction(this)); alarmActions.add(new SendEmailAction(this)); alarmActions.add(new AlarmUDPAction(this)); +// alarmActions.add(new TastAction(this)); // uncomment when alarm action string ready } /* (non-Javadoc) diff --git a/src/alarm/actions/tast/TastAction.java b/src/alarm/actions/tast/TastAction.java new file mode 100644 index 00000000..76276d75 --- /dev/null +++ b/src/alarm/actions/tast/TastAction.java @@ -0,0 +1,26 @@ +package alarm.actions.tast; + +import alarm.AlarmControl; +import alarm.AlarmDataUnit; +import alarm.actions.serial.AlarmSerialAction; + +public class TastAction extends AlarmSerialAction { + + public TastAction(AlarmControl alarmControl) { + super(alarmControl); + } + + @Override + public String getActionName() { + return "TAST Trigger"; + } + + + @Override + protected String createAlarmString(AlarmDataUnit alarmDataUnit) { + // TODO. To define serial string to send to TAST device once we hear back + // from GenusWave. + return null; + } + +} From 75d349e33c9051e9fdd7e722ed95f61a536f031b Mon Sep 17 00:00:00 2001 From: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com> Date: Thu, 14 Dec 2023 18:52:17 +0000 Subject: [PATCH 3/4] Echo offline detection Fix up affected datablocks for offline echo detection --- .../offlineFuncs/EchoDetectionTask.java | 2 +- src/offlineProcessing/OfflineTask.java | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/clickDetector/offlineFuncs/EchoDetectionTask.java b/src/clickDetector/offlineFuncs/EchoDetectionTask.java index 1b16b482..01c6bed8 100644 --- a/src/clickDetector/offlineFuncs/EchoDetectionTask.java +++ b/src/clickDetector/offlineFuncs/EchoDetectionTask.java @@ -24,7 +24,7 @@ public class EchoDetectionTask extends OfflineTask { this.clickControl = clickControl; echoDetectionSystem = clickControl.getEchoDetectionSystem(); setParentDataBlock(clickControl.getClickDataBlock()); -// addAffectedDataBlock(clickControl.getClickDataBlock()); + addAffectedDataBlock(clickControl.getClickDataBlock()); } @Override diff --git a/src/offlineProcessing/OfflineTask.java b/src/offlineProcessing/OfflineTask.java index 7f3e0ec1..dab50a6b 100644 --- a/src/offlineProcessing/OfflineTask.java +++ b/src/offlineProcessing/OfflineTask.java @@ -301,6 +301,21 @@ public abstract class OfflineTask { public PamDataBlock getAffectedDataBlock(int iBlock) { return affectedDataBlocks.get(iBlock); } + + /** + * Get a formatted string list of affected data blocks + * @return + */ + public String getAffectedBlocksList() { + if (affectedDataBlocks == null || affectedDataBlocks.size() == 0) { + return null; + } + String blocks = affectedDataBlocks.get(0).getDataName(); + for (int i = 1; i < affectedDataBlocks.size(); i++) { + blocks += "; " + affectedDataBlocks.get(i).getDataName(); + } + return blocks; + } /** * Return whether or not the task SHOULD be run - i.e. if it is selected in From 0039ff742287ab70bedab39735163a99800c3e9e Mon Sep 17 00:00:00 2001 From: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com> Date: Sun, 17 Dec 2023 12:19:18 +0000 Subject: [PATCH 4/4] fix module import System for importing modules from other psfx files was not working. Probably wasn't working for quite some time. Now fixed. --- src/PamController/PSFXReadWriter.java | 2 + src/PamController/PamConfiguration.java | 2 +- src/PamController/PamController.java | 12 +- src/PamController/PamSettingsGroup.java | 4 +- src/PamController/UsedModuleInfo.java | 3 +- .../settings/SettingsImport.java | 121 +++++++++++++----- .../settings/SettingsImportDialog.java | 2 + .../settings/SettingsImportGroup.java | 44 +++++-- 8 files changed, 142 insertions(+), 48 deletions(-) diff --git a/src/PamController/PSFXReadWriter.java b/src/PamController/PSFXReadWriter.java index b3c07cd0..883e1c76 100644 --- a/src/PamController/PSFXReadWriter.java +++ b/src/PamController/PSFXReadWriter.java @@ -198,6 +198,7 @@ public class PSFXReadWriter { BinaryHeader bh = new BinaryHeader(); bh.readHeader(dis); PamSettingsGroup psg = new PamSettingsGroup(bh.getDataDate()); + ArrayList moduleNames = new ArrayList(); /* * dos.writeInt(totalLen); @@ -217,6 +218,7 @@ public class PSFXReadWriter { dis.read(data); if (objectId == ModuleNameObject.typeId) { ModuleNameObject mno = new ModuleNameObject(data); + moduleNames.add(mno); } else if (objectId == 2) { PamControlledUnitSettings pcsu = PamControlledUnitSettings.createFromNamedByteArray(data); diff --git a/src/PamController/PamConfiguration.java b/src/PamController/PamConfiguration.java index dd9daf1e..44866e39 100644 --- a/src/PamController/PamConfiguration.java +++ b/src/PamController/PamConfiguration.java @@ -26,7 +26,7 @@ import offlineProcessing.OfflineTaskGroup; * them, but for some of the batch processing control, we need to be able to load and * manipulate a second set of modules, which do nothing within the running * configuration, but are there to allow us to set up a configuration to send to - * other batch processes in viewer mode. + * other batch processes in viewer mode. This is also being used in an improved module import system. * @author dg50 * */ diff --git a/src/PamController/PamController.java b/src/PamController/PamController.java index fecb0463..93dc4205 100644 --- a/src/PamController/PamController.java +++ b/src/PamController/PamController.java @@ -141,6 +141,12 @@ public class PamController implements PamControllerInterface, PamSettings { // flag used in main() to indicate that pamguard should exit as soon as processing ends. public static final String AUTOEXIT = "-autoexit"; + /** + * Never changed. Needed to identify settings for list of modules in prfx files. + */ + public static final String unitName = "Pamguard Controller"; + public static final String unitType = "PamController"; + /** * The pam model. */ @@ -1835,15 +1841,15 @@ public class PamController implements PamControllerInterface, PamSettings { public long getSettingsVersion() { return 0; } - + @Override public String getUnitName() { - return "Pamguard Controller"; + return unitName; } @Override public String getUnitType() { - return "PamController"; + return unitType; } @Override diff --git a/src/PamController/PamSettingsGroup.java b/src/PamController/PamSettingsGroup.java index c4d665b9..5baa766e 100644 --- a/src/PamController/PamSettingsGroup.java +++ b/src/PamController/PamSettingsGroup.java @@ -33,9 +33,7 @@ public class PamSettingsGroup implements Comparable { * @param settingsTime settings time in milliseconds. */ public PamSettingsGroup(long settingsTime) { - super(); - this.settingsTime = settingsTime; - unitSettings = new ArrayList(); + this(settingsTime, new ArrayList()); } /** diff --git a/src/PamController/UsedModuleInfo.java b/src/PamController/UsedModuleInfo.java index 7c70ef4d..88756866 100644 --- a/src/PamController/UsedModuleInfo.java +++ b/src/PamController/UsedModuleInfo.java @@ -7,7 +7,8 @@ import PamModel.parametermanager.PamParameterSet; /** * Very simple class used in an ArrayList of used modules that - * get's saved between runs. + * get's saved between runs. This forms the core of the settings system + * so don't f*** with it ! * @author Doug * */ diff --git a/src/PamController/settings/SettingsImport.java b/src/PamController/settings/SettingsImport.java index 2269b3f7..0c52fb31 100644 --- a/src/PamController/settings/SettingsImport.java +++ b/src/PamController/settings/SettingsImport.java @@ -15,10 +15,12 @@ import PamController.PamController; import PamController.PamSettingManager; import PamController.PamSettings; import PamController.PamSettingsGroup; +import PamController.UsedModuleInfo; import PamModel.PamModel; import PamModel.PamModuleInfo; import PamModel.SMRUEnable; import PamView.dialog.PamFileBrowser; +import PamView.dialog.warn.WarnOnce; /** * Class to handle the import of settings from other psf files. @@ -180,9 +182,16 @@ public class SettingsImport { /** * Now make a new Pamcontrolled unit with the given name ... */ + // need to find the module information in the PamModel +// PamModel pamModel = PamModel.getPamModel(); +// pamModel. + PamModuleInfo moduleInfo = PamModuleInfo.findModuleInfo(importGroup.getUsedModuleInfo().className); // find the module info for this one - PamModuleInfo moduleInfo = importGroup.getModuleInfo(); +// PamModuleInfo moduleInfo = importGroup.getUsedModuleInfo(); if (moduleInfo == null) { + String msg = String.format("Unable to find module information for type %s main class %s in model", + importGroup.getUsedModuleInfo().getUnitType(), importGroup.getUsedModuleInfo().className); + WarnOnce.showWarning("Module creating error!", msg, WarnOnce.WARNING_MESSAGE); return null; } @@ -206,6 +215,7 @@ public class SettingsImport { } } loadSubUnitSettings(importGroup, unit.getUnitName()); + unit.setupControlledUnit(); return unit; } @@ -215,45 +225,64 @@ public class SettingsImport { * @return */ ArrayList organiseSettingsGroups(ArrayList settings) { + /** + * this needs rewriting for psfx files which are organised differently. first we need to find + * a list of PAMGuard modules by finding the settings group of the PAMController. + */ + ArrayList groupedSettings = new ArrayList<>(); - // first pull out the settings for PamControlledNnits. - boolean[] used = new boolean[settings.size()]; - for (int i = 0; i < settings.size(); i++) { - PamControlledUnitSettings aSet = settings.get(i); - if (aSet.getOwnerClassName() == null) { - continue; - } - Class ownerClass = null; - try { - ownerClass = Class.forName(aSet.getOwnerClassName()); - } catch (ClassNotFoundException e) { - // TODO Auto-generated catch block -// e.printStackTrace(); - // this is happening since the ownerclassname is not set correctly in psfx files - // so we have to deserialise the data to find the class. -// ownerClass = getClassFromData(aSet.getSerialisedByteArray()); -// ownerClass = PamModuleInfo.findModuleClass(aSet.getUnitType()); - } - if (ownerClass == null) { - continue; - } - if (PamControlledUnit.class.isAssignableFrom(ownerClass)) { - PamModuleInfo moduleInfo = PamModuleInfo.findModuleInfo(aSet.getOwnerClassName()); - groupedSettings.add(new SettingsImportGroup(aSet, moduleInfo)); - used[i] = true; - } + ArrayList usedModules = findPamControllerSettings(settings); + // make the group list based on the list of modules. + for (UsedModuleInfo usedModule : usedModules) { + groupedSettings.add(new SettingsImportGroup(usedModule)); } + + +// // first pull out the settings for PamControlledNnits. + boolean[] used = new boolean[settings.size()]; +// for (int i = 0; i < settings.size(); i++) { +// PamControlledUnitSettings aSet = settings.get(i); +// if (aSet.getOwnerClassName() == null) { +// continue; +// } +// Class ownerClass = null; +// try { +// ownerClass = Class.forName(aSet.getOwnerClassName()); +// } catch (ClassNotFoundException e) { +// // TODO Auto-generated catch block +//// e.printStackTrace(); +// // this is happening since the ownerclassname is not set correctly in psfx files +// // so we have to deserialise the data to find the class. +//// ownerClass = getClassFromData(aSet.getSerialisedByteArray()); +//// ownerClass = PamModuleInfo.findModuleClass(aSet.getUnitType()); +// } +// if (ownerClass == null) { +// continue; +// } +// if (PamControlledUnit.class.isAssignableFrom(ownerClass)) { +// PamModuleInfo moduleInfo = PamModuleInfo.findModuleInfo(aSet.getOwnerClassName()); +// groupedSettings.add(new SettingsImportGroup(moduleInfo)); +// used[i] = true; +// } +// } // now match all the remaining settings into the first set based on ModuleName. for (int i = 0; i < settings.size(); i++) { PamControlledUnitSettings aSet = settings.get(i); - if (used[i]) continue; +// if (used[i]) continue; SettingsImportGroup mainGroup = findGroup(groupedSettings, aSet.getUnitName()); if (mainGroup != null) { - mainGroup.addSubSettings(aSet); + // main settings will have same type as well as same name. + boolean mainType = isMainType(mainGroup, aSet); + if (mainType) { + mainGroup.setMainSettings(aSet); + } + else { + mainGroup.addSubSettings(aSet); + } used[i] = true; - System.out.println(String.format("Adding %s-%s to %s-%s group", aSet.getUnitType(), aSet.getUnitName(), - mainGroup.getMainSettings().getUnitType(), mainGroup.getMainSettings().getUnitName())); +// System.out.println(String.format("Adding %s-%s to %s-%s group", aSet.getUnitType(), aSet.getUnitName(), +// mainGroup.getMainSettings().getUnitType(), mainGroup.getMainSettings().getUnitName())); } } @@ -272,6 +301,34 @@ public class SettingsImport { return groupedSettings; } + /** + * IS this the main settings group for this module ? If it is, it should have the same + * type as well as the same name. + * @param mainGroup + * @param aSet + * @return + */ + private boolean isMainType(SettingsImportGroup mainGroup, PamControlledUnitSettings aSet) { + boolean isMain = mainGroup.getUsedModuleInfo().getUnitType().equals(aSet.getUnitType()); + return isMain; + } + + private ArrayList findPamControllerSettings(ArrayList settings) { + if (settings == null) { + return null; + } + for (PamControlledUnitSettings aSet : settings) { + if (aSet.getUnitName().equals(PamController.unitName) && + aSet.getUnitType().equals(PamController.unitType)) { + Object sets = aSet.getSettings(); + if (sets instanceof ArrayList) { + return (ArrayList) sets; + } + } + } + return null; + } + private Class getClassFromData(byte[] data) { try { ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data)); @@ -285,7 +342,7 @@ public class SettingsImport { private SettingsImportGroup findGroup(ArrayList groupedSettings, String unitName) { for (SettingsImportGroup iG:groupedSettings) { - if (iG.getMainSettings().getUnitName().equals(unitName)) { + if (iG.getUsedModuleInfo().unitName.equals(unitName)) { return iG; } } diff --git a/src/PamController/settings/SettingsImportDialog.java b/src/PamController/settings/SettingsImportDialog.java index 8c9c09bd..6f6621e6 100644 --- a/src/PamController/settings/SettingsImportDialog.java +++ b/src/PamController/settings/SettingsImportDialog.java @@ -17,6 +17,7 @@ import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.border.EmptyBorder; +import javax.swing.border.TitledBorder; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.AbstractTableModel; @@ -66,6 +67,7 @@ public class SettingsImportDialog extends PamDialog { moduleTable.getColumnModel().getColumn(2).setPreferredWidth(200); JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.setBorder(new TitledBorder("Module import selection")); JScrollPane scrollPanel = new JScrollPane(moduleTable); mainPanel.add(BorderLayout.CENTER, scrollPanel); mainPanel.setPreferredSize(new Dimension(600, 250)); diff --git a/src/PamController/settings/SettingsImportGroup.java b/src/PamController/settings/SettingsImportGroup.java index b7bb3f36..a74a6885 100644 --- a/src/PamController/settings/SettingsImportGroup.java +++ b/src/PamController/settings/SettingsImportGroup.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import PamController.PamControlledUnit; import PamController.PamControlledUnitSettings; import PamController.PamController; +import PamController.UsedModuleInfo; import PamModel.PamModuleInfo; /** @@ -20,19 +21,26 @@ public class SettingsImportGroup { private ArrayList subSettings = new ArrayList<>(); - private PamModuleInfo moduleInfo; + private UsedModuleInfo usedModuleInfo; private ArrayList importChoices; private ImportChoice importChoice; + + + public SettingsImportGroup(UsedModuleInfo moduleInfo) { + super(); + this.usedModuleInfo = moduleInfo; + } + /** * Constructor takes the main settings * @param mainSettings * @param moduleInfo */ - public SettingsImportGroup(PamControlledUnitSettings mainSettings, PamModuleInfo moduleInfo) { + public SettingsImportGroup(PamControlledUnitSettings mainSettings, UsedModuleInfo moduleInfo) { this.mainSettings = mainSettings; - this.moduleInfo = moduleInfo; + this.usedModuleInfo = moduleInfo; } /** @@ -72,7 +80,7 @@ public class SettingsImportGroup { importChoices.add(importChoice = new ImportChoice(ImportChoice.DONT_IMPORT, null)); Class ownerClass = null; try { - ownerClass = Class.forName(mainSettings.getOwnerClassName()); + ownerClass = Class.forName(usedModuleInfo.className); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -80,8 +88,9 @@ public class SettingsImportGroup { ArrayList existingModules = PamController.getInstance().findControlledUnits(ownerClass); int maxnumber = 1; // this will only ever be used by the Array Manager which doesn't have a moduleInfo. - if (this.moduleInfo != null) { - maxnumber = moduleInfo.getMaxNumber(); + PamModuleInfo pamModuleInfo = getPamModuleInfo(); + if (pamModuleInfo != null) { + maxnumber = pamModuleInfo.getMaxNumber(); } if (existingModules != null) { for (int i = 0; i < existingModules.size(); i++) { @@ -111,10 +120,29 @@ public class SettingsImportGroup { } /** + * This is the information from an existing module, which may not + * have the full class name, but does have the type and name of the + * module being imported. * @return the moduleInfo */ - public PamModuleInfo getModuleInfo() { - return moduleInfo; + public UsedModuleInfo getUsedModuleInfo() { + return usedModuleInfo; + } + + /** + * this is the module information held in the PamModel which + * is used to create a module. + * @return + */ + public PamModuleInfo getPamModuleInfo() { + return PamModuleInfo.findModuleInfo(usedModuleInfo.className); + } + + /** + * @param mainSettings the mainSettings to set + */ + public void setMainSettings(PamControlledUnitSettings mainSettings) { + this.mainSettings = mainSettings; }