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.model.devices.etd.information.EtdClassification;
import art.library.interop.serialization.Serialization;
import art.library.model.transactions.traces.Trace;
import art.servers.etdserver.Shared;
import art.servers.etdserver.protocols.diamond.Diamond_Message;
import art.servers.etdserver.protocols.diamond.Diamond_ProtocolAnalyser;
import art.servers.etdserver.protocols.diamond.Diamond_ProtocolConstructor;
import art.servers.etdserver.protocols.diamond.configuration.DIAMOND_LengthBinnedData;
import art.servers.etdserver.protocols.diamond.configuration.DIAMOND_SpeedBinnedData;
import art.servers.etdserver.protocols.diamond.file.DIAMOND_File;
import art.servers.etdserver.protocols.diamond.files.DIAMOND_Directory;
import art.servers.etdserver.protocols.diamond.files.DIAMOND_Subdirectory;
import java.io.InputStream;
import java.io.OutputStream;
import static java.lang.Thread.sleep;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class ControllerDiamond 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 long lastOffline = System.currentTimeMillis();
public ControllerDiamond(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);
//
status = DeviceStatus.STATUS_ONLINE;
while ((isInterrupted() == false) && (exit == false))
{
long startTimestamp = System.currentTimeMillis();
try
{
if (art.servers.Shared.isServerEnabled() == true)
{
if (connected == false)
{
connect();
}
update();
}
}
catch (Exception e)
{
e.printStackTrace();
}
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)
{
}
}
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(15000);
EtdInformation etdInformation = (EtdInformation)etdclone.getDeviceInformation();
// Connect with Counter
disconnectCounter();
connectCounter(etdclone);
sendPassword(etdInformation.connection.password);
startCollecting(etdclone);
// Get Length and Speed bin tables
DIAMOND_LengthBinnedData lengthBinnedData = getLengthBinTable(etdclone);
DIAMOND_SpeedBinnedData speedBinnedData = getSpeedBinTable(etdclone);
// Get File open data
retrieveFileOpenData(etdclone, lengthBinnedData, speedBinnedData);
// Get system status and check datetime
checkDatetime(etdclone);
// Disconnect from Counter
disconnectCounter();
return;
}
catch (Exception exception)
{
if ((etdclone.alarms.alarm_offline <= 0) || (firstTime == true))
{
firstTime = false;
art.servers.Shared.println(name, exception);
}
offline(etdclone);
}
finally
{
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
{
System.out.println(this.device.getIdentifier() + " 1.Offline " + this.device.getAlarm("alarm_offline") + " - " + this.device.getDeviceStatus().status);
if ((isError() == true) ||
(
(this.device.getAlarm("alarm_offline") > 0) ||
(this.device.getDeviceStatus().status == DeviceStatus.STATUS_DISABLE) ||
(this.device.getDeviceStatus().status == DeviceStatus.STATUS_UNKNOWN) ||
(this.device.getDeviceStatus().status == DeviceStatus.STATUS_SIMULATION) ||
(this.device.getDeviceStatus().status == DeviceStatus.STATUS_INVALID)
)
)
{
if (etdclone.getAlarm("alarm_offline") <= 0)
{
etdclone.getDeviceAlarms().clear();
}
etdclone.setAlarm("alarm_offline", true);
System.out.println(this.device.getIdentifier() + " 2.Offline " + etdclone.getAlarm("alarm_offline") + " - " + etdclone.getDeviceStatus().status);
Shared.model.updateDevice(device, etdclone);
System.out.println(this.device.getIdentifier() + " 3.Offline " + this.device.getAlarm("alarm_offline") + " - " + this.device.getDeviceStatus().status);
}
}
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);
}
System.out.println(this.device.getIdentifier() + " 1.Online " + this.device.getAlarm("alarm_offline") + " - " + this.device.getDeviceStatus().status);
etdclone.setAlarm("alarm_offline", false);
etdclone.setAlarm("alarm_invalid", false);
System.out.println(this.device.getIdentifier() + " 2.Online " + etdclone.getAlarm("alarm_offline") + " - " + etdclone.getDeviceStatus().status);
Shared.model.updateDevice(device, etdclone);
System.out.println(this.device.getIdentifier() + " 3.Online " + this.device.getAlarm("alarm_offline") + " - " + this.device.getDeviceStatus().status);
}
private void connectCounter (Etd etdclone) throws Exception
{
byte[] command = Diamond_ProtocolConstructor.connectCounter();
Diamond_Message response = read(command);
try
{
updateVersion(etdclone, response.getResponseString());
}
catch (Exception e)
{
}
}
private void disconnectCounter ()
{
try
{
byte[] command = Diamond_ProtocolConstructor.disconnectCounter();
Diamond_Message response = read(command);
}
catch (Exception e)
{
}
try
{
byte[] XMODEMEND = Diamond_ProtocolConstructor.XMODEMEND();
Diamond_Message response = read(XMODEMEND);
}
catch (Exception e)
{
}
try
{
byte[] CR = Diamond_ProtocolConstructor.CR();
Diamond_Message response = read(CR);
}
catch (Exception e)
{
}
}
private void sendPassword (String password) throws Exception
{
byte[] command = Diamond_ProtocolConstructor.sendPasswordCounter(password);
Diamond_Message response = read(command);
response.checkError();
Diamond_ProtocolAnalyser.analyseSendPasswordResponse(response);
}
private DIAMOND_LengthBinnedData getLengthBinTable (Etd etdclone) throws Exception
{
byte[] command = Diamond_ProtocolConstructor.getLengthBinTable();
Diamond_Message response = read(command);
response.checkError();
response.checkCommand(response.getResponseString().getBytes(), command);
Diamond_Message message = new Diamond_Message();
message.setData(response.getDataByte(), command);
DIAMOND_LengthBinnedData lengthBinnedData = Diamond_ProtocolAnalyser.analyseGetLengthBinTableResponse(etdclone.getDeviceInformation().firmwareVersion, message);
return(lengthBinnedData);
}
private DIAMOND_SpeedBinnedData getSpeedBinTable (Etd etdclone) throws Exception
{
byte[] command = Diamond_ProtocolConstructor.getSpeedBinTable();
Diamond_Message response = read(command);
response.checkError();
response.checkCommand(response.getResponseString().getBytes(), command);
Diamond_Message message = new Diamond_Message();
message.setData(response.getDataByte(), command);
DIAMOND_SpeedBinnedData speedBinnedData = createSpeedBinTable(); // Diamond_ProtocolAnalyser.analyseGetSpeedBinTableResponse(message);
EtdInformation etdInformation = etdclone.getDeviceInformation();
etdInformation.lSpeedClassification.clear();
for (int i=0; i -1)
{
message.get6X();
message.get2X();
message.get2X();
message.get2X();
message.get4X();
message.get4X();
message.get4X();
message.get6X();
message.get6X();
message.get1X();
collecting = (message.get1X() == 0x01);
int hour = message.get2X();
int minute = message.get2X();
int seconds = message.get2X();
int mseconds = message.get2X();
int month = message.get2X();
int date = message.get2X();
int year = message.get2X();
int dayOfWeek = message.get2X();
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, seconds);
calendar.set(Calendar.MILLISECOND, mseconds);
calendar.set(Calendar.YEAR, year+2000);
calendar.set(Calendar.MONTH, month-1);
calendar.set(Calendar.DATE, date);
currenttime = calendar.getTimeInMillis();
timeDifference = Math.abs((currenttime-timestamp));
}
else
{
message.get6X();
message.get2X();
message.get2X();
message.get4X();
message.get4X();
message.get6X();
message.get6X();
message.get1X();
collecting = (message.get1X() == 0x01);
int hour = message.get2X();
int minute = message.get2X();
int seconds = message.get2X();
int mseconds = message.get2X();
int month = message.get2X();
int date = message.get2X();
int year = message.get2X();
int dayOfWeek = message.get2X();
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, seconds);
calendar.set(Calendar.MILLISECOND, mseconds);
calendar.set(Calendar.YEAR, year+2000);
calendar.set(Calendar.MONTH, month-1);
calendar.set(Calendar.DATE, date);
currenttime = calendar.getTimeInMillis();
timeDifference = Math.abs((currenttime-timestamp));
}
if (timeDifference >= 60000)
{
Shared.println(device.information.name, "Datetime incorrect: " + new Date(timestamp).toString() + " - " + new Date(currenttime).toString() + " - DIF: " + timeDifference + " - Collecting?: " + collecting);
if (collecting == true)
{
// Stop collecting before set datetime
stopCollecting();
}
updateDatetimeCounter();
}
}
catch (Exception e)
{
}
}
private void updateDatetimeCounter ()
{
try
{
byte[] command = Diamond_ProtocolConstructor.sendDatetimeCounter();
Diamond_Message response = read(command);
response.checkError();
response.checkCommand(response.getResponseString().getBytes(), command);
Shared.println(device.information.name, "Datetime updated OK");
}
catch (Exception e)
{
e.printStackTrace();
Shared.println(device.information.name, e);
}
}
private void retrieveFilesDirectoryOld (Etd etdclone, DIAMOND_Directory directory, DIAMOND_LengthBinnedData lengthBinnedData, DIAMOND_SpeedBinnedData speedBinnedData) throws Exception
{
for (int i=0; i -1)
{
String sversion = connectionString.substring(index+4, index+7);
int version = Integer.parseInt(sversion);
float f = (float)(((float)version) / 100f);
if ((etdclone.getDeviceInformation().firmwareVersion == null) || (etdclone.getDeviceInformation().firmwareVersion.length() == 0))
etdclone.getDeviceInformation().firmwareVersion = "" + f;
}
}
catch (Exception e)
{
}
}
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 Diamond_Message read(byte[] command) throws Exception
{
try
{
if (command.length > 0) send(command);
return receive();
}
catch (Exception e)
{
throw e;
}
}
private void send(byte[] command) throws Exception
{
try
{
socket.getOutputStream().write(command);
socket.getOutputStream().flush();
}
catch (Exception e)
{
disconnect();
throw e;
}
}
private Diamond_Message receive() throws Exception
{
boolean salir = false;
int res = 0;
byte[] trama = null;
int longitud = 0;
int apuntador = 0;
try
{
while ((res = is.read()) == 0){sleep(10);};
trama = new byte[65535];
trama[apuntador] = (byte)res;
apuntador++;
res = is.read();
while (true)
{
trama[apuntador] = (byte)res;
apuntador++;
res = is.read();
}
}
catch (SocketTimeoutException e)
{
if (apuntador > 0)
{
longitud = apuntador;
}
else
throw e;
}
catch (Exception e)
{
throw e;
}
byte[] resultado = new byte[longitud];
System.arraycopy(trama, 0, resultado, 0, longitud);
Diamond_Message message = new Diamond_Message();
message.setData(resultado);
return(message);
}
private DIAMOND_SpeedBinnedData createSpeedBinTable() throws Exception
{
// if ((this.device.getIdentifier().equalsIgnoreCase("etd-wisznice-1") == false) &&
// (this.device.getIdentifier().equalsIgnoreCase("etd-sławatycze-1") == false))
// {
DIAMOND_SpeedBinnedData speedBinnedData = new DIAMOND_SpeedBinnedData();
speedBinnedData.numberOfBins = 17; // 16;
speedBinnedData.fileName = "POLONIA.SPD"; // "DEFAULTX.SPD";
speedBinnedData.createBins();
return speedBinnedData;
// }
// DIAMOND_SpeedBinnedData speedBinnedData = new DIAMOND_SpeedBinnedData();
// speedBinnedData.numberOfBins = 16;
// speedBinnedData.fileName = "DEFAULTX.SPD";
// speedBinnedData.createBinsOld();
// return speedBinnedData;
}
}