package art.servers.etdserver.historical; import art.library.interop.serialization.Serialization; import art.library.model.devices.Device; import art.library.model.devices.DevicePersistenceHistorical; import art.library.model.devices.DeviceStatus; import art.library.model.devices.etd.Etd; import art.library.model.devices.etd.EtdStatus; import art.library.model.devices.etd.status.EtdStatusAggregation; import art.library.model.devices.etd.status.EtdStatusAggregationLane; import art.library.model.devices.etd.status.EtdStatusLane; import art.servers.ServerException; import art.servers.Shared; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; public class HistoricalPeriods { private Etd etd = null; private String identifier = null; private int lane = -1; private int section = -1; private long timestamp1 = 0; private long timestamp2 = 0; private String name = null; private String language = null; private int aggregationPeriod = 0; private int etdPeriod = 0; private int numberOfPeriods = 0; private Register register = null; private EtdStatus[] lEtdStatus = new EtdStatus[0]; public HistoricalPeriods(String identifier, int lane, int section, long timestamp1, long timestamp2, int aggregationPeriod, String language) { Calendar calendar1 = Calendar.getInstance(); calendar1.setTimeInMillis(timestamp1); calendar1.set(Calendar.SECOND,0); calendar1.set(Calendar.MILLISECOND,0); Calendar calendar2 = Calendar.getInstance(); calendar2.setTimeInMillis(timestamp2); calendar2.set(Calendar.SECOND,0); calendar2.set(Calendar.MILLISECOND,0); this.identifier = identifier; this.lane = lane; this.section = section; this.timestamp1 = calendar1.getTimeInMillis(); this.timestamp2 = calendar2.getTimeInMillis(); this.aggregationPeriod = aggregationPeriod; this.language = language; } public EtdStatusAggregation generate() throws ServerException { ResultSet result = null; try { long timestampStart = this.timestamp1 - (300000L); long timestampEnd = this.timestamp2 + (600000L); String command = "SELECT value FROM DEVICES WHERE identifier = '" + identifier + "' AND type = '" + Etd.class.getName() + "' AND timestamp >= " + timestampStart + " AND timestamp < " + timestampEnd + " ORDER BY timestamp ASC"; String message = "From " + Device.getDate(timestamp1) + " to " + Device.getDate(timestamp2); Shared.println("Historical", message); Shared.println("Historical", command); result = Shared.controllerDatabase.getHistoricalPersistance().get(0).executeQuery(command); while (result.next() == true) { String value = result.getString(1); if (etd == null) { etd = (Etd)((DevicePersistenceHistorical)Serialization.deserialize(DevicePersistenceHistorical.class, value)).device; if (etd != null) { initialise(); } } else { etd = (Etd)((DevicePersistenceHistorical)Serialization.deserialize(DevicePersistenceHistorical.class, value)).device; if (etd != null) { if (etd.getDeviceInformation().period != etdPeriod) throw new ServerException(Shared.getMessage(language, "Selected time range has several integration periods")); if (name == null) name = etd.getDeviceInformation().getName(); } } try { EtdStatus status = etd.getDeviceStatus(); int position = (int)((status.measurementTimestamp - timestamp1)/(aggregationPeriod * 1000)); if ((status.measurementTimestamp-timestamp1) < 0) position = -1; if ((position >= 0) && (position < numberOfPeriods)) // Podemos tener un registro con timestamp1 < measurementTimestamp por una alarma o algo { if (register == null) { register = new Register(position); } else { if (register.position != position) { register.aggregation(); register = new Register(position); } } register.mstatus.put(status.measurementTimestamp, status); } } catch (Exception e) { e.printStackTrace(); } } if (etd == null) throw new ServerException("No data available in selected time range"); if (register != null) register.aggregation(); EtdStatusAggregation response = new EtdStatusAggregation(); response.device = identifier; response.name = name; response.section = (section >= 0); if (response.section == true) response.number = section; else response.number = lane; response.timestamp1 = timestamp1; response.timestamp2 = timestamp2; response.aggregationPeriod = aggregationPeriod; for (EtdStatus status : lEtdStatus) { EtdStatusAggregationLane data = new EtdStatusAggregationLane(); data.timestamp = status.measurementTimestamp; if (lane >=0) data.lane = status.getLane(lane); else data.lane = status.getSection(section); response.ldata.add(data); } for (int i=0; i timestamp2) { throw new ServerException(Shared.getMessage(language, "From timestamp must be lower than to timestamp")); } timestamp1 = timestamp1 - (timestamp1 % (aggregationPeriod * 1000)); timestamp2 = timestamp2 - (timestamp2 % (aggregationPeriod * 1000)); numberOfPeriods = (int)((timestamp2 - timestamp1)/(aggregationPeriod * 1000)); if (numberOfPeriods > 133920) throw new ServerException(Shared.getMessage(language, "Result would produce too much registers. Select lower date range or higher period")); lEtdStatus = new EtdStatus[numberOfPeriods]; long timestamp = timestamp1; for (int i=0; i mstatus = new HashMap(); public int position; public Register(int position) { this.position = position; } public void aggregation() { int totalMeasurements = aggregationPeriod / etd.getDeviceInformation().period; int correctMeasurements = 0; ArrayList lstatus = new ArrayList(mstatus.values()); EtdStatus etdStatus = lstatus.get(0); // Lanes for (int i=0; i 0) { apuntes = apuntes + 1; etdStatus.llane.get(i).counting += lstatus.get(j).llane.get(i).counting; etdStatus.llane.get(i).unclassified += lstatus.get(j).llane.get(i).unclassified; etdStatus.llane.get(i).speed += (lstatus.get(j).llane.get(i).counting) * (lstatus.get(j).llane.get(i).speed); etdStatus.llane.get(i).occupancy += (lstatus.get(j).llane.get(i).counting) * (lstatus.get(j).llane.get(i).occupancy); for (int k=0; k 0) { if (etdStatus.llane.get(i).counting > 0) { // etdStatus.llane.get(i).speed /= apuntes; // etdStatus.llane.get(i).occupancy /= apuntes; etdStatus.llane.get(i).speed /= etdStatus.llane.get(i).counting; etdStatus.llane.get(i).occupancy /= etdStatus.llane.get(i).counting; } etdStatus.llane.get(i).speed = (int)(etdStatus.llane.get(i).speed); int occupancy = (int)(etdStatus.llane.get(i).occupancy*10); etdStatus.llane.get(i).occupancy = (float)((float)occupancy / 10f); } int length = (int)(etdStatus.llane.get(i).length*10); etdStatus.llane.get(i).length = (double)((double)length / 10d); int distance = (int)(etdStatus.llane.get(i).distance*10); etdStatus.llane.get(i).distance = (double)((double)distance / 10d); // Write status lane try { EtdStatusLane statusLane = etdStatus.llane.get(i); statusLane.correctMeasurements = correctMeasurementsLane; statusLane.totalMeasurements = totalMeasurementsLane; lEtdStatus[position].llane.add(statusLane); } catch (Exception e) { } } // Sections for (int i=0; i 0) { apuntes = apuntes + 1; etdStatus.lsection.get(i).counting += lstatus.get(j).lsection.get(i).counting; etdStatus.lsection.get(i).unclassified += lstatus.get(j).lsection.get(i).unclassified; etdStatus.lsection.get(i).speed += (lstatus.get(j).lsection.get(i).counting) * (lstatus.get(j).lsection.get(i).speed); etdStatus.lsection.get(i).occupancy += (lstatus.get(j).lsection.get(i).counting) * (lstatus.get(j).lsection.get(i).occupancy); for (int k=0; k 0) { if (etdStatus.lsection.get(i).counting > 0) { etdStatus.lsection.get(i).speed /= etdStatus.lsection.get(i).counting; etdStatus.lsection.get(i).occupancy /= etdStatus.lsection.get(i).counting; } etdStatus.lsection.get(i).speed = (int)(etdStatus.lsection.get(i).speed); int occupancy = (int)(etdStatus.lsection.get(i).occupancy*10); etdStatus.lsection.get(i).occupancy = (float)((float)occupancy / 10f); } int length = (int)(etdStatus.lsection.get(i).length*10); etdStatus.lsection.get(i).length = (double)((double)length / 10d); int distance = (int)(etdStatus.lsection.get(i).distance*10); etdStatus.lsection.get(i).distance = (double)((double)distance / 10d); // Write status section try { EtdStatusLane statusSection = etdStatus.lsection.get(i); statusSection.correctMeasurements = correctMeasurementsSection; statusSection.totalMeasurements = totalMeasurementsSection; lEtdStatus[position].lsection.add(statusSection); } catch (Exception e) { } } // Totals { int apuntes = 0; for (int j=1; j 0) { apuntes = apuntes + 1; etdStatus.total.counting += lstatus.get(j).total.counting; etdStatus.total.unclassified += lstatus.get(j).total.unclassified; etdStatus.total.speed += (lstatus.get(j).total.counting) * (lstatus.get(j).total.speed); etdStatus.total.occupancy += (lstatus.get(j).total.counting) * (lstatus.get(j).total.occupancy); for (int k=0; k 0) { if (etdStatus.total.counting > 0) { etdStatus.total.speed /= etdStatus.total.counting; etdStatus.total.occupancy /= etdStatus.total.counting; } etdStatus.total.speed = (int)etdStatus.total.speed; int occupancy = (int)(etdStatus.total.occupancy*10); etdStatus.total.occupancy = (float)((float)occupancy / 10f); } int length = (int)(etdStatus.total.length*10); etdStatus.total.length = (double)((double)length / 10d); int distance = (int)(etdStatus.total.distance*10); etdStatus.total.distance = (double)((double)distance / 10d); try { lEtdStatus[position].total = etdStatus.total; } catch (Exception e) { } } } } } }