package art.servers.etdserver.controller; import art.library.interop.InteropParameter; import art.library.interop.InteropParameters; import art.library.interop.InteropResponse; import art.library.model.devices.DeviceStatus; import art.library.model.devices.etd.Etd; import art.library.interop.serialization.Serialization; import art.library.interop.serialization.SerializationException; import art.library.model.devices.Device; import art.library.model.devices.DevicePersistenceTimeless; import art.library.model.devices.application.Application; import art.library.model.devices.etd.EtdInformation; import art.library.model.devices.etd.EtdStatus; import art.library.model.devices.etd.information.EtdInformationSection; import art.library.model.devices.etd.status.EtdStatusLane; import art.library.model.transactions.traces.Trace; import art.library.utils.common.NumberUtils; import art.library.utils.synchro.Mutex; import art.servers.ServerException; import art.servers.etdserver.Shared; import static java.lang.Thread.sleep; import java.net.Socket; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class ControllerMController extends ControllerEtd { private SimpleDateFormat sdh = new SimpleDateFormat("HH:mm"); private Socket socket = null; private boolean connected = false; private long lastTimestamp = 0; private int status = DeviceStatus.STATUS_ALARM; private boolean firstTime = true; private List letdStatus = new ArrayList(); private String serverAddress = ""; private int serverPort = 0; private int serverTimeout = 30000; private Mutex mutexEtdStatus = new Mutex(); public ControllerMController(Etd etd) { super(etd); this.device = etd; this.name = Shared.getMessage("Controller etd") + " " + etd.information.name; } public void run() { String message = Shared.getMessage("Running"); // 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) { getColorsServer(); 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); // } public EtdStatus[] getRealtimeTrafficData (long timestamp1, long timestamp2) { List list = new ArrayList(); try { mutexEtdStatus.lockRead(); for (EtdStatus etdStatus : letdStatus) { if ((timestamp1 <= etdStatus.measurementTimestamp) && (etdStatus.measurementTimestamp <= timestamp2)) { list.add(etdStatus); } } } catch (Exception e) { } finally { mutexEtdStatus.releaseRead(); } return(list.toArray(new EtdStatus[0])); } /* Private controller functions */ private void getColorsServer() { try { List ldevice = (List)DevicePersistenceTimeless.getDevices((List)(List)Shared.controllerDatabase.timeless_getObject(DevicePersistenceTimeless.class.getName(), "type = '" + Application.class.getName() + "'")); for (Device device : ldevice) { if (device instanceof Application) { Application application = (Application)device; if (application.getDeviceInformation().serverServiceName.equalsIgnoreCase("colors") == true) { String serverAddress = application.getDeviceInformation().serverAddress; int serverPort = application.getDeviceInformation().serverPort; if ((this.serverAddress.equalsIgnoreCase(serverAddress) == false) || (this.serverPort != serverPort)) { disconnect(); } this.serverAddress = serverAddress; this.serverPort = serverPort; } } } } catch (Exception e) { // If any error, we continues with last serverAddress and serverPort values } } private EtdStatus getRealtimeTrafficData() throws ServerException, SerializationException, Exception { InteropParameters parameters = new InteropParameters(); parameters.addParameter(new InteropParameter("service", name)); parameters.addParameter(new InteropParameter("operation", "getRealtimeTrafficData")); parameters.addParameter(new InteropParameter("language", Shared.configuration.general.language)); parameters.addParameter(new InteropParameter("identifier", this.device.getIdentifier().replaceAll("etd-", ""))); parameters.addParameter(new InteropParameter("timestamp", String.valueOf(lastTimestamp))); InteropResponse response = (InteropResponse)Serialization.invoke("get", parameters, socket); EtdStatus[] etdStatus = Arrays.copyOf(response.getValue(), response.getValue().length, EtdStatus[].class); lastTimestamp = etdStatus[0].measurementTimestamp; return(etdStatus[0]); } private void update() throws Exception { Etd etdclone = (Etd)Serialization.clone(device); try { EtdStatus etdStatus = getRealtimeTrafficData(); updateEtdStatus(etdclone, etdStatus); addEtdStatus(etdclone.getDeviceStatus()); online(etdclone); return; } catch (Exception exception) { Shared.printstack(name, 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 void offline(Etd etdclone)throws Exception { 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 { 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 addEtdStatus (EtdStatus etdStatus) { try { mutexEtdStatus.lockWrite(); if (letdStatus.size() == this.device.getDeviceInformation().realTimeSavingPeriods) { letdStatus.remove(0); } letdStatus.add(etdStatus); } catch (Exception e) { } finally { mutexEtdStatus.releaseWrite(); } } private void updateEtdStatus (Etd etdclone, EtdStatus etdStatusController) { try { EtdStatus etdStatusCurrent = etdclone.getDeviceStatus(); etdStatusCurrent.measurementTimestamp = etdStatusController.measurementTimestamp; etdStatusCurrent.period = etdclone.getDeviceInformation().period; etdStatusCurrent.llane.clear(); etdStatusCurrent.llane = etdStatusController.llane; etdStatusCurrent.lsection.clear(); if (etdStatusCurrent.total == null) { etdStatusCurrent.total = new EtdStatusLane(); } emptyTotal(etdclone, etdStatusCurrent); etdStatusCurrent.total.status = DeviceStatus.STATUS_OFFLINE; for (EtdStatusLane laneStatus : etdStatusCurrent.llane) { addLaneToTotal(laneStatus, etdStatusCurrent); List lsectionInformation = getSectionInformationLane(etdclone.getDeviceInformation(), laneStatus.number); for (EtdInformationSection sectionInformation : lsectionInformation) { EtdStatusLane sectionStatus = etdStatusCurrent.getSection(sectionInformation.number); if (sectionStatus == null) { sectionStatus = new EtdStatusLane(); sectionStatus.number = sectionInformation.number; sectionStatus.status = DeviceStatus.STATUS_OFFLINE; etdStatusCurrent.lsection.add(sectionStatus); } addLaneToSection(laneStatus, sectionStatus); } } // Adjust Total and Sections values if (etdStatusCurrent.total.counting > 0) { etdStatusCurrent.total.speed = (int)(etdStatusCurrent.total.speed / etdStatusCurrent.total.counting); etdStatusCurrent.total.length = (etdStatusCurrent.total.length / etdStatusCurrent.total.counting); etdStatusCurrent.total.distance = (etdStatusCurrent.total.speed / etdStatusCurrent.total.counting); etdStatusCurrent.total.occupancy = (etdStatusCurrent.total.occupancy / etdStatusCurrent.total.counting); etdStatusCurrent.total.occupancy = NumberUtils.ajustarDecimales(etdStatusCurrent.total.occupancy, 1); etdStatusCurrent.total.length = NumberUtils.ajustarDecimales((float)(etdStatusCurrent.total.length/10d), 1); etdStatusCurrent.total.distance = NumberUtils.ajustarDecimales((float)etdStatusCurrent.total.distance, 1); if (etdStatusCurrent.total.occupancy > 100) etdStatusCurrent.total.occupancy = 100; if (etdStatusCurrent.total.occupancy < 0) etdStatusCurrent.total.occupancy = 0; if (etdStatusCurrent.total.length < 0) etdStatusCurrent.total.length = 0; if (etdStatusCurrent.total.distance < 0) etdStatusCurrent.total.distance = 0; if (etdStatusCurrent.total.speed < 0) etdStatusCurrent.total.speed = 0; } for (EtdStatusLane sectionStatus : etdStatusCurrent.lsection) { sectionStatus.speed = (int)(sectionStatus.speed / sectionStatus.counting); sectionStatus.length = (sectionStatus.length / sectionStatus.counting); sectionStatus.distance = (sectionStatus.speed / sectionStatus.counting); sectionStatus.occupancy = (sectionStatus.occupancy / sectionStatus.counting); sectionStatus.occupancy = NumberUtils.ajustarDecimales(sectionStatus.occupancy, 1); sectionStatus.length = NumberUtils.ajustarDecimales((float)(sectionStatus.length/10d), 1); sectionStatus.distance = NumberUtils.ajustarDecimales((float)sectionStatus.distance, 1); if (sectionStatus.occupancy > 100) sectionStatus.occupancy = 100; if (sectionStatus.occupancy < 0) sectionStatus.occupancy = 0; if (sectionStatus.length < 0) sectionStatus.length = 0; if (sectionStatus.distance < 0) sectionStatus.distance = 0; if (sectionStatus.speed < 0) sectionStatus.speed = 0; } } catch (Exception e) { e.printStackTrace(); } } private void connect() { try { if (socket != null) { if (this.connected == true) { return; } } socket = new Socket(serverAddress, serverPort); socket.setSoTimeout(serverTimeout); this.connected = true; } catch (Exception e) { try{disconnect();} catch (Exception ex){}; } } private void disconnect() throws ServerException, Exception { try { socket.close(); }catch (Exception e) {} socket = null; this.connected = false; } private List getSectionInformationLane (EtdInformation etdInformation, int lane) { List lresult = new ArrayList(); for (EtdInformationSection sectionInformation : etdInformation.lSection) { for (Integer number : sectionInformation.llane) { if ((number.intValue()) == lane) lresult.add(sectionInformation); } } return(lresult); } private void addLaneToTotal (EtdStatusLane laneStatus, EtdStatus etdStatus) { etdStatus.total.totalMeasurements += 1; if (laneStatus.status == DeviceStatus.STATUS_ONLINE) { etdStatus.total.status = DeviceStatus.STATUS_ONLINE; etdStatus.total.correctMeasurements += 1; etdStatus.total.counting += laneStatus.counting; etdStatus.total.speed += (laneStatus.counting*laneStatus.speed); etdStatus.total.occupancy += (laneStatus.counting*laneStatus.occupancy); etdStatus.total.length += (laneStatus.counting*laneStatus.length); etdStatus.total.distance += (laneStatus.counting*laneStatus.distance); etdStatus.total.unclassified += laneStatus.unclassified; for (int i=0; i