Compare commits

...

22 Commits

Author SHA1 Message Date
Harald Christian Joachim Wolff 098199123a RTC fixes 5 years ago
Harald Wolff c0286e6a2e WIP 5 years ago
Harald Christian Joachim Wolff a3e32ad3e5 +SimpleLinkDeviceConnector 5 years ago
Harald Christian Joachim Wolff 630d79ac88 Merged 5 years ago
Harald Wolff beb88f1b8d WIP170310 6 years ago
Harald Wolff 4624fa0903 WIP161121 6 years ago
Harald Wolff 4332bb8a14 WIP161117 6 years ago
Harald Wolff a7e43ec0b4 WIP161026 6 years ago
Harald Wolff ccf6e4d9f7 WIP161013 6 years ago
Harald Wolff 52cac8e5d9 WIP 20161013 6 years ago
Harald Wolff 756f0f2d4d WIP / Beta 161006 6 years ago
Harald Wolff 88c7073dcb PulsCOunterDatabase 6 years ago
Harald Wolff 4a1bdab688 Projekteinstellungen 6 years ago
Harald Wolff 40ef4b06f2 Schema SQL Update 6 years ago
Harald Wolff 0582ec77e6 Sammelupdate 20160915 / HSQLDB, MultiDevice 6 years ago
Harald Wolff 84e912b73e WIP 160913 6 years ago
haraldwolff 246955f622 Merge branch 'WIP-PC2' of schwann.lupus:/git/java/org.hwo.pulscounter.git into WIP-PC2 6 years ago
haraldwolff 610b7637f1 WIP 6 years ago
haraldwolff ce2d831fa2 HSQLDB Store... 6 years ago
haraldwolff e903133b95 WIP-160909 Simulation / MultiDevice 6 years ago
Harald Wolff 94877bb85f hsqldb.jar 6 years ago
Harald Wolff 876db0c37b WIP 20160908 6 years ago
  1. 4
      .classpath
  2. 2
      .gitignore
  3. 6
      .settings/org.eclipse.jdt.core.prefs
  4. 3
      Manifest
  5. 69
      PulsCounterApplication.msg.xml
  6. 7
      PulsCounterApplication.msg_en.xml
  7. BIN
      hsqldb.jar
  8. 99
      missing-translation.txt
  9. BIN
      postgresql-9.1-901.jdbc4.jar
  10. 3
      src/org/hwo/pulscounter/AbstractPulsCounterApplicationListener.java
  11. 19
      src/org/hwo/pulscounter/Application.java
  12. 244
      src/org/hwo/pulscounter/DeviceTester.java
  13. 132
      src/org/hwo/pulscounter/ExportSetting.java
  14. 4
      src/org/hwo/pulscounter/NewPulsCounterDevice.java
  15. 231
      src/org/hwo/pulscounter/PulsCounter2Application.java
  16. 560
      src/org/hwo/pulscounter/PulsCounterApplication.java
  17. 6
      src/org/hwo/pulscounter/PulsCounterApplicationListener.java
  18. 98
      src/org/hwo/pulscounter/SnapShot.java
  19. 321
      src/org/hwo/pulscounter/SnapshotManager.java
  20. 87
      src/org/hwo/pulscounter/application/InspectorApplication.java
  21. 303
      src/org/hwo/pulscounter/db/PulsCounterDatabase.java
  22. 15
      src/org/hwo/pulscounter/db/schema/schema.sql
  23. 82
      src/org/hwo/pulscounter/device/IDeviceConnector.java
  24. 11
      src/org/hwo/pulscounter/device/NoDeviceConnectionException.java
  25. 848
      src/org/hwo/pulscounter/device/ServiceLinkDeviceConnector.java
  26. 869
      src/org/hwo/pulscounter/device/SimpleLinkDeviceConnector.java
  27. 310
      src/org/hwo/pulscounter/device/SimulatedCounter.java
  28. 112
      src/org/hwo/pulscounter/device/SimulatedCounterSettingsDialog.java
  29. 11
      src/org/hwo/pulscounter/elements/RawValueEntry.java
  30. 73
      src/org/hwo/pulscounter/elements/WorkShift.java
  31. 142
      src/org/hwo/pulscounter/elements/WorkShiftRecord.java
  32. 349
      src/org/hwo/pulscounter/simplescript/SimpleScript.java
  33. 46
      src/org/hwo/pulscounter/simplescript/SimpleScriptAddress.java
  34. 53
      src/org/hwo/pulscounter/ui/AppSettingsFrame.java
  35. 82
      src/org/hwo/pulscounter/ui/BatchRunner.java
  36. 94
      src/org/hwo/pulscounter/ui/ChannelDisplay.java
  37. 2
      src/org/hwo/pulscounter/ui/ChannelDisplayListener.java
  38. 302
      src/org/hwo/pulscounter/ui/CheckWorkshiftRecords.java
  39. 331
      src/org/hwo/pulscounter/ui/DeviceConfiguration.java
  40. 157
      src/org/hwo/pulscounter/ui/DeviceTestFrame.java
  41. 52
      src/org/hwo/pulscounter/ui/ExportFilesFrame.java
  42. 1
      src/org/hwo/pulscounter/ui/ExportSettingsEditorDialog.java
  43. 122
      src/org/hwo/pulscounter/ui/InspectionMainFrame.java
  44. 664
      src/org/hwo/pulscounter/ui/LiveViewFrame.java
  45. 1014
      src/org/hwo/pulscounter/ui/NewMainWindow.java
  46. 38
      src/org/hwo/pulscounter/ui/ShutdownNotification.java
  47. 153
      src/org/hwo/pulscounter/ui/SimpleScriptAddressEditor.java
  48. 313
      src/org/hwo/pulscounter/ui/SimpleScriptEditor.java
  49. 260
      src/org/hwo/pulscounter/ui/SimpleScriptElementEditor.java
  50. 286
      src/org/hwo/pulscounter/ui/SimpleScriptSetup.java
  51. 452
      src/org/hwo/pulscounter/ui/SnapshotManager.java
  52. 32
      synololog.jardesc

4
.classpath

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.hwo"/>
<classpathentry kind="lib" path="postgresql-9.1-901.jdbc4.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.hwo.ui"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.hwo.servicelink"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.hwo.platform"/>
<classpathentry kind="lib" path="hsqldb.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

2
.gitignore

@ -6,3 +6,5 @@ chnames.prop
*.dat
*.log
*.old
*.cfg
synololog-hsql.*

6
.settings/org.eclipse.jdt.core.prefs

@ -1,12 +1,12 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.7
org.eclipse.jdt.core.compiler.source=1.8

3
Manifest

@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: org.hwo.pulscounter.Application

