package art.servers.signalsboardserver.controller; import art.library.interop.serialization.Serialization; import art.library.model.devices.DeviceStatus; import art.library.model.devices.signalsboard.SignalsBoard; import art.library.model.devices.signalsboard.SignalsBoardAlarms; import art.library.model.devices.signalsboard.SignalsBoardInformation; import art.library.model.devices.signalsboard.SignalsBoardStatus; import art.library.model.devices.signalsboard.alarms.SignalAlarm; import art.library.model.devices.signalsboard.information.SignalInformation; import art.library.model.devices.signalsboard.information.SignalsInformation_BOX; import art.library.model.devices.signalsboard.information.SignalsInformation_ERU; import art.library.model.devices.signalsboard.information.SignalsInformation_MODBUSTCP; import art.library.model.devices.signalsboard.information.SignalsInformation_SNMP; import art.library.model.devices.signalsboard.status.SignalStatus; import art.library.model.devices.signalsboard.status.SignalStatusGroup; import art.library.utils.synchro.Mutex; import art.servers.Shared; import art.servers.signalsboardserver.configuration.Configuration; import art.servers.signalsboardserver.configuration.ConfigurationDetail_Manufacturer; import art.servers.signalsboardserver.configuration.ConfigurationDetail_Model; import art.servers.signalsboardserver.controller.pollers.PollerERU; import art.servers.signalsboardserver.controller.pollers.PollerModbus; import art.servers.signalsboardserver.controller.pollers.PollerSNMP; import java.util.ArrayList; import java.util.List; import org.snmp4j.smi.VariableBinding; public class ControllerUniversal extends art.servers.controller.ControllerDevice { protected SignalsBoard device = null; private String name = null; private Mutex mutex = new Mutex(); public ControllerUniversal(SignalsBoard signalsboard) { super(signalsboard); this.device = signalsboard; this.name = Shared.getMessage("Controller universal") + " " + signalsboard.toString(); this.setName(name); try { SignalsBoardInformation information = this.device.getDeviceInformation(); SignalsBoardAlarms alarms = this.device.getDeviceAlarms(); ConfigurationDetail_Manufacturer manufacturer = ((Configuration)Shared.configuration).detail.manufacturers.get(information.manufacturer); ConfigurationDetail_Model model = manufacturer.models.get(information.model); Shared.println(name, "Model: " + information.model + " - " + model); if (alarms.alarms == null) alarms.alarms = new ArrayList(); alarms.alarms.clear(); for (SignalsInformation_BOX box : model.signals.boxes) { if (box instanceof SignalsInformation_SNMP) { SignalsInformation_SNMP snmpbox = (SignalsInformation_SNMP)box; art.servers.signalsboardserver.Shared.controllersSnmp.put(((SignalsInformation_SNMP)box).address, this); } alarms.alarms.addAll(box.alarms); } } catch (Exception exception) { } } public SignalsBoard getSignalsBoard() { return device; } public void run() { Shared.traceInformation(name, "Starting"); int currentIteration = 0; while ((isInterrupted() == false) && (exit == false)) { long startTimestamp = System.currentTimeMillis(); try { if (Shared.isServerEnabled() == true) { update(currentIteration == 0); currentIteration = (currentIteration + 1) % device.getDeviceInformation().pollingFactor; } } catch (Exception exception) { Shared.traceError(name, Shared.getMessage("Update"), exception); } long timetowait = (device.getDeviceInformation().polling * 1000) - (System.currentTimeMillis() - startTimestamp); timetowait = Math.min(timetowait, (device.getDeviceInformation().polling * 1000)); if (timetowait > 0) { try { sleep(timetowait); } catch (Exception e) { } } try{sleep(50);} catch (Exception e){}; if (Shared.model.existsDevice(device.getIdentifier()) == false) { Shared.println(name, Shared.getMessage("Device no longer exists")); exit = true; } } Shared.traceInformation(name, "Finishing"); } // private void update(boolean updateStatus) throws Exception { mutex.lockWrite(); SignalsBoard clone = (SignalsBoard)Serialization.clone(device); try { clone.status = new SignalsBoardStatus(); SignalsBoardInformation information = clone.getDeviceInformation(); ConfigurationDetail_Manufacturer manufacturer = ((Configuration)Shared.configuration).detail.manufacturers.get(information.manufacturer); ConfigurationDetail_Model model = manufacturer.models.get(information.model); // A device can have several boxes, but must not be usual // If ONLY ONE box fails, que change estatus device to offline for simplicity // For same reason we execute Pollers sequentially not in parallel // Must be change in the future when needed // Signals from type in server configuration files boolean result = false; try { for (SignalsInformation_BOX box : model.signals.boxes) { if (box instanceof SignalsInformation_SNMP) { PollerSNMP poller = new PollerSNMP(name, model, clone, (SignalsInformation_SNMP)box); boolean resultPoller = poller.update(); result = resultPoller || result; } else if (box instanceof SignalsInformation_ERU) { PollerERU poller = new PollerERU(name, model, clone, (SignalsInformation_ERU)box); result = poller.update() || result; } else if (box instanceof SignalsInformation_MODBUSTCP) { PollerModbus poller = new PollerModbus(name, model, clone, (SignalsInformation_MODBUSTCP)box); result = poller.update() || result; } } } catch (Exception e) { } // Signals from model try { for (SignalsInformation_BOX box : device.getDeviceInformation().signals.boxes) { if (box instanceof SignalsInformation_SNMP) { PollerSNMP poller = new PollerSNMP(name, model, clone, (SignalsInformation_SNMP)box); boolean resultPoller = poller.update(); result = resultPoller || result; } else if (box instanceof SignalsInformation_ERU) { PollerERU poller = new PollerERU(name, model, clone, (SignalsInformation_ERU)box); result = poller.update() || result; } else if (box instanceof SignalsInformation_MODBUSTCP) { PollerModbus poller = new PollerModbus(name, model, clone, (SignalsInformation_MODBUSTCP)box); result = poller.update() || result; } } } catch (Exception e) { } if (updateStatus == false) { // Update value only of signals that are marked for update always try { for (SignalsInformation_BOX box : model.signals.boxes) { if (box.inputs != null) { for (SignalInformation signalInformation : box.inputs) { SignalStatus signalStatus = clone.getDeviceStatus().getSignal(signalInformation.name); if (signalStatus != null) { if (signalInformation.updateAlways == false) { SignalStatus signalStatusCurrent = this.device.getDeviceStatus().getSignal(signalInformation.name); signalStatus.format = signalStatusCurrent.format; signalStatus.value = signalStatusCurrent.value; } else { SignalStatus signalStatusCurrent = this.device.getDeviceStatus().getSignal(signalInformation.name); if ((signalStatus.value != null) && (signalStatusCurrent.value != null)) { if (signalStatus.value.equalsIgnoreCase(signalStatusCurrent.value) == false) { Shared.println(name, "Signal: " + signalStatus.name + ", Current: " + signalStatusCurrent.value + ", New: " + signalStatus.value); } } } } } } if (box.inouts != null) { for (SignalInformation signalInformation : box.inouts) { SignalStatus signalStatus = clone.getDeviceStatus().getSignal(signalInformation.name); if (signalStatus != null) { if (signalInformation.updateAlways == false) { SignalStatus signalStatusCurrent = this.device.getDeviceStatus().getSignal(signalInformation.name); signalStatus.format = signalStatusCurrent.format; signalStatus.value = signalStatusCurrent.value; } } } } } } catch (Exception e) { } } if (result == true) { online(clone); } else { offline(clone); } } catch (Exception exception) { Shared.traceError(name, Shared.getMessage("Update"), exception); offline(clone); } finally { Shared.model.updateDevice(device, clone); mutex.releaseWrite(); } } private void offline(SignalsBoard device)throws Exception { device.getDeviceStatus().status = DeviceStatus.STATUS_OFFLINE; long tsOffline = device.getAlarm("alarm_offline"); device.alarms.clear(); if (tsOffline <= 0) { Shared.println(this.name, Shared.getMessage("Signalsboard offline")); device.setAlarm("alarm_offline", true); } else { device.setAlarm("alarm_offline", tsOffline); } } private void online(SignalsBoard device) throws Exception { device.getDeviceStatus().status = DeviceStatus.STATUS_ONLINE; if (device.getAlarm("alarm_offline") > 0) { Shared.println(this.name, Shared.getMessage("Signalsboard online")); } device.setAlarm("alarm_offline", false); device.setAlarm("alarm_invalid", false); } public void trapReceived (String sourceAddress, List variables) { try { // TODO Search OID in SignalInformation_SNMP of model.boxes of signalsboard ConfigurationDetail_Manufacturer manufacturer = ((Configuration)Shared.configuration).detail.manufacturers.get(this.device.getDeviceInformation().manufacturer); ConfigurationDetail_Model model = manufacturer.models.get(this.device.getDeviceInformation().model); for (SignalsInformation_BOX box : model.signals.boxes) { if (box instanceof SignalsInformation_SNMP) { if (((SignalsInformation_SNMP)box).address.equalsIgnoreCase(sourceAddress) == true) { try { // If exists then must be set mutex.lockWrite() to avoid change when is changing update mutex.lockWrite(); // TODO: Do what do PollerSNMP when find a signal, fill signalStatus and SignalAlarm if exist SignalsBoard clone = Serialization.clone(this.device); SignalsBoardStatus status = clone.getDeviceStatus(); for (VariableBinding variable : variables) { try { writeSignalStatus(status, variable); } catch (Exception e) { } } Shared.model.updateDevice(device, clone); } catch (Exception e) { Shared.printstack(name, e); } finally { mutex.releaseWrite(); } return; } } } } catch (Exception exception) { Shared.printstack(name, exception); } } private void writeSignalStatus (SignalsBoardStatus status, VariableBinding variable) { try { for (SignalStatusGroup group : status.inputs) { for (SignalStatus signalStatus : group.signals) { } } } catch (Exception exception) { Shared.printstack(name, exception); } } }