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.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.ServiceLink; 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 ServiceLinkDeviceConnector implements IDeviceConnector { private ServiceLink serviceLink; private Integer deviceSerial; private int debugMode; public ServiceLinkDeviceConnector() { serviceLink = new ServiceLink(new NewSerialPort("COM1:")); } private void checkOpen(){ if (!serviceLink.isOpen()){ try { serviceLink.open(); serviceLink.getSerialPort().setTimeOut(250); } catch (ServiceLinkException e) { throw new NoDeviceConnectionException(); } } } @Override public String toString() { return String.format("Serial [%s]", this.serviceLink.getSerialPort().getPortName()); } public ServiceLink getServiceLink() { return serviceLink; } private Integer readDeviceSerial(){ checkOpen(); try { Integer v = serviceLink.readInt(13, 0, 0x0001 ); return v; } catch (IOException | ServiceLinkException e) { throw new NoDeviceConnectionException(); } } @Override public Integer getDeviceSerial() { Integer serial = readDeviceSerial(); deviceSerial = serial; return serial; } public void setDeviceSerial(int serial) { checkOpen(); try { serviceLink.writeInt(13, 0, 0x0004, -1895890944); serviceLink.writeInt(13, 0, 0x0001, serial ); serviceLink.writeInt(13, 0, 0x0004, 0x0); } catch (IOException | ServiceLinkException e) { throw new NoDeviceConnectionException(); } } @Override public boolean showConnctionSetup(Component parent) { NewSerialPort newSerialPort = SerialPortChooser.execute(parent,serviceLink.getSerialPort().getPortName()); if (newSerialPort != null){ serviceLink.close(); serviceLink.getSerialPort().setPortName(newSerialPort.getPortName()); return true; } return false; } @Override public String getConnectionSettings() { return serviceLink.getSerialPort().getPortName(); } @Override public void setConnectionSettings(String connectionSettings) { serviceLink.close(); serviceLink.getSerialPort().setPortName(connectionSettings); } @Override public String getConnectionSettingsText() { return String.format("Port: %s",getConnectionSettings()); } @Override public int[] getCounters() { int[] values = new int[32]; for (int n=0;n<32;n++){ values[n] = getCounter(n); } checkRealTimeClock(); return values; } @Override public void setCounters(int[] values) { for (int n=0;n<32;n++){ setCounter(n, values[n]); } } @Override public int getCounter(int channel) { Integer v = null; checkOpen(); try { v = serviceLink.readInt(13, 0, 0x600 + 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 { serviceLink.writeInt(13, 0, 0x0600 + channel, counter); } catch (IOException | ServiceLinkException e) { e.printStackTrace(); } } @Override public int[] getSimpleScript() { try { Integer l = serviceLink.readInt(13, 0, 0x0700); log(DEBUG,"%d ScriptElements on Device.",l); if (l<=0) return new int[0]; int[] script = new int[l]; int p; serviceLink.writeInt(13, 0, 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; sbrk = serviceLink.readInt(13, 0, 0x0020); stacklimit = serviceLink.readInt(13, 0, 0x0021); cycletime = serviceLink.readInt(13, 0, 0x1310); enginestate = serviceLink.readInt(13, 0, 0x0703); 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 = serviceLink.readInt(13, 0, 0x0581); sssize = serviceLink.readInt(13, 0, 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 { serviceLink.writeInt(13, 0, 0x0500, ind); id = serviceLink.readInt(13, 0, 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 = serviceLink.readInt(13, 0, 0x0501); flags = serviceLink.readInt(13, 0, 0x0502); in = serviceLink.readInt(13, 0, 0x0503); out = serviceLink.readInt(13, 0, 0x0504); pu = serviceLink.readInt(13, 0, 0x0505); inv = serviceLink.readInt(13, 0, 0x0506); trigger = serviceLink.readInt(13, 0, 0x0507); id = serviceLink.readInt(13, 0, 0x0530); counters = new Integer[32]; analogs = new Integer[8]; for (int n=0;n<32;n++){ counters[n] = serviceLink.readInt(13, 0, 0x0510 + n); } for (int n=0;n<8;n++){ analogs[n] = serviceLink.readInt(13, 0, 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 = serviceLink.readInt(13, 0, 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); serviceLink.writeInt((byte)13, (byte)0, 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 = serviceLink.readInt(13, 0, 0x0026); assert_code = serviceLink.readInt(13, 0, 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); serviceLink.writeInt(13, 0, 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"); serviceLink.writeInt((byte)13, (byte)0, 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."); serviceLink.setForceSynchronousRequests(true); return 0; case ESC_UNPREPARE_DEVICETEST: log(DEBUG,"Un-Prepare Device after testing."); serviceLink.setForceSynchronousRequests(false); return 0; } return 0; } @Override public int[] getIncrements() { int[] values = new int[32]; for (int n=0;n<32;n++){ values[n] = getIncrement(n); } return values; } @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 = serviceLink.readInt(13, 0, 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 { serviceLink.writeInt(13, 0, 0x12A0 + channel, increment); } catch (IOException | ServiceLinkException e) { e.printStackTrace(); } } @Override public void shutdown() { serviceLink.close(); } }