69
PulsCounterApplication.msg.xml

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>missing translations</comment>
<entry key="tooltip.synololog.einstellen">tooltip.synololog.einstellen</entry>
<entry key="tooltip.export.list">tooltip.export.list</entry>
<entry key="Zähler #31">Zähler #31</entry>
<entry key="Zähler #30">Zähler #30</entry>
<entry key="Export Einstellungen...">Export Einstellungen...</entry>
<entry key="Export löschen">Export löschen</entry>
<entry key="Anschlusseinstellungen">Anschlusseinstellungen</entry>
<entry key="tooltip.daten.exportieren">&lt;html&gt;\n&lt;b&gt;Daten exportieren&lt;/b&gt;&lt;br/&gt;\n&lt;br/&gt;\nExport definitionen bearbeiten und ausführen.&lt;br/&gt;\nHiermit können die Aufzeichnungsdaten in Textdateien exportiert werden.&lt;br/&gt;\n&lt;/html&gt;</entry>
<entry key="Gerät">Gerät</entry>
<entry key="tooltip.export.run">tooltip.export.run</entry>
<entry key="Einstellungen">Einstellungen</entry>
<entry key="Zeitstempel">Zeitstempel</entry>
<entry key="Zähler #29">Zähler #29</entry>
<entry key="Zähler #28">Zähler #28</entry>
<entry key="Zähler #27">Zähler #27</entry>
<entry key="Zähler #26">Zähler #26</entry>
<entry key="Zähler #25">Zähler #25</entry>
<entry key="Zähler #24">Zähler #24</entry>
<entry key="Automatiklauf">Automatiklauf</entry>
<entry key="Zähler #23">Zähler #23</entry>
<entry key="Zähler #22">Zähler #22</entry>
<entry key="Zähler #21">Zähler #21</entry>
<entry key="tooltip.export.configuration">tooltip.export.configuration</entry>
<entry key="Zähler #20">Zähler #20</entry>
<entry key="Skripte">Skripte...</entry>
<entry key="HW-Index">HW-Index</entry>
<entry key="Verzeichnis">Verzeichnis</entry>
<entry key="Dateiname">Dateiname</entry>
<entry key="Synololog einstellen">Synololog einstellen</entry>
<entry key="Cancel">abbrechen</entry>
<entry key="Zähler #9">Zähler #9</entry>
<entry key="Zähler #8">Zähler #8</entry>
<entry key="Zähler #7">Zähler #7</entry>
<entry key="Zähler #6">Zähler #6</entry>
<entry key="Zähler #5">Zähler #5</entry>
<entry key="Verbindung">Verbindung</entry>
<entry key="Zähler #4">Zähler #4</entry>
<entry key="Zähler #19">Zähler #19</entry>
<entry key="Zähler #3">Zähler #3</entry>
<entry key="Export hinzufügen">Export hinzufügen</entry>
<entry key="Zähler #18">Zähler #18</entry>
<entry key="Zähler #2">Zähler #2</entry>
<entry key="Auslöser">Auslöser</entry>
<entry key="Zähler #17">Zähler #17</entry>
<entry key="Meldungen">Meldungen</entry>
<entry key="Zähler #1">Zähler #1</entry>
<entry key="Zähler #16">Zähler #16</entry>
<entry key="Zähler #0">Zähler #0</entry>
<entry key="Zähler #15">Zähler #15</entry>
<entry key="Zähler #14">Zähler #14</entry>
<entry key="Zähler #13">Zähler #13</entry>
<entry key="Zähler #12">Zähler #12</entry>
<entry key="Export ausführen">Export ausführen</entry>
<entry key="Zähler #11">Zähler #11</entry>
<entry key="Zähler #10">Zähler #10</entry>
<entry key="Daten exportieren">Daten exportieren</entry>
<entry key="schliessen">schliessen</entry>
<entry key="Differenzieren">Differenzieren</entry>
<entry key="Aufgezeichnete Werte verwalten">Aufgezeichnete Werte verwalten</entry>
<entry key="tooltip.export.add">tooltip.export.add</entry>
<entry key="Autostart">Autostart</entry>
<entry key="tooltip.export.remove">tooltip.export.remove</entry>
<entry key="Benennung">Benennung</entry>
<entry key="Aufzeichnungen verwalten">Aufzeichnungen bearbeiten</entry>
</properties>

7
PulsCounterApplication.msg_en.xml

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>missing translations</comment>
<entry key="Skripte">Scripts...</entry>
<entry key="Cancel">cancel</entry>
</properties>

BIN
hsqldb.jar

Binary file not shown.

