package org.hwo.pulscounter.device; import java.awt.Component; import java.io.IOException; import java.text.DateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.LinkedList; import java.util.List; import org.hwo.ArrayHelper; import org.hwo.io.NewSerialPort.NewSerialPort; import org.hwo.pulscounter.SnapShot; import org.hwo.pulscounter.simplescript.SimpleScript.SimpleScriptElement; import org.hwo.pulscounter.ui.DeviceConfiguration; import org.hwo.servicelink.SimpleLink; import org.hwo.servicelink.exceptions.*; import org.hwo.ui.dialog.SerialPortChooser; import static org.hwo.logging.Logging.*; import static org.hwo.logging.LogLevel.*; public class SimpleLinkDeviceConnector implements IDeviceConnector { private SimpleLink simpleLink; private Integer deviceSerial; private int debugMode; public SimpleLinkDeviceConnector() { simpleLink = new SimpleLink(new NewSerialPort("COM1:")); } private void checkOpen(){ if (!simpleLink.isOpen()){ try { simpleLink.open(); simpleLink.setTimeOut(1000); } catch (IOException | ServiceLinkException e) { throw new NoDeviceConnectionException(); } } } @Override public String toString() { return String.format("Serial [%s]", this.simpleLink.getSerialPort().getPortName()); } public SimpleLink getSimpleLink() { return simpleLink; } private Integer readDeviceSerial(){ checkOpen(); try { Integer v = simpleLink.readInt(0x0001); return v; } catch (IOException | ServiceLinkException e) { log(e); throw new NoDeviceConnectionException(); } } @Override public Integer getDeviceSerial() { Integer serial = readDeviceSerial(); deviceSerial = serial; return serial; } public void setDeviceSerial(int serial) { checkOpen(); try { simpleLink.writeInt(0x0004, -1895890944); simpleLink.writeInt(0x0001, serial ); simpleLink.writeInt(0x0004, 0x0); } catch (IOException | ServiceLinkException e) { throw new NoDeviceConnectionException(); } } @Override public boolean showConnctionSetup(Component parent) { NewSerialPort newSerialPort = SerialPortChooser.execute(parent,simpleLink.getSerialPort().getPortName()); if (newSerialPort != null){ simpleLink.close(); simpleLink.getSerialPort().setPortName(newSerialPort.getPortName()); return true; } return false; } @Override public String getConnectionSettings() { return simpleLink.getSerialPort().getPortName(); } @Override public void setConnectionSettings(String connectionSettings) { simpleLink.close(); simpleLink.getSerialPort().setPortName(connectionSettings); } @Override public String getConnectionSettingsText() { return String.format("Port: %s",getConnectionSettings()); } @Override public int[] getCounters() { checkOpen(); checkRealTimeClock(); try { return ArrayHelper.unbox(this.simpleLink.readInt(0x0600,32)); } catch (ServiceLinkException | IOException e){ log(e); return null; } } @Override public void setCounters(int[] values) { try { simpleLink.writeInt(0x0600, values); } catch (IOException | ServiceLinkException e) { log(e); } } @Override public int getCounter(int channel) { Integer v = null; checkOpen(); try { v = simpleLink.readInt( 0x0600 + channel ); } catch (Exception e) { throw new NoDeviceConnectionException(); } if (v != null){ return v; } else { return 0; } } @Override public void setCounter(int channel, int counter) { checkOpen(); try { simpleLink.writeInt(0x0600 + channel, counter); } catch (IOException | ServiceLinkException e) { e.printStackTrace(); } } @Override public int[] getSimpleScript() { try { Integer l = simpleLink.readInt(0x0700); log(DEBUG,"%d ScriptElements on Device.",l); if (l<=0) return new int[0]; int[] script = new int[l]; int p; simpleLink.writeInt(0x0701, 0); for (p=0;p snapshots = new LinkedList<>(); if (s != null){ Integer newest,sssize; int ind; Integer id; try { Integer sbrk,stacklimit,cycletime,enginestate; Integer[] rd = simpleLink.readInt(new int[]{0x0020,0x0021,0x1310,0x0703}); sbrk = rd[0]; stacklimit = rd[1]; cycletime = rd[2]; enginestate = rd[3]; log(INFO,"HEAP END: 0x%04x SYS-STACK: 0x%04x",sbrk,stacklimit); log(INFO,"I/O cycle time: %dus",cycletime); log(INFO,"Engine-State: 0x%08x",enginestate); newest = simpleLink.readInt(0x0581); sssize = simpleLink.readInt(0x0582); if ((newest == null) || (sssize == null)){ return null; } if (startIndex < (newest - sssize)){ startIndex = newest - sssize; } if (startIndex < 0){ startIndex = 0; } log(INFO,"ServiceLinkDeviceConnector: reading snapshots [%d ... %d]",startIndex,newest); for (ind = startIndex; ind <= newest; ind++){ try { simpleLink.writeInt(0x0500, ind); id = simpleLink.readInt(0x0500); if (!id.equals(ind)){ log(WARN,"Snapshot could not be selected [%d != %d]",ind,id); } else { Integer timestamp, flags, in, out, pu, inv, trigger; Integer[] counters, analogs; timestamp = simpleLink.readInt(0x0501); flags = simpleLink.readInt(0x0502); in = simpleLink.readInt(0x0503); out = simpleLink.readInt(0x0504); pu = simpleLink.readInt(0x0505); inv = simpleLink.readInt(0x0506); trigger = simpleLink.readInt(0x0507); id = simpleLink.readInt(0x0530); counters = new Integer[32]; analogs = new Integer[8]; for (int n=0;n<32;n++){ counters[n] = simpleLink.readInt(0x0510 + n); } for (int n=0;n<8;n++){ analogs[n] = simpleLink.readInt(0x0508 + n); } SnapShot ss = new SnapShot(s); ss.setTimestamp(timestamp); ss.setIndex(id); ss.setField0(flags); ss.setInputmask(in); ss.setOutputmask(out); ss.setInvertmask(inv); ss.setTriggermask(trigger); ss.setPullupmask(pu); for (int i=0;i<32;i++){ ss.setValue(i, counters[i]); } for (int i=0;i<8;i++){ ss.setAnalog(i, analogs[i]); } log(INFO,"Snapshot read: %s",id); snapshots.add(ss); }; } catch (ServiceLinkRequestFailedException e){ log(e); } } } catch (IOException | ServiceLinkException e) { log(e); } checkForAssertions(); } return snapshots.toArray(new SnapShot[0]); } @Override public int getInterval(int iNo) { checkOpen(); iNo %= 4; try { Integer v = simpleLink.readInt( 0x1010 + iNo ); return v; } catch (IOException | ServiceLinkException e) { throw new NoDeviceConnectionException(); } } @Override public boolean isIntervalDailyBased(int iNo) { iNo %= 4; return ((getDailyBaseMask() & (1< 1)){ log(INFO,"realtime clock has a %d seconds shift",delta); simpleLink.writeInt(0x001C, (int)(calendar.getTimeInMillis() / 1000L)); log(INFO,"realtime clock has been corrected."); } } else { log(DEBUG,"SCHEDULER_DEBUG: DeviceTime is %s",DateFormat.getInstance().format(new Date(((long)deviceTime)*1000))); } } catch (ServiceLinkRequestFailedException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ServiceLinkException e) { e.printStackTrace(); } } private void checkForAssertions(){ Integer assert_error,assert_code; try { assert_error = -1; for (int i=0;i<8;i++){ assert_error = simpleLink.readInt(0x0026); assert_code = simpleLink.readInt(0x0025); if (assert_error >= 0) break; log(WARN,"Assertion: Error: 0x%08x (%d) Position: 0x%04x Mark: %d", assert_error,assert_error, assert_code & 0xffff, (assert_code >> 16) & 0xffff); simpleLink.writeInt(0x0025, -1); }; } catch (Exception ex){ System.err.println("Exception while checking for assertions..."); ex.printStackTrace(); } } @Override public int escape(int escape, int parm) { if ((escape & ESC_DEBUG_MASK)!=0){ debugMode = escape; } switch (escape){ case ESC_DEBUG_SCHEDULER_BUG: try { Long currentTime = (System.currentTimeMillis()/1000); currentTime -= currentTime % 86400; currentTime += -920; log(DEBUG,"ESC_DEBUG_SCHEDULER_BUG"); simpleLink.writeInt(0x001C, (currentTime.intValue())); } catch (ServiceLinkRequestFailedException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ServiceLinkException e) { e.printStackTrace(); } return 0; case ESC_PREPARE_DEVICETEST: log(DEBUG,"Prepare Device for testing."); return 0; case ESC_UNPREPARE_DEVICETEST: log(DEBUG,"Un-Prepare Device after testing."); return 0; } return 0; } @Override public int[] getIncrements() { checkOpen(); try { return ArrayHelper.unbox(this.simpleLink.readInt(0x12A0,32)); } catch (ServiceLinkException | IOException e){ log(e); return null; } } @Override public void setIncrements(int[] increments) { for (int n=0;n<32;n++){ setIncrement(n, increments[n]); } } public int getIncrement(int channel) { Integer v = null; checkOpen(); try { v = simpleLink.readInt( 0x12A0 + channel ); } catch (Exception e) { throw new NoDeviceConnectionException(); } if (v != null){ return v; } else { return 0; } } public void setIncrement(int channel, int increment) { checkOpen(); try { simpleLink.writeInt(0x12A0 + channel, increment); } catch (IOException | ServiceLinkException e) { e.printStackTrace(); } } @Override public void shutdown() { simpleLink.close(); } }