package de.desy.tine.server.alarms;
import de.desy.tine.client.*;
import de.desy.tine.dataUtils.*;
import de.desy.tine.server.devices.TDevice;
import de.desy.tine.server.devices.TRegion;
import de.desy.tine.server.equipment.TEquipmentModule;
import de.desy.tine.structUtils.*;
import de.desy.tine.definitions.*;
public class TAlarmMessage extends TTaggedStructure implements Comparable<Object>
{
private static TLinkFactory gLinkFactory = null;
private static TLinkFactory getLinkFactory()
{
if (gLinkFactory == null) gLinkFactory = TLinkFactory.getInstance();
return gLinkFactory;
}
private char[] server = new char[TStrings.EXPORT_NAME_SIZE];
private String serverString;
private char[] device = new char[TStrings.DEVICE_NAME_SIZE];
private String deviceString;
private char[] alarmTag = new char[TStrings.ALARM_TAG_SIZE];
private String alarmTagString;
private int[] alarmCode = new int[1];
private int[] timestamp = new int[1];
private int[] timestampUSec = new int[1];
private int[] starttime = new int[1];
private int[] starttimeUSec = new int[1];
private int[] alarmMask = new int[1];
private byte[] alarmData = new byte[TStrings.ALARM_DATA_SIZE];
private byte[] alarmDataFormat = new byte[1];
private byte[] alarmDataArraySize = new byte[1];
private TDataType tAlarmData;
private byte[] severity = new byte[1];
private byte[] descriptor = new byte[1];
private short[] alarmSystem = new short[1];
private byte[] alarmOscillationWindow = new byte[1];
private byte[] alarmOscillationWindowPinned = new byte[1];
public int getAlarmCode() { return alarmCode[0]; }
public int getAlarmSeverity() { return severity[0]; }
public int getAlarmDescriptor() { return descriptor[0]; }
public String getAlarmDescriptorAsString()
{
return TAlarmDescriptor.toLongString(descriptor[0]);
}
public boolean isTransient()
{
return ((descriptor[0] & TAlarmDescriptor.TRANSIENT) == TAlarmDescriptor.TRANSIENT);
}
public boolean isDataChange()
{
return ((descriptor[0] & TAlarmDescriptor.DATACHANGE) == TAlarmDescriptor.DATACHANGE);
}
public boolean isTerminated()
{
return ((descriptor[0] & TAlarmDescriptor.TERMINATE) == TAlarmDescriptor.TERMINATE);
}
public boolean isNew()
{
return ((descriptor[0] & TAlarmDescriptor.NEW) == TAlarmDescriptor.NEW);
}
public boolean isOscillating()
{
return ((descriptor[0] & TAlarmDescriptor.OSCILLATION) == TAlarmDescriptor.OSCILLATION);
}
public boolean isHearbeat()
{
return ((descriptor[0] & TAlarmDescriptor.HEARTBEAT) == TAlarmDescriptor.HEARTBEAT);
}
public boolean isActive()
{
if ((descriptor[0] & TAlarmDescriptor.TERMINATE) != TAlarmDescriptor.TERMINATE)
{ // definitely active !
return true;
}
if ((descriptor[0] & TAlarmDescriptor.TRANSIENT) == TAlarmDescriptor.TRANSIENT)
{ // this will let the transient alarms appear in the active list
return true;
}
return false;
}
public int getAlarmSystem() { return alarmSystem[0]; }
public void setAlarmSystem(int value) { alarmSystem[0] = (short)value; }
public long getTimeStamp()
{
return((long)timestamp[0]*1000) + (timestampUSec[0]/1000);
}
public long getStartTime()
{
return ((long)starttime[0]*1000) + (starttimeUSec[0]/1000);
}
public int getAlarmMask() { return alarmMask[0]; }
public boolean hasData() { return alarmDataArraySize[0] > 0 ? true : false; }
public TDataType getAlarmData()
{
if (tAlarmData == null)
{
int dsiz = alarmDataArraySize[0];
short dfmt = (short)(alarmDataFormat[0]);
//TODO: make this more memory efficient ...
tAlarmData = new TDataType(dsiz,dfmt);
if (dsiz > 0 && dfmt != TFormat.CF_NULL)
{ // the data are in TINE (i.e. little-endian) byte order!
if (dfmt == TFormat.CF_TEXT)
{ // make sure the end is zeroed!
int i;
for (i=0; i<dsiz && alarmData[i] != 0; i++);
while (i<dsiz) alarmData[i++] = 0;
}
tAlarmData.pushBytes(alarmData);
getLinkFactory().fillinIncomingData(tAlarmData);
}
}
return tAlarmData;
}
public String getServer()
{
if (serverString == null) serverString = new String(server).trim();
return serverString;
}
public String getDevice()
{
if (deviceString == null) deviceString = new String(device).trim();
return deviceString;
}
public String getAlarmTag()
{
if (alarmTagString == null) alarmTagString = new String(alarmTag).trim();
return alarmTagString;
}
private void initStructDescription()
{
addField(server,"server");
addField(device,"device");
addField(alarmTag,"almTag");
addField(alarmCode,"almCode");
addField(timestamp,"timestamp");
addField(timestampUSec,"timestampUSec");
addField(starttime,"starttime");
addField(starttimeUSec,"starttimeUSec");
addField(alarmMask,"almMask");
addField(alarmData,"almData");
addField(alarmDataFormat,"almDataFormat");
addField(alarmDataArraySize,"almDataArraySize");
addField(severity,"severity");
addField(descriptor,"descriptor");
addField(alarmSystem,"almSystem");
addField(alarmOscillationWindow,"almOscWindow");
addField(alarmOscillationWindowPinned,"almOscPinned");
initDone();
}
public TAlarmMessage()
{
super("AMSr4");
initStructDescription();
}
private void pushByteArray(byte[] barray)
{
for (int i=0; i<TStrings.ALARM_DATA_SIZE; i++) alarmData[i] = 0;
if (barray == null) return;
int len = Math.min(barray.length, TStrings.ALARM_DATA_SIZE);
// TODO: don't we have to worry about swapping ?
for (int i=0; i<len; i++) alarmData[i] = barray[i];
}
private void pushString(String s,char[] c)
{
if (s != null)
{
int len = s.length();
if (len > c.length) len = c.length;
s.getChars(0, len, c, 0);
}
}
public TAlarmMessage(String srv,String dev,String tag,int code,int sev,TAlarmDynSet almDynSet,TDataType data)
{
super("AMSr4");
initStructDescription();
pushString(srv,server);
pushString(dev == null ? "" : dev,device);
pushString(tag,alarmTag);
alarmCode[0] = code;
severity[0] = (byte)sev;
alarmSystem[0] = 0;
if (data != null && data.dArrayLength > 0 && data.dFormat != TFormat.CF_NULL)
{
alarmDataFormat[0] = (byte)data.dFormat;
alarmDataArraySize[0] = (byte)data.dArrayLength;
pushByteArray(data.getDataBuffer());
}
timestamp[0] = almDynSet.timestamp;
timestampUSec[0] = almDynSet.timestampUSec;
starttime[0] = almDynSet.starttime;
starttimeUSec[0] = almDynSet.starttimeUSec;
descriptor[0] = almDynSet.descriptor;
}
public TAlarmMessage(TEquipmentModule eqm, String dev,TAlarm alm)
{
this(eqm, dev, null, alm);
}
public TAlarmMessage(TEquipmentModule eqm, String dev,String tag, TAlarm alm)
{
super("AMSr4");
initStructDescription();
int code = alm.getCode();
pushString(eqm.getExportName(),server);
pushString(dev == null ? "" : dev,device);
TAlarmDefinition adef = alm.getAlmDef();
String atag = tag;
if (adef != null)
{
short afmt = (short)adef.getAlarmDataFormat();
if (atag == null)
{ // normal case (unless link error)
atag = adef.getAlarmTag();
TAlarmWatchEntry awe = alm.getWatchEntry();
if (awe != null && code < TErrorList.errorString.length)
{ // a watched alarm
String pstr = awe.getPrp();
if (atag.length() < 11 && pstr != null)
{ // enough room to append the watched property
int plen = pstr.length();
if (plen > 21) plen = 21; // java is pretty stupid at this juncture
atag = awe.getPrp().substring(0,plen)+" "+atag;
}
}
else if (TFormat.isSimpleString(afmt) && adef.isDataToTag())
{
try
{
String addstr = new String(alm.getData(),"UTF-8");
atag += ": "+addstr;
} catch (Exception e) {}
}
}
pushString(atag,alarmTag);
TDevice dv = eqm.getDevice(dev);
alarmMask[0] = (dv != null) ? dv.getRegionCode() : TRegion.DEV_REGION_CENTRAL;
alarmDataFormat[0] = (byte)adef.getAlarmDataFormat();
alarmDataArraySize[0] = (byte)adef.getAlarmDataArraySize();
severity[0] = (byte)adef.getAlarmSeverity();
alarmSystem[0] = (short)adef.getAlarmSystem();
alarmOscillationWindow[0] = (byte)adef.getAlarmOscillationWindow();
alarmOscillationWindowPinned[0] = (byte)(adef.isOscillationWindowPinned() ? 0xff : 0);
}
else
{
alarmOscillationWindow[0] = (byte)TAlarm.getAlmOscillationWindow();
alarmOscillationWindowPinned[0] = (byte)(TAlarm.getAlmOscillationWindowPinned() ? 0xff : 0);
}
alarmCode[0] = code;
timestamp[0] = alm.getTimeStamp();
timestampUSec[0] = alm.getTimeStampUSec();
starttime[0] = alm.getStarttime();
starttimeUSec[0] = alm.getStarttimeUSec();
pushByteArray(alm.getData());
descriptor[0] = alm.getDescriptor();
}
public static final int sizeInBytes =
TStrings.EXPORT_NAME_SIZE +
TStrings.DEVICE_NAME_SIZE +
TStrings.ALARM_TAG_SIZE +
6 * 4 + TStrings.ALARM_DATA_SIZE + 8;
public int compareTo(Object a)
{
if (a == null) return 999999;
if (a instanceof TAlarmMessage)
{
int dt = timestamp[0] - ((TAlarmMessage)a).timestamp[0];
dt *= 1000;
return dt + (timestampUSec[0] - ((TAlarmMessage)a).timestampUSec[0])/1000;
}
return 999998;
}
public boolean isInstanceOf(TAlarmMessage reference)
{
if (reference == null) return false;
if (reference.alarmCode[0] != alarmCode[0]) return false;
if (reference.getDevice().compareToIgnoreCase(getDevice()) != 0) return false;
if (reference.getServer().compareToIgnoreCase(getServer()) != 0) return false;
if (reference.starttime[0] != starttime[0]) return false;
if (reference.starttimeUSec[0] != starttimeUSec[0]) return false;
return true;
}
}