99
missing-translation.txt

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>missing translations</comment>
<entry key="Skript bearbeiten">Skript bearbeiten</entry>
<entry key="neu...">neu...</entry>
<entry key="Intervall 2 basiert auf Tageszeit">Intervall 2 basiert auf Tageszeit</entry>
<entry key="Intervall 1:">Intervall 1:</entry>
<entry key="Schnittstelle wählen...">Schnittstelle wählen...</entry>
<entry key="5x neu">5x neu</entry>
<entry key="Niemals">Niemals</entry>
<entry key="auf Zähler übertragen....">auf Zähler übertragen....</entry>
<entry key="Meldungen">Meldungen</entry>
<entry key="Synololog einstellen">Synololog einstellen</entry>
<entry key="ARITHEMTIK = B - 1">ARITHEMTIK = B - 1</entry>
<entry key="tooltip.synololog.einstellen">tooltip.synololog.einstellen</entry>
<entry key="ARITHEMTIK = A / B">ARITHEMTIK = A / B</entry>
<entry key="Von Gerät %s geholt am %s">Von Gerät %s geholt am %s</entry>
<entry key="A &lt; B">A &lt; B</entry>
<entry key="Intervall 0:">Intervall 0:</entry>
<entry key="Intervall 0 basiert auf Tageszeit">Intervall 0 basiert auf Tageszeit</entry>
<entry key="Anschlusseinstellungen">Anschlusseinstellungen</entry>
<entry key="ARITHEMTIK = B + 1">ARITHEMTIK = B + 1</entry>
<entry key="Aufzeichnungen verwalten">Aufzeichnungen verwalten</entry>
<entry key="Ausgang">Ausgang</entry>
<entry key="von Zähler holen....">von Zähler holen....</entry>
<entry key="SnapShot Speicher zurücksetzen">SnapShot Speicher zurücksetzen</entry>
<entry key="Alle Zähler zurücksetzen">Alle Zähler zurücksetzen</entry>
<entry key="ARITHEMTIK = A - B">ARITHEMTIK = A - B</entry>
<entry key="A &gt; B">A &gt; B</entry>
<entry key="Skripte">Skripte</entry>
<entry key="Snapshot Index zurücksetzen">Snapshot Index zurücksetzen</entry>
<entry key="A == B">A == B</entry>
<entry key="ARITHEMTIK = A + B">ARITHEMTIK = A + B</entry>
<entry key="Signalfenster">Signalfenster</entry>
<entry key="Alle Zählerstände zurücksetzen">Alle Zählerstände zurücksetzen</entry>
<entry key="ARITHEMTIK = A - 1">ARITHEMTIK = A - 1</entry>
<entry key="ARITHEMTIK = A * B">ARITHEMTIK = A * B</entry>
<entry key="tooltip.daten.exportieren">tooltip.daten.exportieren</entry>
<entry key="LOGIK = A or B">LOGIK = A or B</entry>
<entry key="bearbeiten...">bearbeiten...</entry>
<entry key="ARITHEMTIK = A + 1">ARITHEMTIK = A + 1</entry>
<entry key="A == 0">A == 0</entry>
<entry key="Löst Snapshot aus">Löst Snapshot aus</entry>
<entry key="Entfernen">Entfernen</entry>
<entry key="entfernen">entfernen</entry>
<entry key="Daten exportieren">Daten exportieren</entry>
<entry key="Inkrement">Inkrement</entry>
<entry key="1x neu">1x neu</entry>
<entry key="SnapShot Speicher auf letzten bekannten SnapShot setzen">SnapShot Speicher auf letzten bekannten SnapShot setzen</entry>
<entry key="Bedingung">Bedingung</entry>
<entry key="Wählen Sie die Schnittstelle über die das Skript übertragen werden soll.">Wählen Sie die Schnittstelle über die das Skript übertragen werden soll.</entry>
<entry key="&lt;html&gt;Diese Funktion sollte nur auf Aufforderung durch den Support ausgeführt werden.&lt;br/&gt;Soll der Snapshot Index auf dem Gerät wirklich zurückgesetzt werden?&lt;/html&gt;">&lt;html&gt;Diese Funktion sollte nur auf Aufforderung durch den Support ausgeführt werden.&lt;br/&gt;Soll der Snapshot Index auf dem Gerät wirklich zurückgesetzt werden?&lt;/html&gt;</entry>
<entry key="warning.selftest">warning.selftest</entry>
<entry key="Intervall 3 basiert auf Tageszeit">Intervall 3 basiert auf Tageszeit</entry>
<entry key="Z">Z</entry>
<entry key="warning.title.selftest">warning.title.selftest</entry>
<entry key="LOGIK = A and B">LOGIK = A and B</entry>
<entry key="ARITHEMTIK = B">ARITHEMTIK = B</entry>
<entry key="ARITHEMTIK = A">ARITHEMTIK = A</entry>
<entry key="A != B">A != B</entry>
<entry key="name">name</entry>
<entry key="Invertiert">Invertiert</entry>
<entry key="Kanal">Kanal</entry>
<entry key="B">B</entry>
<entry key="A">A</entry>
<entry key="ARITHEMTIK = 1">ARITHEMTIK = 1</entry>
<entry key="ARITHEMTIK = 0">ARITHEMTIK = 0</entry>
<entry key="Immer">Immer</entry>
<entry key="Ausgangswert Z">Ausgangswert Z</entry>
<entry key="A != 0">A != 0</entry>
<entry key="Beschreibung:">Beschreibung:</entry>
<entry key="Intervall 1 basiert auf Tageszeit">Intervall 1 basiert auf Tageszeit</entry>
<entry key="Signalfilter">Signalfilter</entry>
<entry key="Bezeichnung">Bezeichnung</entry>
<entry key="Intervall 3:">Intervall 3:</entry>
<entry key="tooltip.intervall">tooltip.intervall</entry>
<entry key="Tageszeitabhängigkeit:">Tageszeitabhängigkeit:</entry>
<entry key="Verbindung">Verbindung</entry>
<entry key="tooltip.tagesbasierte.intervalle">tooltip.tagesbasierte.intervalle</entry>
<entry key="Nur nach Rücksprache mit Support:">Nur nach Rücksprache mit Support:</entry>
<entry key="Passiver Schalter">Passiver Schalter</entry>
<entry key="Skriptelement bearbeiten">Skriptelement bearbeiten</entry>
<entry key="OK">OK</entry>
<entry key="Wählen Sie die Schnittstelle über die das Skript empfangen werden soll.">Wählen Sie die Schnittstelle über die das Skript empfangen werden soll.</entry>
<entry key="LOGIK = A xor B">LOGIK = A xor B</entry>
<entry key="Der Selbsttest für Zähler #%d war erfolgreich.">Der Selbsttest für Zähler #%d war erfolgreich.</entry>
<entry key="Eingangswert B">Eingangswert B</entry>
<entry key="Eingangswert A">Eingangswert A</entry>
<entry key="Intervall 2:">Intervall 2:</entry>
<entry key="LOGIK = not B">LOGIK = not B</entry>
<entry key="LOGIK = not A">LOGIK = not A</entry>
<entry key="Formeln">Formeln</entry>
<entry key="Es konnte kein Skript vom gerät empfangen werden.">Es konnte kein Skript vom gerät empfangen werden.</entry>
<entry key="Operation">Operation</entry>
<entry key="Bezeichnung:">Bezeichnung:</entry>
<entry key="Wollen Sie wirklich alle Zählerstände auf 0 zurücksetzen?">Wollen Sie wirklich alle Zählerstände auf 0 zurücksetzen?</entry>
<entry key="Der Selbsttest für Zähler #%d ist fehlgeschlagen.">Der Selbsttest für Zähler #%d ist fehlgeschlagen.</entry>
</properties>

BIN
postgresql-9.1-901.jdbc4.jar

Binary file not shown.

3
src/org/hwo/pulscounter/AbstractPulsCounterApplicationListener.java

@ -2,9 +2,6 @@ package org.hwo.pulscounter;
public abstract class AbstractPulsCounterApplicationListener implements PulsCounterApplicationListener {
@Override
public void serialPortChanged() {
}
}

19
src/org/hwo/pulscounter/Application.java

@ -0,0 +1,19 @@
package org.hwo.pulscounter;
import static org.hwo.logging.Logging.log;
import org.hwo.logging.LogLevel;
import org.hwo.logging.Logging;
public class Application {
public static void main(String[] args) {
Logging.Init(args, "synololog.log");
PulsCounterApplication application = new PulsCounterApplication(args);
log(LogLevel.INFO,"Application initialized, starting up user interface");
application.start();
}
}

244
src/org/hwo/pulscounter/DeviceTester.java

