package art.servers.rtzserver.utils; import art.library.model.devices.colors.controller.RTZ32.RTZ32_Controller; import art.library.model.devices.colors.controller.RTZ32.RTZ32_ControllerInformation; import art.library.model.devices.colors.controller.RTZ32.configuration.RTZ32_Configuration; import art.library.model.devices.colors.controller.RTZ32.configuration.RTZ32_Configuration_Group; import art.library.model.devices.colors.controller.RTZ32.configuration.RTZ32_Configuration_Program; import art.library.model.devices.colors.controller.RTZ32.configuration.RTZ32_Configuration_Program_Group; import art.library.model.devices.colors.controller.RTZ32.configuration.RTZ32_Configuration_Program_Trolley_Cancellation; import art.library.model.devices.colors.controller.RTZ32.configuration.RTZ32_Configuration_Program_Trolley_Correlation_Master; import art.library.model.devices.colors.controller.RTZ32.configuration.RTZ32_Configuration_Program_Trolley_Correlation_Slave; import art.library.model.devices.colors.controller.RTZ32.configuration.RTZ32_Configuration_Program_Trolley_Retractable; import art.library.model.devices.colors.controller.RTZ32.configuration.RTZ32_Configuration_Program_Trolley_Saturation; import art.library.model.devices.colors.controller.RTZ32.configuration.RTZ32_Configuration_Program_VariablePhase; import art.library.model.devices.colors.controller.RTZ32.configuration.constants.RTZ32_Constants_Colors; import art.library.model.devices.colors.controller.RTZ32.information.RTZ32_Information_Program; import art.library.model.devices.colors.controller.RTZ32.types.RTZ32_Distribution; import art.library.model.devices.colors.controller.RTZ32.types.RTZ32_Distribution_Group; import art.library.model.devices.colors.controller.RTZ32.types.RTZ32_Distribution_Group_Segment; import art.library.model.devices.colors.controller.RTZ32.types.RTZ32_Validation_Result; import art.servers.Shared; import java.util.ArrayList; import java.util.List; public class VALIDATION { // Validaciones según se va configurando el reparto: // Valores mayor que el ciclo // Fases Variables ERROR --> "La Fase Variable con Inicio xx y Fin yy está fuera de los límites temporales" // Fases Escamoteables ERROR --> "La Fase Escamoteable con Inicio xx y Fin yy está fuera de los límites temporales" // Puntos de Cancelación ERROR --> "El Punto de Cancelación está fuera de los límites temporales" // Puntos de Correlación ERROR --> "El Punto de Correlación está fuera de los límites temporales" // Zonas de Saturación ERROR --> "La Zona de Saturación con Inicio xx y Fin yy está fuera de los límites temporales" // Impulsos WARNING --> "El impulso rebasa el tiempo del ciclo, esta operación sólo es válida para grupos especiales de bomberos. ¿Está seguro que desea modificar este dato? // Valores igual al ciclo // Fases Variables WARNING --> "La Fase Variable con Inicio xx y Fin yy está fuera de los límites temporales" // Fases Escamoteables WARNING --> "La Fase Escamoteable con Inicio xx y Fin yy está fuera de los límites temporales" // Puntos de Cancelación WARNING --> "El Punto de Cancelación está fuera de los límites temporales" // Puntos de Correlación WARNING --> "El Punto de Correlación está fuera de los límites temporales" // Zonas de Saturación WARNING --> "La Zona de Saturación con Inicio xx y Fin yy está fuera de los límites temporales" // Impulsos WARNING --> "El grupo con orden X y Tipo X tiene impulsos fuera de rango" // Repartir Tiempos // Si al repartir tiempos el valor del ciclo no se ve modificado, únicamente se mostrará // un MessageBox "El reparto de movimiento se ha realizado correctamente // Si al repartir tiempos el valor del ciclo se modifica, // se informará con MessageBox "Esta operación variará el tiempo del ciclo" WARNING, // y tras realizarse otro con "El reparto de movimiento se ha realizado correctamente" public static RTZ32_Validation_Result validate(RTZ32_Controller controller, RTZ32_Information_Program program_information, String language) throws Exception { RTZ32_Validation_Result result = new RTZ32_Validation_Result(); RTZ32_Configuration configuration = program_information.configuration.rtz32; RTZ32_Configuration_Program program = configuration.getProgram(program_information.program); // Comprobar el número de grupos y tipos // No se completan las Observaciones ERROR --> "El campo "Observaciones" no puede estar vacío" if ((program_information.description == null) || (program_information.description.length() == 0)) { result.errors.add(Shared.getMessage(language, "Description field cannot be empty")); } // Si existe un cambio de estados de Grupo dentro de la Fase Variable (No comprobar grupos tipo 30 y 40) WARNING --> // "La Fase Variable con Inicio xx y Final yy tiene cambios de estado en el Grupo con orden X y Tipo X" for (RTZ32_Configuration_Program_Group group : program.groups) { if ((group != null) && (group.isEmpty() == false)) { // Ha de existir el grupo dentro de la configuración del regulador // Si el numero de grupo es 0 siginifica que no tiene impulsos y que por lo tanto // no existe en la configuración del regulador. if (group.group > 0) { int type = configuration.getGroup(group.group).getType(); if ((type != 30) && (type != 40)) { for (Integer impulse : group.impulses) { for (RTZ32_Configuration_Program_VariablePhase variable : program.variablePhases) { if ((variable != null) && (impulse >= variable.startTime) && (impulse < variable.endTime) && (variable.isEmpty() == false)) { String message = Shared.getMessage(language, "Impulse detected inside variable phase") + "\r\n"; message = message + Shared.getMessage(language, "Group number") + " " + group.group + "\r\n"; message = message + Shared.getMessage(language, "Variable phase") + " [ " + variable.startTime + " → " + variable.endTime + " ]\r\n"; message = message + Shared.getMessage(language, "Impulse time") + " " + impulse; result.warnings.add(message); } } } } } } } // Si el final de la FV no coincide con un cambio de estado WARNING --> " // La Fase Variable con Inicio xx y Final xx debe tener al menos un cambio de estado de algún grupo en su final" for (RTZ32_Configuration_Program_VariablePhase variable : program.variablePhases) { if ((variable != null) && (variable.isEmpty() == false)) { if (check_end_phase(program, variable) == false) { String message = Shared.getMessage(language, "No group changes at the end of the variable phase") + " [ " + variable.startTime + " → " + variable.endTime + " ]"; result.warnings.add(message); } } } // Debe haber entre 2 y 8 fases Variables WARNING --> "Debe haber al menos 2 Fases Variables" int totalVariablePhases = getNumberVariablePhases(program); if (totalVariablePhases < 2) { String message = Shared.getMessage(language, "The number or variable phases is less than 2"); result.warnings.add(message); } if (totalVariablePhases > 8) { String message = Shared.getMessage(language, "The number or variable phases is greater than 8"); result.warnings.add(message); } // Fase Escamoteable dentro de Fase Variable WARNING --> " La fase variable con inicio xx y fin xx tiene solapada una fase escamoteable" for (RTZ32_Configuration_Program_Trolley_Retractable retractable : program.trolley.retractables) { for (RTZ32_Configuration_Program_VariablePhase variable : program.variablePhases) { if ((retractable != null) && (variable != null) && (retractable.isEmpty() == false) && (variable.isEmpty() == false)) { if ( ((variable.startTime >= retractable.startTime) && (variable.startTime < retractable.endTime)) || ((variable.endTime > retractable.startTime) && (variable.startTime <= retractable.endTime)) ) { String message = Shared.getMessage(language, "Variable phase overlaps retractable phase") + "\r\n"; message = message + Shared.getMessage(language, "Variable phase") + " [ " + variable.startTime + " → " + variable.endTime + " ]\r\n"; message = message + Shared.getMessage(language, "Retractable phase") + " [ " + retractable.startTime + " → " + retractable.endTime + " ]"; result.warnings.add(message); } } } } // Nº Puntos Correlación según el tipo de regulador: // CTMaestro: WARNING --> " Debe tener entre 1 y 4 Puntos de Correlación Maestro" // Esclavo: WARNING --> " Debe tener entre 1 y 4 Puntos de Correlación Esclavo" // MaestroEsclavo: WARNING --> "Debe tener 1 Maestro o 1 Esclavo" // EsclavoMaestro: WARNING --> "Debe tener 1 Maestro o 1 Esclavo " if (controller.getDeviceInformation().mode == RTZ32_ControllerInformation.MODE_CENTRALIZED_MASTER) { if (getNumberCorrelationsMaster(program) < 1) { String message = Shared.getMessage(language, "The number of masters correlations is less than 1"); result.warnings.add(message); } if (getNumberCorrelationsMaster(program) > 4) { String message = Shared.getMessage(language, "The number of masters correlations is greater than 4"); result.warnings.add(message); } } if (controller.getDeviceInformation().mode == RTZ32_ControllerInformation.MODE_CENTRALIZED_SLAVE) { if (getNumberCorrelationsSlave(program) < 1) { String message = Shared.getMessage(language, "The number of slaves correlations is less than 1"); result.warnings.add(message); } if (getNumberCorrelationsSlave(program) > 4) { String message = Shared.getMessage(language, "The number of slaves correlations is greater than 4"); result.warnings.add(message); } } if (controller.getDeviceInformation().mode == RTZ32_ControllerInformation.MODE_CENTRALIZED_MASTER_SLAVE) { int masters = getNumberCorrelationsMaster(program); int slaves = getNumberCorrelationsSlave(program); if (masters == 1) result.warnings.add(Shared.getMessage(language, "A minimum of 1 correlation master is required")); if (slaves == 1) result.warnings.add(Shared.getMessage(language, "A minimum of 1 correlation slave is required")); if (masters > 4) result.warnings.add(Shared.getMessage(language, "A maximum of 4 correlation master are allowed")); if (slaves > 4) result.warnings.add(Shared.getMessage(language, "A minimum of 4 correlation slave are allowed")); } if (controller.getDeviceInformation().mode == RTZ32_ControllerInformation.MODE_CENTRALIZED_SLAVE_MASTER) { int masters = getNumberCorrelationsMaster(program); int slaves = getNumberCorrelationsSlave(program); if (masters == 1) result.warnings.add(Shared.getMessage(language, "A minimum of 1 correlation master is required")); if (slaves == 1) result.warnings.add(Shared.getMessage(language, "A minimum of 1 correlation slave is required")); if (masters > 4) result.warnings.add(Shared.getMessage(language, "A maximum of 4 correlation master are allowed")); if (slaves > 4) result.warnings.add(Shared.getMessage(language, "A minimum of 4 correlation slave are allowed")); } // Punto Correlación tipo Esclavo y de Pto. de Cancelación: // Si el Time Out del esclavo no está programado WARNING --> "El Punto de correlación esclavo con valor XX no tiene valor para TimeOut" // Si el Tiempo de espera del punto de cancelación no está programado WARNING --> "El Punto de cancelación con valor XX no tiene valor para el tiempo máximo de espera" for (RTZ32_Configuration_Program_Trolley_Correlation_Slave correlation : program.trolley.correlationsSlave) { if ((correlation != null) && (correlation.isEmpty() == false)) { if (correlation.timeout == 0) { String message = Shared.getMessage(language, "Timeout for slave correlation not set") + " [ " + correlation.time + ", " + correlation.timeout + " ]"; result.warnings.add(message); } } } for (RTZ32_Configuration_Program_Trolley_Cancellation cancellation : program.trolley.cancellations) { if ((cancellation != null) && (cancellation.isEmpty() == false)) { if (cancellation.timeout == 0) { String message = Shared.getMessage(language, "Timeout for cancelation point not set") + " [ " + cancellation.time + ", " + cancellation.timeout + " ]"; result.warnings.add(message); } } } // Punto de Correlación Esclavo no están al final de una fase variable WARNING --> "El Punto de Correlación con valor XX debe estar situado en el final de una Fase Variable" for (RTZ32_Configuration_Program_Trolley_Correlation_Slave correlation : program.trolley.correlationsSlave) { if ((correlation != null) && (correlation.isEmpty() == false)) { if (existsVariablePhaseWithEndTime(program, correlation.time) == false) { String message = Shared.getMessage(language, "Slave correlation time does not match with the end of any phase") + " [ " + correlation.time + " ]"; result.warnings.add(message); } } } // Número de grupos de peatones <= 6 if (configuration.getGroupType(20).size() > 6) { String message = Shared.getMessage(language, "The maximum number of pedestrians groups (trolley) is 6"); result.errors.add(message); } // Número de grupos de tranvia =< 4 if (configuration.getGroupType(30).size() > 4) { String message = Shared.getMessage(language, "The maximum number of trolley groups is 4"); result.errors.add(message); } if (configuration.getGroupType(40).size() > 4) { String message = Shared.getMessage(language, "The maximum number of trolley groups is 4"); result.errors.add(message); } // Tiempo mínimo de peatones RTZ32_Distribution distribution = new RTZ32_Distribution(program_information.configuration.rtz32, program_information.program); int pedestrianPosition = 0; for (int i=0; i segments = group.listBars.get(j); if (segments.size() > 0) { int minimumGreenTime = configuration.trolleys.trolleys[j].pedestrians[pedestrianPosition].minimumGreenTime; for (Integer time : getGreensTimes(segments)) { if (time < minimumGreenTime) { String message = Shared.getMessage(language, "Pedestrian group (trolley) with green times less than minimim green time configured") + "\r\n"; message = message + Shared.getMessage(language, "Group number") + " " + group.groupNumber + "\r\n"; message = message + Shared.getMessage(language, "Pedestrian order") + " " + (pedestrianPosition + 1) + "\r\n"; message = message + Shared.getMessage(language, "Trolley order") + " " + (j + 1) + "\r\n"; message = message + Shared.getMessage(language, "Minimum green time") + " " + minimumGreenTime + "\r\n"; message = message + Shared.getMessage(language, "Green time") + " " + time; result.warnings.add(message); } } } } pedestrianPosition = pedestrianPosition + 1; } } // Valores mayor que el ciclo: // Fases Variables ERROR --> "La Fase Variable con Inicio xx y Fin yy está fuera de los límites temporales" for (RTZ32_Configuration_Program_VariablePhase variable : program.variablePhases) { if ((variable != null) && (variable.isEmpty() == false)) { if ((variable.startTime >= program.cycle) || (variable.endTime > program.cycle) || (variable.startTime < 0) || (variable.endTime < 1)) { String message = Shared.getMessage(language, "Variable phase out of bounds") + " [" + variable.startTime + " → " + variable.endTime + " ]"; result.errors.add(message); } } } // Fases Escamoteables ERROR --> "La Fase Escamoteable con Inicio xx y Fin yy está fuera de los límites temporales" for (RTZ32_Configuration_Program_Trolley_Retractable retractable : program.trolley.retractables) { if ((retractable != null) && (retractable.isEmpty() == false)) { if ((retractable.startTime >= program.cycle) || (retractable.endTime > program.cycle) || (retractable.startTime < 0) || (retractable.endTime < 1)) { String message = Shared.getMessage(language, "Retractable phase out of bounds") + " : [ " + retractable.startTime + " → " + retractable.endTime + " ]"; result.errors.add(message); } } } // Puntos de Cancelación ERROR --> "El Punto de Cancelación está fuera de los límites temporales" for (RTZ32_Configuration_Program_Trolley_Cancellation cancellation : program.trolley.cancellations) { if ((cancellation != null) && (cancellation.isEmpty() == false)) { if ((cancellation.time > program.cycle) || (cancellation.time < 0)) { String message = Shared.getMessage(language, "Cancellation point out of bounds") + " [ " + cancellation.time + " ]"; result.errors.add(message); } } } // Puntos de Correlación ERROR --> "El Punto de Correlación está fuera de los límites temporales" for (RTZ32_Configuration_Program_Trolley_Correlation_Master correlation : program.trolley.correlationsMaster) { if ((correlation != null) && (correlation.isEmpty() == false)) { if ((correlation.time > program.cycle) || (correlation.time < 0)) { String message = Shared.getMessage(language, "Correlation master out of bounds") + " [ " + correlation.time + " ]"; result.errors.add(message); } } } for (RTZ32_Configuration_Program_Trolley_Correlation_Slave correlation : program.trolley.correlationsSlave) { if ((correlation != null) && (correlation.isEmpty() == false)) { if ((correlation.time > program.cycle) || (correlation.time < 0)) { String message = Shared.getMessage(language, "Correlation slave out of bounds") + " [ " + correlation.time + " ]"; result.errors.add(message); } } } // Zonas de Saturación ERROR --> "La Zona de Saturación con Inicio xx y Fin yy está fuera de los límites temporales" for (RTZ32_Configuration_Program_Trolley_Saturation saturation : program.trolley.saturations) { if ((saturation != null) && (saturation.isEmpty() == false)) { if ((saturation.startTime >= program.cycle) || (saturation.endTime > program.cycle) || (saturation.startTime < 0) || (saturation.endTime < 1)) { String message = Shared.getMessage(language, "Saturation out of bounds") + " [ " + saturation.startTime + " → " + saturation.endTime + " ]"; result.errors.add(message); } } } // Impulsos WARNING --> "El impulso rebasa el tiempo del ciclo, esta operación sólo es válida para grupos especiales de bomberos. ¿Está seguro que desea modificar este dato? for (RTZ32_Configuration_Program_Group group : program.groups) { for (Integer impulse : group.impulses) { if ((impulse > program.cycle) || (impulse < 0)) { String message = Shared.getMessage(language, "Impulse time out of bounds") + "\r\n"; message = message + Shared.getMessage(language, "Group number") + " " + group.group + "\r\n"; message = message + Shared.getMessage(language, "Impulse time") + " " + impulse; result.warnings.add(message); } } } // Valores igual al ciclo: // Fases Variables WARNING --> "La Fase Variable con Inicio xx y Fin yy está fuera de los límites temporales" // Fases Escamoteables WARNING --> "La Fase Escamoteable con Inicio xx y Fin yy está fuera de los límites temporales" // Puntos de Cancelación WARNING --> "El Punto de Cancelación está fuera de los límites temporales" // Puntos de Correlación WARNING --> "El Punto de Correlación está fuera de los límites temporales" // Zonas de Saturación WARNING --> "La Zona de Saturación con Inicio xx y Fin yy está fuera de los límites temporales" // Impulsos WARNING --> "El grupo con orden X y Tipo X tiene impulsos fuera de rango" // Esto no tiene sentido return result; } public static RTZ32_Validation_Result eprom(RTZ32_Controller controller, RTZ32_Information_Program program_information, String language) throws Exception { RTZ32_Validation_Result result = new RTZ32_Validation_Result(); RTZ32_Configuration configuration1 = program_information.configuration.rtz32; RTZ32_Configuration configuration2 = controller.getDeviceConfiguration().rtz32; RTZ32_Configuration_Program program1 = configuration1.getProgram(program_information.program); RTZ32_Configuration_Program program2 = configuration2.getProgram(program_information.program); String header91 = Shared.getMessage(language, "Table") + " 91:\r\n"; String header92 = Shared.getMessage(language, "Table") + " 92:\r\n"; String header93 = Shared.getMessage(language, "Table") + " 93:\r\n"; String header95 = Shared.getMessage(language, "Table") + " 95:\r\n"; List lwarningsTabla95 = new ArrayList(); // Nº de Regulador distinto al de la tabla 95 WARNING if (configuration1.controllerNumber != configuration2.controllerNumber) { lwarningsTabla95.add(Shared.getMessage(language, "Controller number does not match") + "\r\n"); } // Nº de grupos distinto al de la tabla 95 WARNING if (configuration1.getNumberValidGroups() != configuration2.numberGroups) { lwarningsTabla95.add(Shared.getMessage(language, "Number of groups does not match") + "\r\n"); } else if (configuration1.getNumberValidGroups() != configuration2.getNumberValidGroups()) { lwarningsTabla95.add(Shared.getMessage(language, "Number of groups does not match") + "\r\n"); } // Incompatibilidad de impulsos con tabla 91 (entre verdes). WARNING // tabla 92 (de los marcados como incompatibles en la tabla 91 // que no se produzca ninguna coincidencia entre verde y ámbar). WARNING RTZ32_Distribution distribution = new RTZ32_Distribution(configuration1, program1.number); List lgroupsRedError = new ArrayList(); List lgroupsNoRedError = new ArrayList(); List lgroupsTable91Error = new ArrayList(); List lgroupsTable92Error = new ArrayList(); // Tabla 93 si existe algún grupo que pasa por rojo y no existe un 1 en la tabla. WARNING for (RTZ32_Configuration_Program_Group group : program1.groups) { if ((group != null) && (group.isEmpty() == false)) { if (group.group > 0) { RTZ32_Configuration_Group groupCfg = configuration1.getGroup(group.group); int type = groupCfg.getType(); if ((type != 0) && (type != 7) && (type != 10) && (type != 24) && (type != 25) && (type != 35) && (type != 36) && (type != 44) && (type != 45)) { if (groupCfg.redLampFlashing == false) { lgroupsRedError.add(group.group); } } else { if (groupCfg.redLampFlashing == true) { lgroupsNoRedError.add(group.group); } } for (int i=0; i 0) { String message = header91; message = message + Shared.getMessage(language, "Incompatibility with greens in table 91") + ", " + Shared.getMessage(language, "Groups") + " : " + "\r\n"; for (int i=0; i 0) { String message = header92; message = message + Shared.getMessage(language, "Incompatibility with greens and yellows in table 92") + ", " + Shared.getMessage(language, "Groups") + " : " + "\r\n"; for (int i=0; i 0) { String message = header93; message = message + Shared.getMessage(language, "Have a 0 in table 93 and have red impulse") + ", " + Shared.getMessage(language, "Groups") + " : " + "\r\n"; for (int i=0; i 0) { String message = header93; message = message + Shared.getMessage(language, "Have a 1 in table 93 and have not red impulse") + ", " + Shared.getMessage(language, "Groups") + " : " + "\r\n"; for (int i=0; i 0) { String message = header95; for (int i=0; i getGreensTimes(List segments) { List result = new ArrayList(); // Get number of reds for (int i=0; i