org.hwo.pulscounter/src/org/hwo/pulscounter/device/ServiceLinkDeviceConnector....

849 lines
19 KiB
Java

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<l;p++){
script[p] = serviceLink.readInt(13, 0, 0x0702);
SimpleScriptElement e = new SimpleScriptElement(script[p]);
log(DEBUG,"Element: 0x%08x [A=0x%02x B=0x%02x C=0x%02x O=0x%02x Z=0x%02x]",script[p],e.getA(),e.getB(),e.getCondition(),e.getOperation(),e.getZ());
}
log(INFO,"%d von %d Skript Elementen empfangen.",p,l);
return script;
} catch (Exception e){
log(e);
}
return null;
}
@Override
public void setSimpleScript(int[] simpleScript) {
try {
serviceLink.writeInt(13, 0, 0x0700, simpleScript.length);
for (int i=0;i<simpleScript.length;i++){
serviceLink.writeInt(13, 0, 0x0702, simpleScript[i]);
SimpleScriptElement e = new SimpleScriptElement(simpleScript[i]);
log(DEBUG,"Element: 0x%08x [A=0x%02x B=0x%02x C=0x%02x O=0x%02x Z=0x%02x]",simpleScript[i],e.getA(),e.getB(),e.getCondition(),e.getOperation(),e.getZ());
}
Integer p = serviceLink.readInt(13, 0, 0x0701);
if (!p.equals(simpleScript.length)){
log(INFO,"ServiceLinkDeviceConnector: Skript konnte nicht geschrieben werden (%d von %d Elementen erkannt)",p,simpleScript.length);
} else {
serviceLink.writeInt(13, 0, 0x0703, 1);
}
} catch (Exception e){
log(e);
}
}
@Override
public int getInputs() {
checkOpen();
try {
Integer v = serviceLink.readInt(13, 0, 0x0681 );
return v;
} catch (IOException | ServiceLinkException e) {
throw new NoDeviceConnectionException();
}
}
@Override
public int getOutputs() {
checkOpen();
try {
Integer v = serviceLink.readInt(13, 0, 0x0682 );
return v;
} catch (IOException | ServiceLinkException e) {
throw new NoDeviceConnectionException();
}
}
@Override
public void setOutputs(int outputs) {
try {
serviceLink.writeInt(13, 0, 0x0682, outputs);
} catch (IOException | ServiceLinkException e) {
log(e);
}
}
@Override
public int getPullups() {
checkOpen();
try {
Integer v = serviceLink.readInt(13, 0, 0x0683 );
return v;
} catch (IOException | ServiceLinkException e) {
throw new NoDeviceConnectionException();
}
}
@Override
public void setPullups(int pullups) {
try {
serviceLink.writeInt(13, 0, 0x0683, pullups);
} catch (IOException | ServiceLinkException e) {
log(e);
}
}
@Override
public int getInverts() {
checkOpen();
try {
Integer v = serviceLink.readInt(13, 0, 0x0684 );
return v;
} catch (IOException | ServiceLinkException e) {
throw new NoDeviceConnectionException();
}
}
@Override
public void setInverts(int inverts) {
try {
serviceLink.writeInt(13, 0, 0x0684, inverts);
} catch (IOException | ServiceLinkException e) {
log(e);
}
}
@Override
public int getTriggers(){
checkOpen();
try {
Integer v = serviceLink.readInt(13, 0, 0x0685 );
return v;
} catch (IOException | ServiceLinkException e) {
throw new NoDeviceConnectionException();
}
};
@Override
public void setTriggers(int triggers){
try {
serviceLink.writeInt(13, 0, 0x0685, triggers);
} catch (IOException | ServiceLinkException e) {
log(e);
}
};
@Override
public float[] getAnalogs() {
float[] values = new float[32];
for (int n=0;n<8;n++){
values[n] = getAnalog(n);
}
return values;
}
@Override
public float getAnalog(int channel) {
Integer v = null;
checkOpen();
try {
v = serviceLink.readInt(13, 0, 0x8000 + channel );
} catch (Exception e) {
throw new NoDeviceConnectionException();
}
if (v != null){
return (v / 6553.60f);
} else {
return 0.0f;
}
}
@Override
public int getHighestSnapShotIndex() {
Integer s = readDeviceSerial();
if (s != null){
try {
return serviceLink.readInt(13, 0, 0x0581);
} catch (IOException | ServiceLinkException e) {
log(ERROR,"ServiceLinkDeviceConnector: getHighestSnapShotIndex(): Exception: %s",e.toString());
}
}
return -1;
}
@Override
public SnapShot[] readSnapShots(int startIndex) {
Integer s = readDeviceSerial();
List<SnapShot> 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<<iNo))!=0);
}
@Override
public void setInterval(int iNo, Integer intervall, boolean dailyBase) {
checkOpen();
iNo %= 4;
try {
Integer v = serviceLink.readInt(13, 0, 0x1003 );
if (dailyBase){
v |= (1<<iNo);
} else {
v &= ~(1<<iNo);
}
serviceLink.writeInt(13, 0, 0x1003, v);
serviceLink.writeInt(13, 0, 0x1010 + iNo , intervall == null ? 0 : intervall);
} catch (IOException | ServiceLinkException e) {
throw new NoDeviceConnectionException(e);
}
}
@Override
public int getDailyBaseMask() {
checkOpen();
try {
Integer v = serviceLink.readInt(13, 0, 0x1003 );
return v;
} catch (IOException | ServiceLinkException e) {
throw new NoDeviceConnectionException();
}
}
private int getDebounce(int channel){
checkOpen();
try {
Integer v = serviceLink.readInt(13, 0, 0x1020 + channel );
return v;
} catch (IOException | ServiceLinkException e) {
throw new NoDeviceConnectionException();
}
}
private void setDebounce(int channel,int value){
checkOpen();
try {
serviceLink.writeInt(13, 0, 0x1020 + channel, value );
} catch (IOException | ServiceLinkException e) {
throw new NoDeviceConnectionException();
}
}
@Override
public int[] getDebounce() {
int[] filters = new int[32];
for (int i=0;i<32;i++){
filters[i] = getDebounce(i);
}
return filters;
}
@Override
public void setDebounce(int[] filters) {
for (int i=0;i<32;i++){
setDebounce(i,filters[i]);
}
}
private int getWindow(int channel){
checkOpen();
try {
Integer v = serviceLink.readInt(13, 0, 0x1280 + channel );
return v;
} catch (IOException | ServiceLinkException e) {
throw new NoDeviceConnectionException();
}
}
private void setWindow(int channel,int value){
checkOpen();
try {
serviceLink.writeInt(13, 0, 0x1280 + channel, value );
} catch (IOException | ServiceLinkException e) {
throw new NoDeviceConnectionException();
}
}
@Override
public int[] getWindows() {
int[] windows = new int[32];
for (int i=0;i<32;i++){
windows[i] = getWindow(i);
}
return windows;
}
@Override
public void setWindows(int[] windows) {
for (int i=0;i<32;i++){
setWindow(i,windows[i]);
}
}
@Override
public void syncConfigToLive() {
checkOpen();
try {
serviceLink.writeInt(13, 0, 0x1001, 1 );
} catch (IOException | ServiceLinkException e) {
throw new NoDeviceConnectionException();
}
}
@Override
public void reset(int flags) {
checkOpen();
try {
serviceLink.writeInt(13, 0, 0x0581, flags );
} catch (IOException | ServiceLinkException e) {
throw new NoDeviceConnectionException();
}
}
@Override
public int getConfigOutputs() {
checkOpen();
try {
Integer v = serviceLink.readInt(13, 0, 0x1008 );
return v;
} catch (IOException | ServiceLinkException e) {
throw new NoDeviceConnectionException();
}
}
@Override
public void setConfigOutputs(int outputs) {
try {
serviceLink.writeInt(13, 0, 0x1008, outputs);
} catch (IOException | ServiceLinkException e) {
log(e);
}
}
@Override
public int getConfigPullups() {
checkOpen();
try {
Integer v = serviceLink.readInt(13, 0, 0x1009 );
return v;
} catch (IOException | ServiceLinkException e) {
throw new NoDeviceConnectionException();
}
}
@Override
public void setConfigPullups(int pullups) {
try {
serviceLink.writeInt(13, 0, 0x1009, pullups);
} catch (IOException | ServiceLinkException e) {
log(e);
}
}
@Override
public int getConfigInverts() {
checkOpen();
try {
Integer v = serviceLink.readInt(13, 0, 0x100A );
return v;
} catch (IOException | ServiceLinkException e) {
throw new NoDeviceConnectionException();
}
}
@Override
public void setConfigInverts(int inverts) {
try {
serviceLink.writeInt(13, 0, 0x100A, inverts);
} catch (IOException | ServiceLinkException e) {
log(e);
}
}
@Override
public int getConfigTriggers(){
checkOpen();
try {
Integer v = serviceLink.readInt(13, 0, 0x100B );
return v;
} catch (IOException | ServiceLinkException e) {
throw new NoDeviceConnectionException();
}
};
@Override
public void setConfigTriggers(int triggers){
try {
serviceLink.writeInt(13, 0, 0x100B, triggers);
} catch (IOException | ServiceLinkException e) {
log(e);
}
};
public void checkRealTimeClock(){
Calendar calendar = Calendar.getInstance();
try {
Integer deviceTime = serviceLink.readInt(13, 0, 0x001C);
Long currentTime = (System.currentTimeMillis()/1000);
if (debugMode != ESC_DEBUG_SCHEDULER_BUG){
Long delta = deviceTime - currentTime;
if ((delta < -1) || (delta > 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();
}
}