914 lines
27 KiB
Java
914 lines
27 KiB
Java
package org.hwo.pulscounter.ui;
|
|
|
|
import java.awt.EventQueue;
|
|
|
|
import javax.swing.JFrame;
|
|
import java.awt.GridBagLayout;
|
|
import java.awt.BorderLayout;
|
|
import javax.swing.JToolBar;
|
|
import javax.swing.JSplitPane;
|
|
import javax.swing.JPanel;
|
|
import java.awt.GridBagConstraints;
|
|
import javax.swing.border.TitledBorder;
|
|
|
|
import org.hwo.Smoother;
|
|
import org.hwo.datetime.DateTime;
|
|
import org.hwo.io.NewSerialPort.NewSerialPort;
|
|
import org.hwo.logging.Logging;
|
|
import org.hwo.platform.Platform;
|
|
import org.hwo.pulscounter.PulsCounter2Application;
|
|
import org.hwo.pulscounter.PulsCounterApplicationListener;
|
|
import org.hwo.pulscounter.SnapshotManager.Notification;
|
|
import org.hwo.servicelink.ServiceLinkException;
|
|
import org.hwo.servicelink.ServiceLinkRequestFailedException;
|
|
import org.hwo.tasklet.Tasklet;
|
|
import org.hwo.tasklet.TaskletListener;
|
|
import org.hwo.tasklet.TaskletManager;
|
|
import org.hwo.ui.dialog.SerialPortChooser;
|
|
import org.omg.CORBA.Environment;
|
|
|
|
import javax.swing.JLabel;
|
|
import javax.swing.JTextField;
|
|
import java.awt.Insets;
|
|
|
|
import javax.swing.DefaultListModel;
|
|
import javax.swing.JButton;
|
|
import java.awt.event.ActionListener;
|
|
import java.awt.event.KeyEvent;
|
|
import java.awt.event.WindowEvent;
|
|
import java.awt.event.WindowListener;
|
|
import java.awt.event.WindowStateListener;
|
|
import java.io.IOException;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Calendar;
|
|
import java.util.Enumeration;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Timer;
|
|
import java.util.TimerTask;
|
|
import java.awt.event.ActionEvent;
|
|
import java.awt.Color;
|
|
import java.awt.Dialog.ModalityType;
|
|
|
|
import javax.swing.JScrollPane;
|
|
import javax.swing.JList;
|
|
import java.awt.Font;
|
|
import javax.swing.SwingConstants;
|
|
import javax.swing.ToolTipManager;
|
|
import javax.swing.UIManager;
|
|
import javax.swing.UnsupportedLookAndFeelException;
|
|
|
|
import java.awt.Dimension;
|
|
import javax.swing.BoxLayout;
|
|
import javax.swing.border.EmptyBorder;
|
|
import javax.swing.JCheckBox;
|
|
import javax.swing.event.ChangeListener;
|
|
import javax.swing.plaf.metal.MetalBorders.ToolBarBorder;
|
|
import javax.swing.event.ChangeEvent;
|
|
import static org.hwo.logging.Logging.log;
|
|
|
|
public class NewMainWindow implements PulsCounterApplicationListener, TaskletListener{
|
|
|
|
private JFrame frmSynolog;
|
|
private JTextField tfSerialPortName;
|
|
private JSplitPane splitter;
|
|
private JButton btnNewButton;
|
|
private JTextField tfConnection;
|
|
private JButton btnSetup;
|
|
|
|
private DefaultListModel<String> messageListModel;
|
|
private JList lMessages;
|
|
|
|
private Timer timerReconnect;
|
|
private JPanel pChannels;
|
|
|
|
private ChannelDisplay[] channelDisplays;
|
|
private JButton btnC;
|
|
private JPanel panel_3;
|
|
private JScrollPane scrollPane_1;
|
|
private JList lTasklets;
|
|
|
|
private DefaultListModel<Tasklet> knownTasklets;
|
|
|
|
private Boolean connected;
|
|
private JButton btnDatenExportieren;
|
|
|
|
private Integer trimTicksOnConnect;
|
|
private Long trimTimeOnConnect;
|
|
private Integer trimDeviceTimeSlice;
|
|
private JCheckBox cbTrimDevice;
|
|
|
|
private Smoother smoothTrim;
|
|
|
|
|
|
/**
|
|
* Launch the application.
|
|
*/
|
|
public static void main(String[] args) {
|
|
|
|
boolean batchRun = false;
|
|
boolean deviceSetup = false;
|
|
String logFileName = "synololog.log";
|
|
|
|
Iterator<String> aiter = Arrays.asList(args).iterator();
|
|
|
|
while (aiter.hasNext()){
|
|
String opt = aiter.next();
|
|
|
|
switch (opt){
|
|
case "-b":
|
|
batchRun = true;
|
|
break;
|
|
case "--device-setup":
|
|
deviceSetup = true;
|
|
batchRun = false;
|
|
break;
|
|
case "--log":
|
|
logFileName = aiter.next();
|
|
break;
|
|
}
|
|
}
|
|
|
|
Logging.setLogFileName(logFileName);
|
|
|
|
logStartup();
|
|
|
|
if (deviceSetup){
|
|
startDeviceSetup();
|
|
} else if (batchRun){
|
|
startBATCH();
|
|
} else {
|
|
startGUI();
|
|
}
|
|
}
|
|
|
|
private static void logStartup(){
|
|
log("%s.logStartup()",NewMainWindow.class.getCanonicalName());
|
|
log("Synololog Java Software 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 static void startGUI(){
|
|
|
|
try {
|
|
// Set cross-platform Java L&F (also called "Metal")
|
|
UIManager.setLookAndFeel(
|
|
UIManager.getCrossPlatformLookAndFeelClassName());
|
|
}
|
|
catch (UnsupportedLookAndFeelException e) {
|
|
// handle exception
|
|
}
|
|
catch (ClassNotFoundException e) {
|
|
// handle exception
|
|
}
|
|
catch (InstantiationException e) {
|
|
// handle exception
|
|
}
|
|
catch (IllegalAccessException e) {
|
|
// handle exception
|
|
}
|
|
|
|
ToolTipManager.sharedInstance().setDismissDelay( 20000 );
|
|
ToolTipManager.sharedInstance().setInitialDelay( 1250 );
|
|
ToolTipManager.sharedInstance().setReshowDelay( 500 );
|
|
|
|
EventQueue.invokeLater(new Runnable() {
|
|
public void run() {
|
|
try {
|
|
NewMainWindow window = new NewMainWindow();
|
|
window.frmSynolog.setVisible(true);
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
public static void startBATCH(){
|
|
|
|
BatchRunner batchRunner = new BatchRunner();
|
|
batchRunner.run();
|
|
|
|
}
|
|
|
|
public static void startDeviceSetup(){
|
|
EventQueue.invokeLater(new Runnable() {
|
|
public void run() {
|
|
try {
|
|
DeviceTestFrame deviceTestFrame = new DeviceTestFrame();
|
|
deviceTestFrame.setVisible(true);
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
/**
|
|
* @wbp.parser.entryPoint
|
|
*/
|
|
public NewMainWindow() {
|
|
initialize();
|
|
|
|
this.connected = false;
|
|
|
|
knownTasklets = new DefaultListModel<Tasklet>();
|
|
lTasklets.setModel(knownTasklets);
|
|
TaskletManager.instance().addTaskletListener(this);
|
|
|
|
messageListModel = new DefaultListModel<String>();
|
|
lMessages.setModel(messageListModel);
|
|
|
|
timerReconnect = new Timer("ReconnectThread",true);
|
|
|
|
application().addPulsCounterApplicationListener(this);
|
|
|
|
application().fireConnectionStateChanged();
|
|
application().fireSerialPortChanged();
|
|
|
|
application().message("Synololog Applikation wurde gestartet.");
|
|
|
|
channelDisplays = new ChannelDisplay[32];
|
|
|
|
for (int i=0;i<32;i++){
|
|
channelDisplays[i] = new ChannelDisplay();
|
|
channelDisplays[i].setChannelName(String.format("%02d",i));
|
|
if (i > 7){
|
|
channelDisplays[i].setAnalog(false);
|
|
}
|
|
GridBagConstraints gbc = new GridBagConstraints();
|
|
gbc.insets = new Insets(2, 2, 2, 2);
|
|
gbc.anchor = GridBagConstraints.NORTHWEST;
|
|
gbc.fill = GridBagConstraints.HORIZONTAL;
|
|
gbc.weightx = 1;
|
|
gbc.weighty = 1;
|
|
gbc.gridx = i & 0x03;
|
|
gbc.gridy = i >> 2;
|
|
|
|
channelDisplays[i].addChannelDisplayListener(new ChannelDisplayListener() {
|
|
|
|
@Override
|
|
public void set(ChannelDisplay sender, int setValue) {
|
|
channelSet(sender, setValue);
|
|
}
|
|
|
|
@Override
|
|
public void reset(ChannelDisplay sender) {
|
|
channelReset(sender);
|
|
}
|
|
});
|
|
|
|
pChannels.add(channelDisplays[i], gbc);
|
|
}
|
|
|
|
timerReconnect.scheduleAtFixedRate(new TimerTask() {
|
|
|
|
@Override
|
|
public void run() {
|
|
updateChannelView();
|
|
}
|
|
}, 5000, 500);
|
|
|
|
timerReconnect.schedule(new TimerTask() {
|
|
|
|
@Override
|
|
public void run() {
|
|
if (application().getServiceLink().isOpen()){
|
|
application().getSnapshotManager().notify(Notification.SYNC);
|
|
}
|
|
}
|
|
}, 15000, 15000);
|
|
|
|
timerReconnect.schedule(new TimerTask() {
|
|
|
|
@Override
|
|
public void run() {
|
|
if (application().getServiceLink().isOpen()){
|
|
if (cbTrimDevice.isSelected()){
|
|
trimDevice();
|
|
}
|
|
syncClock();
|
|
}
|
|
}
|
|
}, 52000, 15000);
|
|
|
|
frmSynolog.addWindowListener(new WindowListener() {
|
|
|
|
@Override
|
|
public void windowOpened(WindowEvent e) {
|
|
// TODO Auto-generated method stub
|
|
|
|
}
|
|
|
|
@Override
|
|
public void windowIconified(WindowEvent e) {
|
|
// TODO Auto-generated method stub
|
|
|
|
}
|
|
|
|
@Override
|
|
public void windowDeiconified(WindowEvent e) {
|
|
// TODO Auto-generated method stub
|
|
|
|
}
|
|
|
|
@Override
|
|
public void windowDeactivated(WindowEvent e) {
|
|
// TODO Auto-generated method stub
|
|
|
|
}
|
|
|
|
@Override
|
|
public void windowClosing(WindowEvent e) {
|
|
// TODO Auto-generated method stub
|
|
|
|
}
|
|
|
|
@Override
|
|
public void windowClosed(WindowEvent e) {
|
|
|
|
}
|
|
|
|
@Override
|
|
public void windowActivated(WindowEvent e) {
|
|
// TODO Auto-generated method stub
|
|
|
|
}
|
|
});
|
|
|
|
}
|
|
|
|
/**
|
|
* Initialize the contents of the frame.
|
|
*/
|
|
private void initialize() {
|
|
frmSynolog = new JFrame();
|
|
frmSynolog.setTitle("Synololog");
|
|
frmSynolog.setBounds(100, 100, 1000, 580);
|
|
frmSynolog.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
frmSynolog.getContentPane().setLayout(new BorderLayout(0, 0));
|
|
frmSynolog.setBackground(Color.WHITE);
|
|
|
|
JToolBar toolBar = new JToolBar();
|
|
toolBar.setBorder(new EmptyBorder(3, 3, 3, 3));
|
|
toolBar.setBackground(Color.WHITE);
|
|
toolBar.setFloatable(false);
|
|
frmSynolog.getContentPane().add(toolBar, BorderLayout.NORTH);
|
|
|
|
btnSetup = new JButton("S");
|
|
btnSetup.addActionListener(new ActionListener() {
|
|
public void actionPerformed(ActionEvent e) {
|
|
AppSettingsFrame asf = new AppSettingsFrame();
|
|
asf.setModalityType(ModalityType.APPLICATION_MODAL);
|
|
|
|
if ((e.getModifiers() & ActionEvent.CTRL_MASK) != 0)
|
|
asf.debugging();
|
|
|
|
asf.setVisible(true);
|
|
}
|
|
});
|
|
btnSetup.setToolTipText("<html>\n<b>Einstellungen</b><br/>\n<br/>\nEinstellungen der Synololog PC Software ändern.\n</html>");
|
|
toolBar.add(btnSetup);
|
|
|
|
btnC = new JButton("C");
|
|
btnC.setToolTipText("<html>\n<b>Konfiguration</b><br/>\n<br/>\nKonfiguration des Synololog bearbeiten.\n</html>");
|
|
btnC.addActionListener(new ActionListener() {
|
|
public void actionPerformed(ActionEvent e) {
|
|
DeviceConfiguration cc = new DeviceConfiguration();
|
|
cc.setVisible(true);
|
|
}
|
|
});
|
|
toolBar.add(btnC);
|
|
|
|
btnDatenExportieren = new JButton("Daten exportieren...");
|
|
btnDatenExportieren.setToolTipText("<html>\n<b>Daten exportieren</b><br/>\n<br/>\nExport definitionen bearbeiten und ausführen.<br/>\nHiermit können die Aufzeichnungsdaten in Textdateien exportiert werden.<br/>\n</html>");
|
|
btnDatenExportieren.addActionListener(new ActionListener() {
|
|
public void actionPerformed(ActionEvent e) {
|
|
ExportFilesFrame eff = new ExportFilesFrame();
|
|
eff.setVisible(true);
|
|
}
|
|
});
|
|
toolBar.add(btnDatenExportieren);
|
|
|
|
splitter = new JSplitPane();
|
|
splitter.setBorder(null);
|
|
splitter.setOneTouchExpandable(true);
|
|
splitter.setResizeWeight(0.6);
|
|
frmSynolog.getContentPane().add(splitter, BorderLayout.CENTER);
|
|
|
|
JPanel panel = new JPanel();
|
|
panel.setBackground(Color.WHITE);
|
|
splitter.setRightComponent(panel);
|
|
GridBagLayout gbl_panel = new GridBagLayout();
|
|
gbl_panel.columnWidths = new int[]{0, 0};
|
|
gbl_panel.rowHeights = new int[]{0, 0, 0, 0, 0, 0, 0};
|
|
gbl_panel.columnWeights = new double[]{1.0, Double.MIN_VALUE};
|
|
gbl_panel.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 1.0, 0.0, Double.MIN_VALUE};
|
|
panel.setLayout(gbl_panel);
|
|
|
|
JPanel panel_1 = new JPanel();
|
|
panel_1.setBackground(Color.WHITE);
|
|
panel_1.setBorder(new TitledBorder(null, "Verbindung", TitledBorder.LEADING, TitledBorder.TOP, null, null));
|
|
GridBagConstraints gbc_panel_1 = new GridBagConstraints();
|
|
gbc_panel_1.insets = new Insets(0, 0, 5, 0);
|
|
gbc_panel_1.anchor = GridBagConstraints.NORTH;
|
|
gbc_panel_1.fill = GridBagConstraints.HORIZONTAL;
|
|
gbc_panel_1.gridx = 0;
|
|
gbc_panel_1.gridy = 0;
|
|
panel.add(panel_1, gbc_panel_1);
|
|
GridBagLayout gbl_panel_1 = new GridBagLayout();
|
|
gbl_panel_1.columnWidths = new int[]{0, 0, 0, 0};
|
|
gbl_panel_1.rowHeights = new int[]{0, 0, 0, 0, 0, 0};
|
|
gbl_panel_1.columnWeights = new double[]{1.0, 1.0, 0.0, Double.MIN_VALUE};
|
|
gbl_panel_1.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
|
|
panel_1.setLayout(gbl_panel_1);
|
|
|
|
JLabel lblAnschluss = new JLabel("Anschluss:");
|
|
GridBagConstraints gbc_lblAnschluss = new GridBagConstraints();
|
|
gbc_lblAnschluss.insets = new Insets(0, 0, 5, 5);
|
|
gbc_lblAnschluss.anchor = GridBagConstraints.WEST;
|
|
gbc_lblAnschluss.gridx = 0;
|
|
gbc_lblAnschluss.gridy = 0;
|
|
panel_1.add(lblAnschluss, gbc_lblAnschluss);
|
|
|
|
tfSerialPortName = new JTextField();
|
|
tfSerialPortName.setToolTipText("<html>\n<b>Ausgewählter Anschluss</b><br/>\n<br/>\nHier wird der momentan gewählte Anschluss gezeigt,<br/>\ndurch den die Software mit dem Synololog kommuniziert.\n</html>");
|
|
tfSerialPortName.setEditable(false);
|
|
GridBagConstraints gbc_tfSerialPortName = new GridBagConstraints();
|
|
gbc_tfSerialPortName.gridwidth = 3;
|
|
gbc_tfSerialPortName.insets = new Insets(0, 0, 5, 0);
|
|
gbc_tfSerialPortName.fill = GridBagConstraints.HORIZONTAL;
|
|
gbc_tfSerialPortName.gridx = 0;
|
|
gbc_tfSerialPortName.gridy = 1;
|
|
panel_1.add(tfSerialPortName, gbc_tfSerialPortName);
|
|
tfSerialPortName.setColumns(10);
|
|
|
|
btnNewButton = new JButton("auswählen...");
|
|
btnNewButton.setToolTipText("<html>\n<b>Auswahl eines anderen Anschlusses</b>\n</html>");
|
|
btnNewButton.addActionListener(new ActionListener() {
|
|
public void actionPerformed(ActionEvent e) {
|
|
chooseSerialPort();
|
|
}
|
|
});
|
|
|
|
cbTrimDevice = new JCheckBox("Trimmung justieren");
|
|
cbTrimDevice.setToolTipText("<html>\n<b>Abgleich der Zeitmessung</b><br/>\n<br/>\nDiese Funktion gleicht die Geschwindigkeit der Echtzeituhr des<br/>\nSynololog mit der des Rechners ab und korrigiert diese Laufzeitdifferenz.<br/>\n<br/>\nHierdurch kann der Synololog auch ohne angeschlossenen Rechner über<br/>\nmehrere Tage hinweg eine genaue Systemzeit vorhalten.<br/>\n<br/>\nDie Trimmung sollte vor allem dann ausgeführt werden, wenn die durchschnittliche<br/>\nUmgebungstemperatur am Einsatzort des Synololog sich stark verändert.\n</html>");
|
|
cbTrimDevice.addActionListener(new ActionListener() {
|
|
public void actionPerformed(ActionEvent e) {
|
|
trimTicksOnConnect = null;
|
|
if (cbTrimDevice.isSelected()){
|
|
trimDevice();
|
|
}
|
|
}
|
|
});
|
|
|
|
GridBagConstraints gbc_cbTrimDevice = new GridBagConstraints();
|
|
gbc_cbTrimDevice.anchor = GridBagConstraints.WEST;
|
|
gbc_cbTrimDevice.insets = new Insets(0, 0, 5, 5);
|
|
gbc_cbTrimDevice.gridx = 0;
|
|
gbc_cbTrimDevice.gridy = 2;
|
|
panel_1.add(cbTrimDevice, gbc_cbTrimDevice);
|
|
GridBagConstraints gbc_btnNewButton = new GridBagConstraints();
|
|
gbc_btnNewButton.insets = new Insets(0, 0, 5, 0);
|
|
gbc_btnNewButton.gridx = 2;
|
|
gbc_btnNewButton.gridy = 2;
|
|
panel_1.add(btnNewButton, gbc_btnNewButton);
|
|
|
|
tfConnection = new JTextField();
|
|
tfConnection.setHorizontalAlignment(SwingConstants.CENTER);
|
|
tfConnection.setText("...");
|
|
tfConnection.setBackground(Color.WHITE);
|
|
tfConnection.setEditable(false);
|
|
GridBagConstraints gbc_tfConnection = new GridBagConstraints();
|
|
gbc_tfConnection.fill = GridBagConstraints.HORIZONTAL;
|
|
gbc_tfConnection.gridwidth = 3;
|
|
gbc_tfConnection.gridx = 0;
|
|
gbc_tfConnection.gridy = 4;
|
|
panel_1.add(tfConnection, gbc_tfConnection);
|
|
tfConnection.setColumns(10);
|
|
|
|
JPanel panel_2 = new JPanel();
|
|
panel_2.setBackground(Color.WHITE);
|
|
panel_2.setBorder(new TitledBorder(null, "Meldungen", TitledBorder.LEADING, TitledBorder.TOP, null, null));
|
|
GridBagConstraints gbc_panel_2 = new GridBagConstraints();
|
|
gbc_panel_2.insets = new Insets(0, 0, 5, 0);
|
|
gbc_panel_2.fill = GridBagConstraints.BOTH;
|
|
gbc_panel_2.gridx = 0;
|
|
gbc_panel_2.gridy = 4;
|
|
panel.add(panel_2, gbc_panel_2);
|
|
GridBagLayout gbl_panel_2 = new GridBagLayout();
|
|
gbl_panel_2.columnWidths = new int[]{142, 0};
|
|
gbl_panel_2.rowHeights = new int[]{3, 0};
|
|
gbl_panel_2.columnWeights = new double[]{1.0, Double.MIN_VALUE};
|
|
gbl_panel_2.rowWeights = new double[]{1.0, Double.MIN_VALUE};
|
|
panel_2.setLayout(gbl_panel_2);
|
|
|
|
JScrollPane scrollPane = new JScrollPane();
|
|
GridBagConstraints gbc_scrollPane = new GridBagConstraints();
|
|
gbc_scrollPane.fill = GridBagConstraints.BOTH;
|
|
gbc_scrollPane.gridx = 0;
|
|
gbc_scrollPane.gridy = 0;
|
|
panel_2.add(scrollPane, gbc_scrollPane);
|
|
|
|
lMessages = new JList();
|
|
lMessages.setFont(new Font("Cantarell", Font.PLAIN, 10));
|
|
scrollPane.setViewportView(lMessages);
|
|
|
|
panel_3 = new JPanel();
|
|
panel_3.setBackground(Color.WHITE);
|
|
panel_3.setBorder(new TitledBorder(null, "Aktive Aufgaben", TitledBorder.LEADING, TitledBorder.TOP, null, null));
|
|
GridBagConstraints gbc_panel_3 = new GridBagConstraints();
|
|
gbc_panel_3.fill = GridBagConstraints.BOTH;
|
|
gbc_panel_3.gridx = 0;
|
|
gbc_panel_3.gridy = 5;
|
|
panel.add(panel_3, gbc_panel_3);
|
|
panel_3.setLayout(new BoxLayout(panel_3, BoxLayout.X_AXIS));
|
|
|
|
scrollPane_1 = new JScrollPane();
|
|
panel_3.add(scrollPane_1);
|
|
|
|
lTasklets = new JList();
|
|
scrollPane_1.setViewportView(lTasklets);
|
|
|
|
pChannels = new JPanel();
|
|
pChannels.setBorder(new EmptyBorder(10, 10, 10, 10));
|
|
pChannels.setBackground(Color.WHITE);
|
|
pChannels.setMinimumSize(new Dimension(600, 10));
|
|
splitter.setLeftComponent(pChannels);
|
|
GridBagLayout gbl_pChannels = new GridBagLayout();
|
|
gbl_pChannels.columnWidths = new int[]{0};
|
|
gbl_pChannels.rowHeights = new int[]{0};
|
|
gbl_pChannels.columnWeights = new double[]{Double.MIN_VALUE};
|
|
gbl_pChannels.rowWeights = new double[]{Double.MIN_VALUE};
|
|
pChannels.setLayout(gbl_pChannels);
|
|
|
|
}
|
|
|
|
private PulsCounter2Application application(){
|
|
return PulsCounter2Application.getApplication();
|
|
}
|
|
|
|
private void chooseSerialPort(){
|
|
SerialPortChooser spc = new SerialPortChooser();
|
|
NewSerialPort nsp = spc.execute( application().getSerialPort().getPortName() );
|
|
if (nsp != null)
|
|
setSerialPort(nsp);
|
|
}
|
|
|
|
private void setSerialPort(NewSerialPort serialPort){
|
|
PulsCounter2Application.getApplication().setSerialPort(serialPort);
|
|
}
|
|
|
|
@Override
|
|
public void serialPortChanged() {
|
|
tfSerialPortName.setText(application().getSerialPort().getPortName());
|
|
}
|
|
|
|
@Override
|
|
public void connectionStateChanged(Boolean connected) {
|
|
if (connected){
|
|
Integer version = application().getServiceLink().getServiceRegisterCache().getCachedInteger(13, 0, 0x001A);
|
|
Integer uptime = application().getServiceLink().getServiceRegisterCache().getCachedInteger(13, 0, 0x0022);
|
|
Integer eesize = application().getServiceLink().getServiceRegisterCache().getCachedInteger(13, 0, 0x9000);
|
|
|
|
if (version != null){
|
|
tfConnection.setText(String.format("Version %d.%d.%d", version >> 16, (version >> 8) & 0xff, version & 0xff));
|
|
tfConnection.setBackground(Color.GREEN);
|
|
tfConnection.setForeground(Color.BLACK);
|
|
|
|
|
|
|
|
application().message(String.format("Synololog verbunden (Version %d.%d.%d) (Uptime: %d:%d:%d)", version >> 16, (version >> 8) & 0xff, version & 0xff, uptime / 3600, (uptime / 60)%60, uptime % 60));
|
|
application().message(String.format("EEPROM Size: 0x%08x Bytes", eesize));
|
|
|
|
trimDeviceTimeSlice = application().getServiceLink().getServiceRegisterCache().getCachedInteger(13, 0, 0x1302);
|
|
|
|
/* Trim helper initialisieren */
|
|
trimTicksOnConnect = null;
|
|
|
|
application().getSnapshotManager().notify(Notification.FULLSYNC);
|
|
|
|
} else {
|
|
tfConnection.setText("Version unbekannt");
|
|
tfConnection.setBackground(Color.YELLOW);
|
|
tfConnection.setForeground(Color.BLACK);
|
|
|
|
application().getServiceLink().close();
|
|
}
|
|
} else {
|
|
tfConnection.setText("Nicht verbunden");
|
|
tfConnection.setBackground(Color.RED);
|
|
tfConnection.setForeground(Color.WHITE);
|
|
|
|
trimTicksOnConnect = null;
|
|
|
|
if (timerReconnect != null){
|
|
timerReconnect.schedule(new TimerTask() {
|
|
|
|
@Override
|
|
public void run() {
|
|
if (!application().getServiceLink().isOpen()){
|
|
try {
|
|
application().getServiceLink().open();
|
|
} catch (ServiceLinkException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
}, 3000);
|
|
}
|
|
|
|
if (this.connected)
|
|
application().message("Verbindung getrennt");
|
|
}
|
|
this.connected = connected;
|
|
|
|
}
|
|
|
|
@Override
|
|
public synchronized void messageArrived(String message) {
|
|
if (EventQueue.isDispatchThread()){
|
|
int pos = messageListModel.size();
|
|
String t = String.format("%s: %s",DateTime.NOW().getSQLDateTime(),message);
|
|
messageListModel.addElement(t);
|
|
lMessages.ensureIndexIsVisible(messageListModel.size()-1);
|
|
} else {
|
|
final String msg = message;
|
|
EventQueue.invokeLater(new Runnable() {
|
|
|
|
@Override
|
|
public void run() {
|
|
messageArrived(msg);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
private void updateChannelView(){
|
|
Integer inputs,outputs,pullups;
|
|
|
|
if (application().getServiceLink().isOpen()){
|
|
|
|
inputs = application().getServiceLink().getServiceRegisterCache().getCachedInteger(13, 0, 0x0681 );
|
|
outputs = application().getServiceLink().getServiceRegisterCache().getCachedInteger(13, 0, 0x0682 );
|
|
pullups = application().getServiceLink().getServiceRegisterCache().getCachedInteger(13, 0, 0x0683 );
|
|
|
|
if (inputs == null)
|
|
inputs = 0;
|
|
if (outputs == null)
|
|
outputs = 0;
|
|
if (pullups == null)
|
|
pullups = 0;
|
|
|
|
Integer[] values = new Integer[32];
|
|
Float[] analog = new Float[8];
|
|
|
|
for (int i=0;i<32;i++){
|
|
values[i] = application().getServiceLink().getServiceRegisterCache().getCachedInteger(13, 0, 0x0600 + i);
|
|
|
|
if (i<8){
|
|
analog[i] = application().getServiceLink().getServiceRegisterCache().getCachedFloat(13, 0, 0x8000 + i ) * 10;
|
|
}
|
|
|
|
};
|
|
|
|
for (int i=0;i<32;i++){
|
|
channelDisplays[i].setInput( (inputs & 1<<i) != 0 );
|
|
channelDisplays[i].setOutput( (outputs & 1<<i) != 0);
|
|
channelDisplays[i].setPullup( (pullups & 1<<i) != 0);
|
|
channelDisplays[i].setCounter(values[i]);
|
|
|
|
if (i<8){
|
|
channelDisplays[i].setVoltage(new Double(analog[i]));
|
|
}
|
|
}
|
|
|
|
Calendar calendar = Calendar.getInstance();
|
|
|
|
|
|
|
|
try {
|
|
Integer deviceTime = application().getServiceLink().readInt(13, 0, 0x001C);
|
|
Long delta = deviceTime - (System.currentTimeMillis()/1000);
|
|
|
|
if ((delta < -1) || (delta > 1)){
|
|
application().message(String.format("Abweichung ist %d Sekunde(-n)",delta));
|
|
application().getServiceLink().writeInt((byte)13, (byte)0, 0x001C, (int)(calendar.getTimeInMillis() / 1000L));
|
|
application().message("Uhr der Elektronik wurde korrigiert.");
|
|
|
|
}
|
|
} catch (ServiceLinkRequestFailedException e) {
|
|
e.printStackTrace();
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
} catch (ServiceLinkException e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
checkForAssertions();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
private Integer syncClock(){
|
|
return null;
|
|
}
|
|
|
|
private Integer trimDevice(){
|
|
try {
|
|
|
|
if (trimTicksOnConnect != null){
|
|
long s1,s2,T;
|
|
Integer device_us;
|
|
|
|
|
|
s1 = System.currentTimeMillis();
|
|
device_us = application().getServiceLink().readInt(13, 0, 0x1300);
|
|
s2 = System.currentTimeMillis();
|
|
T = (s1+s2)>>1;
|
|
|
|
if (device_us < 0){
|
|
trimTicksOnConnect = null;
|
|
} else {
|
|
long elapsed_us;
|
|
long diff_us;
|
|
long trim_ns_per_slice;
|
|
|
|
elapsed_us = (T - trimTimeOnConnect) * 1000;
|
|
diff_us = elapsed_us - device_us;
|
|
|
|
System.err.println(String.format("Device Triming: Elapsed us: Dev: %d PC %d Diff: %d", device_us,elapsed_us,diff_us));
|
|
|
|
trim_ns_per_slice = (diff_us * 1000) * trimDeviceTimeSlice / elapsed_us;
|
|
|
|
smoothTrim.cycle((int)trim_ns_per_slice);
|
|
|
|
System.err.println(String.format("Device Triming: Trim %dns / %dus",smoothTrim.getWert(),trimDeviceTimeSlice));
|
|
|
|
application().getServiceLink().writeInt(13, 0, 0x1002, smoothTrim.getWert());
|
|
|
|
application().message(String.format("Trimmung wurde korrigiert auf %dns / %dus",smoothTrim.getWert(),trimDeviceTimeSlice));
|
|
|
|
}
|
|
} else {
|
|
long s1,s2,T;
|
|
|
|
try {
|
|
trimTicksOnConnect = application().getServiceLink().getServiceRegisterCache().getCachedInteger(13, 0, 0x0027);
|
|
s1 = System.currentTimeMillis();
|
|
application().getServiceLink().writeInt(13, 0, 0x1301, 0);
|
|
s2 = System.currentTimeMillis();
|
|
trimTimeOnConnect = (s1+s2)>>1;
|
|
|
|
smoothTrim = new Smoother();
|
|
smoothTrim.setTn( 10 );
|
|
smoothTrim.setWert( application().getServiceLink().readInt(13, 0, 0x1002) );
|
|
|
|
} catch (Exception e){
|
|
System.err.println("trimDevice(): init failed");
|
|
e.printStackTrace();
|
|
trimTicksOnConnect = null;
|
|
}
|
|
}
|
|
|
|
|
|
} catch (Exception e){
|
|
e.printStackTrace();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
|
|
private void checkForAssertions(){
|
|
Integer assert_error,assert_code;
|
|
|
|
try
|
|
{
|
|
assert_error = -1;
|
|
for (int i=0;i<8;i++){
|
|
assert_error = application().getServiceLink().readInt(13, 0, 0x0026);
|
|
assert_code = application().getServiceLink().readInt(13, 0, 0x0025);
|
|
|
|
if (assert_error >= 0)
|
|
break;
|
|
|
|
application().message(String.format("Assertion: Error: 0x%08x (%d) Position: 0x%04x Mark: %d", assert_error,assert_error, assert_code & 0xffff, (assert_code >> 16) & 0xffff));
|
|
application().getServiceLink().writeInt(13, 0, 0x0025, -1);
|
|
};
|
|
} catch (Exception ex){
|
|
System.err.println("Exception while checking for assertions...");
|
|
ex.printStackTrace();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public synchronized void taskletQueued(final TaskletManager manager, final Tasklet tasklet) {
|
|
if (EventQueue.isDispatchThread())
|
|
knownTasklets.addElement(tasklet);
|
|
else {
|
|
EventQueue.invokeLater(new Runnable() {
|
|
|
|
@Override
|
|
public void run() {
|
|
taskletQueued(manager, tasklet);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public synchronized void taskletStarted(final TaskletManager manager, final Tasklet tasklet) {
|
|
if (EventQueue.isDispatchThread())
|
|
lTasklets.repaint();
|
|
else
|
|
EventQueue.invokeLater(new Runnable() {
|
|
|
|
@Override
|
|
public void run() {
|
|
taskletStarted(manager, tasklet);
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public synchronized void taskletFinished(final TaskletManager manager, final Tasklet tasklet) {
|
|
if (EventQueue.isDispatchThread())
|
|
knownTasklets.removeElement(tasklet);
|
|
else
|
|
EventQueue.invokeLater(new Runnable() {
|
|
|
|
@Override
|
|
public void run() {
|
|
taskletFinished(manager, tasklet);
|
|
}
|
|
});
|
|
}
|
|
@Override
|
|
public synchronized void taskletProgressChanged(final TaskletManager manager, final Tasklet tasklet) {
|
|
if (EventQueue.isDispatchThread())
|
|
lTasklets.repaint();
|
|
else
|
|
EventQueue.invokeLater(new Runnable() {
|
|
|
|
@Override
|
|
public void run() {
|
|
taskletProgressChanged(manager, tasklet);
|
|
}
|
|
});
|
|
}
|
|
|
|
private void channelReset(ChannelDisplay display){
|
|
for (int n=0;n<32;n++){
|
|
if (display == channelDisplays[n]){
|
|
channelReset(n,0);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void channelReset(int channel,int setValue){
|
|
try {
|
|
|
|
application().getServiceLink().writeInt(13, 0, 0x0600 + channel, setValue);
|
|
|
|
} catch (ServiceLinkRequestFailedException e) {
|
|
e.printStackTrace();
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
} catch (ServiceLinkException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
private void channelSet(ChannelDisplay display,int setValue){
|
|
for (int n=0;n<32;n++){
|
|
if (display == channelDisplays[n]){
|
|
channelReset(n,setValue);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|