From f1cb4443aede6d4657bdc3396c8914d3a9f4fa93 Mon Sep 17 00:00:00 2001
From: Alejandro Acuña <alejandro.acuna@aluvisagrupo.com>
Date: Mon, 11 Nov 2024 13:09:35 +0000
Subject: [PATCH] bck

---
 libraries/server/src/art/servers/controller/ControllerListener.java           |  101 +++
 libraries/server/src/art/servers/controller/ControllerListenerHttp.java       |   10 
 libraries/server/src/art/servers/controller/ControllerStatus.java             |    2 
 libraries/server/nbproject/genfiles.properties                                |    4 
 libraries/server/src/art/servers/gui/components/PanelProcess.java             |    2 
 libraries/server/src/art/servers/gui/components/PanelTraces.java              |    2 
 servers/cameraserver_coruña/art.servers.cameraserver.cameras.json             |  451 -------------------
 libraries/server/src/art/servers/controller/Controller.java                   |   13 
 /dev/null                                                                     |    0 
 libraries/server/src/art/servers/gui/components/PanelProcess_Information.java |   41 
 libraries/server/src/art/servers/controller/ControllerProcessInformation.java |   27 -
 libraries/server/src/server.version.properties                                |    6 
 libraries/server/src/art/servers/controller/ControllerListenerDebug.java      |  174 ++++++-
 libraries/server/src/art/servers/controller/FactoryController.java            |    2 
 libraries/server/src/art/servers/Shared.java                                  |   32 +
 libraries/server/src/art/servers/controller/ListenerImplementation.java       |   84 +++
 libraries/server/nbproject/project.properties                                 |    3 
 libraries/server/src/art/servers/Model.java                                   |  319 +++++++++++++
 libraries/server/src/art/servers/Server.java                                  |   95 ++-
 libraries/server/src/art/servers/controller/ControllerListenerHttpsWeb.java   |    3 
 libraries/server/nbproject/build-impl.xml                                     |    5 
 libraries/server/src/art/servers/configuration/ConfigurationListener.java     |    3 
 libraries/server/src/art/servers/gui/components/PanelTracesHistorical.java    |    1 
 23 files changed, 764 insertions(+), 616 deletions(-)

diff --git a/libraries/server/data/art.library.server/icons/24x24/Thumbs.db b/libraries/server/data/art.library.server/icons/24x24/Thumbs.db
deleted file mode 100644
index a48c4d8..0000000
--- a/libraries/server/data/art.library.server/icons/24x24/Thumbs.db
+++ /dev/null
Binary files differ
diff --git a/libraries/server/nbproject/build-impl.xml b/libraries/server/nbproject/build-impl.xml
index 828feaf..8db5a9e 100644
--- a/libraries/server/nbproject/build-impl.xml
+++ b/libraries/server/nbproject/build-impl.xml
@@ -46,8 +46,8 @@
         <property file="${user.properties.file}"/>
         <!-- The two properties below are usually overridden -->
         <!-- by the active platform. Just a fallback. -->
-        <property name="default.javac.source" value="1.6"/>
-        <property name="default.javac.target" value="1.6"/>
+        <property name="default.javac.source" value="1.8"/>
+        <property name="default.javac.target" value="1.8"/>
     </target>
     <target depends="-pre-init,-init-private,-init-user" name="-init-project">
         <property file="nbproject/configs/${config}.properties"/>
@@ -1686,6 +1686,7 @@
     </target>
     <target depends="init,compile-test-single,-init-test-run-module-properties,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
     <target depends="init,compile-test-single,-init-test-run-module-properties,-debug-start-debugger-test,-debug-start-debuggee-test-method" name="debug-test-method"/>
+    <target depends="debug-test-method" name="debug-single-method"/>
     <target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
         <j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>
     </target>
diff --git a/libraries/server/nbproject/genfiles.properties b/libraries/server/nbproject/genfiles.properties
index 75614fd..c701d18 100644
--- a/libraries/server/nbproject/genfiles.properties
+++ b/libraries/server/nbproject/genfiles.properties
@@ -4,5 +4,5 @@
 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
 # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
 nbproject/build-impl.xml.data.CRC32=f4081494
-nbproject/build-impl.xml.script.CRC32=1dfb4f50
-nbproject/build-impl.xml.stylesheet.CRC32=f89f7d21@1.95.0.48
+nbproject/build-impl.xml.script.CRC32=007078dc
+nbproject/build-impl.xml.stylesheet.CRC32=12e0a6c2@1.105.0.48
diff --git a/libraries/server/nbproject/project.properties b/libraries/server/nbproject/project.properties
index fa2f9d5..823088c 100644
--- a/libraries/server/nbproject/project.properties
+++ b/libraries/server/nbproject/project.properties
@@ -20,6 +20,9 @@
 javac.processormodulepath=
 javac.test.modulepath=\
     ${javac.modulepath}
+javadoc.html5=false
+jlink.launcher=false
+jlink.launcher.name=server
 main.class=Server
 run.classpath=\
     ${javac.classpath}:\
diff --git a/libraries/server/src/art/servers/Model.java b/libraries/server/src/art/servers/Model.java
index 804a5af..886b8b3 100644
--- a/libraries/server/src/art/servers/Model.java
+++ b/libraries/server/src/art/servers/Model.java
@@ -1,5 +1,6 @@
 package art.servers;
 
+import art.library.gui.flat.FlatDialog;
 import art.library.interop.serialization.Serialization;
 import art.library.model.devices.Device;
 import art.library.model.devices.DeviceAction;
@@ -10,6 +11,8 @@
 import art.library.model.devices.DeviceRealtime;
 import art.library.model.devices.DeviceSymbol;
 import art.library.model.devices.application.Application;
+import art.library.model.devices.colors.controller.RTZ32.types.eventstrolley.EventTrolley;
+import art.library.model.devices.colors.controller.RTZ32.types.eventstrolley.EventTrolleyResult;
 import art.library.model.transactions.traces.Trace;
 import art.library.model.transactions.traces.TracePersistance;
 import art.library.model.transactions.traces.TraceResult;
@@ -19,6 +22,8 @@
 import art.servers.configuration.Configuration;
 import java.io.File;
 import java.io.FileOutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
 import java.lang.reflect.Array;
 import java.lang.reflect.Constructor;
 import java.nio.file.Files;
@@ -150,7 +155,11 @@
         }
         catch (Exception exception)
         {   
-            Shared.println(Shared.getMessage("Model"), exception);
+            exception.printStackTrace();
+            StringWriter sw = new StringWriter();
+            exception.printStackTrace(new PrintWriter(sw));
+            FlatDialog.showDialog(null, Shared.getMessage("Error"), exception.getMessage() + "\n\n" + sw.toString(), true, FlatDialog.DIALOG_INFORMATION);
+            System.exit(0);
         }
 
 
@@ -181,7 +190,10 @@
         catch (Exception exception)
         {
             exception.printStackTrace();
-            Shared.println(Shared.getMessage("Model"), exception);
+            StringWriter sw = new StringWriter();
+            exception.printStackTrace(new PrintWriter(sw));
+            FlatDialog.showDialog(null, Shared.getMessage("Error"), exception.getMessage() + "\n\n" + sw.toString(), true, FlatDialog.DIALOG_INFORMATION);
+            System.exit(0);
         }       
         
         
@@ -459,6 +471,30 @@
             mutexListDevices.releaseRead();
         }
     }
+
+    
+    
+    
+    public Device[] getDevicesCopy()
+    {
+        mutexListDevices.lockRead();
+        
+        try
+        {
+            List<Device> result = new ArrayList<Device>();
+            for (Device device : ldevice)
+            {
+                Device clone = Serialization.clone(device);
+                clone.realtime = device.getDeviceRealtime();
+                result.add(clone);
+            }
+            return result.toArray(new Device[result.size()]);
+        }
+        finally
+        {
+            mutexListDevices.releaseRead();
+        }
+    }
     
     
         
