asd
Alejandro Acuña
2024-09-16 816cb391a192e357426312ab8e591fd49d1d242e
asd
6 files deleted
4 files modified
340 ■■■■ changed files
.gitignore 3 ●●●●● patch | view | raw | blame | history
servers/enforcement/gost-access-server/build/built-jar.properties 4 ●●●● patch | view | raw | blame | history
servers/enforcement/gost-access-server/build/classes/art/servers/gost/access/controller/Controller_ACCESS_Neural.class patch | view | raw | blame | history
servers/enforcement/gost-access-server/build/classes/art/servers/gost/access/controller/Controller_ACCESS_Neural_Detections$1.class patch | view | raw | blame | history
servers/enforcement/gost-access-server/build/classes/art/servers/gost/access/controller/Controller_ACCESS_Neural_Detections.class patch | view | raw | blame | history
servers/enforcement/gost-access-server/nbproject/private/private.xml 18 ●●●●● patch | view | raw | blame | history
servers/enforcement/gost-access-server/src/art/servers/gost/access/controller/Controller_ACCESS_Neural.java 14 ●●●● patch | view | raw | blame | history
servers/enforcement/gost-access-server/src/art/servers/gost/access/controller/Controller_ACCESS_Neural_Detections.java 48 ●●●●● patch | view | raw | blame | history
servers/enforcement/gost-access-server/src/version.properties 8 ●●●●● patch | view | raw | blame | history
svgDevicesTest/maps/VigicatCUC.java 245 ●●●● patch | view | raw | blame | history
.gitignore
@@ -31,3 +31,6 @@
*.exe
*.rar
*.jar
servers/enforcement/gost-access-server/build/
servers/enforcement/gost-access-server/nbproject/private/private.xml
servers/enforcement/gost-access-server/src/version.properties
servers/enforcement/gost-access-server/build/built-jar.properties
File was deleted
servers/enforcement/gost-access-server/build/classes/art/servers/gost/access/controller/Controller_ACCESS_Neural.class
Binary files differ
servers/enforcement/gost-access-server/build/classes/art/servers/gost/access/controller/Controller_ACCESS_Neural_Detections$1.class
Binary files differ
servers/enforcement/gost-access-server/build/classes/art/servers/gost/access/controller/Controller_ACCESS_Neural_Detections.class
Binary files differ
servers/enforcement/gost-access-server/nbproject/private/private.xml
File was deleted
servers/enforcement/gost-access-server/src/art/servers/gost/access/controller/Controller_ACCESS_Neural.java
@@ -73,7 +73,7 @@
            }
        }
        // Shared.println(getName(), "Finished");
        Shared.println(getName(), "Finished");
        Shared.traceInformation(getName(), Shared.getMessage("Finishing"));
    }
@@ -90,7 +90,7 @@
        }
        catch (Exception e)
        {
            // Shared.printstack(getName(), e);
            Shared.printstack(getName(), e);
        }
    }
