/*
* Created on Aug 23, 2005
*
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
package de.desy.tine.server.alarms;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import de.desy.tine.definitions.TErrorList;
import de.desy.tine.definitions.TStrings;
import de.desy.tine.endianUtils.Swap;
import de.desy.tine.server.devices.TDevice;
import de.desy.tine.server.equipment.TEquipmentModule;
import de.desy.tine.server.logger.MsgLog;
import de.desy.tine.types.TCompoundDataObject;
// each device has a (rather dynamic) linked list of these at any given time ...
public class TAlarm
{
public static final int ALM_SYSTEM_DEFAULT = 0x10000000; // from the std lib
public static final int ALM_LINK_ERROR = 0x20000000; // used to flag TLink error alarms
public static final int ALM_DISK_SPACE = 0x40000000; // used to flag TLink error alarms
public static final int ALM_SYSTEM_HIDE = 0x08000000; // used to signal the alarm server to 'hide' the alam
public static int getBaseCode(int code) { return code & 0x7ffffff; }
public static int encodeLinkErrorAlarm(int id)
{
return ALM_LINK_ERROR + (id<<16) + TErrorList.link_error;
}
public static int decodeLinkErrorAlarm(int code)
{
code -= ALM_LINK_ERROR + TErrorList.link_error;
return (code>>16);
}
public static boolean isLinkErrorAlarm(int code)
{
return (code & ALM_LINK_ERROR) == ALM_LINK_ERROR;
}
public static int encodeDiskSpaceAlarm(int id,int code)
{
return ALM_DISK_SPACE + (id<<16) + code;
}
public static boolean isDiskSpaceAlarm(int code)
{
return (code & ALM_DISK_SPACE) == ALM_DISK_SPACE;
}
public static boolean isHiddenAlarm(int code)
{
return (code & ALM_SYSTEM_HIDE) == ALM_SYSTEM_HIDE;
}
public static int hideAlarm(int code) { return code | ALM_SYSTEM_HIDE; }
public static final int ALM_SYSTEM_SYSTEM = 5000;
public static final int ALM_SYSTEM_HARDWARE = 5001;
private static final int ALM_SYSTEM_HIDDEN = 0x00004000;
public static int hideAlarmSystem(int alarmSystem) { return (alarmSystem|ALM_SYSTEM_HIDDEN); }
public static int unhideAlarmSystem(int alarmSystem) { return (alarmSystem & ~ALM_SYSTEM_HIDDEN); }
public static final int ALM_SEVERITY_NONE = 0;
public static final int ALM_SEVERITY_INFO = 3;
public static final int ALM_SEVERITY_WARN = 8;
public static final int ALM_SEVERITY_ERR = 12;
public static final int ALM_SEVERITY_FATAL = 15;
public static final int ALM_OSCILLATION_DEFAULT = 8;
public static final int ALM_OSCILLATION_MAXIMUM = 127;
public static final int ALM_OSCILLATION_CUSHION = 3;
private long almTimestamp; // alarm timestamp
private long almStarttime; // alarm start time
private int almCode; // alarm code;
private boolean almRemovalBlocked; // flag to keep alarm in table for CAS readout
private byte almDescriptor; // alarm descriptor
private byte almClearCount; // alarm's clear counter
private byte[] almData = null;
private TAlarmDefinition almDef = null;
private TDevice almDevice = null;
private boolean isTerminated = false;
private static int almCollapseWindow = 100; // total number of alarms
public static int getAlmCollapseWindow() { return almCollapseWindow; }
public static void setAlmCollapseWindow(int window) { if (window > 10) almCollapseWindow = window; }
private static boolean almOscillationWindowPinned = false;
public static boolean getAlmOscillationWindowPinned() { return almOscillationWindowPinned; }
private static int almOscillationWindow = ALM_OSCILLATION_DEFAULT; // clear counts
public static int getAlmOscillationWindow() { return almOscillationWindow; }
public static void setAlmOscillationWindow(int window)
{
setAlmOscillationWindow(window,true);
}
public static void setAlmOscillationWindow(int window,boolean pinned)
{
if (window > 1) almOscillationWindow = window;
almOscillationWindowPinned = pinned;
}
private TAlarmWatchEntry wte = null;
public TAlarmWatchEntry getWatchEntry() { return wte; }
public void setWatchEntry(TAlarmWatchEntry watchEntry) { wte = watchEntry; }
private static int almTerminationWindow = 30; // seconds
private static int almHeartbeatWindow = 1200; // seconds
private static int almDataChangeWindow = 30; // seconds
public static int getAlmDataChangeWindow() { return almDataChangeWindow; }
public static void setAlmDataChangeWindow(int window) { almDataChangeWindow = window; }
public static int getAlmHeartbeatWindow() { return almHeartbeatWindow; }
public static void setAlmHeartbeatWindow(int window) { almHeartbeatWindow = window; }
public static int getTerminationWindow () { return almTerminationWindow; }
public static void setTerminationWindow(int window) { if (window > 0) almTerminationWindow = window; }
public int getTimeStamp() { return (int)(almTimestamp/1000); }
public int getTimeStampUSec() { return (int)((almTimestamp%1000)*1000); }
public int getStarttime() { return (int)(almStarttime/1000); }
public int getStarttimeUSec() { return (int)((almStarttime%1000)*1000); }
public void setTimeStamp(long timestamp) { if (timestamp > 0) almTimestamp = timestamp; }
public void setTimeStamp(int timestamp) { if (timestamp > 0) almTimestamp = ((long)timestamp)*1000; }
public int getCode() { return almCode; }
public boolean isRemovalBlocked() { return almRemovalBlocked; }
public void blockRemoval() { almRemovalBlocked = true; }
public void allowRemoval() { almRemovalBlocked = false; }
public byte getDescriptor() { return almDescriptor; }
public void setDescriptor(byte flags) { almDescriptor = flags; }
public byte getClearCount() { return almClearCount; }
public void resetClearCount() { almClearCount = 0; }
public void clear()
{
if ((almDescriptor & TAlarmDescriptor.TERMINATE) == TAlarmDescriptor.TERMINATE)
almClearCount = (byte)ALM_OSCILLATION_MAXIMUM;
if (almClearCount < ALM_OSCILLATION_MAXIMUM) almClearCount++;
}
public byte[] getData() { return almData; }
public void setData(byte[] data) { almData = data; }
public void setData(Object data)
{
ByteArrayOutputStream baos = new ByteArrayOutputStream(TStrings.ALARM_DATA_SIZE);
DataOutputStream ds = new DataOutputStream(baos);
int range = TStrings.ALARM_DATA_SIZE;
int mrange;
try
{
if (data instanceof short[])
{
mrange = ((short[])data).length;
range = Math.min(range/2, mrange);
for (int i=0; i<range; i++) ds.writeShort(Swap.Short(((short[])data)[i]));
}
if (data instanceof int[])
{
mrange = ((int[])data).length;
range = Math.min(range/4, mrange);
for (int i=0; i<range; i++) ds.writeInt(Swap.Long(((int[])data)[i]));
}
if (data instanceof float[])
{
mrange = ((float[])data).length;
range = Math.min(range/4, mrange);
for (int i=0; i<range; i++) ds.write(Swap.Float(((float[])data)[i]));
}
if (data instanceof double[])
{
mrange = ((double[])data).length;
range = Math.min(range/8, mrange);
for (int i=0; i<range; i++) ds.write(Swap.Double(((double[])data)[i]));
}
if (data instanceof char[])
{
mrange = ((char[])data).length;
range = Math.min(range, mrange);
ds.writeBytes(new String((char[])data,0,range));
}
if (data instanceof String)
{
mrange = ((String)data).length();
range = Math.min(range, mrange);
ds.writeBytes(((String)data).substring(0, range));
}
if (data instanceof StringBuffer)
{
mrange = ((StringBuffer)data).length();
range = Math.min(range, mrange);
ds.writeBytes(((StringBuffer)data).toString().substring(0, range));
}
if (data instanceof TCompoundDataObject[])
{
TCompoundDataObject[] tdo = (TCompoundDataObject[])data;
mrange = ((TCompoundDataObject[])data).length;
range = Math.min(range/tdo[0].getSizeInBytes(), mrange);
for (int i=0; i<range; i++) ds.write(tdo[i].toByteArray());
}
}
catch (Exception e)
{ // TODO: log or debug it
MsgLog.log("TAlarm.setData", e.toString(),TErrorList.code_failure,e,1);
}
}
public int getSeverity() { return almDef == null ? 0 : almDef.getAlarmSeverity(); }
public String getTag() { return almDef == null ? "" : almDef.getAlarmTag(); }
public TAlarm(int code, byte flags, byte[] data,TDevice device)
{
almTimestamp = System.currentTimeMillis();
almClearCount = 0;
almRemovalBlocked = false;
almCode = code;
almDescriptor = flags;
almData = data;
almDevice = device;
TEquipmentModule eqm = null;
// fix the code for what happens below ...
if (isLinkErrorAlarm(code))
code = TErrorList.link_error;
else if (isDiskSpaceAlarm(code))
code = (code & 0xff);
else
code = getBaseCode(code);
if (almDevice != null && (eqm=almDevice.getEqm()) != null)
{ // try the configured definitions list
almDef = (TAlarmDefinition)eqm.getAlarmDefinitionList().get(code);
}
if (almDef == null)
{ // now try the stock definitions
// almDef = (TAlarmDefinition)eqm.getEquipmentModuleFactory().getStockAlarmDefinitions().get(Integer.toString(code));
almDef = (TAlarmDefinition)TAlarmStockAlarm.getStockAlarmDefinitions().get(Integer.toString(code));
}
if (almDef == null)
{ // still nothing, so make a new one ...
String as = TErrorList.getErrorString(code);
almDef = new TAlarmDefinition(as,as,"this device",code,TAlarm.ALM_SEVERITY_WARN,0);
}
if ((flags & TAlarmDescriptor.TERMINATE) == TAlarmDescriptor.TERMINATE)
{
isTerminated = true;
}
if ((flags & TAlarmDescriptor.NEW) == TAlarmDescriptor.NEW)
{ // as this is a constructor, the NEW bit almost assuredly set!
almStarttime = almTimestamp;
}
}
public TAlarmDefinition getAlmDef() { return almDef; }
public void setAlarmDefinition(TAlarmDefinition almDef)
{
this.almDef = almDef;
}
// see XPropertyQuery for template to make an Alarm Message Structure on the fly from
// a stock property query !
public boolean isTerminated()
{
return isTerminated;
}
public boolean isTransient()
{
return (almDescriptor & TAlarmDescriptor.TRANSIENT) == TAlarmDescriptor.TRANSIENT;
}
public boolean isDataChange()
{
return (almDescriptor & TAlarmDescriptor.DATACHANGE) == TAlarmDescriptor.DATACHANGE;
}
public boolean isOscillating()
{
return (almDescriptor & TAlarmDescriptor.OSCILLATION) == TAlarmDescriptor.OSCILLATION;
}
public void setTerminated(boolean isTerminated)
{
almDescriptor &= ~TAlarmDescriptor.NEW;
almDescriptor |= TAlarmDescriptor.TERMINATE;
this.isTerminated = isTerminated;
}
}