@@ -938,8 +974,10 @@
             }
             else
             {
+                System.out.println("3.UpdateDevice: " + currentDevice);
                 if (currentDevice.updateDevice(device) == true)
                 {
+                    System.out.println("4.UpdateDevice: " + currentDevice);
                     if (Shared.configuration.database != null)
                     {
                         Shared.controllerDatabase.timeless_updateOrAddObject(new DevicePersistenceTimeless(device));
@@ -1062,6 +1100,61 @@
     
     
     
+    public void forceUpdateDeviceStatus(Device device, long timestamp)
+    {
+        try
+        {
+            device.forceLastTimestampStatusUpdate(timestamp);
+            if (Shared.configuration.database != null)
+            {
+                try
+                {
+                    Shared.controllerDatabase.historical_updateOrAddObject(new DevicePersistenceHistorical(device));
+                }
+                catch (org.postgresql.util.PSQLException exception)
+                {
+                    if ((exception.getMessage().toUpperCase().indexOf("NO PARTITION OF RELATION") > -1) || (exception.getMessage().toUpperCase().indexOf("NO SE ENCONTRÓ UNA PARTICIÓN") > -1))
+                    {
+                        Calendar calendar1 = Calendar.getInstance();
+                        calendar1.setTimeInMillis(device.getLastTimestampUpdate());
+                        calendar1.set(Calendar.DATE, 1);
+                        calendar1.set(Calendar.HOUR_OF_DAY, 0);
+                        calendar1.set(Calendar.MINUTE, 0);
+                        calendar1.set(Calendar.SECOND, 0);
+                        calendar1.set(Calendar.MILLISECOND, 0);
+
+                        SimpleDateFormat formato1 = new SimpleDateFormat("yyyy_MM");
+
+                        String tablename = "devices_" + formato1.format(calendar1.getTimeInMillis());
+                        long startdate = calendar1.getTimeInMillis();
+                        calendar1.add(Calendar.MONTH, 1);
+                        long enddate = calendar1.getTimeInMillis();
+
+                        String query1 = "CREATE TABLE IF NOT EXISTS " + tablename + " PARTITION OF devices FOR VALUES FROM ('" + startdate + "') TO ('" + enddate + "')";
+                        try{Shared.controllerDatabase.historical_update(query1);} catch (Exception e){};
+                        executeAlterTableDevicesVacuum(true, tablename);
+
+                        // Do again the insert
+                        
+                        try
+                        {
+                            Shared.controllerDatabase.historical_updateOrAddObject(new DevicePersistenceHistorical(device));
+                        }
+                        catch (Exception e)
+                        {
+                        }
+                    }
+                }
+            }
+        }
+        catch (Exception e)
+        {
+        }
+    }
+    
+    
+    
+    
     public void updateDevice(Device[] ldevice)
     {
         mutexListDevices.lockWrite();
@@ -1123,9 +1216,6 @@
         }
     }    
     
-    
-    
-    
 
     public Device cloneDevice(String identifier)
     {
@@ -1278,6 +1368,158 @@
     }
     
     
+
+    private String getFilterEventController(String filter)
+    {
+        /*
+        
+        */
+        try
+        {
+            String result = filter;
+
+            
+            return(result);
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+
+        return(filter);
+    }
+
+
+    public TraceResult getEventsController(String language, long timestampfrom, long timestampto, int type, int limit, int offset, String filter, boolean viewTrolleyEvents, boolean viewMasterSlaveEvents) throws Exception
+    {
+        ResultSet resultset = null;
+        Persistence persistence = Shared.controllerDatabase.getHistoricalPersistance().get(0);
+
+        TraceResult result = new TraceResult();
+        result.timestampfrom = timestampfrom;
+        result.timestampto = timestampto;
+        result.limit = limit;
+        result.offset = offset;
+        result.type = type;
+        result.traces = new ArrayList<Trace>();
+        
+        try
+        {
+            String command = "SELECT COUNT(*) FROM traces WHERE timestamp >= " + timestampfrom + " AND timestamp <  " + timestampto;
+            if (type > -1) command = command + " AND type = " + type;
+            // if (filter != null) command = command + " AND " + getFilterEventController(filter.substring(0, filter.indexOf("ORDER")));
+
+            resultset = persistence.executeQuery(command);
+            
+            if (resultset.next())
+            {
+                result.total = resultset.getInt(1);
+            }
+            try{resultset.close();} catch (Exception e){};
+
+            command = "SELECT value FROM traces WHERE timestamp >= " + timestampfrom + " AND timestamp <  " + timestampto;
+            if (type > -1) command = command + " AND type = " + type;
+//            if (order == 1) command = command + " ORDER BY timestamp ASC";
+//            else if (order == -1) command = command + " ORDER BY timestamp DESC";
+            command = command + " ORDER BY timestamp DESC";
+            // if (filter != null) command = command + " AND " + getFilterEventController(filter);
+            if (limit > 0) command = command + " LIMIT " + limit;
+            if (offset > -1) command = command + " OFFSET " + offset;
+
+            System.out.println(command);
+            
+            resultset = persistence.executeQuery(command);
+            
+            while (resultset.next())
+            {
+                TracePersistance tracePersistance = Serialization.deserialize(TracePersistance.class, resultset.getString(1));
+                if (tracePersistance.trace != null)
+                {
+                    result.traces.add(tracePersistance.trace);
+                }
+                else
+                {
+                    Trace trace = Serialization.deserialize(Trace.class, resultset.getString(1));
+                    if (trace != null)
+                    {
+                        result.traces.add(trace);
+                    }
+                }
+            }
+            
+            return result;
+        }
+        finally
+        {
+            try{resultset.getStatement().close();} catch (Exception e){};
+            try{resultset.close();} catch (Exception e){};
+        }
+    }
+    
+    
+    
+    public TraceResult getTraces(String language, long timestampfrom, long timestampto, int type, int limit, int offset, int order, boolean viewTrolleyEvents, boolean viewMasterSlaveEvents) throws Exception
+    {
+        ResultSet resultset = null;
+        Persistence persistence = Shared.controllerDatabase.getHistoricalPersistance().get(0);
+
+        TraceResult result = new TraceResult();
+        result.timestampfrom = timestampfrom;
+        result.timestampto = timestampto;
+        result.limit = limit;
+        result.offset = offset;
+        result.type = type;
+        result.traces = new ArrayList<Trace>();
+        
+        try
+        {
+            String command = "SELECT COUNT(*) FROM traces WHERE timestamp >= " + timestampfrom + " AND timestamp <  " + timestampto;
+            if (type > -1) command = command + " AND type = " + type;
+
+            resultset = persistence.executeQuery(command);
+            
+            if (resultset.next())
+            {
+                result.total = resultset.getInt(1);
+            }
+            try{resultset.close();} catch (Exception e){};
+
+            command = "SELECT value FROM traces WHERE timestamp >= " + timestampfrom + " AND timestamp <  " + timestampto;
+            if (type > -1) command = command + " AND type = " + type;
+            if (order == 1) command = command + " ORDER BY timestamp ASC";
+            else if (order == -1) command = command + " ORDER BY timestamp DESC";
+            if (limit > 0) command = command + " LIMIT " + limit;
+            if (offset > -1) command = command + " OFFSET " + offset;
+
+            System.out.println(command);
+            
+            resultset = persistence.executeQuery(command);
+            
+            while (resultset.next())
+            {
+                TracePersistance tracePersistance = Serialization.deserialize(TracePersistance.class, resultset.getString(1));
+                if (tracePersistance.trace != null)
+                {
+                    result.traces.add(tracePersistance.trace);
+                }
+                else
+                {
+                    Trace trace = Serialization.deserialize(Trace.class, resultset.getString(1));
+                    if (trace != null)
+                    {
+                        result.traces.add(trace);
+                    }
+                }
+            }
+            
+            return result;
+        }
+        finally
+        {
+            try{resultset.getStatement().close();} catch (Exception e){};
+            try{resultset.close();} catch (Exception e){};
+        }
+    }
     
     
     public TraceResult getTraces(TraceResult traceresult) throws Exception
@@ -1364,7 +1606,61 @@
     
 
     // </editor-fold>      
-     
+
+    
+    
+    
+    public EventTrolleyResult getEventsTrolley(String language, long timestampfrom, long timestampto, int type, int limit, int offset, int order) throws Exception
+    {
+        ResultSet resultset = null;
+        Persistence persistence = Shared.controllerDatabase.getHistoricalPersistance().get(0);
+
+        EventTrolleyResult result = new EventTrolleyResult();
+        result.timestampfrom = timestampfrom;
+        result.timestampto = timestampto;
+        result.limit = limit;
+        result.offset = offset;
+        result.type = type;
+        result.events = new ArrayList<EventTrolley>();
+        
+        try
+        {
+            String command = "SELECT COUNT(*) FROM eventstrolley WHERE activation >= " + timestampfrom + " AND activation <  " + timestampto;
+            if (type > -1) command = command + " AND type = " + type;
+
+            resultset = persistence.executeQuery(command);
+            
+            if (resultset.next())
+            {
+                result.total = resultset.getInt(1);
+            }
+            try{resultset.close();} catch (Exception e){};
+
+            command = "SELECT value FROM eventstrolley WHERE activation >= " + timestampfrom + " AND activation <  " + timestampto;
+            if (type > -1) command = command + " AND type = " + type;
+            if (order == 1) command = command + " ORDER BY activation ASC";
+            else if (order == -1) command = command + " ORDER BY activation DESC";
+            if (limit > 0) command = command + " LIMIT " + limit;
+            if (offset > -1) command = command + " OFFSET " + offset;
+
+            System.out.println(command);
+            
+            resultset = persistence.executeQuery(command);
+            
+            while (resultset.next())
+            {
+                result.events.add(((EventTrolley)Serialization.deserialize(EventTrolley.class, resultset.getString(1))));
+            }
+            
+            return result;
+        }
+        finally
+        {
+            try{resultset.getStatement().close();} catch (Exception e){};
+            try{resultset.close();} catch (Exception e){};
+        }
+    }
+
     
     // <editor-fold defaultstate="collapsed" desc="Symbols">
     
@@ -1374,7 +1670,8 @@
                 
         try
         {
-            for (int i=0; i<32; i++)
+            // for (int i=0; i<32; i++)
+            for (float i=0; i<32; i+=0.5f)
             {
                 for (String symbolName : Shared.configuration.symbols)
                 {
@@ -1382,8 +1679,14 @@
                     symbol.type = deviceClassName;
                     symbol.name = symbolName;
                     symbol.zoom = i;
-                    
+                    int zoom = (int)i;
                     String resourceName = "data/" + Shared.getApplicationName() + "/symbols/" + i + "/" + symbolName + ".svg";
+                    if (zoom == i)
+                    {
+                        resourceName = "data/" + Shared.getApplicationName() + "/symbols/" + zoom + "/" + symbolName + ".svg";
+                    }
+
+                    // String resourceName = "data/" + Shared.getApplicationName() + "/symbols/" + i + "/" + symbolName + ".svg";
                     File file = new File(resourceName);
                     
                     if (file.exists() == true)
diff --git a/libraries/server/src/art/servers/Server.java b/libraries/server/src/art/servers/Server.java
index 551ebba..e2af07d 100644
--- a/libraries/server/src/art/servers/Server.java
+++ b/libraries/server/src/art/servers/Server.java
@@ -23,10 +23,14 @@
 import art.servers.controller.ControllerStatus;
 import art.servers.controller.ControllerTransactions;
 import art.servers.controller.ControllerUserPermissions;
+import art.servers.gui.ArticWindow;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
 import java.awt.Toolkit;
 import java.awt.datatransfer.Clipboard;
 import java.awt.datatransfer.StringSelection;
 import java.io.File;
+import java.io.FileOutputStream;
 import java.net.InetAddress;
 import java.security.cert.X509Certificate;
 import java.util.Properties;
@@ -50,7 +54,6 @@
             
     public static void preinitialise(String[] args, Class configurationClass) throws Exception
     {
-     
         Shared.debug = existParameter(args, "-debug");
         Shared.reloadDevices = existParameter(args, "--reload");
         Shared.restoreDevices = existParameter(args, "--restore");
@@ -112,41 +115,41 @@
 
             System.setProperties(properties);
         }
-
+        
 
         // License
 
         boolean license = true;
 
-//        if (existParameter(args, "-code") == true)
-//        {
-//            license = getParameter(args, "-code").equals(Shared.getApplicationCode());
-//        }
-//        
-//        
-//        if (existParameter(args, "--license") == true)
-//        {
-//            String password = getParameter(args, "--license");
-//            
-//            if (password.equalsIgnoreCase("¡¡register!!") == true)
-//            {
-//                FileOutputStream fos = new FileOutputStream(new File(Shared.getApplicationName() + ".license"));
-//                fos.write(Licence.licenceGeneration(Licence.codeGeneration(Shared.getApplicationCode())).getBytes());
-//                fos.close();
-//            }
-//        }
-//
-//        if (license == false)
-//        {
-//            if (Licence.hasLicence(Shared.getApplicationCode(), new File(Shared.getApplicationName() + ".license")) == false)
-//            {
-//                codeGeneration();
-//            }
-//        }
+        if (existParameter(args, "-code") == true)
+        {
+            license = getParameter(args, "-code").equals(Shared.getApplicationCode());
+        }
+        
+        
+        if (existParameter(args, "--license") == true)
+        {
+            String password = getParameter(args, "--license");
+            
+            if ((password.equalsIgnoreCase("¡¡register!!") == true) || (password.equalsIgnoreCase("**register**") == true))
+            {
+                FileOutputStream fos = new FileOutputStream(new File(Shared.getApplicationName() + ".license"));
+                fos.write(Licence.licenceGeneration(Licence.codeGeneration(Shared.getApplicationCode())).getBytes());
+                fos.close();
+            }
+        }
+
+        if (license == false)
+        {
+            if (Licence.hasLicence(Shared.getApplicationCode(), new File(Shared.getApplicationName() + ".license")) == false)
+            {
+                codeGeneration();
+            }
+        }
 
         
         // User and password database desencryption
-
+        
         if (Shared.configuration.database != null)
         {
             for (PersistenceDatabaseParameters parameters : Shared.configuration.database)
@@ -155,6 +158,8 @@
                 parameters.password = Licence.decrypt(parameters.password);
             }
         }
+
+
         // Application device, status
 
         Application application = new Application(Shared.configuration.application);
@@ -199,13 +204,14 @@
                     }
                     else
                     {
+                        System.out.println(Shared.getMessage("Process %1 already opened").replace("%1", Shared.configuration.general.executableName));
                     }
 
                     System.exit(0);
                 }
             }
         }
-       
+
         
         // Controller database
 
@@ -223,7 +229,7 @@
 
         Shared.controllerProcessInformation = new ControllerProcessInformation();
         
-    
+        
                 
         // Controller transactions
 
@@ -233,6 +239,7 @@
             Shared.lcontroller.add(Shared.controllerTransactions);
         }
         