@@ -118,11 +118,11 @@
        }
        catch (Exception exception)
        {
            // exception.printStackTrace();
            exception.printStackTrace();
            if ((access.alarms.alarm_offline > 0) || (firstTime == true))
            {
                firstTime = false;
                // Shared.printstack(getName(), exception);
                Shared.printstack(getName(), exception);
            }
            offline(accessclone); // todas las camaras offline
@@ -147,7 +147,7 @@
        if ((accessclone.alarms.alarm_offline > 0) || (firstTime == true))
        {
            firstTime = false;
            // Shared.println(getName(), Shared.getMessage("Access online"));
            Shared.println(getName(), Shared.getMessage("Access online"));
        }
        lastOnline = System.currentTimeMillis();
@@ -164,7 +164,7 @@
        AccessEnforcementInformation information = accessclone.getDeviceInformation();
        // https://10.106.7.18/art?operation=getStatus
        String url = "https://" + information.neural.connection.address + ":" + information.neural.connection.port + "/art?operation=getStatus";
        String url = "https://" + information.neural.connection.address + "/art?operation=getStatus";
        String user = Shared.getText(information.neural.connection.user);
        String password = Shared.getText(information.neural.connection.password);
@@ -176,7 +176,7 @@
        url += "&token=" + user + "," + password;
        // System.out.println(getName() + " - " + url);
        System.out.println(getName() + " - " + url);
        byte[] response = HttpsRequest.requestBytes(url, user, password, new byte[0], 30000, 60000);
        NeuralStatus neuralStatus = Serialization.deserialize(NeuralStatus.class, response);
servers/enforcement/gost-access-server/src/art/servers/gost/access/controller/Controller_ACCESS_Neural_Detections.java
@@ -18,7 +18,6 @@
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -61,14 +60,17 @@
        {
            try
            {
                System.out.println(getName() + " - 1.RUN");
                if (Shared.isServerEnabled() == true)
                {
                    System.out.println(getName() + " - 2.RUN");
                    update();
                    System.out.println(getName() + " - 3.RUN");
                }
            }
            catch (Exception exception)
            {
                // exception.printStackTrace();
                exception.printStackTrace();
            }
            try 
@@ -97,9 +99,6 @@
    private void update() throws Exception
    {
        while (readDetections() == true);
        {
            try{sleep(100);} catch (Exception e){};
        }
    }
@@ -141,7 +140,6 @@
                if (detectionsCameraLane.size() > 0) detectionsCamera.addAll(detectionsCameraLane);
            }
            // Shared.println(this.getName(), "1.ReadDetections: " + detectionsCamera.size());
            for (AccessEnforcement_Detection detection  : detectionsCamera)
            {
                lastDetectionTimestamp = Math.max(lastDetectionTimestamp, detection.timestamp);
@@ -149,7 +147,6 @@
            }
            this.lastDetection = lastDetectionTimestamp;
            // Shared.println(this.getName(), "2.ReadDetections: " + detectionsCamera.size() + " - " + new Date(this.lastDetection).toString());
            
            
            //  Insert into database and update timestamps
@@ -160,10 +157,6 @@
                {
                    try
                    {
                        // Shared.println(this.getName(), "3.ReadDetections Detection: " + detection);
                        // Shared.println(this.getName(), "4.ReadDetections Detection: " + detection.images);
                        // Shared.println(this.getName(), "5.ReadDetections Detection: " + detection.getLastState());
                        // Shared.println(this.getName(), "5.ReadDetections Detection: " + detection.getLastState().vehicle);
                        if ((detection.images == null) || (detection.images.size() == 0))
                        {
                            getImagesDetectionUC(access, detection);
@@ -171,14 +164,12 @@
                    }
                    catch (Exception e)
                    {
                        // Shared.printstack(this.getName(), e);
                        Shared.printstack(this.getName(), e);
                    }
                    AccessEnforcement_Detection_State detectionState = detection.getLastState();
                    if (detectionState == null) detectionState = new AccessEnforcement_Detection_State();
                    if ((detection.images != null) && (detection.images.size() >= 2))
                    {
                        if (Shared.controllerDetections.hasPermission(detection, detectionState.vehicle.plate) != null)
@@ -188,7 +179,7 @@
                            detectionState.discarded.code = AccessEnforcement_Detection_State_Discarded.DISCARDED_ALLOWED;
                            detectionState.discarded.timestamp = System.currentTimeMillis();
                            detectionState.discarded.user = Shared.getApplicationName();
                            // Shared.printcorrect(getName(),Shared.getMessage("Successful (allowed), plate")  + " = " + detectionState.vehicle.plate + ", " + Shared.getMessage("date") + " = " + formato2.format(detection.timestamp));
                            Shared.printcorrect(getName(),Shared.getMessage("Successful (allowed), plate")  + " = " + detectionState.vehicle.plate + ", " + Shared.getMessage("date") + " = " + formato2.format(detection.timestamp));
                        }
                        else if ((this.detail.detections != null) && (detectionState.vehicle.confidence.floatValue() < this.detail.detections.plateConfidence) &&
                                 (this.detail.detections.enabled == true))
@@ -198,13 +189,13 @@
                            detectionState.discarded.code = AccessEnforcement_Detection_State_Discarded.DISCARDED_LOW_OCR_CONFIDENCE;
                            detectionState.discarded.timestamp = System.currentTimeMillis();
                            detectionState.discarded.user = Shared.getApplicationName();
                            // Shared.printerr(getName(),Shared.getMessage("Low ocr confidence, plate")  + " = " + detectionState.vehicle.plate + ", " + Shared.getMessage("confidence") + " = " + detectionState.vehicle.confidence.floatValue() + ", " + Shared.getMessage("date") + " = " + formato2.format(detection.timestamp));
                            Shared.printerr(getName(),Shared.getMessage("Low ocr confidence, plate")  + " = " + detectionState.vehicle.plate + ", " + Shared.getMessage("confidence") + " = " + detectionState.vehicle.confidence.floatValue() + ", " + Shared.getMessage("date") + " = " + formato2.format(detection.timestamp));
                        }
                        else
                        {
                            detectionState.state = AccessEnforcement_Detection_State.STATE_REVISION_PENDING;
                            detectionState.timestamp = System.currentTimeMillis();
                            // Shared.printcorrect(getName(),Shared.getMessage("Successful (revision pending), plate")  + " = " + detectionState.vehicle.plate + ", " + Shared.getMessage("date") + " = " + formato2.format(detection.timestamp));
                            Shared.printcorrect(getName(),Shared.getMessage("Successful (revision pending), plate")  + " = " + detectionState.vehicle.plate + ", " + Shared.getMessage("date") + " = " + formato2.format(detection.timestamp));
                        }
                    }
                    else
@@ -214,7 +205,7 @@
                        detectionState.discarded.code = AccessEnforcement_Detection_State_Discarded.DISCARDED_MISSING_PICTURES;
                        detectionState.discarded.timestamp = System.currentTimeMillis();
                        detectionState.discarded.description = detectionState.discarded.getDescription(detectionState.discarded.code);
                        // Shared.printerr(getName(),Shared.getMessage("Missing images, plate")  + " = " + detectionState.vehicle.plate + ", " + Shared.getMessage("date") + " = " + formato2.format(detection.timestamp));
                        Shared.printerr(getName(),Shared.getMessage("Missing images, plate")  + " = " + detectionState.vehicle.plate + ", " + Shared.getMessage("date") + " = " + formato2.format(detection.timestamp));
                    }
                    this.controller.updateDatabaseDetection(information, detection);
