package art.servers.etdserver.controller; import art.library.model.devices.DeviceStatus; import art.library.model.devices.etd.Etd; import art.library.model.devices.etd.EtdInformation; import art.library.interop.serialization.Serialization; import art.library.model.transactions.traces.Trace; import art.library.utils.synchro.Mutex; import art.servers.etdserver.Shared; import art.servers.etdserver.protocols.skp3.SKP3_Message; import art.servers.etdserver.protocols.skp3.SKP3_ProtocolAnalyser; import art.servers.etdserver.protocols.skp3.SKP3_ProtocolConstructor; import art.servers.etdserver.protocols.skp3.SKP3_ProtocolWriter; import java.io.InputStream; import java.io.OutputStream; import static java.lang.Thread.sleep; import java.net.Socket; import java.text.SimpleDateFormat; public class ControllerSKP3 extends ControllerEtd { private SimpleDateFormat sdh = new SimpleDateFormat("HH:mm"); private boolean connected = false; private Socket socket = null; private InputStream is = null; private OutputStream os = null; private long lastTimestamp = 0; private int status = DeviceStatus.STATUS_ALARM; private boolean firstTime = true; private Mutex mutexPort = new Mutex(); public ControllerSKP3(Etd etd) { super(etd); this.device = etd; this.name = Shared.getMessage("Controller etd") + " " + etd.information.name; super.setName(this.name); } public void run() { // art.servers.Shared.println(Trace.getTraceInformation(art.servers.Shared.getApplicationName(), name, art.servers.Shared.getMessage("Starting"), art.servers.Shared.getMessage("Success")), true); // while ((isInterrupted() == false) && (exit == false)) { long startTimestamp = System.currentTimeMillis(); try { if (art.servers.Shared.isServerEnabled() == true) { // if (connected == false) // { // connect(); // } update(); } } catch (Exception e) { } if (startTimestamp > System.currentTimeMillis()) { startTimestamp = System.currentTimeMillis(); } long stopTimestamp = startTimestamp + (device.getDeviceInformation().polling * 1000); while ((System.currentTimeMillis() < stopTimestamp) && (exit == false)) { try { sleep(50); } catch (Exception e) { } } try { sleep(1000); } catch (Exception e) { } if (art.servers.Shared.model.existsDevice(device.getIdentifier()) == false) { art.servers.Shared.println(name, art.servers.Shared.getMessage("Device no longer exists")); exit = true; } } // art.servers.Shared.println(Trace.getTraceInformation(art.servers.Shared.getApplicationName(), name, art.servers.Shared.getMessage("Finishing"), art.servers.Shared.getMessage("Success")), true); // } /* Private controller functions */ private void update() throws Exception { Etd etdclone = (Etd)Serialization.clone(device); try { sleep(5000); EtdInformation etdInformation = (EtdInformation)etdclone.getDeviceInformation(); // Update serial number { readSerialNumber(etdclone); } // Status / Alarms { readStatus(etdclone); } // Data { readCurrentTrafficDataPeriod(etdclone); } online(etdclone); return; } catch (Exception exception) { if ((etdclone.alarms.alarm_offline <= 0) || (firstTime == true)) { firstTime = false; String message = art.servers.Shared.getMessage("Etd offline"); art.servers.Shared.println(name, exception); } offline(etdclone); try{disconnect();} catch (Exception ex){}; } } private boolean isError() { errorsNumber = errorsNumber + 1; if (errorsNumber >= maxErrorsNumber) return(true); return(false); } private void offline(Etd etdclone)throws Exception { if (isError() == true) { if (etdclone.getAlarm("alarm_offline") <= 0) { if (etdclone.getAlarm("alarm_offline") <= 0) { etdclone.getDeviceAlarms().clear(); } etdclone.setAlarm("alarm_offline", true); } Shared.model.updateDevice(device, etdclone); } } private void online(Etd etdclone) throws Exception { errorsNumber = 0; if ((etdclone.alarms.alarm_offline > 0) || (firstTime == true)) { firstTime = false; String message = art.servers.Shared.getMessage("Etd online"); art.servers.Shared.println(name, message); } etdclone.setAlarm("alarm_offline", false); etdclone.setAlarm("alarm_invalid", false); Shared.model.updateDevice(device, etdclone); } private void readSerialNumber (Etd etdclone) throws Exception { byte[] command = SKP3_ProtocolConstructor.readSerialNumber(0x00); SKP3_Message response = read(command); int serialNumber = SKP3_ProtocolAnalyser.analyseReadSerialNumberResponse(response); if (etdclone.getDeviceInformation().serialNumber.equalsIgnoreCase(""+serialNumber) == false) { etdclone.getDeviceInformation().serialNumber = ""+serialNumber; } } private void readStatus (Etd etdclone) throws Exception { byte[] command = SKP3_ProtocolConstructor.readStatus(Integer.parseInt(etdclone.getDeviceInformation().serialNumber)); SKP3_Message response = read(command); SKP3_ProtocolAnalyser.analyseReadStatusResponse(etdclone, response); } private void readCurrentTrafficDataPeriod (Etd etdclone) throws Exception { byte[] command = SKP3_ProtocolConstructor.readCurrentTrafficData(Integer.parseInt(etdclone.getDeviceInformation().serialNumber), 0, 1); SKP3_Message response = read(command); SKP3_ProtocolAnalyser.analyseReadCurrentTrafficDataPeriodResponse(etdclone, response); } private void connect() { try { // if (this.socket != null) // { // if (this.connected == true) // { // return; // } // } this.socket = new Socket(this.device.getDeviceInformation().connection.address, this.device.getDeviceInformation().connection.port); this.socket.setSoTimeout(this.device.getDeviceInformation().connection.timeout); this.is = this.socket.getInputStream(); this.os = this.socket.getOutputStream(); this.connected = true; if (status != DeviceStatus.STATUS_ONLINE) { String message = Shared.getMessage("Connected, address = %1, port = %2, timeout = %3"); message = message.replace("%1", device.getDeviceInformation().connection.address); message = message.replace("%2", "" +device.getDeviceInformation().connection.port); message = message.replace("%3", "" + device.getDeviceInformation().connection.timeout); Shared.println(device.information.name, message); status = DeviceStatus.STATUS_ONLINE; } } catch (Exception e) { try{disconnect();} catch (Exception ex){}; } } private void disconnect() throws Exception { try { is.close(); }catch (Exception e) {} try { os.close(); }catch (Exception e) {} try { socket.close(); }catch (Exception e) {} is = null; os = null; socket = null; this.connected = false; } private SKP3_Message read(byte[] command) throws Exception { try { //send(command); //return receive(); mutexPort.lockWrite(); try { connect(); send(command); return receive(); } catch (Exception e) { throw e; } finally { disconnect(); mutexPort.releaseWrite(); } } catch (Exception e) { throw e; } } private void send(byte[] command) throws Exception { socket.getOutputStream().write(command); socket.getOutputStream().flush(); } private SKP3_Message receive() throws Exception { boolean salir = false; int res = 0; byte[] trama = null; int longitud = 0; long ts = System.currentTimeMillis(); try { while ((res = is.read()) == 0){sleep(10);}; if (res != SKP3_ProtocolWriter.STX) { while ((res != SKP3_ProtocolWriter.STX) && (res != -1) && ((System.currentTimeMillis()-ts) <= device.getDeviceInformation().connection.timeout)) { res = is.read(); } } if (res == SKP3_ProtocolWriter.STX) { ts = System.currentTimeMillis(); int apuntador = 0; trama = new byte[65535]; trama[apuntador] = (byte)res; apuntador++; res = is.read(); while ((res != SKP3_ProtocolWriter.STX) && (res != -1) && ((System.currentTimeMillis()-ts) <= device.getDeviceInformation().connection.timeout)) { trama[apuntador] = (byte)res; apuntador++; res = is.read(); } trama[apuntador] = (byte)res; apuntador++; longitud = apuntador; } } catch (Exception e) { throw e; } if ((res == -1) || (longitud == 0)) throw new Exception("Timeout-Error"); byte[] resultado = new byte[longitud]; System.arraycopy(trama, 0, resultado, 0, longitud); SKP3_Message message = new SKP3_Message(); message.setData(resultado); return(message); } }