package de.ctdo.crashtest.domotics; import de.ctdo.crashtest.log.Logger; import gnu.io.*; import java.io.IOException; import java.io.OutputStream; import java.util.*; import java.util.concurrent.ConcurrentHashMap; public class Relaisboard implements IRelaisboard { private SerialPort serialPort; private OutputStream outputStream; private Boolean serialPortGeoeffnet = false; private String portName = "/dev/ttyUSB0"; private final Object mLock = new Object(); private final Map threadMap = new ConcurrentHashMap(); private final Map stopMap = new ConcurrentHashMap(); public Relaisboard(final String port) { this.portName = port; } private void sendData(final int relais, final boolean state) { synchronized (mLock) { if(relais >= 0 && relais < 8 && outputStream != null) { char charsOff[] = { 'a','b','c','d','e','f','g','h' }; char charsOn[] = { 'A','B','C','D','E','F','G','H' }; try { if(state) { outputStream.write(charsOn[relais]); } else { outputStream.write(charsOff[relais]); } System.out.println("Relaisboard: sendData " + relais + " = " + state); outputStream.flush(); } catch (IOException e) { Logger.sLog("Relaisboard error: Fehler beim Senden"); } } } } @Override public boolean open() { serialPortGeoeffnet = false; Boolean foundPort = false; if (serialPortGeoeffnet) { Logger.sLog("Serialport bereits geƶffnet"); return false; } Enumeration enumComm = CommPortIdentifier.getPortIdentifiers(); CommPortIdentifier serialPortId = null; while(enumComm.hasMoreElements()) { serialPortId = (CommPortIdentifier) enumComm.nextElement(); if (portName.contentEquals(serialPortId.getName())) { foundPort = true; break; } } if (!foundPort) { Logger.sLog("Serialport nicht gefunden: " + portName); return false; } try { // open port and tell the OS who we are. Wait max 500ms for release if port is currently owned. serialPort = (SerialPort) serialPortId.open("crashtest app", 500); serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE); outputStream = serialPort.getOutputStream(); serialPortGeoeffnet = true; return true; } catch (PortInUseException e) { Logger.sLog("Relaisboard error: Port belegt " + portName); } catch (IOException e) { Logger.sLog("Relaisboard error: Keinen Zugriff auf OutputStream"); } catch(UnsupportedCommOperationException e) { Logger.sLog("Relaisboard error: Konnte Schnittstellen-Paramter nicht setzen"); } return false; } @Override public void close() { if ( serialPortGeoeffnet ) { serialPort.close(); } serialPortGeoeffnet = false; outputStream = null; } @Override public void setRelais(final int relais, final boolean state) { if(!serialPortGeoeffnet) return; stopRelaisThread(relais); Runnable r = new Runnable() { @Override public void run() { sendData(relais, state); } }; new Thread(r).start(); } @Override public void toggleRelais(final int relais, final int milliseconds) { if(!serialPortGeoeffnet) return; stopRelaisThread(relais); Runnable r = new Runnable() { @Override public void run() { sendData(relais, true); try { Thread.sleep(milliseconds); } catch (InterruptedException ignored) { } sendData(relais, false); } }; new Thread(r).start(); } @Override public void blinkRelais(final int relais, final int pause) { if(!serialPortGeoeffnet) return; stopRelaisThread(relais); Runnable r = new Runnable() { @Override public void run() { while(true) { sendData(relais, true); try { Thread.sleep(pause); } catch (InterruptedException ignored) { } if(stopMap.get(relais)) return; sendData(relais, false); try { Thread.sleep(pause); } catch (InterruptedException ignored) { } if(stopMap.get(relais)) return; } } }; stopMap.put(relais, false); Thread thread = new Thread(r); threadMap.put(relais,thread); thread.start(); } @Override public void blinkRelaisStop(final int relais) { stopRelaisThread(relais); } private void stopRelaisThread(final int relais) { Thread thread = threadMap.get(relais); if(thread != null) { stopMap.put(relais, true); thread.interrupt(); threadMap.remove(relais); } } }