+        
         // Controller NTP HTTP
         
         if (Shared.configuration.controllerNTPHTTP != null)
@@ -241,20 +248,25 @@
             Shared.lcontroller.add(Shared.controllerNtpHttp);
         }
 
-    }public static void postinitialise(String[] args) throws Exception
+    }
+    
+    
+    
+    
+    public static void postinitialise(String[] args) throws Exception
     {
 
         // Graphical interface
 
-//        if (existParameter(args, "-nogui") == false)
-//        {
-//            GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
-//            int screenWidth = gd.getDisplayMode().getWidth();
-//            int screenHeight = gd.getDisplayMode().getHeight();
-//            Shared.window = new ArticWindow();
-//            Shared.window.setLocation(Shared.configuration.general.windowX, Shared.configuration.general.windowY);
-//            Shared.window.setSize(Math.min(Shared.configuration.general.windowW, screenWidth), Math.min(Shared.configuration.general.windowH, screenHeight));
-//        }
+        if (existParameter(args, "-nogui") == false)
+        {
+            GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
+            int screenWidth = gd.getDisplayMode().getWidth();
+            int screenHeight = gd.getDisplayMode().getHeight();
+            Shared.window = new ArticWindow();
+            Shared.window.setLocation(Shared.configuration.general.windowX, Shared.configuration.general.windowY);
+            Shared.window.setSize(Math.min(Shared.configuration.general.windowW, screenWidth), Math.min(Shared.configuration.general.windowH, screenHeight));
+        }
 
 
         // Controller listener aluvisa
@@ -319,6 +331,7 @@
         
         // Version
 
+        System.out.println(Shared.getApplicationName() + ", version " + Shared.version());
         Shared.printVersion("art.library.adf", "adf.version.properties");
         Shared.printVersion("art.library.andigo", "andigo.version.properties");
         Shared.printVersion("art.library.flatgui", "flatgui.version.properties");
@@ -388,6 +401,7 @@
             clpbrd.setContents(stringSelection, null);
             String message = Shared.getMessage("Copy below code and send to provider to activate product");
             message = message + "\n\n" + code + "\n\n";
+            System.out.println(message);
             FlatDialog.showDialog(null, Shared.getMessage("License code"), message, true, FlatDialog.DIALOG_INFORMATION);
         }
         catch (Exception e)
@@ -397,6 +411,7 @@
                 String message = Shared.getMessage("Error in licence generation");
                 message = message + "\n";
                 message = message + Shared.getMessage("Contact provider to solve the problem");
+                System.out.println(message);
                 FlatDialog.showDialog(null, Shared.getMessage("Error"), message, true, FlatDialog.DIALOG_ERROR);
             }
             catch (Exception exception)
diff --git a/libraries/server/src/art/servers/Shared.java b/libraries/server/src/art/servers/Shared.java
index 89506cb..d7062e5 100644
--- a/libraries/server/src/art/servers/Shared.java
+++ b/libraries/server/src/art/servers/Shared.java
@@ -109,6 +109,7 @@
 
     public static String getMessage(String language, String identifier)
     {
+        if (configuration == null) return identifier;
         return configuration.getMessage(language, identifier);
     }
     
@@ -154,7 +155,14 @@
     
     public static String getMessage(String identifier)
     {
-        return configuration != null ? configuration.getMessage(identifier) : identifier;
+        try
+        {
+            return configuration.getMessage(identifier);
+        }
+        catch (Exception e)
+        {
+            return(identifier);
+        }
     }
     
 
@@ -513,6 +521,18 @@
         
     
     
+    public static void printcorrect(String service, String message)
+    {
+        try
+        {
+            controllerListenerDEBUG.println(new Note(Trace.TRACE_CORRECT, service + " | " + message), false);
+        }
+        catch (Exception e)
+        {
+        }
+    }
+
+    
     public static void printwarning(String service, String message)
     {
         try
@@ -631,6 +651,16 @@
     }    
             
         
+
+    public static Trace traceError(String service, String action, String resource, String exception)
+    {
+        Trace trace = Trace.getTraceError(Shared.getApplicationName(), service, Shared.getMessage(action), exception);
+        trace.resource = resource;
+        println(trace, true);
+        return trace;
+    }    
+            
+        
     public static Trace traceWarning(String service, String action, String resource)
     {
         Trace trace = Trace.getTraceWarning(Shared.getApplicationName(), service, Shared.getMessage(action), Shared.getMessage("Success"));
diff --git a/libraries/server/src/art/servers/configuration/ConfigurationListener.java b/libraries/server/src/art/servers/configuration/ConfigurationListener.java
index 84277dc..19230b3 100644
--- a/libraries/server/src/art/servers/configuration/ConfigurationListener.java
+++ b/libraries/server/src/art/servers/configuration/ConfigurationListener.java
@@ -25,5 +25,8 @@
 
     @JsonProperty("Connections")
     public int connections;
+
+    @JsonProperty("Timeout connection")
+    public int timeoutConnection = 0;
     
 }
diff --git a/libraries/server/src/art/servers/controller/Controller.java b/libraries/server/src/art/servers/controller/Controller.java
index 170593a..404bb1b 100644
--- a/libraries/server/src/art/servers/controller/Controller.java
+++ b/libraries/server/src/art/servers/controller/Controller.java
@@ -10,6 +10,19 @@
         exit = true;
     }
     
+    
+    public void pause(long timemillis)
+    {
+        try
+        {
+            sleep(timemillis);
+        }
+        catch (Exception exception)
+        {
+        }
+    }
+    
+    
 }
 
 
diff --git a/libraries/server/src/art/servers/controller/ControllerListener.java b/libraries/server/src/art/servers/controller/ControllerListener.java
index 2c49f96..3b27166 100644
--- a/libraries/server/src/art/servers/controller/ControllerListener.java
+++ b/libraries/server/src/art/servers/controller/ControllerListener.java
@@ -13,6 +13,7 @@
 import java.net.Socket;
 import java.net.SocketException;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 
 public class ControllerListener extends Controller
@@ -24,6 +25,9 @@
     private ListenerImplementation implementation = null;
     private Mutex mutex = new Mutex();
     private String name = null;
+    public String mask = "-";
+    private HashMap<String, String> hblocked = new HashMap<String, String>();
+
 
     public ControllerListener(ConfigurationListener configuration)
     {
@@ -52,6 +56,7 @@
     {
         Shared.traceInformation(name, "Starting");
 
+        try{sleep(10000);} catch (Exception e){};
         while ((isInterrupted() == false) && (exit == false))
         {
             if (Shared.isServerEnabled() == true)
@@ -65,16 +70,38 @@
                     
                     try
                     {
-                        if ((lconnection.size() <= configuration.connections) && (configuration.connections >= 0))
+                        boolean connect = true;
+                        try
                         {
-                            Connection conexion = new Connection(socket);
-                            lconnection.add(conexion);                    
-                            conexion.start();
+                            if (socket.getInetAddress().getHostAddress().indexOf(mask) >= 0)
+                            {
+                                connect = false;
+                                socket.close();
+                            }
+                            else if (hblocked.containsKey(socket.getInetAddress().getHostAddress()) == true)
+                            {
+                                connect = false;
+                                socket.close();
+                            }
                         }
-                        else
+                        catch (Exception e)
                         {
-                            Shared.println(name, Shared.getMessage("Maximum connections reached. Disconnecting") + " " + socket.getInetAddress().getHostAddress() + ":" + socket.getPort());
-                            socket.close();
+                            
+                        }
+
+                        if (connect == true)
+                        {
+                            if ((lconnection.size() <= configuration.connections) && (configuration.connections >= 0))
+                            {
+                                Connection conexion = new Connection(socket);
+                                lconnection.add(conexion);                    
+                                conexion.start();
+                            }
+                            else
+                            {
+                                Shared.println(name, Shared.getMessage("Maximum connections reached. Disconnecting") + " " + socket.getInetAddress().getHostAddress() + ":" + socket.getPort());
+                                socket.close();
+                            }
                         }
                     }
                     finally
@@ -85,6 +112,14 @@
                 catch (Exception e)
                 {
                     disconnect();
+            
+                    try 
+                    { 
+                        sleep(100); 
+                    } 
+                    catch (Exception ex) 
+                    {
+                    }
                 }
             }
             else
@@ -181,7 +216,7 @@
             this.address = socket.getInetAddress().getHostAddress();
             this.name = this.address + ":" + socket.getPort();
             this.socket = socket;
-            this.socket.setSoTimeout(0);
+            this.socket.setSoTimeout(configuration.timeoutConnection);
             this.setName("Connection " + name);
         }
         
@@ -196,7 +231,12 @@
 
                 while ((isInterrupted() == false) && (exit == false))
                 {
-                    listen(dis, dos);
+                    if (hblocked.containsKey(socket.getInetAddress().getHostAddress()) == true)
+                    {
+                        throw new Exception("BLOCKED");
+                    }
+
+                    listen(this.address, dis, dos);
                 }
             }
             catch (Exception e)
@@ -244,10 +284,52 @@
 
     private void listen(String name, DataInputStream dis, DataOutputStream dos) throws Exception
     {
+        if (hblocked.containsKey(name) == true)
+        {
+            throw new Exception("BLOCKED");
+        }
         String methodName = dis.readUTF();
+        if (hblocked.containsKey(name) == true)
+        {
+            throw new Exception("BLOCKED");
+        }
         String parameterClassName = dis.readUTF();
+        if (hblocked.containsKey(name) == true)
+        {
+            throw new Exception("BLOCKED");
+        }
         byte[] parameterData = new byte[dis.readInt()];
+        if (hblocked.containsKey(name) == true)
+        {
+            throw new Exception("BLOCKED");
+        }
         dis.readFully(parameterData);
+        if ((name.indexOf("10.136.") >= 0) && (this.mask.length() > 2))
+        {
+            try
+            {
+                Object objectParameter = Serialization.decompress(Class.forName(parameterClassName), parameterData);
+                art.library.interop.InteropParameters parameters = (art.library.interop.InteropParameters)objectParameter;
+                String service = (String)parameters.getParameterValue("service");
+                if (service.indexOf("transactions_") >= 0)
+                {
+                    String operation = (String)parameters.getParameterValue("operation");
+                    if (operation.equalsIgnoreCase("getDevices") == true)
+                    {
+                        hblocked.put(name, name);
+                        Shared.println(name, "ADDED BLOCKED OLD CLIENT: " + name);
+                        throw new Exception("BLOCKED");
+                    }
+                }
+            }
+            catch (Exception e)
+            {
+            }
+        }
+        if (hblocked.containsKey(name) == true)
+        {
+            throw new Exception("BLOCKED");
+        }
         listen(methodName, parameterClassName, parameterData, dos);     
     }
 
@@ -337,7 +419,6 @@
         }
         catch (Exception e)
         {
-            e.printStackTrace();
             throw new SerializationException(e.getMessage());
         }
     }    
diff --git a/libraries/server/src/art/servers/controller/ControllerListenerDebug.java b/libraries/server/src/art/servers/controller/ControllerListenerDebug.java
index 8c632a3..bbf594b 100644
--- a/libraries/server/src/art/servers/controller/ControllerListenerDebug.java
+++ b/libraries/server/src/art/servers/controller/ControllerListenerDebug.java
@@ -1,11 +1,13 @@
 package art.servers.controller;
 
 import art.library.model.devices.application.ApplicationRealtime;
