package art.client.maps; import art.client.models.Shared; import art.library.interop.serialization.Serialization; import art.library.model.devices.Device; import art.library.model.devices.DeviceGraphicsRuntime; import art.library.model.devices.DeviceStatus; import art.library.model.devices.barrier.Barrier; import art.library.model.devices.barrier.BarrierAlarms; import art.library.model.devices.barrier.BarrierRealtime; import art.library.model.devices.barrier.BarrierStatus; import art.library.model.devices.barrier.realtime.BarrierRealtimeITC; import art.library.model.devices.signalsboard.SignalsBoard; import art.library.model.devices.signalsboard.status.SignalStatus; import art.library.model.devices.vms.asf.Asf; import art.library.model.devices.vms.asf.AsfStatus; import art.library.model.devices.vms.general.VmsGeneral; import art.library.model.devices.vms.general.status.VmsGeneralStatusMessage; import static art.library.utils.ArticScalableVectorGraphics.getBoundingBox; import art.library.vmsboard.BoardDocument; import com.kitfox.svg.*; import java.awt.Graphics2D; import java.awt.Image; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.image.BufferedImage; import java.text.DecimalFormat; import java.util.*; import java.util.stream.Stream; public class LaGoleta extends DeviceGraphicsRuntime { private boolean even = false; private final DecimalFormat decimalFormat = new DecimalFormat("0.00"); private final Class[] ldeviceClasses = new Class[] { SignalsBoard.class, Asf.class, Barrier.class, VmsGeneral.class, }; public LaGoleta (SVGDiagram diagram) { super(diagram); } public void status() { Calendar calendardate = java.util.Calendar.getInstance(); calendardate.set(java.util.Calendar.MILLISECOND, 0); long seconds = calendardate.getTimeInMillis() / 1000; even = (seconds % 2) == 0; for (SVGElement element : getElementsContainingField("art.device")) { try { for (Class deviceClass : ldeviceClasses) { if (Shared.model.modelDevices.getDevice(getAttribute(element, "art.device")).getClassName().equals(deviceClass.getName())) { this.getClass() .getMethod("status", deviceClass, SVGElement.class) .invoke(this, Shared.model.modelDevices.getDevice(getAttribute(element, "art.device")), element); break; } } } catch (Exception e){} } } // public void status(SignalsBoard svgDevice, SVGElement element) { String[] signals = getAttribute(element, "art.device.signal").contains(";") ? getAttribute(element, "art.device.signal").split(";") : new String[] {getAttribute(element, "art.device.signal")} ; if (signals.length > 0) { System.out.println("<>"); Stream.of(signals).forEach(System.out::println); System.out.println("Device signals"); svgDevice.getDeviceStatus().inputs.forEach(input -> input.signals.forEach(isignal -> System.out.println(isignal.name))); SignalStatus signal = svgDevice.getDeviceStatus().getSignal(signals[0]); if (signal != null) { setText(element, decimalFormat.format(Float.valueOf(signal.value)) + " " + Shared.getMessage(signal.units)); } else { boolean floodAlarm = Stream.of(signals).anyMatch(signalAlarm -> svgDevice.getAlarm(signalAlarm) > 0); if (signals.length > 1) { System.out.println("FLOOD ALARMS -> " + floodAlarm); setAttribute(element, "display", floodAlarm ? "inline" : "none", 999); } else { String backgroundColor = "#FF00FF"; switch (svgDevice.getDeviceStatus().status) { case DeviceStatus.STATUS_ALARM: backgroundColor = "#00FF00"; case DeviceStatus.STATUS_ONLINE: backgroundColor = "#00FF00"; break; } if(floodAlarm) { backgroundColor = "#FF0000"; } setAttribute(element, "fill", backgroundColor, 999); } } } } // // public void status(Asf svgDevice, SVGElement element) throws Exception { AsfStatus status = svgDevice.getDeviceStatus(); SVGElement alarm = getChildContainingField(element,"art.id","Alarm"); SVGElement border = getChildContainingField(element,"art.id","Border"); SVGElement background = getChildContainingField(element,"art.id","Background"); SVGElement arrow = getChildContainingField(element,"art.id","Arrow"); SVGElement cross = getChildContainingField(element,"art.id","Cross"); SVGElement right = getChildContainingField(element, "art.id", "Right"); SVGElement left = getChildContainingField(element, "art.id", "Left"); setAttribute(arrow, "display", "none", 999); setAttribute(cross, "display", "none", 999); setAttribute(right, "display", "none", 999); setAttribute(left, "display", "none", 999); boolean knownStatus = status.state != DeviceStatus.STATUS_OFFLINE && status.state != DeviceStatus.STATUS_UNKNOWN; if (knownStatus) { setAttribute(arrow, "display", status.state == AsfStatus.STATE_ARROW ? "inline" : "none", 999); setAttribute(cross, "display", status.state == AsfStatus.STATE_CROSS ? "inline" : "none", 999); setAttribute(right, "display", status.state == AsfStatus.STATE_RIGHT ? "inline" : "none", 999); setAttribute(left, "display", status.state == AsfStatus.STATE_LEFT ? "inline" : "none", 999); } String colorBackground = "#000000"; String colorAlarm = "#FF0000"; switch (status.status) { case DeviceStatus.STATUS_ALARM: colorAlarm = "#FF0000"; break; case DeviceStatus.STATUS_OFFLINE: case DeviceStatus.STATUS_UNKNOWN: colorBackground = "#FF00FF"; colorAlarm = "#800080"; break; } setAttribute(border, "stroke", colorAlarm, 999); setAttribute(background, "fill", colorBackground,999); } // // public void status(VmsGeneral svgDevice, SVGElement element) throws Exception { SVGElement background = getChildContainingField(element,"art.id","Background"); SVGElement alarm = getChildContainingField(element, "art.id","Alarm"); String backGroundColor = "#000000"; String alarmColor = "#00FF00"; switch (svgDevice.getDeviceStatus().status) { case DeviceStatus.STATUS_ALARM: alarmColor = "#FF0000"; break; case DeviceStatus.STATUS_OFFLINE: case DeviceStatus.STATUS_UNKNOWN: backGroundColor = "#FF00FF"; alarmColor = "#800080"; break; } setAttribute(background, "fill", backGroundColor,999); setAttribute(alarm, "stroke", alarmColor,999); //TODO SET PANEL IMAGES } //element,"art.id", // public void status(Barrier svgDevice, SVGElement element) throws Exception //BARRIER { BarrierRealtimeITC realtime = ((BarrierRealtime) device.getDeviceRealtime()).itc; { barrierStatus(element, realtime); semaphoreStatus(element, realtime); roadSensor(element, realtime); } barierDeviceStatus(element,svgDevice.getDeviceStatus()); barrierAlarms(element, svgDevice.getDeviceAlarms()); } private void barrierStatus(SVGElement element, BarrierRealtimeITC realtimeItc) { SVGElement[] barrierElements = new SVGElement[] { getChildContainingField(element,"art.id","Barrier.Opened"), getChildContainingField(element,"art.id","Barrier.Closed"), getChildContainingField(element,"art.id","Barrier.Closing"), getChildContainingField(element,"art.id","Barrier.Opening"), getChildContainingField(element,"art.id","Barrier.Locked") }; Stream.of(barrierElements).forEach(svgElement -> setAttribute(svgElement, "display", "none", 999)); SVGElement elementToShow = null; switch (realtimeItc.position) { case BarrierRealtimeITC.POSITION_UP: elementToShow = barrierElements[0]; break; case BarrierRealtimeITC.POSITION_DOWN: elementToShow = barrierElements[1]; break; case BarrierRealtimeITC.POSITION_CLOSING: elementToShow = barrierElements[2]; break; case BarrierRealtimeITC.POSITION_OPENING: elementToShow = barrierElements[3]; break; } if(elementToShow != null) setAttribute(elementToShow, "display", "inline", 999); if(realtimeItc.lock == BarrierRealtimeITC.LOCK_LOCK) setAttribute(barrierElements[4], "display", "inline", 999); } private void roadSensor(SVGElement element, BarrierRealtimeITC realtimeItc) { SVGElement loop1 = getChildContainingField(element,"art.id","Loop1"); SVGElement loop2 = getChildContainingField(element,"art.id","Loop2"); setAttribute(loop1, "fill", "#E0E0E0"); setAttribute(loop2,"fill", "#E0E0E0"); if (realtimeItc.loopInput == BarrierRealtimeITC.LOOP_ACTIVE) setAttribute(loop1, "fill", "#ffff0080"); if (realtimeItc.loopOutput == BarrierRealtimeITC.LOOP_ACTIVE) setAttribute(loop2, "fill", "#ffff0080"); } private void semaphoreStatus(SVGElement element, BarrierRealtimeITC realtimeItc) { SVGElement semaphoreRed = getChildContainingField(element,"art.id","Sempahore.Red"); SVGElement semaphoreYellow = getChildContainingField(element,"art.id","Sempahore.Yellow"); SVGElement semaphoreGreen = getChildContainingField(element,"art.id","Sempahore.Green"); setAttribute(semaphoreGreen, "fill", "#000000",999); setAttribute(semaphoreYellow, "fill", "#000000",999); setAttribute(semaphoreRed, "fill", "#000000",999); switch (realtimeItc.trafficLight) { case BarrierRealtimeITC.TRAFFIC_LIGHT_GREEN: setAttribute(semaphoreGreen, "fill", "#00FF00",999); case BarrierRealtimeITC.TRAFFIC_LIGHT_YELLOW: setAttribute(semaphoreGreen, "fill", "#FFFF00",999); case BarrierRealtimeITC.TRAFFIC_LIGHT_RED: setAttribute(semaphoreGreen, "fill", "#FF0000",999); } } private void barrierAlarms(SVGElement element, BarrierAlarms alarms) { String[] semaphoreAlarms = new String[] { "alarm_blown_green", "alarm_blown_yellow", "alarm_blown_red", "alarm_damaged_green", "alarm_damaged_green", "alarm_damaged_red", }; String[] barrierAlarms = new String[] { "alarm_opening", "alarm_closing", "alarm_broken", "alarm_manual", }; String[] loopInputAlarms = new String[] { "alarm_error_loop_input", "alarm_loop_input_active", "alarm_internal_error", }; String[] loopOutputAlarms = new String[] { "alarm_error_loop_output", "alarm_internal_error", }; boolean semaphoreActiveAlarm = Stream.of(semaphoreAlarms).anyMatch(alarm -> alarms.getAlarm(alarm) > 0); boolean barrierActiveAlarm = Stream.of(barrierAlarms).anyMatch(alarm -> alarms.getAlarm(alarm) > 0); boolean loopInputActiveAlarm = Stream.of(loopInputAlarms).anyMatch(alarm -> alarms.getAlarm(alarm) > 0); boolean loopOutputActiveAlarm = Stream.of(loopOutputAlarms).anyMatch(alarm -> alarms.getAlarm(alarm) > 0); SVGElement semaphoreAlarm = getChildContainingField(element,"art.id","Sempahore.Alarm"); SVGElement barrierAlarm = getChildContainingField(element,"art.id","Barrier.Alarm"); setAttribute(semaphoreAlarm, "fill", semaphoreActiveAlarm ? "#FF0000" : "#00FF00", 999); setAttribute(barrierAlarm, "fill", barrierActiveAlarm ? "#FF0000" : "#00FF00", 999); SVGElement barrierBackground = getChildContainingField(element,"art.id","Barrier.Background"); SVGElement semaphoreBackground = getChildContainingField(element,"art.id","Sempahore.Background"); SVGElement loop1 = getChildContainingField(element,"art.id","Loop1"); SVGElement loop2 = getChildContainingField(element,"art.id","Loop2"); if (barrierActiveAlarm) setAttribute(barrierBackground, "fill", "#FF0000",999); if(semaphoreActiveAlarm) setAttribute(semaphoreBackground, "fill", "#FF0000",999); if(loopInputActiveAlarm) setAttribute(loop1, "fill", "#FF0000",999); if(loopOutputActiveAlarm) setAttribute(loop2, "fill", "#FF0000",999); } private void barierDeviceStatus(SVGElement element, BarrierStatus deviceStatus) { SVGElement barrierBackground = getChildContainingField(element,"art.id","Barrier.Background"); SVGElement semaphoreBackground = getChildContainingField(element,"art.id","Sempahore.Background"); String statusColor = "#00FF00"; switch (deviceStatus.status) { case DeviceStatus.STATUS_OFFLINE: case DeviceStatus.STATUS_UNKNOWN: statusColor = "#FF00FF"; break; } setAttribute(barrierBackground, "fill", statusColor, 999); setAttribute(semaphoreBackground, "fill", statusColor, 999); } // private final HashMap mapMessages = new HashMap<>(); public void paint(Graphics2D g2) { System.out.println("PAINTING VMS"); for (SVGElement element : getElementsContainingField("art.device")) { Device device = Shared.model.modelDevices.getDevice(getAttribute(element, "art.device")); if (device instanceof VmsGeneral) { VmsGeneral vms = (VmsGeneral) device; VmsMessageStorage storemessage = new VmsMessageStorage(); if(!mapMessages.containsKey(vms.getIdentifier())) mapMessages.put(vms.getIdentifier(),storemessage); VmsMessageStorage messageStore = mapMessages.get(vms.getIdentifier()); SVGElement background = getChildContainingField(element, "art.id", "Background"); Shape shape = getBoundingBox(background); double w = shape.getBounds2D().getWidth() * g2.getTransform().getScaleX(); double h = shape.getBounds2D().getHeight() * g2.getTransform().getScaleY(); messageStore.getNextMessage(vms.getDeviceStatus().lmessage).ifPresent(message -> { BoardDocument document = message.document; boolean width = w < document.width * 1.25f; boolean height = h < document.height * 1.25f; if (width || height) { BufferedImage image = document.getBufferedImage(); g2.drawImage(image.getScaledInstance((int) shape.getBounds2D().getWidth(), (int) shape.getBounds2D().getHeight(), Image.SCALE_FAST), (int) shape.getBounds2D().getX(), (int) shape.getBounds2D().getY(), null); } else { BufferedImage image = document.getRealisticImage((int)shape.getBounds2D().getWidth(), (int)shape.getBounds2D().getHeight(), true); g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g2.drawImage(image, (int) shape.getBounds2D().getX(), (int) shape.getBounds2D().getY(), null); g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); } }); } } } public class VmsMessageStorage { private List lMessage; private long currentMessageTimestamp = 0; private VmsGeneralStatusMessage currentMessage; public Optional getNextMessage(List currentMessages) { checkMessageList(currentMessages); Optional messageOpt = Optional.empty(); if(lMessage.isEmpty()) return messageOpt; if(currentMessage == null) { messageOpt = Optional.of(lMessage.get(0)); currentMessageTimestamp = System.currentTimeMillis(); currentMessage = messageOpt.get(); } else { if((System.currentTimeMillis() - currentMessageTimestamp) >= currentMessage.time * 1000) { currentMessageTimestamp = System.currentTimeMillis(); int messageIndex = lMessage.indexOf(currentMessage); int nextIndex = messageIndex >= lMessage.size() - 1 ? 0 : messageIndex + 1 ; currentMessage = lMessage.get(nextIndex); } messageOpt = Optional.of(currentMessage); } return messageOpt; } private void checkMessageList(List currentMessages) { try { if (!Serialization.equals(currentMessages, lMessage)) { lMessage = currentMessages; currentMessage = null; } } catch (Exception ex){} } } }