@@ -228,7 +219,7 @@
        }
        catch (Exception exception)
        {
            // Shared.printstack(getName(), exception);
            Shared.printstack(getName(), exception);
        }
        return false;
@@ -250,7 +241,7 @@
            SimpleDateFormat formato1 = new SimpleDateFormat("dd/MM/yyyy");
            SimpleDateFormat formato2 = new SimpleDateFormat("HH:mm:ss");
            String url = "https://" + information.neural.connection.address + ":" + information.neural.connection.port + "/art?operation=getDetections";
            String url = "https://" + information.neural.connection.address + "/art?operation=getDetections";
            url += "&from=" + formato1.format(from) + "%20" + formato2.format(from);
            url += "&to=" + formato1.format(to) + "%20" + formato2.format(to);
            url += "&lane=" + lane;
@@ -266,10 +257,9 @@
            url += "&token=" + user + "," + password;
            // Shared.println(this.getName(), "1.URL GetDEtections: " + url);
            Shared.println(this.getName(), "URL: " + url);
            byte[] response = HttpsRequest.requestBytes(url, user, password, new byte[0], 30000, 60000);
            AccessEnforcement_Detection[] ucDetections = Serialization.deserialize(AccessEnforcement_Detection[].class, response);
            // Shared.println(this.getName(), "2.GetDEtections: " + ucDetections.length);
            for (AccessEnforcement_Detection ucDetection : ucDetections)
            {
@@ -284,7 +274,7 @@
                        }
                        catch (Exception e)
                        {
                            // Shared.printstack(this.getName(), e);
                            e.printStackTrace();
                        }
                    }
                }
@@ -293,7 +283,7 @@
        }
        catch (Exception e)
        {
            // Shared.printstack(this.getName(), e);
            Shared.printstack(this.getName(), e);
        }
        return detections;
@@ -360,7 +350,7 @@
            // https://10.106.7.18/art?operation=getImage&incidence=22758&name=overview&token=write,EdubVmde
            // https://10.106.7.18/art?operation=getImage&incidence=22758&name=plate&token=write,EdubVmde
            String urlOverview = "https://" + access.getDeviceInformation().neural.connection.address + ":" + access.getDeviceInformation().neural.connection.port + "/art?operation=getImage";
            String urlOverview = "https://" + access.getDeviceInformation().neural.connection.address + "/art?operation=getImage";
            urlOverview += "&incidence=" + detection.incidence;
            urlOverview += "&name=overview";
@@ -373,9 +363,7 @@
            }
            urlOverview += "&token=" + user + "," + password;
            // Shared.println(this.getName(), "1.GetImages URLOver: " + urlOverview);
            byte[] response = HttpsRequest.requestBytes(urlOverview, user, password, new byte[0], 30000, 60000);
            // Shared.println(this.getName(), "2.GetImages URLOver: " + urlOverview);
            AccessEnforcement_Detection_Image imageOverview = new AccessEnforcement_Detection_Image();
            imageOverview.format = "jpg";