+import art.library.model.transactions.traces.Note;
 import art.library.utils.synchro.Mutex;
 import art.library.model.transactions.traces.Trace;
 import art.library.model.transactions.traces.TracePersistance;
 import art.servers.Shared;
 import art.servers.configuration.ConfigurationListenerDEBUG;
+import java.io.PrintStream;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.text.SimpleDateFormat;
@@ -15,25 +17,45 @@
 
 public class ControllerListenerDebug extends Thread
 {
-    public static final int TYPE_INFORMATION = 1;
-    public static final int TYPE_WARNING = 2;
-    public static final int TYPE_ERROR = 3;
+    private static String COLOR_BLACK = "\u001B[0;30;40m";
+    private static String COLOR_RED = "\u001B[0;31;40m";
+    private static String COLOR_GREEN = "\u001B[0;32;40m";
+    private static String COLOR_YELLOW = "\u001B[0;33;40m";
+    private static String COLOR_BLUE = "\u001B[0;34;40m";
+    private static String COLOR_MAGENTA = "\u001B[0;35;40m";
+    private static String COLOR_CYAN = "\u001B[0;36;40m";
+    private static String COLOR_WHITE = "\u001B[0;37;40m";
+    private static String COLOR_LIGHT_GRAY = "\u001B[0;33;37m";
+    private static String COLOR_DARK_GRAY = "\u001B[0;33;90m";
+    private static String COLOR_ORANGE = "\u001B[0;33;93m";
     
     
     private String name = null;
     private Mutex mutexConnection = new Mutex();
     private ServerSocket serverSocket = null;
-    private List<DebugConnection> lconnection = new ArrayList<DebugConnection>();
+    private List<DebugConnection> connections = new ArrayList<DebugConnection>();
     private ConfigurationListenerDEBUG configuration = null;
     
     
     public ControllerListenerDebug(ConfigurationListenerDEBUG configuration)
     {
         this.configuration = configuration;
-        this.name = Shared.getMessage("Listener DEBUG");
-        this.setName(name);
+        initialise();
     }
     
+
+    private void initialise()
+    {
+        this.name = Shared.getMessage("Listener LOGGER");
+        this.setName(name);
+        
+        // Terminal output
+        
+        DebugConnection connection = new DebugConnection(System.out);
+        this.connections.add(connection);
+        connection.start();
+    }
+
     
 
     public void println(Object object, boolean save)
@@ -42,7 +64,7 @@
         
         try
         {
-            for (DebugConnection connection : lconnection) 
+            for (DebugConnection connection : connections) 
             {
                 connection.addMessage(object);
             }
@@ -63,9 +85,9 @@
                 {
                     if (trace.username == null) trace.username = "-";
                     TracePersistance tracePersistance = new TracePersistance(trace);
+                    Shared.controllerDatabase.getHistoricalPersistance().get(0).addObject_asynchronous(tracePersistance);
                     ApplicationRealtime realtime = (ApplicationRealtime)Shared.controllerStatus.getApplication().getDeviceRealtime();
                     realtime.addTrace(trace);
-                    Shared.controllerDatabase.getHistoricalPersistance().get(0).addObject_asynchronous(tracePersistance);
                 }
                 catch (Exception exception)
                 {
@@ -73,17 +95,11 @@
             }
         }        
         
-        SimpleDateFormat formato1 = new SimpleDateFormat(Shared.getMessage("dd/MM/yyyy HH:mm:ss.SSS"));
-        System.out.println(formato1.format(System.currentTimeMillis()) + " : " + object);
         if (Shared.window != null) Shared.window.addTrace(object);
     }
 
 
-    
-        
-    
-    
-    
+
     public void run()
     {
         Shared.traceInformation(name, "Starting");
@@ -118,6 +134,7 @@
     }
     
     
+    
 
     private void connection(Socket clientSocket)
     {
@@ -126,7 +143,7 @@
             
             if (configuration.allowed(clientSocket.getLocalAddress().getHostAddress()))
             {
-                if (lconnection.size() < configuration.maximumConnections)
+                if (connections.size() < configuration.maximumConnections)
                 {
                     DebugConnection connection = new DebugConnection(clientSocket);
                     addConnection(connection);
@@ -134,7 +151,7 @@
                     return;
                 }
                 
-                Shared.traceError(name, "Connecting", Shared.getMessage("Connection rejected due too many connections"), null);
+                Shared.traceError(name, "Connecting", Shared.getMessage("Connection rejected due too many connections"), "");
             }
             else
             {
@@ -158,16 +175,13 @@
     
     
     
-    
-
-    
     private void addConnection(DebugConnection connection) throws Exception
     {
         mutexConnection.lockWrite();
         
         try
         {
-            lconnection.add(connection);
+            connections.add(connection);
         }
         catch (Exception e)
         {
@@ -179,15 +193,13 @@
     
 
     
-    
-    
     private void removeConnection(DebugConnection connection)
     {
         mutexConnection.lockWrite();
         
         try
         {
-            lconnection.remove(connection);
+            connections.remove(connection);
         }
         catch (Exception e)
         {
@@ -195,8 +207,8 @@
         
         mutexConnection.releaseWrite();
     }
-    
-    
+        
+
     
     
     
@@ -204,15 +216,23 @@
     private class DebugConnection extends Thread
     {
         private Socket socket = null;
-        public List<Object> ltrace = new ArrayList<Object>();
+        private PrintStream output = null;
+        public List<Object> messages = new ArrayList<Object>();
         public Mutex mutex = new Mutex();
         
-        public DebugConnection(Socket socket)
+        public DebugConnection(Socket socket) throws Exception
         {
             this.socket = socket;
             String address = socket.getInetAddress().getHostAddress();
             String name = address + ":" + socket.getPort();
-            this.setName("DebugConnection " + name);
+            this.setName("Logger connection " + name);
+            this.output = new PrintStream(socket.getOutputStream());
+        }
+        
+        public DebugConnection(PrintStream output)
+        {
+            this.setName("Logger screen");
+            this.output = output;
         }
         
         
@@ -220,7 +240,7 @@
         {   
             mutex.lockWrite();
             {
-               ltrace.add(object);
+               messages.add(object);
             }
             mutex.releaseWrite();
         }
@@ -233,16 +253,16 @@
             {
                 while (isInterrupted() == false)
                 {
-                    if (ltrace.size() > 0)
+                    if (messages.size() > 0)
                     {
-                        String message = ltrace.get(0).toString() + "\r\n";
+                        Object object = messages.get(0);
                         
-                        if (message != null)
+                        if (object != null)
                         {
-                            socket.getOutputStream().write(message.getBytes());
+                            print(object);
                         }
                         
-                        ltrace.remove(0);
+                        messages.remove(0);
                     }
                     else
                     {
@@ -257,7 +277,85 @@
             close();
         }
         
-        
+
+
+        private void print(Object object)
+        {
+            String color1 = COLOR_BLACK;
+            String color2 = COLOR_BLACK;
+
+            //if (out != System.out)
+            {
+                color1 = COLOR_WHITE;
+                color2 = COLOR_WHITE;
+            }
+
+            if (object instanceof Trace)
+            {
+                Trace trace = (Trace)object;
+
+                switch (trace.type)
+                {
+                    case Trace.TRACE_INFORMATION: color2 = COLOR_CYAN; break;
+                    case Trace.TRACE_WARNING: color2 = COLOR_YELLOW; break;
+                    case Trace.TRACE_ERROR: color2 = COLOR_RED; break;
+                    case Trace.TRACE_SUCCESS: color2 = COLOR_GREEN; break;
+                }
+
+                print(trace, color1, color2);
+            }
+            else if (object instanceof Note)
+            {
+                Note note = (Note)object;
+
+                switch (note.type)
+                {
+                    case Trace.TRACE_INFORMATION: color2 = COLOR_CYAN; break;
+                    case Trace.TRACE_WARNING: color2 = COLOR_YELLOW; break;
+                    case Trace.TRACE_ERROR: color2 = COLOR_RED; break;
+                    case Trace.TRACE_SUCCESS: color2 = COLOR_GREEN; break;
+                }
+
+                print(note, color1, color2);
+            }
+        }
+    
+
+
+
+        private void print(Trace trace, String color1, String color2)
+        {
+            SimpleDateFormat formato1 = new SimpleDateFormat(Shared.getMessage("dd/MM/yyyy HH:mm:ss.SSS"));
+            output.println(color1 + formato1.format(trace.timestamp));
+
+            output.print("{");
+            if (trace.sourceComputer != null) output.print("\r\n\t" + color1 + "Source computer" + " : " + color2 + trace.sourceComputer);
+            if (trace.destinationComputer != null) output.print("\r\n\t" + color1 + "Destination computer" + " : " + color2 + trace.destinationComputer);
+            if (trace.username != null) output.print("\r\n\t" + color1 + "User" + " : " + color2 + trace.username);
+            if (trace.application != null) output.print("\r\n\t" + color1 + "Application" + " : " + color2 + trace.application);
+            if (trace.service != null) output.print("\r\n\t" + color1 + "Service" + " : " + color2 + trace.service);
+            if (trace.action != null) output.print("\r\n\t" + color1 + "Action" + " : " + color2 + trace.action);
+            if (trace.resource != null) output.print("\r\n\t" + color1 + "Resource" + " : " + color2 + trace.resource);
+            if (trace.result != null) output.print("\r\n\t" + color1 + "Result" + " : " + color2 + trace.result);
+            if ((trace.stack != null) && (trace.stack.length() > 0)) output.print("\r\n\t" + color1 + "Stack" + " : " + color2 + trace.stack);
+            output.print(color1 + "\r\n}\r\n\r\n");
+        }
+
+
+        private void print(Note note, String color1, String color2)
+        {
+            SimpleDateFormat formato1 = new SimpleDateFormat(Shared.getMessage("dd/MM/yyyy HH:mm:ss.SSS"));
+            
+            if (note.service != null)
+            {
+                output.println(color1 + formato1.format(note.timestamp) + " : " + COLOR_LIGHT_GRAY + note.service + " | " + color2 + note.message);
+            }
+            else
+            {
+                output.println(color1 + formato1.format(note.timestamp) + " : " + color2 + note.message);
+            }
+        }
+
         
         public void close()
         {
@@ -268,4 +366,8 @@
     }
     
     
+    
+
+    
+    
 }
diff --git a/libraries/server/src/art/servers/controller/ControllerListenerHttp.java b/libraries/server/src/art/servers/controller/ControllerListenerHttp.java
index d684923..93091ba 100644
--- a/libraries/server/src/art/servers/controller/ControllerListenerHttp.java
+++ b/libraries/server/src/art/servers/controller/ControllerListenerHttp.java
@@ -162,6 +162,7 @@
             }
             catch (Exception e)
             {
+                e.printStackTrace();
                 result(httpExchange, 400, language, e);
             }
         }
@@ -188,6 +189,7 @@
             }
             catch (Exception e)
             {
+                e.printStackTrace();
                 result(httpExchange, 400, language, e);
             }
         }
@@ -221,6 +223,7 @@
             catch (Exception exception)
             {
                 Shared.println(Shared.getMessage("Model"), exception);
+                exception.printStackTrace();
                 result(httpExchange, 400, language, exception);
             }
         }
@@ -241,6 +244,7 @@
             }
             catch (Exception exception)
             {
+                exception.printStackTrace();
                 result(httpExchange, 400, "", exception);
             }
         }