@ -0,0 +1,244 @@
package org.hwo.pulscounter;
import org.hwo.i18n.Messages;
import org.hwo.pulscounter.device.IDeviceConnector;
import static org.hwo.logging.Logging.*;
import java.util.Arrays;
import static org.hwo.logging.LogLevel.*;
public class DeviceTester extends Thread{
private IDeviceConnector device;
public DeviceTester(IDeviceConnector device){
this.device = device;
}
@Override
public void run() {
prepare();
try {
if (fullTest()){
PulsCounterApplication.getApplication().message(String.format(
Messages.getString("Der Selbsttest für Zähler #%d war erfolgreich."),
device.getDeviceSerial()
));
} else {
PulsCounterApplication.getApplication().message(String.format(
Messages.getString("Der Selbsttest für Zähler #%d ist fehlgeschlagen."),
device.getDeviceSerial()
));
}
} catch (Exception e){
log(ERROR,"Exception while testing device");
log(e);
}
unprepare();
}
private void sleep(int ms){
try {
Thread.sleep(ms);
} catch (InterruptedException e){
log(e);
}
}
public boolean fullTest(){
if (!setIncrements(1))
return false;
if (!setPullups(false))
return false;
sleep( 50 );
if (!setOutputs(false))
return false;
sleep( 50 );
if (!setInverts(false))
return false;
sleep( 50 );
if (!setCounters(999999))
return false;
sleep( 50 );
if (!setCounters(0))
return false;
sleep( 50 );
for (int i=0;i<10;i++){
if (!setInverts(true))
return false;
sleep( 50 );
if (!setInverts(false))
return false;
sleep( 50 );
}
if (!checkCounters(10))
return false;
for (int i=0;i<10;i++){
if (!setPullups(true))
return false;
sleep( 50 );
if (!setPullups(false))
return false;
sleep( 50 );
}
sleep( 500 );
if (!checkCounters(20))
return false;
if (!setPullups(true))
return false;
sleep( 50 );
for (int i=0;i<10;i++){
if (!setOutputs(true))
return false;
sleep( 50 );
if (!setOutputs(false))
return false;
sleep( 50 );
}
if (!checkCounters(30))
return false;
if (!setPullups(false))
return false;
return true;
}
public void prepare(){
device.escape(IDeviceConnector.ESC_PREPARE_DEVICETEST, 0);
try {
Thread.sleep(250);
} catch (InterruptedException e){
log(e);
}
}
public void unprepare(){
device.escape(IDeviceConnector.ESC_UNPREPARE_DEVICETEST, 0);
}
public boolean setPullups(boolean on){
int set,act;
set = on ? 0xFFFFFFFF : 0;
device.setPullups(set);
act = device.getPullups();
log(INFO,"setPullups(%s): Result: %s",on,(act==set));
return (set == act);
}
public boolean setOutputs(boolean on){
int set,act;
set = on ? 0xFFFFFFFF : 0;
device.setOutputs(set);
act = device.getOutputs();
log(INFO,"setOutputs(%s): Result: %s",on,(act==set));
return (set == act);
}
public boolean setInverts(boolean on){
int set,act;
set = on ? 0xFFFFFFFF : 0;
device.setInverts(set);
act = device.getInverts();
log(INFO,"setInverts(%s): Result: %s",on,(act==set));
return (set == act);
}
public boolean setCounters(int set){
boolean success = true;
int[] _set = new int[32];
int[] _act = new int[32];
Arrays.fill(_set, set);
device.setCounters(_set);
_act = device.getCounters();
for (int i=0;i<32;i++){
if (_set[i] != _act[i]){
success = false;
log(INFO,"Setting Channel Counter %d failed [%d!=%d]",i,_set[i],_act[i]);
}
}
return success;
}
public boolean setIncrements(int set){
boolean success = true;
int[] _set = new int[32];
int[] _act = new int[32];
Arrays.fill(_set, set);
device.setIncrements(_set);
_act = device.getIncrements();
for (int i=0;i<32;i++){
if (_set[i] != _act[i]){
success = false;
log(INFO,"Setting Channel Counter Increment %d failed",i);
}
}
return success;
}
public boolean checkCounters(int check){
boolean success = true;
int[] _check = new int[32];
int[] _act = new int[32];
Arrays.fill(_check, check);
_act = device.getCounters();
for (int i=0;i<32;i++){
if (_check[i] != _act[i]){
success = false;
log(INFO,"Check Channel Counter %d failed (0x%08x != 0x%08x)",i,check,_act[i]);
}
}
return success;
}
}

132
src/org/hwo/pulscounter/ExportSetting.java

