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.cctv.camera.Camera;
|
import art.library.model.devices.cctv.camera.CameraStatus;
|
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.Collectors;
|
import java.util.stream.Stream;
|
|
|
public class TunnelAlmeria extends DeviceGraphicsRuntime
|
{
|
private boolean even = false;
|
private final DecimalFormat decimalFormat = new DecimalFormat("0.00");
|
|
public TunnelAlmeria (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 : Shared.model.modelDevices.getDevicesListRead().stream().map(Device::getClass).collect(Collectors.toSet()))
|
{
|
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){}
|
}
|
}
|
|
//<editor-fold defaultstate="collapsed" desc="SignalsBoard">
|
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)
|
{
|
SignalStatus signal = svgDevice.getDeviceStatus().getSignal(signals[0]);
|
|
if (signal != null)
|
{
|
setText(element, decimalFormat.format(Float.valueOf(signal.value)) + " " + (signal.units != null ? Shared.getMessage(signal.units) : ""));
|
}
|
else
|
{
|
boolean floodAlarm = Stream.of(signals).anyMatch(signalAlarm -> svgDevice.getAlarm(signalAlarm) > 0);
|
|
if (signals.length > 1)
|
{
|
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);
|
}
|
}
|
}
|
}
|
//</editor-fold>
|
|
//<editor-fold defaultstate="collapsed" desc="ASF">
|
public void status(Asf svgDevice, SVGElement element) throws Exception
|
{
|
|
if (element.getStyleAbsolute("display").getStringValue().equals("none"))
|
return;
|
|
AsfStatus status = svgDevice.getDeviceStatus();
|
|
SVGElement alarm = getChildContainingField(element,"art.id","Alarm");
|
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(alarm, "display", "none", 999);
|
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";
|
|
switch (status.status)
|
{
|
case DeviceStatus.STATUS_ALARM:
|
setAttribute(alarm, "display", "inline",999);
|
break;
|
case DeviceStatus.STATUS_OFFLINE:
|
case DeviceStatus.STATUS_UNKNOWN:
|
colorBackground = "#FF00FF";
|
break;
|
}
|
|
setAttribute(background, "fill", colorBackground,999);
|
}
|
//</editor-fold>
|
|
//<editor-fold defaultstate="collapsed" desc="VmsGeneral">
|
public void status(VmsGeneral svgDevice, SVGElement element) throws Exception
|
{
|
if (element.getStyleAbsolute("display").getStringValue().equals("none"))
|
{
|
return;
|
}
|
|
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);
|
}
|
//</editor-fold>
|
|
//<editor-fold defaultstate="collapsed" desc="Barrier">
|
public void status(Barrier svgDevice, SVGElement element) throws Exception //BARRIER
|
{
|
if (element.getStyleAbsolute("display").getStringValue().equals("none"))
|
{
|
return;
|
}
|
|
if (getChildContainingField(element, "art.id", "Semaphore.Arrow") != null)
|
{
|
barrierSignalStatus(element, svgDevice);
|
}
|
else
|
{
|
BarrierRealtimeITC realtime = ((BarrierRealtime) svgDevice.getDeviceRealtime()).itc;
|
{
|
barrierStatus(element, realtime);
|
semaphoreStatus(element, realtime);
|
}
|
|
barrierDeviceStatus(element, svgDevice.getDeviceStatus());
|
barrierAlarms(element, svgDevice.getDeviceAlarms(), realtime);
|
}
|
}
|
|
private void barrierStatus(SVGElement element, BarrierRealtimeITC realtimeItc)
|
{
|
SVGElement[] barrierElements = new SVGElement[]
|
{
|
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));
|
setAttribute(barrierElements[3], "fill", "#FF0000", 999);
|
SVGElement elementToShow = null;
|
|
switch (realtimeItc.position)
|
{
|
case BarrierRealtimeITC.POSITION_DOWN: elementToShow = barrierElements[0]; break;
|
case BarrierRealtimeITC.POSITION_CLOSING: elementToShow = barrierElements[1]; break;
|
case BarrierRealtimeITC.POSITION_OPENING: elementToShow = barrierElements[2]; break;
|
}
|
|
|
|
switch (realtimeItc.lock)
|
{
|
case BarrierRealtimeITC.LOCK_LOCK:
|
setAttribute(barrierElements[3], "display", "inline", 999);
|
break;
|
case BarrierRealtimeITC.LOCK_UNLOCK:
|
setAttribute(barrierElements[3], "display", "none", 999);
|
break;
|
case BarrierRealtimeITC.LOCK_UNKNOWN:
|
setAttribute(barrierElements[3], "display", "inline", 999);
|
setAttribute(barrierElements[3], "fill", "#FF00FF", 999);
|
break;
|
}
|
|
if(elementToShow != null)
|
setAttribute(elementToShow, "display", "inline", 999);
|
|
}
|
|
private void barrierSignalStatus(SVGElement element, Barrier svgDevice)
|
{
|
SVGElement background = getChildContainingField(element, "art.id", "Barrier.Background");
|
SVGElement semaphoreArrow = getChildContainingField(element, "art.id", "Semaphore.Arrow");
|
|
setAttribute(semaphoreArrow, "display", "none", 999);
|
|
switch (svgDevice.getDeviceStatus().status)
|
{
|
case DeviceStatus.STATUS_UNKNOWN:
|
case DeviceStatus.STATUS_OFFLINE:
|
setAttribute(background, "fill", "#FF00FF");
|
break;
|
default:
|
setAttribute(background, "fill", "#808080");
|
break;
|
}
|
|
if (device.getDeviceRealtime() != null)
|
{
|
BarrierRealtime realtime = ((Barrier) device).getDeviceRealtime();
|
|
if (realtime.itc != null)
|
{
|
BarrierRealtimeITC realtimeITC = realtime.itc;
|
|
setAttribute(semaphoreArrow, "display",
|
realtimeITC.trafficLight == BarrierRealtimeITC.TRAFFIC_LIGHT_RED
|
? "inline"
|
: "none",
|
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", "#FFFF00");
|
if (realtimeItc.loopOutput == BarrierRealtimeITC.LOOP_ACTIVE)
|
setAttribute(loop2, "fill", "#FFFF00");
|
|
}
|
|
private void semaphoreStatus(SVGElement element, BarrierRealtimeITC realtimeItc)
|
{
|
|
SVGElement semaphoreRed = getChildContainingField(element,"art.id","Semaphore.Red");
|
SVGElement semaphoreYellow = getChildContainingField(element,"art.id","Semaphore.Yellow");
|
SVGElement semaphoreGreen = getChildContainingField(element,"art.id","Semaphore.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);
|
break;
|
case BarrierRealtimeITC.TRAFFIC_LIGHT_YELLOW:
|
setAttribute(semaphoreYellow, "fill", "#FFFF00", 999);
|
break;
|
case BarrierRealtimeITC.TRAFFIC_LIGHT_RED:
|
setAttribute(semaphoreRed, "fill", "#FF0000", 999);
|
break;
|
case BarrierRealtimeITC.TRAFFIC_LIGHT_UNKNOWN:
|
setAttribute(semaphoreGreen, "fill", "#800080", 999);
|
setAttribute(semaphoreYellow, "fill", "#800080", 999);
|
setAttribute(semaphoreRed, "fill", "#800080", 999);
|
break;
|
}
|
}
|
|
private void barrierAlarms(SVGElement element, BarrierAlarms alarms, BarrierRealtimeITC realtimeItc)
|
{
|
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",
|
"alarm_closed"
|
};
|
|
boolean semaphoreActiveAlarm = Stream.of(semaphoreAlarms).anyMatch(alarm -> alarms.getAlarm(alarm) > 0);
|
boolean barrierActiveAlarm = Stream.of(barrierAlarms).anyMatch(alarm -> alarms.getAlarm(alarm) > 0);
|
boolean semaphoreStatusUnknown = realtimeItc.trafficLight == BarrierRealtimeITC.TRAFFIC_LIGHT_UNKNOWN;
|
boolean barrierStatusUnknown = realtimeItc.position == BarrierRealtimeITC.POSITION_UNKNOWN;
|
|
SVGElement semaphoreAlarm = getChildContainingField(element, "art.id", "Semaphore.Alarm");
|
SVGElement barrierAlarm = getChildContainingField(element, "art.id", "Barrier.Alarm");
|
SVGElement barrierBackground = getChildContainingField(element, "art.id", "Barrier.Background");
|
SVGElement semaphoreBackground = getChildContainingField(element,"art.id","Semaphore.Background");
|
|
setAttribute(semaphoreAlarm, "display", "none", 999);
|
setAttribute(barrierAlarm, "display", "none", 999);
|
setAttribute(barrierBackground, "fill", "#FF00FF", 999);
|
setAttribute(semaphoreBackground, "fill", "#FF00FF", 999);
|
|
if(!barrierStatusUnknown)
|
setAttribute(barrierBackground, "fill", barrierActiveAlarm ? "#FF0000" : "#00FF00", 999);
|
if(!semaphoreStatusUnknown)
|
setAttribute(semaphoreBackground, "fill","#808080", 999);
|
|
if (barrierActiveAlarm && !barrierStatusUnknown)
|
setAttribute(barrierAlarm, "display", "inline",999);
|
if(semaphoreActiveAlarm && !semaphoreStatusUnknown)
|
setAttribute(semaphoreAlarm, "display", "inline",999);
|
}
|
|
private void barrierDeviceStatus(SVGElement element, BarrierStatus deviceStatus)
|
{
|
SVGElement barrierBackground = getChildContainingField(element, "art.id", "Barrier.Background");
|
SVGElement semaphoreBackground = getChildContainingField(element, "art.id", "Semaphore.Background");
|
SVGElement semaphoreAlarm = getChildContainingField(element, "art.id", "Semaphore.Alarm");
|
SVGElement barrierAlarm = getChildContainingField(element, "art.id", "Barrier.Alarm");
|
SVGElement barrierLock = getChildContainingField(element, "art.id", "Barrier.Locked");
|
SVGElement barrierClosed = getChildContainingField(element, "art.id", "Barrier.Closed");
|
SVGElement barrierClosing = getChildContainingField(element, "art.id", "Barrier.Closing");
|
SVGElement barrierOpening = getChildContainingField(element, "art.id", "Barrier.Opening");
|
SVGElement semaphoreRed = getChildContainingField(element, "art.id", "Semaphore.Red");
|
SVGElement semaphoreYellow = getChildContainingField(element, "art.id", "Semaphore.Yellow");
|
SVGElement semaphoreGreen = getChildContainingField(element, "art.id", "Semaphore.Green");
|
|
String statusOfflineColor = "#FF00FF";
|
String statusOfflineColorDarker = "#800080";
|
|
switch (deviceStatus.status)
|
{
|
case DeviceStatus.STATUS_OFFLINE:
|
case DeviceStatus.STATUS_UNKNOWN:
|
setAttribute(barrierBackground, "fill", statusOfflineColor, 999);
|
setAttribute(semaphoreBackground, "fill", statusOfflineColor, 999);
|
setAttribute(semaphoreRed, "fill", statusOfflineColorDarker, 999);
|
setAttribute(semaphoreYellow, "fill", statusOfflineColorDarker, 999);
|
setAttribute(semaphoreGreen, "fill", statusOfflineColorDarker, 999);
|
setAttribute(semaphoreAlarm, "display", "none", 999);
|
setAttribute(barrierAlarm, "display", "none", 999);
|
setAttribute(barrierLock, "display", "none", 999);
|
setAttribute(barrierClosed, "display", "none", 999);
|
setAttribute(barrierClosing, "display", "none", 999);
|
setAttribute(barrierOpening, "display", "none", 999);
|
break;
|
}
|
|
}
|
//</editor-fold>
|
|
//<editor-fold defaultstate="collapsed" desc="Camera">
|
public void status(Camera svgDevice, SVGElement element) throws Exception
|
{
|
if (element.getStyleAbsolute("display").getStringValue().equals("none"))
|
return;
|
|
CameraStatus status = svgDevice.getDeviceStatus();
|
String colorBackground = "#808080";
|
|
switch (status.status)
|
{
|
case DeviceStatus.STATUS_ALARM:
|
colorBackground = "#FF0000";
|
break;
|
case DeviceStatus.STATUS_OFFLINE:
|
case DeviceStatus.STATUS_UNKNOWN:
|
colorBackground = "#FF00FF";
|
break;
|
}
|
|
setAttribute(element, "fill", colorBackground, 999);
|
}
|
//</editor-fold>
|
|
//<editor-fold defaultstate="collapsed" desc="VMS MESSAGE PAINTING">
|
private final HashMap<String,VmsMessageStorage> mapMessages = new HashMap<>();
|
|
public void paint(Graphics2D g2)
|
{
|
for (SVGElement element : getElementsContainingField("art.device"))
|
{
|
Device device = Shared.model.modelDevices.getDevice(getAttribute(element, "art.device"));
|
|
if (device instanceof VmsGeneral)
|
{
|
if(element.getStyleAbsolute("display").getStringValue().equals("none"))
|
continue;
|
|
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<VmsGeneralStatusMessage> lMessage;
|
private long currentMessageTimestamp = 0;
|
private VmsGeneralStatusMessage currentMessage;
|
|
public Optional<VmsGeneralStatusMessage> getNextMessage(List<VmsGeneralStatusMessage> currentMessages)
|
{
|
checkMessageList(currentMessages);
|
|
Optional<VmsGeneralStatusMessage> 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<VmsGeneralStatusMessage> currentMessages)
|
{
|
try
|
{
|
if (!Serialization.equals(currentMessages, lMessage))
|
{
|
lMessage = currentMessages;
|
currentMessage = null;
|
}
|
}
|
catch (Exception ex){}
|
}
|
}
|
//</editor-fold>
|
|
}
|