@@ -383,7 +371,7 @@
            imageOverview.data = response;
            accessDetectionImages.add(imageOverview);
            String urlPlate = "https://" + access.getDeviceInformation().neural.connection.address + ":" + access.getDeviceInformation().neural.connection.port + "/art?operation=getImage";
            String urlPlate = "https://" + access.getDeviceInformation().neural.connection.address + "/art?operation=getImage";
            urlPlate += "&incidence=" + detection.incidence;
            urlPlate += "&name=plate";
            urlPlate += "&token=" + user + "," + password;
@@ -398,7 +386,6 @@
        }
        catch (SerializationException e) 
        {
            // Shared.printstack(this.getName(), e);
            if (e.getMessage().indexOf("NoSuchFileException") < 0)
            {
                throw e;
@@ -406,7 +393,6 @@
        } 
        catch (Exception e)
        {
            // Shared.printstack(this.getName(), e);
            throw e;
        }
@@ -512,7 +498,7 @@
        { 
            public void run() 
            {
                // Shared.println(getName(), Shared.getMessage("Total detections in last minute") + " = " + counterDetections);
                Shared.println(getName(), Shared.getMessage("Total detections in last minute") + " = " + counterDetections);
                counterDetections = 0;
            }
        }, delay, 60000, TimeUnit.MILLISECONDS);
servers/enforcement/gost-access-server/src/version.properties
File was deleted
svgDevicesTest/maps/VigicatCUC.java
@@ -7,19 +7,20 @@
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.util.*;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Stream;
public class VigicatCUC extends DeviceGraphicsRuntime
{
    private static final double rowWidth = 6;
    private double rowHeightBetweenLines = 20;
    private final HashMap<SVGElement,Runnable> mapRunnableElements = new HashMap();
    private final HashMap<SVGElement, double[]> mapTopCoordinates = new HashMap();
@@ -30,8 +31,9 @@
        super(diagram);
    }
    public void status()
    {
    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);
@@ -63,18 +65,121 @@
        } catch (Exception e){}
    }
    
    //<editor-fold defaultstate="collapsed" desc="ASF">
    public void status(Asf svgDevice, SVGElement element)
    {
        DeviceStatus status = svgDevice.getDeviceStatus();
    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)
@@ -86,7 +191,7 @@
        boolean hasAlarm = svgDevice.getAlarm(signal.name) > 0;
        setText(element, signalValueNumber.intValue() + "");
        setAttribute(element, "fill", hasAlarm ? "#db3939" : "#78e678", 999);
        setAttribute(element, "fill", hasAlarm ? "#db3939" : "#000000", 999);
        setAttribute(element, "fill-opacity", 1, 999);
    }
//</editor-fold>
@@ -155,22 +260,106 @@
    private void updateSpeedColumn(SVGElement element)
    {
        try
        {
        {
             Pvv svgDevice = (Pvv) Shared.model.modelDevices.getDevice(getAttribute(element, "art.device"));
        if (!mapTopCoordinates.containsKey(element))
             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)
        {
            mapTopCoordinates.put(element, new double[]{element.getPresAbsolute("y").getDoubleValue() + rowWidth, element.getPresAbsolute("height").getDoubleValue()});
        }
        double baseY = mapTopCoordinates.get(element)[0];
        final int speed = svgDevice.getDeviceStatus().speed;
        final double verticalOffset = getVerticalOffset(element, speed);
        setAttribute(element, "height", Math.abs(baseY - verticalOffset));
        setAttribute(element, "y", verticalOffset);
        update(element);
    }
    private void loadGlobalInfo(SVGElement element)
    {
        try
        {
            if("LineSpeedInfo".equals(getAttribute(element, "art.loadglobalinfo")))
            {
                rowHeightBetweenLines = Double.parseDouble(getAttribute(element, "art.heightbetweenlines"));
            }
        } catch (Exception ex)
        {
        }
@@ -178,6 +367,8 @@
    }
//</editor-fold>
    //<editor-fold defaultstate="collapsed" desc="Etd's">
    private void updateEtdNode(SVGElement element)
    {
@@ -234,15 +425,15 @@
    {
        final double baseValue = mapTopCoordinates.get(element)[0];
        return baseValue - (rowWidth * (value / 10));
        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");
              String startNodeID = getAttribute(element, "art.node.start");
              String endNodeID = getAttribute(element, "art.node.end");
        if (startNodeID != null && endNodeID != null)
        {
@@ -322,4 +513,4 @@
    
}
}