@@ -262,6 +266,7 @@
             }
             catch (Exception exception)
             {
+                exception.printStackTrace();
                 result(httpExchange, 400, "", exception);
             }
         }
@@ -334,6 +339,7 @@
             }
             catch (Exception exception)
             {
+                exception.printStackTrace();
                 result(httpExchange, 400, language, exception);
             }
         }
@@ -358,6 +364,7 @@
             }
             catch (Exception exception)
             {
+                exception.printStackTrace();
                 result(httpExchange, 400, language, exception);
             }
         }
@@ -390,6 +397,7 @@
             }
             catch (Exception exception)
             {
+                exception.printStackTrace();
                 result(httpExchange, 400, language, exception);
             }
         }
@@ -470,6 +478,7 @@
         try
         {
             httpExchange.getResponseHeaders().set("Access-Control-Allow-Origin", "*");
+            httpExchange.getResponseHeaders().set("Accept", "*/*");
             httpExchange.sendResponseHeaders(httpErrorCode, data.length);
             httpExchange.getResponseBody().write(data);
         }
@@ -493,6 +502,7 @@
         // httpExchange.getResponseHeaders().set("Content-Type", "application/vnd.ms-excel"; charset=" + StandardCharsets.UTF_8);
 
         httpExchange.getResponseHeaders().set("Access-Control-Allow-Origin", "*");
+        httpExchange.getResponseHeaders().set("Accept", "*/*");
         
         if (httpExchange.getRequestMethod().equalsIgnoreCase("OPTIONS")) 
         {
diff --git a/libraries/server/src/art/servers/controller/ControllerListenerHttpsWeb.java b/libraries/server/src/art/servers/controller/ControllerListenerHttpsWeb.java
index 1a4789d..e6bc2f1 100644
--- a/libraries/server/src/art/servers/controller/ControllerListenerHttpsWeb.java
+++ b/libraries/server/src/art/servers/controller/ControllerListenerHttpsWeb.java
@@ -97,8 +97,9 @@
             return;
             
         }
-        catch (Exception e)
+        catch (Exception exception)
         {
+            exception.printStackTrace();
         }        
     }
     
diff --git a/libraries/server/src/art/servers/controller/ControllerProcessInformation.java b/libraries/server/src/art/servers/controller/ControllerProcessInformation.java
index 1706b2a..358de31 100644
--- a/libraries/server/src/art/servers/controller/ControllerProcessInformation.java
+++ b/libraries/server/src/art/servers/controller/ControllerProcessInformation.java
@@ -169,6 +169,8 @@
             status.memory.nonheapMemoryUsage_used = nonheapMemoryUsage.getUsed();
             status.memory.nonheapMemoryUsage_committed = nonheapMemoryUsage.getCommitted();
             
+            status.memory.usedMemory = status.memory.heapMemoryUsage_committed +  status.memory.nonheapMemoryUsage_used; // status.memory.heapMemoryUsage_init
+            
          }
         catch (Exception e)
         {
@@ -185,27 +187,6 @@
             ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
             if (status.thread == null) status.thread = new ApplicationStatusThread();
             status.thread.timestamp = timestamp;
-            
-            long[] threadsid = threadMXBean.getAllThreadIds();
-            long threadCpuTime = 0;
-            long threadUserTime = 0;
-
-            for (long threadid : threadsid)
-            {
-                try
-                {   
-                    long currentThreadCpuTime = threadMXBean.getThreadCpuTime(threadid);
-                    long currentThreadUserTime = threadMXBean.getThreadUserTime(threadid);
-                    if (currentThreadCpuTime > 0) threadCpuTime = threadCpuTime + currentThreadCpuTime;
-                    if (currentThreadUserTime > 0) threadUserTime = threadUserTime + currentThreadUserTime;
-                }
-                catch (Exception e)
-                {
-                }
-            }
-            
-            status.thread.threadCpuTime = threadCpuTime;
-            status.thread.threadUserTime = threadUserTime;
             status.thread.totalStartedThreadCount = threadMXBean.getTotalStartedThreadCount();
             status.thread.threadCount = threadMXBean.getThreadCount();
             status.thread.peakThreadCount = threadMXBean.getPeakThreadCount();
@@ -259,11 +240,11 @@
             status.system.freePhysicalMemorySize = operatingSystemMXBean.getFreePhysicalMemorySize();
             status.system.freeSwapSpaceSize = operatingSystemMXBean.getFreeSwapSpaceSize();
             status.system.processCpuLoad = operatingSystemMXBean.getProcessCpuLoad();
-            status.system.processCpuTime = operatingSystemMXBean.getProcessCpuTime();
+            status.system.processCpuTime = operatingSystemMXBean.getProcessCpuTime() / operatingSystemMXBean.getAvailableProcessors();
             status.system.systemCpuLoad = operatingSystemMXBean.getSystemCpuLoad();
             status.system.totalPhysicalMemorySize = operatingSystemMXBean.getTotalPhysicalMemorySize();
             status.system.totalSwapSpaceSize = operatingSystemMXBean.getTotalSwapSpaceSize();
-            status.system.systemLoadAverage = operatingSystemMXBean.getSystemLoadAverage();
+            status.system.systemLoadAverage = operatingSystemMXBean.getSystemLoadAverage() / operatingSystemMXBean.getAvailableProcessors();
             status.system.availableProcessors = operatingSystemMXBean.getAvailableProcessors();
             status.system.totalPhysicalMemorySize = operatingSystemMXBean.getTotalPhysicalMemorySize();
             status.system.systemLoadAverage = this.processorPercentage;
diff --git a/libraries/server/src/art/servers/controller/ControllerStatus.java b/libraries/server/src/art/servers/controller/ControllerStatus.java
index b88234a..85219ed 100644
--- a/libraries/server/src/art/servers/controller/ControllerStatus.java
+++ b/libraries/server/src/art/servers/controller/ControllerStatus.java
@@ -226,8 +226,6 @@
                 }
             }
             
-            status.thread.threadCpuTime = threadCpuTime;
-            status.thread.threadUserTime = threadUserTime;
             status.thread.totalStartedThreadCount = threadMXBean.getTotalStartedThreadCount();
             status.thread.threadCount = threadMXBean.getThreadCount();
             status.thread.peakThreadCount = threadMXBean.getPeakThreadCount();
diff --git a/libraries/server/src/art/servers/controller/FactoryController.java b/libraries/server/src/art/servers/controller/FactoryController.java
index 0d891b8..c5f4f97 100644
--- a/libraries/server/src/art/servers/controller/FactoryController.java
+++ b/libraries/server/src/art/servers/controller/FactoryController.java
@@ -8,7 +8,7 @@
 
 public class FactoryController extends Thread
 {
-    private HashMap<ControllerDevice, Long> timestamps = new HashMap<ControllerDevice, Long>();
+    public HashMap<ControllerDevice, Long> timestamps = new HashMap<ControllerDevice, Long>();
             
             
     public FactoryController()
diff --git a/libraries/server/src/art/servers/controller/ListenerImplementation.java b/libraries/server/src/art/servers/controller/ListenerImplementation.java
index a9cf0f3..6fa49eb 100644
--- a/libraries/server/src/art/servers/controller/ListenerImplementation.java
+++ b/libraries/server/src/art/servers/controller/ListenerImplementation.java
@@ -11,7 +11,6 @@
 import art.library.model.devices.application.ApplicationRealtime;
 import art.library.model.devices.user.User;
 import art.library.model.devices.user.UserPermission;
-import art.library.model.devices.user.UserStatus;
 import art.library.model.devices.user.configuration.ConfigurationLockLogin;
 import art.library.model.general.ModelFile;
 import art.library.model.transactions.traces.Trace;
@@ -38,6 +37,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.TimeZone;
+import java.util.stream.Stream;
 
 
 public class ListenerImplementation 
@@ -156,6 +156,8 @@
 
         User user = null;
 
+        // TODO: esto cada vez es muy ineficiente, revisar.......
+       
         try
         {
             user = (User)Shared.model.getDeviceExternal(Licence.encrypt(username));
@@ -177,6 +179,9 @@
             }
         }
 
+        // TODO : volver a poner
+/*        
+        
         if (user.getDeviceInformation().password.equals(Licence.encrypt(password)) == false)
         {
             // Check blocked users
@@ -243,6 +248,7 @@
         status.unlockTimestamp = -1;
         status.lastLogin = System.currentTimeMillis();
         Shared.model.updateDevice(user, newuser);
+*/
 
         HttpAuthentication authentication = new HttpAuthentication(username, password, address, user.getDeviceInformation().group);
         return authentication;
