From 5a37bfe915925ea2307dd09928538c7e639ca52c Mon Sep 17 00:00:00 2001 From: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com> Date: Fri, 19 Aug 2022 08:17:06 +0100 Subject: [PATCH] Changes from DG branch (#50) * Variable sound output level Mods to SoundPlayback module to allow additional parameters. Implemented system for NI cards to allow changes to selected output voltage range meaning output can be boosted to level higher than current default. * Code to support nogui operations when no screens present on headless system * Fix problem of nogui headless operation trying to access screen size. * Click detector display fixes 1. ICI not displaying correctly 2. Component sizes in display dialog on hres monitors * Work on batch processing, after testing of options to autostart, autoexit and set wav file folder, database and binary store. * Update MHTClickTrainAlgorithm.java Fix unsynchronised access to a datablock in click train detector which was causing index errors. * Revamp of offline process messaging and control Includes some databsae logging of completed tasks * Offline task logging Bit more work, including notes and database storage of task reprocessing. Guess this could all become 'proper' PAMGuard data and be shown in a table on the display but that not priority enough. * Dialog packing Fix a couple of dialogs which don't back well on HDPI monitors * UDP Control Added multiport functionality * Java version Changes unpacker to deal with non numeric characters on Linux * Fix to getVersion() So new version of this command should now work on Linux and Windows. * Multiport test Quick tester for multiport comms * Spectrogram display Stop spectrogram display continually recreating panels since it was unsubscribing discarded ones and sometimes causing crash in observable notifications. * Backup manager bug Error if no database. Fixed. --- src/PamController/PamController.java | 45 ++++++++-- src/PamController/command/MultiportTest.java | 88 +++++++++++++++++++ src/PamguardMVC/PamObservable.java | 14 ++- src/Spectrogram/SpectrogramDisplay.java | 38 ++++++-- .../database/DatabaseCatalog.java | 14 +-- 5 files changed, 174 insertions(+), 25 deletions(-) create mode 100644 src/PamController/command/MultiportTest.java diff --git a/src/PamController/PamController.java b/src/PamController/PamController.java index 611dd9a2..b15d0ee1 100644 --- a/src/PamController/PamController.java +++ b/src/PamController/PamController.java @@ -2629,17 +2629,44 @@ public class PamController implements PamControllerInterface, PamSettings { */ static double getVersion () { String version = System.getProperty("java.version"); - int pos = version.indexOf('.'); // get the index of the first decimal - if (pos==-1) { // if there is no decimal place (e.g. Java 13) then just use the full string - pos=version.length(); - } - else { - pos = version.indexOf('.', pos+1); // get the position of the second decimal - if (pos==-1) { // if there is no second decimal place (e.g. Java 12.0) then just use the full string - pos=version.length(); + /* + * strip down to the first non numeric character. and allow 0 or 1 decimal points. + * This should pull out any valid decimal number from the front of the string. + */ + int iLen = 0; + int nDot = 0; + for (int i = 0; i < version.length(); i++) { + char ch = version.charAt(i); + if (Character.isDigit(ch) || (ch == '.' && nDot == 0)) { + iLen++; + if (ch == '.') { + nDot++; + } } + else { + break; + }; } - return Double.parseDouble (version.substring (0, pos)); + +// int pos = version.indexOf('.'); // get the index of the first decimal +// if (pos==-1) { // if there is no decimal place (e.g. Java 13) then just use the full string +// pos=version.length(); +// } +// else { +// pos = version.indexOf('.', pos+1); // get the position of the second decimal +// if (pos==-1) { // if there is no second decimal place (e.g. Java 12.0) then just use the full string +// pos=version.length(); +// } +// } + double mainVersion = 0; + try { + mainVersion = Double.parseDouble (version.substring (0, iLen)); + } + catch (NumberFormatException e) { + + } + + return mainVersion; } /** diff --git a/src/PamController/command/MultiportTest.java b/src/PamController/command/MultiportTest.java new file mode 100644 index 00000000..3d828066 --- /dev/null +++ b/src/PamController/command/MultiportTest.java @@ -0,0 +1,88 @@ +package PamController.command; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.MulticastSocket; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.net.UnknownHostException; + +/** + * Simple test of multiport communication. + * @author dg50 + * + */ +public class MultiportTest { + + private String addr = "224.100.20.20"; + private int port = 1290; + + private String tstStr = "ping"; + + private int BUFFLEN = 512; + private byte[] retBuffer = new byte[BUFFLEN]; + + public static void main(String[] args) { + new MultiportTest().run(); + } + + public MultiportTest() { + // TODO Auto-generated constructor stub + } + + private void run() { + InetAddress mcastaddr; + DatagramSocket socket = null; +// listInterfaces(); + try { +// mcastaddr = InetAddress.getByName(addr); +// InetSocketAddress group = new InetSocketAddress(mcastaddr, port); +// NetworkInterface netIf = NetworkInterface.getByName("bge0"); +// MulticastSocket socket = new MulticastSocket(port); +// socket.joinGroup(group, netIf); + socket = new DatagramSocket(); + socket.setSoTimeout(1000); + + DatagramPacket dataGram = new DatagramPacket(tstStr.getBytes(), tstStr.length(), + InetAddress.getByName(addr), port); + + socket.send(dataGram); + + DatagramPacket reGram = new DatagramPacket(retBuffer, BUFFLEN); + while (true) { + socket.receive(reGram); + String retStr = new String(reGram.getData(), 0, reGram.getLength()); + System.out.printf("\"%s\" received from %s %s port %d\n", retStr, reGram.getAddress(), reGram.getSocketAddress(), reGram.getPort()); + } + + // clean up +// socket.leaveGroup(group, netIf); + + } catch (IOException e) { + // TODO Auto-generated catch block + System.out.println(e.getMessage()); + } + socket.close(); + System.out.println("Done"); + + } + + private void listInterfaces() { + + try { + // there are 46 of these on my laptop, enumerated from 1. 0 is null. + for (int i = 0; i < 50; i++) { + NetworkInterface netIf = NetworkInterface.getByIndex(i); + System.out.printf("Interface %d : %s\n", i, netIf); + } + } catch (SocketException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + +} diff --git a/src/PamguardMVC/PamObservable.java b/src/PamguardMVC/PamObservable.java index f1514b4b..73897998 100644 --- a/src/PamguardMVC/PamObservable.java +++ b/src/PamguardMVC/PamObservable.java @@ -238,7 +238,8 @@ public class PamObservable {//extends PanelOverlayDraw { * instance of any observer */ // synchronized (pamObservers) { - while (pamObservers.remove(o)); + boolean removed = false; + while (removed = pamObservers.remove(o)); PamObserver threadedObserver = findThreadedObserver(o); if (threadedObserver != null) { deleteObserver(threadedObserver); @@ -247,7 +248,14 @@ public class PamObservable {//extends PanelOverlayDraw { tObs.terminateThread(); } } - while (instantObservers.remove(o)); + while (removed = instantObservers.remove(o)); +// if (removed && o != null) { +// String name = this.toString(); +// if (this instanceof PamDataBlock) { +// name = ((PamDataBlock) this).getLongDataName(); +// } +// System.out.printf("Datablock %s removed observer %s\n", this.toString(), o.getObserverName()); +// } // } // o.removeObservable(this); } @@ -263,7 +271,7 @@ public class PamObservable {//extends PanelOverlayDraw { } /** - * @return Count of PamObservers subscribing to this observable + * @return Count of PamObservers subscribing to this observable including instant and rethreaded */ public int countObservers() { synchronized (pamObservers) { diff --git a/src/Spectrogram/SpectrogramDisplay.java b/src/Spectrogram/SpectrogramDisplay.java index 6766ec2f..99c86de6 100644 --- a/src/Spectrogram/SpectrogramDisplay.java +++ b/src/Spectrogram/SpectrogramDisplay.java @@ -1748,23 +1748,47 @@ InternalFrameListener, DisplayPanelContainer, SpectrogramParametersUser, PamSett int topBorder, bottomBorder; Color borderColour = Color.BLACK; synchronized (innerPanelSynchObject) { + /* + * Update code August 2022 so it only creates and destroys + * panels if the number of panels has changed. + */ + int nOld = 0; + int nNew =spectrogramParameters.nPanels; if (spectrogramPanels != null) { - for (int i = 0; i < spectrogramPanels.length; i++) { - if (spectrogramPanels[i] != null) { + nOld = spectrogramPanels.length; + if (nNew < nOld) { + for (int i = nNew; i < nOld; i++) { spectrogramPanels[i].destroyPanel(); } + spectrogramPanels = Arrays.copyOf(spectrogramPanels, nNew); } +// for (int i = 0; i < spectrogramPanels.length; i++) { +// if (spectrogramPanels[i] != null) { +// spectrogramPanels[i].destroyPanel(); +// } +// } } - spectrogramPanels = new SpectrogramPanel[spectrogramParameters.nPanels]; - //popupListener = new PopupListener(); - nPanels = spectrogramParameters.nPanels; - for (int i = 0; i < nPanels; i++) { + if (spectrogramPanels == null) { + spectrogramPanels = new SpectrogramPanel[spectrogramParameters.nPanels]; + } + else if (nOld != nNew) { + spectrogramPanels = Arrays.copyOf(spectrogramPanels, nNew); + } + for (int i = nOld; i < nNew; i++) { + spectrogramPanels[i] = new SpectrogramPanel(spectrogramDisplay, i); + } +// //popupListener = new PopupListener(); +// nPanels = spectrogramParameters.nPanels; + for (int i = 0; i < nNew; i++) { PamPanel panelBorder = new PamPanel(new BorderLayout()); + if (spectrogramPanels[i].getParent() != null) { + // remove from any previous panel parent if it's being reused. + spectrogramPanels[i].getParent().remove(spectrogramPanels[i]); + } topBorder = 1; bottomBorder = 0; if (i == 0) topBorder = 0; if (i == spectrogramParameters.nPanels-1) bottomBorder = 0; - spectrogramPanels[i] = new SpectrogramPanel(spectrogramDisplay, i); panelBorder.setBorder((BorderFactory.createEmptyBorder(topBorder,0,bottomBorder,0))); panelBorder.add(BorderLayout.CENTER, spectrogramPanels[i]); add(panelBorder); diff --git a/src/backupmanager/database/DatabaseCatalog.java b/src/backupmanager/database/DatabaseCatalog.java index 28200477..27c6c95e 100644 --- a/src/backupmanager/database/DatabaseCatalog.java +++ b/src/backupmanager/database/DatabaseCatalog.java @@ -59,13 +59,15 @@ public class DatabaseCatalog extends BackupCatalog { actionMap.put(action, ++ind); } makeTableDefinition(); - + dbControlUnit = DBControlUnit.findDatabaseControl(); - pamConnection = dbControlUnit.getConnection(); - DBProcess dbProcess = dbControlUnit.getDbProcess(); - boolean tableOk = dbProcess.checkTable(fullTableDef); - if (tableOk == false) { - System.err.println("Error checking backup table " + fullTableDef.getTableName()); + if (dbControlUnit != null) { + pamConnection = dbControlUnit.getConnection(); + DBProcess dbProcess = dbControlUnit.getDbProcess(); + boolean tableOk = dbProcess.checkTable(fullTableDef); + if (tableOk == false) { + System.err.println("Error checking backup table " + fullTableDef.getTableName()); + } } }