package art.client.maps;
|
|
import art.client.models.Shared;
|
import art.library.model.devices.Device;
|
import art.library.model.devices.DeviceGraphicsRuntime;
|
import art.library.model.devices.DeviceStatus;
|
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.pvv.Pvv;
|
import art.library.model.devices.vms.pvv.PvvAlarms;
|
import art.library.model.devices.vms.pvv.PvvStatus;
|
import com.kitfox.svg.*;
|
import java.lang.reflect.Method;
|
import java.math.BigDecimal;
|
import java.util.*;
|
import java.util.stream.Stream;
|
|
public class VigicatCUC extends DeviceGraphicsRuntime
|
{
|
|
private double rowHeightBetweenLines = 20;
|
|
private final HashMap<SVGElement,Runnable> mapRunnableElements = new HashMap();
|
private final HashMap<SVGElement, double[]> mapTopCoordinates = new HashMap();
|
private final HashMap<SVGElement, String> mapBaseColors = new HashMap();
|
|
public VigicatCUC(SVGDiagram diagram)
|
{
|
super(diagram);
|
}
|
|
public void status(){
|
|
getElementsContainingField("art.loadglobalinfo").stream().forEach(this::loadGlobalInfo);
|
getElementsContainingField("art.device").stream().forEach(this::refreshElement);
|
getElementsContainingField("art.signal").stream().forEach(this::refreshElement);
|
getElementsContainingField("art.signal.etd").stream().forEach(this::updateEtdNode);
|
getElementsContainingField("art.node.start").stream().forEach(this::updateNodeLinePosition);
|
getElementsContainingField("art.speed.column").stream().forEach(this::updateSpeedColumn);
|
}
|
|
private void refreshElement(SVGElement element)
|
{
|
try
|
{
|
if (!mapRunnableElements.containsKey(element))
|
{
|
Device device = Shared.model.modelDevices.getDevice(getAttribute(element, "art.device"));
|
Method method = this.getClass().getMethod("status", device.getClass(), SVGElement.class);
|
|
mapRunnableElements.put(element, () ->
|
{
|
try
|
{
|
method.invoke(this, device, element);
|
}
|
catch (Exception ex){}
|
});
|
}
|
|
mapRunnableElements.get(element).run();
|
|
} catch (Exception e){}
|
}
|
|
public void status(Asf svgDevice, SVGElement element) {
|
AsfStatus status = svgDevice.getDeviceStatus();
|
|
SVGElement background = getChildContainingField(element, "art.id", "Background");
|
SVGElement border = getChildContainingField(element, "art.id", "Border");
|
SVGElement alarm = getChildContainingField(element, "art.id", "Alarm");
|
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");
|
SVGElement textBUS = getChildContainingField(element, "art.id", "textBUS");
|
SVGElement left_lane_closed = getChildContainingField(element, "art.id", "left-lane-closed");
|
|
setAttribute(background, "fill", getGenericDualStatusColor(status.status)[0]);
|
setAttribute(border, "stroke", getGenericDualStatusColor(status.status)[1]);
|
|
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);
|
setAttribute(textBUS, "display", "none", 999);
|
|
if (left_lane_closed != null)
|
setAttribute(left_lane_closed, "display", "none", 999);
|
|
boolean knownStatus = status.status != DeviceStatus.STATUS_OFFLINE && status.status != 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);
|
setAttribute(textBUS, "display", status.state == AsfStatus.STATE_BUS ? "inline" : "none", 999);
|
|
if(status.state == AsfStatus.STATE_S52_LEFT && left_lane_closed != null)
|
setAttribute(left_lane_closed, "display", "inline", 999);
|
}
|
|
String colorBackground = "#000000";
|
String colorAlarm = "#000000";
|
|
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);
|
|
}
|
//</editor-fold>
|
|
//<editor-fold defaultstate="collapsed" desc="ASF">
|
/* 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");
|
SVGElement textBUS = getChildContainingField(element, "art.id", "textBUS");
|
SVGElement left_lane_closed = getChildContainingField(element, "art.id", "left-lane-closed");
|
|
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);
|
setAttribute(textBUS, "display", "none", 999);
|
|
if(left_lane_closed != null)
|
setAttribute(left_lane_closed, "display", "none", 999);
|
|
boolean knownStatus = status.status != DeviceStatus.STATUS_OFFLINE && status.status != 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);
|
setAttribute(textBUS, "display", status.state == AsfStatus.STATE_BUS ? "inline" : "none", 999);
|
|
if(status.state == AsfStatus.STATE_S52_LEFT && left_lane_closed != null)
|
setAttribute(left_lane_closed, "display", "inline", 999);
|
}
|
|
String colorBackground = "#000000";
|
String colorAlarm = "#000000";
|
|
switch (status.status){
|
case DeviceStatus.STATUS_ALARM:
|
colorAlarm = "#FF0000";
|
break;
|
case DeviceStatus.STATUS_OFFLINE:
|
case DeviceStatus.STATUS_UNKNOWN:
|
colorBackground = "#FFFFFF";
|
colorAlarm = "#800080";
|
break;
|
}
|
|
setAttribute(border, "stroke", colorAlarm, 999);
|
setAttribute(background, "fill", colorBackground, 999);
|
|
}*/
|
//</editor-fold>
|
|
//<editor-fold defaultstate="collapsed" desc="SignalBoard">
|
public void status(SignalsBoard svgDevice, SVGElement element)
|
{
|
SignalStatus signal = svgDevice.getDeviceStatus().getSignal(getAttribute(element, "art.signal"));
|
|
BigDecimal signalValueNumber = new BigDecimal(signal.value);
|
|
boolean hasAlarm = svgDevice.getAlarm(signal.name) > 0;
|
|
setText(element, signalValueNumber.intValue() + "");
|
setAttribute(element, "fill", hasAlarm ? "#db3939" : "#000000", 999);
|
setAttribute(element, "fill-opacity", 1, 999);
|
}
|
//</editor-fold>
|
|
//<editor-fold defaultstate="collapsed" desc="PVV">
|
public void status(Pvv svgDevice, SVGElement element)
|
{
|
if (getChildContainingField(element, "art.id", "Alarm") != null)
|
paintBigPvvElement(svgDevice, element);
|
else
|
paintSmallPvvElement(svgDevice, element);
|
}
|
|
private void paintSmallPvvElement(Pvv svgDevice, SVGElement element)
|
{
|
DeviceStatus status = svgDevice.getDeviceStatus();
|
|
SVGElement background = getChildContainingField(element, "art.id", "Background");
|
SVGElement border = getChildContainingField(element, "art.id", "Border");
|
|
setAttribute(background, "fill", getGenericDualStatusColor(status.status)[0]);
|
setAttribute(border, "stroke", getGenericDualStatusColor(status.status)[1]);
|
}
|
|
private void paintBigPvvElement(Pvv svgDevice, SVGElement element)
|
{
|
PvvStatus status = svgDevice.getDeviceStatus();
|
PvvAlarms alarms = svgDevice.getDeviceAlarms();
|
|
SVGElement background = getChildContainingField(element, "art.id", "Background");
|
SVGElement border = getChildContainingField(element, "art.id", "Border");
|
SVGElement alarm = getChildContainingField(element, "art.id", "Alarm");
|
SVGElement textUnder100 = getChildContainingField(element, "art.id", "Text1");
|
SVGElement textOver100 = getChildContainingField(element, "art.id", "Text2");
|
|
setAttribute(textUnder100, "display", "none", 999);
|
setAttribute(textOver100, "display", "none", 999);
|
setAttribute(alarm, "display", "inline", 999);
|
setAttribute(alarm, "stroke", "#FF0000", 999);
|
|
setAttribute(background, "fill", "#FF00FF");
|
setAttribute(border, "stroke", "#800080");
|
|
setAttribute(alarm, "stroke-width", alarms.getServerityAlarm());
|
setAttribute(background, "fill", getGenericDualStatusColor(status.status)[0]);
|
setAttribute(border, "stroke", getGenericDualStatusColor(status.status)[1]);
|
|
if(status.state != PvvStatus.STATE_OFF)
|
{
|
SVGElement textObject = status.speed >= 100 ? textOver100 : textUnder100;
|
setText(textObject, String.valueOf(status.speed) );
|
setAttribute(textObject, "display", "inline", 999);
|
}
|
|
switch (status.status)
|
{
|
case PvvStatus.STATUS_OFFLINE:
|
case PvvStatus.STATUS_UNKNOWN:
|
setAttribute(alarm, "display", "none",999);
|
setAttribute(textOver100, "display", "none",999);
|
setAttribute(textUnder100, "display", "none",999);
|
break;
|
}
|
}
|
|
private void updateSpeedColumn(SVGElement element)
|
{
|
try
|
{
|
|
Pvv svgDevice = (Pvv) Shared.model.modelDevices.getDevice(getAttribute(element, "art.device"));
|
SignalsBoard signalsBoard = (SignalsBoard) Shared.model.modelDevices.getDevice(getAttribute(element, "art.algorithm"));
|
|
if (signalsBoard != null)
|
{
|
SignalStatus signal = signalsBoard.getDeviceStatus().getSignal(getAttribute(element, "art.signal"));
|
SignalStatus signalAlgorithmState = signalsBoard.getDeviceStatus().getSignalInput("state-algorithm-dynamic");
|
if (signalAlgorithmState.value == null) signalAlgorithmState.value = "false";
|
boolean algorithmState = Boolean.parseBoolean(signalAlgorithmState.value);
|
if (signal != null)
|
{
|
boolean automatico = Boolean.parseBoolean(signal.value);
|
setAttribute(element, "fill", (automatico && algorithmState) ? "#e6d69040" : "#e0893351"); //si se fija la velocidad
|
}
|
}
|
|
if (!mapTopCoordinates.containsKey(element))
|
{
|
mapTopCoordinates.put(element, new double[]{element.getPresAbsolute("y").getDoubleValue() + rowHeightBetweenLines, element.getPresAbsolute("height").getDoubleValue()});
|
}
|
|
double baseY = mapTopCoordinates.get(element)[0];
|
|
final int speed = svgDevice.getDeviceStatus().speed;
|
final double verticalOffset = getVerticalOffset(element, speed);
|
|
|
Optional<SVGElement> lineElement1 = getElementsContainingField("art.speed.line").stream()
|
.filter(val -> getAttribute(val, "art.signal").replace("-maximum-speed", "").equalsIgnoreCase(svgDevice.getIdentifier()))
|
.findAny();
|
|
String nominalSpeed = "";
|
|
if(lineElement1.isPresent())
|
{
|
SignalStatus signal = signalsBoard.getDeviceStatus().getSignal(getAttribute(lineElement1.get(), "art.signal"));
|
nominalSpeed = signal.value;
|
if (signal != null)
|
{
|
try
|
{
|
setAttribute(lineElement1.get(), "y1", getVerticalOffset(element, Integer.parseInt(signal.value)));
|
setAttribute(lineElement1.get(), "y2", getVerticalOffset(element, Integer.parseInt(signal.value)));
|
setAttribute(lineElement1.get(), "stroke", "#646a73");
|
|
update(lineElement1.get());
|
}
|
catch (Exception ex){}
|
}
|
}
|
|
Optional<SVGElement> lineElement2 = getElementsContainingField("art.speed.line").stream()
|
.filter(val -> getAttribute(val, "art.signal").replace("-nominal-speed", "").equalsIgnoreCase(svgDevice.getIdentifier()))
|
.findAny();
|
|
if(lineElement2.isPresent())
|
{
|
SignalStatus signal = signalsBoard.getDeviceStatus().getSignal(getAttribute(lineElement2.get(), "art.signal"));
|
|
if (signal != null)
|
{
|
try
|
{
|
setAttribute(lineElement2.get(), "y1", getVerticalOffset(element, Integer.parseInt(signal.value)));
|
setAttribute(lineElement2.get(), "y2", getVerticalOffset(element, Integer.parseInt(signal.value)));
|
setAttribute(lineElement2.get(), "stroke", "#646a73");
|
|
if(signal.value != null && signal.value.equals(nominalSpeed) == false)
|
{
|
setAttribute(lineElement1.get(), "stroke", "#fa0000");
|
}
|
|
update(lineElement2.get());
|
}
|
catch (Exception ex){}
|
}
|
}
|
|
setAttribute(element, "height", Math.abs(baseY - verticalOffset));
|
setAttribute(element, "y", verticalOffset);
|
update(element);
|
}
|
catch (Exception ex)
|
{
|
}
|
|
}
|
|
private void loadGlobalInfo(SVGElement element)
|
{
|
try
|
{
|
|
if("LineSpeedInfo".equals(getAttribute(element, "art.loadglobalinfo")))
|
{
|
rowHeightBetweenLines = Double.parseDouble(getAttribute(element, "art.heightbetweenlines"));
|
}
|
|
} catch (Exception ex)
|
{
|
}
|
|
}
|
//</editor-fold>
|
|
|
|
//<editor-fold defaultstate="collapsed" desc="Etd's">
|
private void updateEtdNode(SVGElement element)
|
{
|
try
|
{
|
SignalsBoard signalsBoard = (SignalsBoard) Shared.model.modelDevices.getDevice(getAttribute(element, "art.device"));
|
|
if (signalsBoard != null)
|
{
|
SignalStatus signal = signalsBoard.getDeviceStatus().getSignal(getAttribute(element, "art.signal.etd"));
|
|
boolean alarm = signalsBoard.getAlarm(signal.name) > 0;
|
|
if (!mapTopCoordinates.containsKey(element))
|
{
|
mapTopCoordinates.put(element, new double[]
|
{
|
element.getPresAbsolute("y").getDoubleValue(), 0
|
});
|
}
|
|
if (!mapBaseColors.containsKey(element))
|
{
|
String[] styleAttributes = element
|
.getPresAbsolute("style")
|
.getStringValue()
|
.split(";");
|
|
Optional<String> fillValue = Stream.of(styleAttributes)
|
.filter(val -> val.split(":")[0].equals("fill"))
|
.map(val -> val.split(":")[1])
|
.findAny();
|
|
fillValue.ifPresent(val -> mapBaseColors.put(element, val));
|
}
|
double value = Double.valueOf(signal.value);
|
|
if (element instanceof Text)
|
{
|
setText(element, String.valueOf((int)value));
|
}
|
|
setAttribute(element, "fill", alarm ? "#db3939" : mapBaseColors.get(element));
|
setAttribute(element, "y", getVerticalOffset(element, value));
|
|
update(element);
|
}
|
}
|
catch (Exception ex){}
|
|
}
|
|
private double getVerticalOffset(SVGElement element, double value)
|
{
|
final double baseValue = mapTopCoordinates.get(element)[0];
|
|
return baseValue - (rowHeightBetweenLines * (value / 10));
|
}
|
|
private void updateNodeLinePosition(SVGElement element)
|
{
|
try
|
{
|
String startNodeID = getAttribute(element, "art.node.start");
|
String endNodeID = getAttribute(element, "art.node.end");
|
|
if (startNodeID != null && endNodeID != null)
|
{
|
Optional<SVGElement> nodeStart = getElementsContainingField("art.signal.etd").stream()
|
.filter(el -> getAttribute(el, "art.signal.etd").equals(startNodeID))
|
.findAny();
|
|
Optional<SVGElement> nodeEnd = getElementsContainingField("art.signal.etd").stream()
|
.filter(el -> getAttribute(el, "art.signal.etd").equals(endNodeID))
|
.findAny();
|
|
double startNodeHeight = nodeStart.get().getPresAbsolute("height").getDoubleValue();
|
double endNodeHeight = nodeEnd.get().getPresAbsolute("height").getDoubleValue();
|
|
double startNodeWidth = nodeStart.get().getPresAbsolute("width").getDoubleValue();
|
double endNodeWidth = nodeEnd.get().getPresAbsolute("width").getDoubleValue();
|
|
nodeStart.ifPresent(node -> setAttribute(element, "x1", node.getPresAbsolute("x").getDoubleValue() + (startNodeWidth / 2)));
|
nodeStart.ifPresent(node -> setAttribute(element, "y1", node.getPresAbsolute("y").getDoubleValue() + (startNodeHeight / 2)));
|
|
nodeEnd.ifPresent(node -> setAttribute(element, "x2", node.getPresAbsolute("x").getDoubleValue() + (endNodeWidth / 2)));
|
nodeEnd.ifPresent(node -> setAttribute(element, "y2", node.getPresAbsolute("y").getDoubleValue() + (endNodeHeight / 2)));
|
|
update(element);
|
}
|
} catch (Exception ex)
|
{
|
}
|
|
}
|
//</editor-fold>
|
|
private static String[] getGenericDualStatusColor(int status)
|
{
|
String color1 = "#FF00FF";
|
String color2 = "#7C007C";
|
|
switch (status)
|
{
|
case DeviceStatus.STATUS_ONLINE:
|
color1 = "#00FF00";
|
color2 = "#007C00";
|
break;
|
case DeviceStatus.STATUS_WARNING:
|
color1 = "#FFFF00";
|
color2 = "#7C7C00";
|
break;
|
case DeviceStatus.STATUS_ALARM:
|
color1 = "#FF0000";
|
color2 = "#7C0000";
|
break;
|
case DeviceStatus.STATUS_INVALID:
|
color1 = "#B97A57";
|
color2 = "#5A3B2A";
|
break;
|
case DeviceStatus.STATUS_DISABLE:
|
color1 = "#7C7C7C";
|
color2 = "#3E3E3E";
|
break;
|
case DeviceStatus.STATUS_SIMULATION:
|
color1 = "#0000FF";
|
color2 = "#00007C";
|
break;
|
case DeviceStatus.STATUS_OFFLINE:
|
color1 = "#FF00FF";
|
color2 = "#7C007C";
|
break;
|
case DeviceStatus.STATUS_UNKNOWN:
|
color1 = "#FF00FF";
|
color2 = "#7C007C";
|
break;
|
}
|
|
return new String[] {color1, color2};
|
}
|
|
|
|
|
}
|