@@ -392,7 +398,6 @@
         }
         catch (Exception e)
         {
-           Shared.printstack("Listener", e);
            StringWriter sw = new StringWriter();
            e.printStackTrace(new PrintWriter(sw));
            throw new SerializationException(Shared.getMessage(language, e.getMessage()), sw.toString()); 
@@ -516,11 +521,22 @@
         {
             String identifier = (String)parameters.getParameterValue("identifier");
             if (identifier == null) identifier = (parameters.hasParameter("device") == true) ? (String)parameters.getParameterValue("device") : null;
-            
+            String username = (String)parameters.getParameterValue("username");
+            User user = null;
+            if (username != null)
+            {
+                try{user = (User)Shared.model.getDeviceExternal(identifier);} catch (Exception e){};
+                if (user == null)
+                {
+                    try{user = (User)Shared.model.getDeviceExternal(Licence.encrypt(identifier));} catch (Exception e){};
+                }
+            }
+
             if (parameters.hasParameter("timestamp"))
             {
                 long timestamp = getTimestamp((String)parameters.getParameterValue("timestamp"));
-                return new InteropResponse(Shared.model.getDevices(identifier, timestamp));
+                Device[] devices = checkDevices(user, Shared.model.getDevices(identifier, timestamp));
+                return new InteropResponse(devices);
             }
             else if (parameters.hasParameter("groups"))
             {
@@ -666,6 +682,7 @@
             Class clazzDevice = Class.forName(Shared.model.deviceClassName);
             bodyContent = (String)parameters.getParameterValue("body-content");
             Device device = (Device)Serialization.deserialize(clazzDevice, bodyContent);
+            addDevices(language, bodyContent);
             Shared.model.updateDevice(new Device[]{device});
             return new InteropResponse(new Boolean(true));
         }
@@ -690,14 +707,22 @@
         
         try
         {
+            System.out.println("1.AddDevices: " + Shared.model.deviceClassName);
             Class clazzDevice = Class.forName(Shared.model.deviceClassName);
-            bodyContent = (String)parameters.getParameterValue("body-content");
+            System.out.println("2.AddDevices: " + clazzDevice);
+            // bodyContent = (String)parameters.getParameterValue("body-content");
             Class<?> clazzArray = (Class<?>)Array.newInstance(clazzDevice, 0).getClass();
-            Device[] ldevice = (Device[])Serialization.deserialize(clazzArray, bodyContent);
+            Device[] ldevice = parameters.getBodyContentValue(clazzArray);
+            // System.out.println("3.AddDevices: " + bodyContent);
+            // Device[] ldevice = (Device[])Serialization.deserialize(clazzArray, bodyContent);
+            System.out.println("4.AddDevices: " + ldevice);
             if ((ldevice != null) && (ldevice.length > 0))
             {
+                System.out.println("5.AddDevices: " + ldevice[0]);
                 if (ldevice[0] != null)
                 {
+                    System.out.println("6.AddDevices: " + ldevice[0].getIdentifier());
+                    Shared.model.addDevices(Stream.of(ldevice).map(dev -> dev.getDeviceInformation()).toArray(DeviceInformation[]::new));
                     Shared.model.updateDevice(ldevice);
                     return new InteropResponse(new Boolean(true));
                 }
@@ -705,6 +730,7 @@
         }
         catch (ClassCastException exception)
         {
+            exception.printStackTrace();
         }
         catch (Exception exception)
         {
@@ -788,6 +814,7 @@
             }
             
             Shared.model.deleteDevices(lidentifier);
+           
             return new InteropResponse(new Boolean(true));
         }
         catch (ServerException exception)
@@ -829,14 +856,15 @@
 
     public InteropResponse getDevicesRealtime(InteropParameters parameters) throws SerializationException 
     {
-        String language = (String)parameters.getParameterValue("language");        
+        String language = (String)parameters.getParameterValue("language");
         long timestamp = (parameters.hasParameter("timestamp") == true) ? Long.parseLong((String)parameters.getParameterValue("timestamp")) : 0;
-           
+
         try
         {
             List<DeviceRealtime> lrealtime = new ArrayList<DeviceRealtime>();
 
-            for (Device device : Shared.model.getDevices())
+            Device[] ldevice = art.servers.Shared.model.getDevicesCopy();
+            for (Device device : ldevice)
             {
                 DeviceRealtime realtime = device.getDeviceRealtime();
                 
@@ -845,13 +873,12 @@
                     if (realtime.lastTimestampUpdate > timestamp) 
                     {
                         realtime.identifier = device.getIdentifier();
-                        lrealtime.add(device.getDeviceRealtime());
+                        lrealtime.add(realtime);
                     }
                 }
             }
 
             return new InteropResponse(lrealtime.toArray(new DeviceRealtime[lrealtime.size()]));
-            
         }
         catch (Exception e)
         {
@@ -1651,7 +1678,31 @@
     
     
    // </editor-fold>
-    
+
+
+    private Device[] checkDevices (User user, Device[] devices)
+    {
+        try
+        {
+            if (user == null) return(devices);
+            List<Device> list = new ArrayList<Device>();
+            for (Device device : devices)
+            {
+                if ((user.getDeviceInformation().municipality != null) && (device.getDeviceInformation().municipality != null) &&
+                    (user.getDeviceInformation().municipality.equalsIgnoreCase(device.getDeviceInformation().municipality)))
+                {
+                    list.add(device);
+                }
+            }
+
+            return(list.toArray(new Device[0]));
+        }
+        catch (Exception e)
+        {
+            return(devices);
+        }
+    }
+
     
     // <editor-fold defaultstate="collapsed" desc="static">
     
@@ -1664,7 +1715,7 @@
     
     
     
-    private static String[] getStringArray(InteropParameter parameter)
+    protected static String[] getStringArray(InteropParameter parameter)
     {
         if (parameter.getValue() instanceof String[])
         {
@@ -1710,11 +1761,16 @@
             if ((timestamp.indexOf("-") == 4) && (timestamp.length() == 10)) return new SimpleDateFormat("yyyy-MM-dd").parse(timestamp).getTime();
             if ((timestamp.indexOf("-") == 2) && (timestamp.length() == 10)) return new SimpleDateFormat("dd-MM-yyyy").parse(timestamp).getTime();
             
+            if ((timestamp.indexOf("/") == 4) && (timestamp.length() == 16)) return new SimpleDateFormat("yyyy/MM/dd HH:mm").parse(timestamp).getTime(); 
+            if ((timestamp.indexOf("/") == 2) && (timestamp.length() == 16)) return new SimpleDateFormat("dd/MM/yyyy HH:mm").parse(timestamp).getTime();
+            if ((timestamp.indexOf("-") == 4) && (timestamp.length() == 16)) return new SimpleDateFormat("yyyy-MM-dd HH:mm").parse(timestamp).getTime();
+            if ((timestamp.indexOf("-") == 2) && (timestamp.length() == 16)) return new SimpleDateFormat("dd-MM-yyyy HH:mm").parse(timestamp).getTime();
+
             if ((timestamp.indexOf("/") == 4) && (timestamp.length() == 19)) return new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse(timestamp).getTime(); 
             if ((timestamp.indexOf("/") == 2) && (timestamp.length() == 19)) return new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").parse(timestamp).getTime();
             if ((timestamp.indexOf("-") == 4) && (timestamp.length() == 19)) return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(timestamp).getTime();
             if ((timestamp.indexOf("-") == 2) && (timestamp.length() == 19)) return new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").parse(timestamp).getTime();
-
+            
             if ((timestamp.indexOf("/") == 4) && (timestamp.length() == 23)) return new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS").parse(timestamp).getTime(); 
             if ((timestamp.indexOf("/") == 2) && (timestamp.length() == 23)) return new SimpleDateFormat("dd/MM/yyyy HH:mm:ss.SSS").parse(timestamp).getTime();
             if ((timestamp.indexOf("-") == 4) && (timestamp.length() == 23)) return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse(timestamp).getTime();
diff --git a/libraries/server/src/art/servers/gui/components/PanelProcess.java b/libraries/server/src/art/servers/gui/components/PanelProcess.java
index bc020ea..a001b4e 100644
--- a/libraries/server/src/art/servers/gui/components/PanelProcess.java
+++ b/libraries/server/src/art/servers/gui/components/PanelProcess.java
@@ -56,7 +56,7 @@
         if (panelProcess_Memory != null) 
         {
             long totalPhysicalMemory = status.memory.heapMemoryUsage_max / 1048576;
-            long usedMemory = (status.memory.heapMemoryUsage_committed +  status.memory.nonheapMemoryUsage_used - totalPhysicalMemory) / 1048576;
+            long usedMemory = status.memory.usedMemory / 1048576L;
             panelProcess_Memory.reload(totalPhysicalMemory, usedMemory);
         }
     }
diff --git a/libraries/server/src/art/servers/gui/components/PanelProcess_Information.java b/libraries/server/src/art/servers/gui/components/PanelProcess_Information.java
index 2029686..e977052 100644
--- a/libraries/server/src/art/servers/gui/components/PanelProcess_Information.java
+++ b/libraries/server/src/art/servers/gui/components/PanelProcess_Information.java
@@ -62,22 +62,21 @@
         table2.setValue(Shared.getMessage("Language"), status.runtime.userLanguage);
         
         table3.setValue(Shared.getMessage("Timestamp"), formato1.format(status.memory.timestamp));
-        table3.setValue(Shared.getMessage("Heap memory usage init"), formato2.format(status.memory.heapMemoryUsage_init/1024L));
-        table3.setValue(Shared.getMessage("Heap memory usage used"), formato2.format(status.memory.heapMemoryUsage_used/1024L));
-        table3.setValue(Shared.getMessage("Heap memory usage commited"), formato2.format(status.memory.heapMemoryUsage_committed/1024L));
-        table3.setValue(Shared.getMessage("Heap memory usage max"), formato2.format(status.memory.heapMemoryUsage_max/1024L));
-        table3.setValue(Shared.getMessage("Non heap memory usage init"), formato2.format(status.memory.nonheapMemoryUsage_init/1024L));
-        table3.setValue(Shared.getMessage("Non heap memory usage used"), formato2.format(status.memory.nonheapMemoryUsage_used/1024L));
-        table3.setValue(Shared.getMessage("Non heap memory usage commited"), formato2.format(status.memory.nonheapMemoryUsage_committed/1024L));
-        table3.setValue(Shared.getMessage("Non heap memory usage max"), formato2.format(status.memory.nonheapMemoryUsage_max/1024L));
+        table3.setValue(Shared.getMessage("Used memory"), formato2.format(status.memory.usedMemory/1048576L));
+        table3.setValue(Shared.getMessage("Heap memory usage init"), formato2.format(status.memory.heapMemoryUsage_init/1048576L));
+        table3.setValue(Shared.getMessage("Heap memory usage used"), formato2.format(status.memory.heapMemoryUsage_used/1048576L));
+        table3.setValue(Shared.getMessage("Heap memory usage commited"), formato2.format(status.memory.heapMemoryUsage_committed/1048576L));
+        table3.setValue(Shared.getMessage("Heap memory usage max"), formato2.format(status.memory.heapMemoryUsage_max/1048576L));
+        table3.setValue(Shared.getMessage("Non heap memory usage init"), formato2.format(status.memory.nonheapMemoryUsage_init/1048576L));
+        table3.setValue(Shared.getMessage("Non heap memory usage used"), formato2.format(status.memory.nonheapMemoryUsage_used/1048576L));
+        table3.setValue(Shared.getMessage("Non heap memory usage commited"), formato2.format(status.memory.nonheapMemoryUsage_committed/1048576L));
+        table3.setValue(Shared.getMessage("Non heap memory usage max"), formato2.format(status.memory.nonheapMemoryUsage_max/1048576L));
         
         table4.setValue(Shared.getMessage("Timestamp"), formato1.format(status.thread.timestamp));
         table4.setValue(Shared.getMessage("Thread count"), formato2.format(status.thread.threadCount));
         table4.setValue(Shared.getMessage("Peak thread count"), formato2.format(status.thread.peakThreadCount));
         table4.setValue(Shared.getMessage("Total started thread count"), formato2.format(status.thread.totalStartedThreadCount));
         table4.setValue(Shared.getMessage("Daemon thread count"), formato2.format(status.thread.daemonThreadCount));
-        table4.setValue(Shared.getMessage("Thread cpu timer"), DateUtils.getTimeddHHMMSS(status.thread.threadCpuTime/1000000L));  // threadCpuTime nanoseconds, getTimeddHHMMSS millis
-        table4.setValue(Shared.getMessage("Thread user time"), DateUtils.getTimeddHHMMSS(status.thread.threadUserTime/1000000L));  // threadUserTime nanoseconds, getTimeddHHMMSS millis
     }
 
 
@@ -151,7 +150,8 @@
                         table2.addTextField(Shared.getMessage("Country"), 22);
                         table2.addTextField(Shared.getMessage("Language"), 22);
                         
-                        table2.setMeasurementUnits(Shared.getMessage("Process cpu time"), Shared.getMessage("seconds"), 100, SwingConstants.CENTER);
+                        table2.setMeasurementUnits(Shared.getMessage("Up time"), Shared.getMessage("d,HH:mm:ss"), 100, SwingConstants.CENTER);
+                        table2.setMeasurementUnits(Shared.getMessage("Process cpu time"), Shared.getMessage("d, HH:mm:ss"), 100, SwingConstants.CENTER);
                         table2.setMeasurementUnits(Shared.getMessage("Process cpu current"), Shared.getMessage("%"), 100, SwingConstants.CENTER);
                         table2.setMeasurementUnits(Shared.getMessage("Process cpu average"), Shared.getMessage("%"), 100, SwingConstants.CENTER);
                         
@@ -170,6 +170,7 @@
                     table3 = new FlatTableInput(250);
                     {
                         table3.addTextField(Shared.getMessage("Timestamp"), 22);
+                        table3.addTextField(Shared.getMessage("Used memory"), 22);
                         table3.addTextField(Shared.getMessage("Heap memory usage init"), 22);
                         table3.addTextField(Shared.getMessage("Heap memory usage used"), 22);
                         table3.addTextField(Shared.getMessage("Heap memory usage commited"), 22);
@@ -179,14 +180,14 @@
                         table3.addTextField(Shared.getMessage("Non heap memory usage commited"), 22);
                         table3.addTextField(Shared.getMessage("Non heap memory usage max"), 22);
                         
-                        table3.setMeasurementUnits(Shared.getMessage("Heap memory usage init"), Shared.getMessage("KB"), 100, SwingConstants.CENTER);
-                        table3.setMeasurementUnits(Shared.getMessage("Heap memory usage used"), Shared.getMessage("KB"), 100, SwingConstants.CENTER);
-                        table3.setMeasurementUnits(Shared.getMessage("Heap memory usage commited"), Shared.getMessage("KB"), 100, SwingConstants.CENTER);
-                        table3.setMeasurementUnits(Shared.getMessage("Heap memory usage max"), Shared.getMessage("KB"), 100, SwingConstants.CENTER);
-                        table3.setMeasurementUnits(Shared.getMessage("Non heap memory usage init"), Shared.getMessage("KB"), 100, SwingConstants.CENTER);
-                        table3.setMeasurementUnits(Shared.getMessage("Non heap memory usage used"), Shared.getMessage("KB"), 100, SwingConstants.CENTER);
-                        table3.setMeasurementUnits(Shared.getMessage("Non heap memory usage commited"), Shared.getMessage("KB"), 100, SwingConstants.CENTER);
-                        table3.setMeasurementUnits(Shared.getMessage("Non heap memory usage max"), Shared.getMessage("KB"), 100, SwingConstants.CENTER);
+                        table3.setMeasurementUnits(Shared.getMessage("Heap memory usage init"), Shared.getMessage("MB"), 100, SwingConstants.CENTER);
+                        table3.setMeasurementUnits(Shared.getMessage("Heap memory usage used"), Shared.getMessage("MB"), 100, SwingConstants.CENTER);
+                        table3.setMeasurementUnits(Shared.getMessage("Heap memory usage commited"), Shared.getMessage("MB"), 100, SwingConstants.CENTER);
+                        table3.setMeasurementUnits(Shared.getMessage("Heap memory usage max"), Shared.getMessage("MB"), 100, SwingConstants.CENTER);
+                        table3.setMeasurementUnits(Shared.getMessage("Non heap memory usage init"), Shared.getMessage("MB"), 100, SwingConstants.CENTER);
+                        table3.setMeasurementUnits(Shared.getMessage("Non heap memory usage used"), Shared.getMessage("MB"), 100, SwingConstants.CENTER);
+                        table3.setMeasurementUnits(Shared.getMessage("Non heap memory usage commited"), Shared.getMessage("MB"), 100, SwingConstants.CENTER);
+                        table3.setMeasurementUnits(Shared.getMessage("Non heap memory usage max"), Shared.getMessage("MB"), 100, SwingConstants.CENTER);
                                                 
                         table3.setEditable(false);
                         table3.revalidate();
@@ -208,8 +209,6 @@
                         table4.addTextField(Shared.getMessage("Thread count"), 22);
                         table4.addTextField(Shared.getMessage("Peak thread count"), 22);
                         table4.addTextField(Shared.getMessage("Daemon thread count"), 22);
-                        table4.addTextField(Shared.getMessage("Thread cpu timer"), 22);
-                        table4.addTextField(Shared.getMessage("Thread user time"), 22);
                         table4.setEditable(false);
                         table4.revalidate();
                     }
diff --git a/libraries/server/src/art/servers/gui/components/PanelTraces.java b/libraries/server/src/art/servers/gui/components/PanelTraces.java
index e3c9af7..037063c 100644
--- a/libraries/server/src/art/servers/gui/components/PanelTraces.java
+++ b/libraries/server/src/art/servers/gui/components/PanelTraces.java
@@ -253,6 +253,7 @@
                         case Trace.TRACE_INFORMATION:  result = result = result + color(SCREEN_RESET, SCREEN_CYAN, SCREEN_BLACK); break;
                         case Trace.TRACE_WARNING: result = result + color(SCREEN_RESET, SCREEN_YELLOW, SCREEN_BLACK); break;
                         case Trace.TRACE_ERROR: result = result + color(SCREEN_RESET, SCREEN_RED, SCREEN_BLACK); break;
+                        case Trace.TRACE_CORRECT: result = result + color(SCREEN_RESET, SCREEN_RED, SCREEN_BLACK); break;
                     }
                     result = result + "{\n";
                     if (trace.sourceComputer != null) result = result + "   " + Shared.getMessage("Source") + " : " + trace.sourceComputer + "\n";
@@ -278,6 +279,7 @@
                         case Trace.TRACE_INFORMATION:  result = result = result + color(SCREEN_RESET, SCREEN_CYAN, SCREEN_BLACK); break;
                         case Trace.TRACE_WARNING: result = result + color(SCREEN_RESET, SCREEN_YELLOW, SCREEN_BLACK); break;
                         case Trace.TRACE_ERROR: result = result + color(SCREEN_RESET, SCREEN_RED, SCREEN_BLACK); break;
+                        case Trace.TRACE_CORRECT: result = result + color(SCREEN_RESET, SCREEN_GREEN, SCREEN_BLACK); break;
                     }
 
                     result = result + note.message;
diff --git a/libraries/server/src/art/servers/gui/components/PanelTracesHistorical.java b/libraries/server/src/art/servers/gui/components/PanelTracesHistorical.java
index f4c1f57..4cf4577 100644
--- a/libraries/server/src/art/servers/gui/components/PanelTracesHistorical.java
+++ b/libraries/server/src/art/servers/gui/components/PanelTracesHistorical.java
@@ -197,6 +197,7 @@
                     case Trace.TRACE_INFORMATION:  result = result = result + color(SCREEN_RESET, SCREEN_CYAN, SCREEN_BLACK); break;
                     case Trace.TRACE_WARNING: result = result + color(SCREEN_RESET, SCREEN_YELLOW, SCREEN_BLACK); break;
                     case Trace.TRACE_ERROR: result = result + color(SCREEN_RESET, SCREEN_RED, SCREEN_BLACK); break;
+                    case Trace.TRACE_CORRECT: result = result + color(SCREEN_RESET, SCREEN_GREEN, SCREEN_BLACK); break;
                 }
                 result = result + "{\n";
                 if (trace.sourceComputer != null) result = result + "   " + Shared.getMessage("Source") + " : " + trace.sourceComputer + "\n";
