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<SignalAlarm>();
|
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");
|
}
|
|
|
|
|
// <editor-fold defaultstate="collapsed" desc="Update">
|
|
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<VariableBinding> 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);
|
}
|
}
|
|
}
|