@ -8,6 +8,8 @@ import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import org.hwo.ObjectTable;
import org.hwo.ObjectTable.ObjectSet;
import org.hwo.configuration.ConfigurableAttribute;
import org.hwo.configuration.ConfigurableObject;
import org.hwo.csv.CSV;
@ -17,6 +19,10 @@ import org.hwo.interactiveobjects.ObjectEditorUI;
import org.hwo.models.TableMapper.TableColumn;
import org.hwo.pulscounter.ui.ExportSettingsEditorDialog;
import static org.hwo.logging.Logging.*;
import static org.hwo.logging.LogLevel.*;
@ObjectEditorUI(editor=ExportSettingsEditorDialog.class)
@ConfigurableObject
public class ExportSetting {
@ -113,90 +119,82 @@ public class ExportSetting {
this.recordDelta = recordDelta;
}
private String calculateFileName(String filename,SnapShot ss){
Date d = new Date(((long)ss.getTimestamp())*1000);
private String calculateFileName(String filename, ObjectSet row, int deviceSerial){
Date d = new Date(((long)row.getInteger(0))*1000);
Calendar c = Calendar.getInstance();
c.setTime(d);
return filename
filename = filename
.replaceAll("\\%S", String.format("%d", deviceSerial))
.replaceAll("\\%Y", String.format("%04d", new Integer(c.get(Calendar.YEAR))))
.replaceAll("\\%M", String.format("%02d", new Integer(c.get(Calendar.MONTH)+1)))
.replaceAll("\\%D", String.format("%02d", new Integer(c.get(Calendar.DAY_OF_MONTH))));
.replaceAll("\\%D", String.format("%02d", new Integer(c.get(Calendar.DAY_OF_MONTH))))
.replaceAll("\\%h", String.format("%02d", new Integer(c.get(Calendar.HOUR))))
.replaceAll("\\%m", String.format("%02d", new Integer(c.get(Calendar.MINUTE))))
.replaceAll("\\%s", String.format("%02d", new Integer(c.get(Calendar.SECOND))));
// log(DEBUG, "exportFileName for Snapshot %s from [%s: %04d-%02d-%02d %02d:%02d:%02d] is %s", ss, ss.getDeviceSerial(), c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH), c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE), c.get(Calendar.SECOND),filename);
return filename;
}
public void export(){
SnapshotManager ssm = PulsCounter2Application.getApplication().getSnapshotManager();
Hashtable<String, CSV> hash = new Hashtable<String, CSV>();
for (int n=0;n<ssm.size();n++){
SnapShot ss = ssm.loadSnapShot(n);
String fn = calculateFileName(fileName, ss);
if ((triggerType==TriggerType.ALL)||(ss.getTriggerType()==triggerType)){
if (triggerSource.equals(-1) || triggerSource.equals(ss.getSource())){
if (!hash.containsKey(fn)){
hash.put(fn, new CSV());
if (extended){
hash.get(fn).getRecords().add(new CSVRecord(new Object[]{
"Zeitstempel", "Datum/Zeit", "Trigger", "Quelle",
"CH0","CH1","CH2","CH3","CH4","CH5","CH6","CH7",
"CH8","CH9","CH10","CH11","CH12","CH13","CH14","CH15",
"CH16","CH17","CH18","CH19","CH20","CH21","CH22","CH23",
"CH24","CH25","CH26","CH27","CH28","CH29","CH30","CH31",
"AN0","AN1","AN2","AN3","AN4","AN5","AN6","AN7"}));
} else {
hash.get(fn).getRecords().add(new CSVRecord(new Object[]{
"Datum/Zeit",
"CH0","CH1","CH2","CH3","CH4","CH5","CH6","CH7",
"CH8","CH9","CH10","CH11","CH12","CH13","CH14","CH15",
"CH16","CH17","CH18","CH19","CH20","CH21","CH22","CH23",
"CH24","CH25","CH26","CH27","CH28","CH29","CH30","CH31",
"AN0","AN1","AN2","AN3","AN4","AN5","AN6","AN7"}));
}
}
hash.get(fn).getRecords().add(ss.getCSVRecord(extended));
}
}
}
for (String fn: hash.keySet()){
for (int deviceSerial: PulsCounterApplication.getApplication().getDatabase().getKnownDevices()){
ObjectTable ot = PulsCounterApplication.getApplication().getDatabase().getSnapshotsAsTable(deviceSerial);
if (recordDelta){
CSV csv = hash.get(fn);
if (!csv.getRecords().isEmpty()){
Iterator<CSVRecord> iter = csv.getRecords().iterator();
iter.next();
CSVRecord n = iter.next();
Integer[] vals = new Integer[32];
for (int i=0;i<32;i++){
vals[i] = n.getIntegerValue(extended ? i + 4 : i + 1 );
}
while (iter.hasNext()){
n = iter.next();
PulsCounterApplication.getApplication().getDatabase().calulateTableDeltas(ot);
}
Hashtable<String, CSV> hash = new Hashtable<String, CSV>();
int[] simpleSelection = new int[]{
1,
4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,
36,37,38,39,40,41,42,43
};
for (ObjectSet row: ot.getRows()){
String fn = calculateFileName(fileName, row, deviceSerial);
if ((triggerType==TriggerType.ALL)||(triggerType.getValue().equals(row.getInteger(2)))){
if (triggerSource.equals(-1) || triggerSource.equals( row.getInteger(3) )){
for (int i=0;i<32;i++){
Integer v = n.getIntegerValue(extended ? i + 4 : i + 1 );
n.setValue(extended ? i + 4 : i + 1 , v - vals[i]);
vals[i] = v;
if (!hash.containsKey(fn)){
hash.put(fn, new CSV());
if (extended){
hash.get(fn).getRecords().add(new CSVRecord(new Object[]{
"Zeitstempel", "Datum/Zeit", "Trigger", "Quelle",
"CH0","CH1","CH2","CH3","CH4","CH5","CH6","CH7",
"CH8","CH9","CH10","CH11","CH12","CH13","CH14","CH15",
"CH16","CH17","CH18","CH19","CH20","CH21","CH22","CH23",
"CH24","CH25","CH26","CH27","CH28","CH29","CH30","CH31",
"AN0","AN1","AN2","AN3","AN4","AN5","AN6","AN7"}));
} else {
hash.get(fn).getRecords().add(new CSVRecord(new Object[]{
"Datum/Zeit",
"CH0","CH1","CH2","CH3","CH4","CH5","CH6","CH7",
"CH8","CH9","CH10","CH11","CH12","CH13","CH14","CH15",
"CH16","CH17","CH18","CH19","CH20","CH21","CH22","CH23",
"CH24","CH25","CH26","CH27","CH28","CH29","CH30","CH31",
"AN0","AN1","AN2","AN3","AN4","AN5","AN6","AN7"}));
}
}
hash.get(fn).getRecords().add(new CSVRecord( extended ? row.getValues() : row.selectColums(simpleSelection)));
}
csv.getRecords().remove(1);
}
}
for (String fn: hash.keySet()){
hash.get(fn).saveToFile(new File(path,fn));
}
hash.get(fn).saveToFile(new File(path,fn));
}
}

4
src/org/hwo/pulscounter/NewPulsCounterDevice.java

@ -19,8 +19,8 @@ import org.hwo.io.SerialPort;
import org.hwo.io.SerialPortExeption;
import org.hwo.io.NewSerialPort.NewSerialPort;
import org.hwo.servicelink.ServiceLink;
import org.hwo.servicelink.ServiceLinkException;
import org.hwo.servicelink.ServiceLinkRequestFailedException;
import org.hwo.servicelink.exceptions.ServiceLinkException;
import org.hwo.servicelink.exceptions.ServiceLinkRequestFailedException;
public class NewPulsCounterDevice implements IPulsCounter {
private ServiceLink serviceLink;

231
src/org/hwo/pulscounter/PulsCounter2Application.java

@ -1,231 +0,0 @@
package org.hwo.pulscounter;
import java.io.FileNotFoundException;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
import org.hwo.configuration.ConfigurableObjects;
import org.hwo.io.SerialPort;
import org.hwo.io.NewSerialPort.NewSerialPort;
import org.hwo.servicelink.ServiceLink;
import org.hwo.servicelink.ServiceLinkListener;
import org.hwo.tasklet.TaskletManager;
import org.hwo.pulscounter.SnapshotManager.Notification;
import org.hwo.pulscounter.ui.AppSettingsListener;
import org.hwo.scheduler.Scheduler;
public class PulsCounter2Application implements ServiceLinkListener{
static PulsCounter2Application _application;
public static PulsCounter2Application getApplication(){
if (_application == null)
_application = new PulsCounter2Application();
return _application;
}
private NewSerialPort serialPort;
private ServiceLink serviceLink;
private List<AppSettingsListener> appSettingsListeners;
private List<PulsCounterApplicationListener> applicationListeners;
private boolean snapshotLock;
private Vector<String> unseenMessages;
private SnapshotManager snapshotManager;
private List<ExportSetting> exportSettings;
private Scheduler scheduler;
public PulsCounter2Application() {
appSettingsListeners = new LinkedList<AppSettingsListener>();
applicationListeners = new LinkedList<PulsCounterApplicationListener>();
unseenMessages = new Vector<String>();
exportSettings = new LinkedList<ExportSetting>();
scheduler = new Scheduler();
loadPrefs();
try {
snapshotManager = new SnapshotManager();
snapshotManager.notify(Notification.INITIALIZE);
} catch (FileNotFoundException e){
e.printStackTrace();
}
}
public void addAppSettingsListener(AppSettingsListener listener){
appSettingsListeners.add(listener);
}
public void removeAppSettingsListener(AppSettingsListener listener){
appSettingsListeners.remove(listener);
}
public void addPulsCounterApplicationListener(PulsCounterApplicationListener listener){
applicationListeners.add(listener);
}
public void removePulsCounterApplicationListener(PulsCounterApplicationListener listener){
applicationListeners.remove(listener);
}
public void fireServiceLinkChanged(){
for (AppSettingsListener l: appSettingsListeners){
l.ServiceLinkChanged(serviceLink);
}
}
public void fireSerialPortChanged(){
for (PulsCounterApplicationListener listener: applicationListeners){
listener.serialPortChanged();
}
}
public void fireConnectionStateChanged(){
fireConnectionStateChanged(getServiceLink().isOpen());
}
public void fireConnectionStateChanged(Boolean connected){
for (PulsCounterApplicationListener listener: applicationListeners){
listener.connectionStateChanged(connected);
}
}
public void message(String message){
if (applicationListeners.size() == 0){
unseenMessages.addElement(message);
} else {
while (!unseenMessages.isEmpty()){
String msg = unseenMessages.remove(0);
for (PulsCounterApplicationListener listener: applicationListeners){
listener.messageArrived(msg);
}
}
for (PulsCounterApplicationListener listener: applicationListeners){
listener.messageArrived(message);
}
};
}
public synchronized NewSerialPort getSerialPort() {
if (serialPort == null){
serialPort = new NewSerialPort("COM1:");
}
return serialPort;
}
public synchronized void setSerialPort(NewSerialPort serialPort) {
if (serviceLink != null){
serviceLink.close();
serviceLink = null;
}
this.serialPort = serialPort;
getServiceLink();
fireServiceLinkChanged();
fireSerialPortChanged();
}
public synchronized ServiceLink getServiceLink() {
if (serviceLink == null){
serviceLink = new ServiceLink(getSerialPort());
serviceLink.getSerialPort().setTimeOut(200);
serviceLink.addServiceLinkListener(this);
}
return serviceLink;
}
public synchronized void setServiceLink(ServiceLink serviceLink) {
if (serviceLink != null){
serviceLink.close();
}
this.serviceLink = serviceLink;
fireServiceLinkChanged();
}
private Preferences getPreferencesNode(){
return Preferences.userNodeForPackage(getClass());
}
public void savePrefs(){
Preferences prefs = getPreferencesNode();
if (serialPort != null)
prefs.put("io.port", serialPort.getPortName());
System.out.println(String.format("savePrefs(): %d exportSettings werden gesichert.", exportSettings.size()));
if (exportSettings.size()>0)
{
for (int n=0;n<exportSettings.size();n++){
prefs.put(String.format("export.configuration.%d", n), ConfigurableObjects.getConfiguration(exportSettings.get(n)));
}
prefs.putInt("export.configurations", exportSettings.size());
};
try {
prefs.flush();
} catch (BackingStoreException e)
{
e.printStackTrace();
}
}
private void loadPrefs(){
Preferences prefs = getPreferencesNode();
String sn = prefs.get("io.port", null);
if (sn != null){
NewSerialPort nsp = new NewSerialPort(sn);
setSerialPort(nsp);
}
exportSettings.clear();
int nESC = prefs.getInt("export.configurations", 0);
for (int n=0;n<nESC;n++){
ExportSetting es = new ExportSetting();
ConfigurableObjects.setConfiguration(es, prefs.get(String.format("export.configuration.%d", n), ""));
exportSettings.add(es);
}
System.out.println(String.format("loadPrefs(): %d exportSettings geladen.", nESC));
}
@Override
public void connectionStateChanged(Boolean connected) {
fireConnectionStateChanged(connected);
}
public SnapshotManager getSnapshotManager() {
return snapshotManager;
}
public List<ExportSetting> getExportSettings() {
return exportSettings;
}
public void shutdown(){
System.err.println("Shutting down...");
this.scheduler.shutdown();
this.snapshotManager.doShutdown();
TaskletManager.instance().shutdown();
this.getServiceLink().close();
}
}

560
src/org/hwo/pulscounter/PulsCounterApplication.java

@ -0,0 +1,560 @@
package org.hwo.pulscounter;
import static org.hwo.logging.Logging.log;
import static org.hwo.logging.LogLevel.*;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Frame;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.InvalidPropertiesFormatException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.Vector;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
import javax.swing.JFrame;
import org.hsqldb.persist.EventLogInterface;
import org.hwo.StringHelper;
import org.hwo.configuration.ConfigurableObjects;
import org.hwo.i18n.Messages;
import org.hwo.io.NewSerialPort.NewSerialPort;
import org.hwo.logging.Logging;
import org.hwo.platform.Platform;
import org.hwo.servicelink.ServiceLink;
import org.hwo.servicelink.ServiceLinkListener;
import org.hwo.pulscounter.db.PulsCounterDatabase;
import org.hwo.pulscounter.device.IDeviceConnector;
import org.hwo.pulscounter.device.ServiceLinkDeviceConnector;
import org.hwo.pulscounter.device.SimpleLinkDeviceConnector;
import org.hwo.pulscounter.device.SimulatedCounter;
import org.hwo.pulscounter.ui.AppSettingsListener;
import org.hwo.pulscounter.ui.BatchRunner;
import org.hwo.pulscounter.ui.NewMainWindow;
import org.hwo.pulscounter.ui.ShutdownNotification;
import org.hwo.scheduler.Scheduler;
public class PulsCounterApplication implements ServiceLinkListener{
static PulsCounterApplication _application;
public static PulsCounterApplication getApplication(){
if (_application == null)
_application = new PulsCounterApplication(null);
return _application;
}
private Properties applicationConfiguration,
defaultConfiguration;
private Object uiSynchronization;
private boolean uiIsFinished;
private boolean shouldSaveConfiguration;
private boolean dontLoadTranslations;
private List<PulsCounterApplicationListener>
applicationListeners;
private Vector<String> unseenMessages;
private List<Class<IDeviceConnector>>
interfaceClasses;
private List<IDeviceConnector> interfaces;
private PulsCounterDatabase database;
private List<String> batchCommands;
private NewSerialPort serialPort;
private ServiceLink serviceLink;
private List<AppSettingsListener> appSettingsListeners;
private boolean snapshotLock;
private List<ExportSetting> exportSettings;
private Scheduler scheduler;
private String[] channelDescriptions;
public PulsCounterApplication(String[] args) {
/* Initialize Logging Framework */
logStartup();
/* Check... */
if (_application != null){
throw new InstantiationError("Only one Instance of PulsCounterApplication can exist!");
} else {
_application = this;
}
/* Initialize fields... */
uiIsFinished = false;
uiSynchronization = new Object();
applicationListeners = new LinkedList<PulsCounterApplicationListener>();
unseenMessages = new Vector<String>();
exportSettings = new ArrayList<>();
interfaceClasses = new ArrayList<>();
interfaces = new ArrayList<>();
batchCommands = new ArrayList<>();
/* Prepare Translation Framework */
Messages i18n = Messages.getInstance();
i18n.setMissingKeysFileName("missing-translation.txt");
/* Prepare for Startup */
loadApplicationConfiguration();
/* Parse Command Line Arguments */
Iterator<String> options = Arrays.asList(args).iterator();
while (options.hasNext()){
String option = options.next();
switch (option){
case "--gui":
if (!options.hasNext()){
log(FATAL,"Argument to --gui is missing");
throw new IllegalArgumentException("Argument to --gui is missing");
} else {
applicationConfiguration.setProperty("ui.class", options.next());
}
break;
case "--batch":
case "-B":
applicationConfiguration.setProperty("ui.class", BatchRunner.class.getCanonicalName());
break;
case "-G":
applicationConfiguration.setProperty("ui.class", NewMainWindow.class.getCanonicalName());
break;
case "--batch-execute":
batchCommands.add( options.next() );
break;
case "--no-translation":
dontLoadTranslations = true;
break;
default:
log(WARN,"Unknown command line parameter: %s", option);
}
}
if (!dontLoadTranslations){
Messages.loadMessages(PulsCounterApplication.class);
} else {
log(INFO,"Translation text fragments are NOT loaded, due to command line switch (--no-translation)");
}
/* Old stuff... */
// this.initialize();
}
private Properties createDefaultApplicationConfiguration(){
defaultConfiguration = new Properties();
defaultConfiguration.setProperty("ui.class", NewMainWindow.class.getCanonicalName());
defaultConfiguration.setProperty("interface.classes", StringHelper.join(new String[]{
ServiceLinkDeviceConnector.class.getCanonicalName(),
SimulatedCounter.class.getCanonicalName(),
SimpleLinkDeviceConnector.class.getCanonicalName()
}, ","));
return defaultConfiguration;
}
private void loadApplicationConfiguration(){
createDefaultApplicationConfiguration();
applicationConfiguration = new Properties(defaultConfiguration);
try {
/* Try to load configuration from file */
FileInputStream fis = new FileInputStream("synololog.cfg");
applicationConfiguration.loadFromXML(fis);
fis.close();
} catch (InvalidPropertiesFormatException e) {
log(WARN,"synololog.cfg is misformated");
} catch (FileNotFoundException e) {
log(WARN,"synololog.cfg not found");
} catch (IOException e) {
log(ERROR,"I/O Error reading synololog.cfg");
}
applicationConfiguration.setProperty("ui.class", NewMainWindow.class.getCanonicalName());
}
public Properties getApplicationConfiguration(){
return this.applicationConfiguration;
}
private static void logStartup(){
log("Synololog Application Startup");
log("JAVA Environment: %s (%s)", System.getProperty("java.version"),
System.getProperty("java.vendor"));
log("Operating System: %s [%s] %s", System.getProperty("os.name"),
System.getProperty("os.arch"),
System.getProperty("os.version"));
log("User Environment: %s (%s) (CWD:%s)", System.getProperty("user.name"),
System.getProperty("user.home"),
System.getProperty("user.dir"));
log("Hostname: %s",Platform.getHostName());
log("OS Search Path: %s", System.getenv("PATH"));
}
public String[] getBatchCommands(){
return batchCommands.toArray(new String[0]);
}
public void start(){
initialize();
String uiClassName = applicationConfiguration.getProperty("ui.class");
Object ui = null;
try {
Class uiClazz = PulsCounterApplication.class.getClassLoader().loadClass(uiClassName);
Constructor<?> constructor = uiClazz.getConstructor(PulsCounterApplication.class);
ui = (Object) constructor.newInstance(this);
} catch (ClassNotFoundException e) {
log(FATAL,"user interface class could not be loaded [%s] %s",uiClassName,e.getMessage());
} catch (NoSuchMethodException e) {
log(FATAL,"user interface class misses valid constructor [%s] %s",uiClassName,e.getMessage());
} catch (SecurityException e) {
e.printStackTrace();
} catch (Exception e) {
log(FATAL,"user interface class could not be instantiated. [%s] %s",uiClassName,e.getMessage());
e.printStackTrace();
}
waitUiFinished();
// ShutdownNotification sn = new ShutdownNotification();
// if (Component.class.isInstance(ui)){
// sn.setLocationRelativeTo((Component)ui);
// }
// sn.setVisible(true);
try {
shutdown();
} catch (Exception e){
log(e);
}
// sn.setVisible(false);
}
private void initialize(){
/* Interface Classes should be merged with application well known*/
HashSet<String> interfaceClassNames = new HashSet<>();
for (String icn: applicationConfiguration.getProperty("interface.classes").split(",")){
interfaceClassNames.add(icn);
}
for (String icn: defaultConfiguration.getProperty("interface.classes").split(",")){
interfaceClassNames.add(icn);
}
for (String interfaceClassName: interfaceClassNames){
try {
Class<IDeviceConnector> clazz = (Class<IDeviceConnector>)PulsCounterApplication.class.getClassLoader().loadClass(interfaceClassName);
interfaceClasses.add(clazz);
} catch (ClassNotFoundException e) {
log(ERROR,"Interface class could not be loaded: %s",interfaceClassName);
}
}
Integer nIntf = Integer.parseInt(applicationConfiguration.getProperty("interfaces.n","0"));
for (int n=0;n<nIntf;n++){
Class<IDeviceConnector> clazz = getInterfaceClass(applicationConfiguration.getProperty(String.format("interfaces.%d.class",n)));
addInterface(clazz, applicationConfiguration.getProperty(String.format("interfaces.%d.settings",n)));
}
database = new PulsCounterDatabase();
log(INFO,"Database Schema Version: %s", database.getSchemaVersion());
String sProfiles = database.getProperty("export.profiles");
if (sProfiles != null){
Integer nProfiles = new Integer(sProfiles);
for (int n=0;n<nProfiles;n++){
String profileConf = database.getProperty(String.format("export.profiles.%d",n));
log(INFO,"Export Profile %d: %s",n,profileConf);
if (profileConf != null){
ExportSetting es = new ExportSetting();
ConfigurableObjects.setConfiguration(es, profileConf);
exportSettings.add(es);
}
}
}
}
private void shutdown(){
log(INFO,"Application shutdown...");
for (IDeviceConnector c: interfaces){
c.shutdown();
}
/* Dispose all left frames */
for (Frame frame: JFrame.getFrames()){
frame.setVisible(false);
frame.dispose();
}
if (shouldSaveConfiguration){
applicationConfiguration.setProperty("interfaces.n", Integer.toString(interfaces.size()));
for (int n=0;n<interfaces.size();n++){
applicationConfiguration.setProperty(String.format("interfaces.%d.class", n), interfaces.get(n).getClass().getCanonicalName());
applicationConfiguration.setProperty(String.format("interfaces.%d.settings", n), interfaces.get(n).getConnectionSettings());
}
for (int n=0;n<exportSettings.size();n++){
String conf = ConfigurableObjects.getConfiguration(exportSettings.get(n));
if (conf != null){
database.setProperty(String.format("export.profiles.%d", n), conf);
}
}
database.setProperty("export.profiles", new Integer(exportSettings.size()).toString());
try {
log(INFO,"Save application configuration");
FileOutputStream fos = new FileOutputStream("synololog.cfg");
applicationConfiguration.storeToXML(fos, "Synololog Application Configuration");
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
log(ERROR,"synololog.cfg could not be created/opened for writing");
} catch (IOException e) {
log(ERROR,"synololog.cfg could not be written");
}
}
database.close();
Messages.getInstance().saveMissingStrings();
}
private void waitUiFinished(){
synchronized (uiSynchronization) {
while (!uiIsFinished){
try {
uiSynchronization.wait(250);
} catch (InterruptedException e){
log(e);
}
}
}
log(INFO,"UI notified finish");
}
public void notifyUiIsFinished(boolean saveApplicationConfiguration){
synchronized (uiSynchronization) {
uiIsFinished = true;
shouldSaveConfiguration = saveApplicationConfiguration;
uiSynchronization.notify();
}
}
/* Interface Types */
public List<Class<IDeviceConnector>> getInterfaceClasses(){
return this.interfaceClasses;
}
private Class<IDeviceConnector> getInterfaceClass(String className){
for (Class<IDeviceConnector> c:interfaceClasses){
if (c.getCanonicalName().equals(className))
return c;
}
return null;
}
/* Physical Interfaces */
public List<IDeviceConnector> getInterfaces(){
return this.interfaces;
}
public void addInterface(Class<IDeviceConnector> clazz,String connectionSettings){
try {
IDeviceConnector idc = clazz.newInstance();
idc.setConnectionSettings(connectionSettings);
interfaces.add(idc);
fireinterfacesChanged();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
public void removeInterface(IDeviceConnector intf){
interfaces.remove(intf);
fireinterfacesChanged();
}
private void fireinterfacesChanged(){
log(INFO,"interfaces changed");
for (PulsCounterApplicationListener l: applicationListeners){
l.interfacesChanged(this);
}
}
public PulsCounterDatabase getDatabase() {
return database;
}
/* Snapshots */
public void checkForSnapShots(){
for (IDeviceConnector idc: this.interfaces){
Integer deviceSerial = idc.getDeviceSerial();
Integer highestIndex = database.highestSnapShot(deviceSerial);
log(INFO,"Highest known snapshot index for device #%d is %d", deviceSerial, highestIndex);
SnapShot[] snapshots = idc.readSnapShots(highestIndex+1);
if (snapshots != null){
getDatabase().storeSnapshots(snapshots);
}
}
}
public void addSnapshotToDatabase(SnapShot snapShot){
getDatabase().storeSnapshots(new SnapShot[]{ snapShot });
}
/* ToDO: Upgrade the old stuff ... */
/*
private void initialize(){
appSettingsListeners = new LinkedList<AppSettingsListener>();
exportSettings = new LinkedList<ExportSetting>();
scheduler = new Scheduler();
channelDescriptions = new String[32];
loadPrefs();
try {
snapshotManager = new SnapshotManager();
snapshotManager.notify(Notification.INITIALIZE);
} catch (FileNotFoundException e){
e.printStackTrace();
}
}
*/
public void addAppSettingsListener(AppSettingsListener listener){
appSettingsListeners.add(listener);
}
public void removeAppSettingsListener(AppSettingsListener listener){
appSettingsListeners.remove(listener);
}
public void addPulsCounterApplicationListener(PulsCounterApplicationListener listener){
applicationListeners.add(listener);
}
public void removePulsCounterApplicationListener(PulsCounterApplicationListener listener){
applicationListeners.remove(listener);
}
public void fireServiceLinkChanged(){
for (AppSettingsListener l: appSettingsListeners){
l.ServiceLinkChanged(serviceLink);
}
}
public void message(String message){
log(INFO, message);
if (applicationListeners.size() == 0){
unseenMessages.addElement(message);
} else {
while (!unseenMessages.isEmpty()){
String msg = unseenMessages.remove(0);
for (PulsCounterApplicationListener listener: applicationListeners){
listener.messageArrived(msg);
}
}
for (PulsCounterApplicationListener listener: applicationListeners){
listener.messageArrived(message);
}
};
}
@Override
public void connectionStateChanged(Boolean connected) {
}
public List<ExportSetting> getExportSettings() {
return exportSettings;
}
}

6
src/org/hwo/pulscounter/PulsCounterApplicationListener.java

@ -1,9 +1,9 @@
package org.hwo.pulscounter;
public interface PulsCounterApplicationListener {
void serialPortChanged();
void connectionStateChanged(Boolean connected);
void interfaceClassesChanged(PulsCounterApplication pulsCounterApplication);
void interfacesChanged(PulsCounterApplication pulsCounterApplication);
void messageArrived(String message);

98
src/org/hwo/pulscounter/SnapShot.java

@ -2,26 +2,51 @@ package org.hwo.pulscounter;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.UUID;
import org.hwo.csv.CSVRecord;
import org.hwo.models.TableMapper.TableColumn;
import org.hwo.servicelink.ServiceLink;
import org.hwo.servicelink.ServiceLinkException;