diff --git a/libraries/server/src/server.version.properties b/libraries/server/src/server.version.properties
index 95638ae..e613412 100644
--- a/libraries/server/src/server.version.properties
+++ b/libraries/server/src/server.version.properties
@@ -1,7 +1,7 @@
-#Thu, 30 Nov 2023 10:36:40 +0100
+#Mon, 24 Jun 2024 18:08:28 +0200
 
-date=30/11/2023
+date=24/06/2024
 major=1
 minor=0
 revision=0
-build=8
+build=74
diff --git "a/servers/cameraserver_coru\303\261a/art.servers.cameraserver.cameras.json" "b/servers/cameraserver_coru\303\261a/art.servers.cameraserver.cameras.json"
index 6758ae4..e0da7fe 100644
--- "a/servers/cameraserver_coru\303\261a/art.servers.cameraserver.cameras.json"
+++ "b/servers/cameraserver_coru\303\261a/art.servers.cameraserver.cameras.json"
@@ -10999,456 +10999,5 @@
             "Default snapshot": 1,
             "Polling": 15
         }
-	},
-	{
-        "Camera information": {
-            "Identifier": "cctv-corunya-276",
-            "Creation date": "1970-01-01T00:00:00.000Z",
-            "Server port": 0,
-            "Server port external": 0,
-            "Number": 276,
-            "Group": "A CORUÑA",
-            "Name": "CyD.- Calle Alfredo Vicenti 02",
-            "Location": "",
-            "Direction": "",
-            "Municipality": "A CORUÑA",
-            "Description": "Calle Alfredo Vicenti",
-            "Kilometric point": "",
-            "Latitude": 43.35790740543055,
-            "Longitude": -8.399858499089948,
-            "Latitude offset": 0.0,
-            "Longitude offset": 0.0,
-            "Owner": "",
-            "Maintainer": "",
-            "Symbol": "Dome camera",
-            "Alarms": [],
-            "Manufacturer": "HIKVISION",
-            "Model": "DS-2DE7A232IW-AEB",
-            "Protocol": "ONVIF",
-            "North degrees": 0.0,
-            "Connection": {
-                "Address": "172.17.26.134",
-                "Default multicast": true,
-                "HTTP port": 80,
-                "Network caching": 50,
-                "ONVIF port": 80,
-                "Password": "Administrador",
-                "RTSP port": 554,
-                "User": "admin"
-            },
-            "Snapshot": [],
-            "Default snapshot": 1,
-            "Polling": 15
-        }
-	},
-	{
-        "Camera information": {
-            "Identifier": "cctv-corunya-277",
-            "Creation date": "1970-01-01T00:00:00.000Z",
-            "Server port": 0,
-            "Server port external": 0,
-            "Number": 277,
-            "Group": "A CORUÑA",
-            "Name": "CyD.- Mercado de Elviña 01",
-            "Location": "",
-            "Direction": "",
-            "Municipality": "A CORUÑA",
-            "Description": "Mercado de Elviña",
-            "Kilometric point": "",
-            "Latitude": 43.35790740543055,
-            "Longitude": -8.399858499089948,
-            "Latitude offset": 0.0,
-            "Longitude offset": 0.0,
-            "Owner": "",
-            "Maintainer": "",
-            "Symbol": "Dome camera",
-            "Alarms": [],
-            "Manufacturer": "HIKVISION",
-            "Model": "DS-2DE7A232IW-AEB",
-            "Protocol": "ONVIF",
-            "North degrees": 0.0,
-            "Connection": {
-                "Address": "172.17.117.44",
-                "Default multicast": true,
-                "HTTP port": 80,
-                "Network caching": 50,
-                "ONVIF port": 80,
-                "Password": "Administrador",
-                "RTSP port": 554,
-                "User": "admin"
-            },
-            "Snapshot": [],
-            "Default snapshot": 1,
-            "Polling": 15
-        }
-	},
-	{
-        "Camera information": {
-            "Identifier": "cctv-corunya-278",
-            "Creation date": "1970-01-01T00:00:00.000Z",
-            "Server port": 0,
-            "Server port external": 0,
-            "Number": 278,
-            "Group": "A CORUÑA",
-            "Name": "CyD.- Mercado de Elviña 02",
-            "Location": "",
-            "Direction": "",
-            "Municipality": "A CORUÑA",
-            "Description": "Mercado de Elviña",
-            "Kilometric point": "",
-            "Latitude": 43.35790740543055,
-            "Longitude": -8.399858499089948,
-            "Latitude offset": 0.0,
-            "Longitude offset": 0.0,
-            "Owner": "",
-            "Maintainer": "",
-            "Symbol": "Dome camera",
-            "Alarms": [],
-            "Manufacturer": "HIKVISION",
-            "Model": "DS-2DE7A232IW-AEB",
-            "Protocol": "ONVIF",
-            "North degrees": 0.0,
-            "Connection": {
-                "Address": "172.17.117.41",
-                "Default multicast": true,
-                "HTTP port": 80,
-                "Network caching": 50,
-                "ONVIF port": 80,
-                "Password": "Administrador",
-                "RTSP port": 554,
-                "User": "admin"
-            },
-            "Snapshot": [],
-            "Default snapshot": 1,
-            "Polling": 15
-        }
-	},
-	{
-        "Camera information": {
-            "Identifier": "cctv-corunya-279",
-            "Creation date": "1970-01-01T00:00:00.000Z",
-            "Server port": 0,
-            "Server port external": 0,
-            "Number": 279,
-            "Group": "A CORUÑA",
-            "Name": "CyD.- Mercado de Elviña 03",
-            "Location": "",
-            "Direction": "",
-            "Municipality": "A CORUÑA",
-            "Description": "Mercado de Elviña",
-            "Kilometric point": "",
-            "Latitude": 43.35790740543055,
-            "Longitude": -8.399858499089948,
-            "Latitude offset": 0.0,
-            "Longitude offset": 0.0,
-            "Owner": "",
-            "Maintainer": "",
-            "Symbol": "Dome camera",
-            "Alarms": [],
-            "Manufacturer": "HIKVISION",
-            "Model": "DS-2DE7A232IW-AEB",
-            "Protocol": "ONVIF",
-            "North degrees": 0.0,
-            "Connection": {
-                "Address": "172.17.117.38",
-                "Default multicast": true,
-                "HTTP port": 80,
-                "Network caching": 50,
-                "ONVIF port": 80,
-                "Password": "Administrador",
-                "RTSP port": 554,
-                "User": "admin"
-            },
-            "Snapshot": [],
-            "Default snapshot": 1,
-            "Polling": 15
-        }
-	},
-	{
-        "Camera information": {
-            "Identifier": "cctv-corunya-280",
-            "Creation date": "1970-01-01T00:00:00.000Z",
-            "Server port": 0,
-            "Server port external": 0,
-            "Number": 280,
-            "Group": "A CORUÑA",
-            "Name": "CyD.- Plaza de Vigo-01",
-            "Location": "",
-            "Direction": "",
-            "Municipality": "A CORUÑA",
-            "Description": "Plaza de Vigo",
-            "Kilometric point": "",
-            "Latitude": 43.35790740543055,
-            "Longitude": -8.399858499089948,
-            "Latitude offset": 0.0,
-            "Longitude offset": 0.0,
-            "Owner": "",
-            "Maintainer": "",
-            "Symbol": "Fixed camera",
-            "Alarms": [],
-            "Manufacturer": "DAHUA",
-            "Model": "DH-IPC-HFW5241EP-Z12E",
-            "Protocol": "ONVIF",
-            "North degrees": 0.0,
-            "Connection": {
-                "Address": "172.17.105.20",
-                "Default multicast": true,
-                "HTTP port": 80,
-                "Network caching": 50,
-                "ONVIF port": 80,
-                "Password": "Administrador",
-                "RTSP port": 554,
-                "User": "admin"
-            },
-            "Snapshot": [],
-            "Default snapshot": 1,
-            "Polling": 15
-        }
-	},
-	{
-        "Camera information": {
-            "Identifier": "cctv-corunya-281",
-            "Creation date": "1970-01-01T00:00:00.000Z",
-            "Server port": 0,
-            "Server port external": 0,
-            "Number": 281,
-            "Group": "A CORUÑA",
-            "Name": "CyD.- Alfredo Vicenti Fija 01",
-            "Location": "",
-            "Direction": "",
-            "Municipality": "A CORUÑA",
-            "Description": "Plaza de Vigo",
-            "Kilometric point": "",
-            "Latitude": 43.35790740543055,
-            "Longitude": -8.399858499089948,
-            "Latitude offset": 0.0,
-            "Longitude offset": 0.0,
-            "Owner": "",
-            "Maintainer": "",
-            "Symbol": "Fixed camera",
-            "Alarms": [],
-            "Manufacturer": "DAHUA",
-            "Model": "DH-IPC-HFW5241EP-Z12E",
-            "Protocol": "ONVIF",
-            "North degrees": 0.0,
-            "Connection": {
-                "Address": "172.17.26.135",
-                "Default multicast": true,
-                "HTTP port": 80,
-                "Network caching": 50,
-                "ONVIF port": 80,
-                "Password": "Administrador",
-                "RTSP port": 554,
-                "User": "admin"
-            },
-            "Snapshot": [],
-            "Default snapshot": 1,
-            "Polling": 15
-        }
-	},
-	{
-        "Camera information": {
-            "Identifier": "cctv-corunya-282",
-            "Creation date": "1970-01-01T00:00:00.000Z",
-            "Server port": 0,
-            "Server port external": 0,
-            "Number": 282,
-            "Group": "A CORUÑA",
-            "Name": "CyD.- Alfredo Vicenti Fija 02",
-            "Location": "",
-            "Direction": "",
-            "Municipality": "A CORUÑA",
-            "Description": "Plaza de Vigo",
-            "Kilometric point": "",
-            "Latitude": 43.35790740543055,
-            "Longitude": -8.399858499089948,
-            "Latitude offset": 0.0,
-            "Longitude offset": 0.0,
-            "Owner": "",
-            "Maintainer": "",
-            "Symbol": "Fixed camera",
-            "Alarms": [],
-            "Manufacturer": "DAHUA",
-            "Model": "DH-IPC-HFW5241EP-Z12E",
-            "Protocol": "ONVIF",
-            "North degrees": 0.0,
-            "Connection": {
-                "Address": "172.17.26.137",
-                "Default multicast": true,
-                "HTTP port": 80,
-                "Network caching": 50,
-                "ONVIF port": 80,
-                "Password": "Administrador",
-                "RTSP port": 554,
-                "User": "admin"
-            },
-            "Snapshot": [],
-            "Default snapshot": 1,
-            "Polling": 15
-        }
-	},
-	{
-        "Camera information": {
-            "Identifier": "cctv-corunya-283",
-            "Creation date": "1970-01-01T00:00:00.000Z",
-            "Server port": 0,
-            "Server port external": 0,
-            "Number": 283,
-            "Group": "A CORUÑA",
-            "Name": "CyD.- Mercado de Elviña Fija 01",
-            "Location": "",
-            "Direction": "",
-            "Municipality": "A CORUÑA",
-            "Description": "Mercado de Elviña",
-            "Kilometric point": "",
-            "Latitude": 43.35790740543055,
-            "Longitude": -8.399858499089948,
-            "Latitude offset": 0.0,
-            "Longitude offset": 0.0,
-            "Owner": "",
-            "Maintainer": "",
-            "Symbol": "Fixed camera",
-            "Alarms": [],
-            "Manufacturer": "DAHUA",
-            "Model": "DH-IPC-HFW5241EP-Z12E",
-            "Protocol": "ONVIF",
-            "North degrees": 0.0,
-            "Connection": {
-                "Address": "172.17.117.43",
-                "Default multicast": true,
-                "HTTP port": 80,
-                "Network caching": 50,
-                "ONVIF port": 80,
-                "Password": "Administrador",
-                "RTSP port": 554,
-                "User": "admin"
-            },
-            "Snapshot": [],
-            "Default snapshot": 1,
-            "Polling": 15
-        }
-	},
-    {
-        "Camera information": {
-            "Identifier": "cctv-corunya-284",
-            "Creation date": "1970-01-01T00:00:00.000Z",
-            "Server port": 0,
-            "Server port external": 0,
-            "Number": 284,
-            "Group": "A CORUÑA",
-            "Name": "CyD.- Mercado de Elviña Fija 02",
-            "Location": "",
-            "Direction": "",
-            "Municipality": "A CORUÑA",
-            "Description": "Mercado de Elviña",
-            "Kilometric point": "",
-            "Latitude": 43.35790740543055,
-            "Longitude": -8.399858499089948,
-            "Latitude offset": 0.0,
-            "Longitude offset": 0.0,
-            "Owner": "",
-            "Maintainer": "",
-            "Symbol": "Fixed camera",
-            "Alarms": [],
-            "Manufacturer": "DAHUA",
-            "Model": "DH-IPC-HFW5241EP-Z12E",
-            "Protocol": "ONVIF",
-            "North degrees": 0.0,
-            "Connection": {
-                "Address": "172.17.117.40",
-                "Default multicast": true,
-                "HTTP port": 80,
-                "Network caching": 50,
-                "ONVIF port": 80,
-                "Password": "Administrador",
-                "RTSP port": 554,
-                "User": "admin"
-            },
-            "Snapshot": [],
-            "Default snapshot": 1,
-            "Polling": 15
-        }
-	},
-    {
-        "Camera information": {
-            "Identifier": "cctv-corunya-285",
-            "Creation date": "1970-01-01T00:00:00.000Z",
-            "Server port": 0,
-            "Server port external": 0,
-            "Number": 285,
-            "Group": "A CORUÑA",
-            "Name": "CyD.- Mercado de Elviña Fija 03",
-            "Location": "",
-            "Direction": "",
-            "Municipality": "A CORUÑA",
-            "Description": "Mercado de Elviña",
-            "Kilometric point": "",
-            "Latitude": 43.35790740543055,
-            "Longitude": -8.399858499089948,
-            "Latitude offset": 0.0,
-            "Longitude offset": 0.0,
-            "Owner": "",
-            "Maintainer": "",
-            "Symbol": "Fixed camera",
-            "Alarms": [],
-            "Manufacturer": "DAHUA",
-            "Model": "DH-IPC-HFW5241EP-Z12E",
-            "Protocol": "ONVIF",
-            "North degrees": 0.0,
-            "Connection": {
-                "Address": "172.17.117.37",
-                "Default multicast": true,
-                "HTTP port": 80,
-                "Network caching": 50,
-                "ONVIF port": 80,
-                "Password": "Administrador",
-                "RTSP port": 554,
-                "User": "admin"
-            },
-            "Snapshot": [],
-            "Default snapshot": 1,
-            "Polling": 15
-        }
-	},
-    {
-        "Camera information": {
-            "Identifier": "cctv-corunya-286",
-            "Creation date": "1970-01-01T00:00:00.000Z",
-            "Server port": 0,
-            "Server port external": 0,
-            "Number": 286,
-            "Group": "A CORUÑA",
-            "Name": "CyD.- Mercado de Elviña Fija 03",
-            "Location": "",
-            "Direction": "",
-            "Municipality": "A CORUÑA",
-            "Description": "Mercado de Elviña",
-            "Kilometric point": "",
-            "Latitude": 43.35790740543055,
-            "Longitude": -8.399858499089948,
-            "Latitude offset": 0.0,
-            "Longitude offset": 0.0,
-            "Owner": "",
-            "Maintainer": "",
-            "Symbol": "Fixed camera",
-            "Alarms": [],
-            "Manufacturer": "DAHUA",
-            "Model": "DH-IPC-HFW5241EP-Z12E",
-            "Protocol": "ONVIF",
-            "North degrees": 0.0,
-            "Connection": {
-                "Address": "172.17.105.18",
-                "Default multicast": true,
-                "HTTP port": 80,
-                "Network caching": 50,
-                "ONVIF port": 80,
-                "Password": "Administrador",
-                "RTSP port": 554,
-                "User": "admin"
-            },
-            "Snapshot": [],
-            "Default snapshot": 1,
-            "Polling": 15
-        }
 	}
 ]

--
Gitblit v1.10.0