Skip to content
Snippets Groups Projects
Commit 6fa4a15d authored by gwen-soleil's avatar gwen-soleil Committed by Antonin Hottois
Browse files

Changes after code review

parent 5992efe2
Branches
Tags
No related merge requests found
...@@ -8,3 +8,4 @@ dserver/ ...@@ -8,3 +8,4 @@ dserver/
Gestion_des_erreurs.docx Gestion_des_erreurs.docx
~$stion_des_erreurs.docx ~$stion_des_erreurs.docx
.classpath .classpath
bin/
\ No newline at end of file
## [1.0.6] - 02/07/2020
### Changed
- TextTalker not being reachable no longer stop the monitoring task
- TextTalker not being in a valid state no longer stop the monitoring task
- sent message list is now handled by a Queue class
- Init, stop and starts are now logged
## [1.0.5] - 23/06/2020 ## [1.0.5] - 23/06/2020
### This version is the result of actual tests within RCM1 ### This version is the result of actual tests within RCM1
......
No preview for this file type
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
<groupId>fr.soleil.deviceservers</groupId> <groupId>fr.soleil.deviceservers</groupId>
<artifactId>MessageTrigger</artifactId> <artifactId>MessageTrigger</artifactId>
<version>1.0.5</version> <version>1.0.6</version>
<name>MessageTrigger</name> <name>MessageTrigger</name>
<description>Message Trigger Device Server</description> <description>Message Trigger Device Server</description>
<packaging>jar</packaging> <packaging>jar</packaging>
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
</dependencies> </dependencies>
<build> <build>
<finalName>fr.soleil.deviceservers-MessageTrigger-${version}</finalName> <finalName>fr.soleil.deviceservers-MessageTrigger-${project.version}</finalName>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
<groupId>fr.soleil.deviceservers</groupId> <groupId>fr.soleil.deviceservers</groupId>
<artifactId>MessageTrigger</artifactId> <artifactId>MessageTrigger</artifactId>
<version>1.0.5</version> <version>1.0.6</version>
<name>MessageTrigger</name> <name>MessageTrigger</name>
<description>Message Trigger Device Server</description> <description>Message Trigger Device Server</description>
<packaging>jar</packaging> <packaging>jar</packaging>
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
</dependencies> </dependencies>
<build> <build>
<finalName>MessageTrigger-${version}-jar-with-dependencies</finalName> <finalName>MessageTrigger-${project.version}-jar-with-dependencies</finalName>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
......
package fr.soleil.tango.server.messagetrigger; package fr.soleil.tango.server.messagetrigger;
import org.tango.utils.DevFailedUtils;
import fr.esrf.Tango.DevFailed; import fr.esrf.Tango.DevFailed;
import fr.soleil.tango.clientapi.TangoAttribute; import fr.soleil.tango.clientapi.TangoAttribute;
import org.tango.utils.DevFailedUtils;
//----------------------------------------------------------------------------------------- /**
// Class to handle each attribute and its messages * Class to handle each attribute and its messages
//----------------------------------------------------------------------------------------- */
final public class AttributeParser { final public class AttributeParser {
// Members // Members
final private TangoAttribute m_attribute; final private TangoAttribute currentAttribute;
final private String m_true_message; final private String trueMessage;
final private String m_false_message; final private String falseMessage;
final private String m_device_name; final private String deviceName;
private boolean m_previous_state; private boolean previousState;
//----------------------------------------------------------------------------------------- /**
// Constructor * Constructor
//----------------------------------------------------------------------------------------- *
public AttributeParser(String message_string) throws DevFailed * @param messageString
{ */
public AttributeParser(String messageString) throws DevFailed {
// Split the message // Split the message
String[] tokens = message_string.split(";"); String[] tokens = messageString.split(";");
// Check for its length // Check for its length
if(tokens.length != 3) if (tokens.length != 3) {
{
throw DevFailedUtils.newDevFailed("MessageList property is not formated properly! Check the number of separators (;)"); throw DevFailedUtils.newDevFailed("MessageList property is not formated properly! Check the number of separators (;)");
} }
// Get a new attribute from first part of the string // Get a new currentAttribute from first part of the string
m_attribute = new TangoAttribute(tokens[0]); currentAttribute = new TangoAttribute(tokens[0]);
// Get the "message_if_true" // Get the "message_if_true"
if(tokens[1].contentEquals("") || tokens[1].equalsIgnoreCase("NULL") || tokens[2].matches("^\\s*$")) if (tokens[1].contentEquals("") || tokens[1].equalsIgnoreCase("NULL") || tokens[2].matches("^\\s*$")) {
{ trueMessage = "NULL";
m_true_message = "NULL"; } else {
} trueMessage = tokens[1];
else
{
m_true_message = tokens[1];
} }
// Check the "message_if_false" // Check the "message_if_false"
if(tokens[2].contentEquals("") || tokens[2].equalsIgnoreCase("NULL") || tokens[2].matches("^\\s*$")) if (tokens[2].contentEquals("") || tokens[2].equalsIgnoreCase("NULL") || tokens[2].matches("^\\s*$")) {
{ falseMessage = "NULL";
m_false_message = "NULL"; } else {
} falseMessage = tokens[2];
else
{
m_false_message = tokens[2];
} }
// Initialize previous state variable // Initialize previous state variable
m_previous_state = m_attribute.read(boolean.class); previousState = currentAttribute.read(boolean.class);
// Get the name of the device the attribute is from // Get the name of the device the currentAttribute is from
m_device_name = m_attribute.getDeviceName(); deviceName = currentAttribute.getDeviceName();
} }
//----------------------------------------------------------------------------------------- /**
// Return the message if the attribute changed, return "NULL" if no message to be sent * Check if the attribute has changed and return the corresponding message
//----------------------------------------------------------------------------------------- *
public String check_attribute() throws DevFailed * @return Return the message if attribute has changed, return "NULL" if no message to be send
{ * @throws DevFailed
// Reading attribute as boolean */
boolean result = m_attribute.read(boolean.class); public String checkAttribute() throws DevFailed {
// Reading currentAttribute as boolean
// Has the attribute changed since last time? boolean result = currentAttribute.read(boolean.class);
if(result != m_previous_state)
{ // Has the currentAttribute changed since last time?
m_previous_state = result; if (result != previousState) {
return result? m_true_message : m_false_message; previousState = result;
return result ? trueMessage : falseMessage;
} }
return "NULL"; return "NULL";
} }
//----------------------------------------------------------------------------------------- /**
// Return the name of the attribute * Get Attribute name
//----------------------------------------------------------------------------------------- *
public String get_name() * @return Return the name of current attribute
{ */
return m_attribute.getName(); public String getName() {
return currentAttribute.getName();
} }
//----------------------------------------------------------------------------------------- /**
// Return the name of the device the attribute is from * Get Device name
//----------------------------------------------------------------------------------------- *
public String get_device_name() * @return Return the name of the device current attribute is from.
{ */
return m_device_name; public String getDeviceName() {
return deviceName;
} }
} }
package fr.soleil.tango.server.messagetrigger;
import java.util.Arrays;
import java.util.Date;
//-----------------------------------------------------------------------------------------
// Class to handle the list of messages as an array of a fixed size
//-----------------------------------------------------------------------------------------
final public class MessageListArray {
// Members
final private int m_nb_messages;
final private String[] m_message_list; // Array we will work with
private int m_index;
//-----------------------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------------------
public MessageListArray(String[] message_list, int nb_messages)
{
// Getting the array and initializing it
m_message_list = message_list;
Arrays.fill(m_message_list, "");
m_nb_messages = nb_messages;
m_index = 0;
}
//-----------------------------------------------------------------------------------------
// Adds a new message to the array
//-----------------------------------------------------------------------------------------
public void push_message(String message)
{
// Get today's date
Date date=new Date();
// The message array might be accessed by several thread
synchronized(m_message_list[0])
{
// If we reached max number of messages
if(m_index == m_nb_messages)
{
// We move every message and remove the older one
for(int i = 0; i < m_nb_messages-1; i++)
{
m_message_list[i] = m_message_list[i+1];
}
m_index --;
}
// We add our new message
m_message_list[m_index] = date.toString() + "\n" + message + "\n";
m_index++;
}
}
//-----------------------------------------------------------------------------------------
// Clears the array
//-----------------------------------------------------------------------------------------
public void clear_messages()
{
// The message array might be accessed by several thread
synchronized(m_message_list[0])
{
// Loop through all the elements and remove them
for(int i = 0; i < m_nb_messages; i++)
{
m_message_list[i] = "";
}
m_index = 0;
}
}
}
package fr.soleil.tango.server.messagetrigger; package fr.soleil.tango.server.messagetrigger;
import java.util.HashMap; import fr.esrf.Tango.DevFailed;
import java.util.Vector; import fr.soleil.tango.clientapi.TangoDevice;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.tango.DeviceState; import org.tango.DeviceState;
import org.tango.server.ServerManager; import org.tango.server.ServerManager;
import org.tango.server.annotation.Attribute; import org.tango.server.annotation.*;
import org.tango.server.annotation.Command;
import org.tango.server.annotation.Delete;
import org.tango.server.annotation.Device;
import org.tango.server.annotation.DeviceProperty;
import org.tango.server.annotation.Init;
import org.tango.server.annotation.State;
import org.tango.server.annotation.StateMachine;
import org.tango.server.annotation.Status;
import org.tango.utils.DevFailedUtils; import org.tango.utils.DevFailedUtils;
import fr.esrf.Tango.DevFailed; import java.util.ArrayList;
import fr.soleil.tango.clientapi.TangoDevice; import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
* MessageTrigger Tango-Controls server * MessageTrigger Tango-Controls server
* *
...@@ -30,29 +24,17 @@ import fr.soleil.tango.clientapi.TangoDevice; ...@@ -30,29 +24,17 @@ import fr.soleil.tango.clientapi.TangoDevice;
@Device @Device
public class MessageTrigger implements StateUpdates { public class MessageTrigger implements StateUpdates {
private final Logger logger = LoggerFactory.getLogger(MessageTrigger.class);
private static final int MSG_LOG_SIZE = 100;
private TriggerPulserTask m_trigger_task; private final Logger logger = LoggerFactory.getLogger(MessageTrigger.class);
private MessageListArray m_message_array; private final List<AttributeParser> monitoredAttributesList = new ArrayList<>();
private TangoDevice m_text_talker; private final Map<String, TangoDevice> monitoredDevicesMap = new HashMap<String, TangoDevice>();
private Vector<AttributeParser> m_monitored_attributes_list; private TriggerPulserTask triggerTask;
private HashMap<String,TangoDevice> m_monitored_devices; private MessagesArray sentMessagesArray;
private String m_monitored_attributes_string; private TangoDevice textTalkerDevice;
private String monitoredAttributesString;
//-----------------------------------------------------------------------------------------
// ATTRIBUTES
//-----------------------------------------------------------------------------------------
@Attribute
public String[] sentMessageList;
//-----------------------------------------------------------------------------------------
// PROPERTIES
//-----------------------------------------------------------------------------------------
// MessageList // Property MessageList
@DeviceProperty(defaultValue = {"test/test/Parser/Attribute1;MessageIfTrue;MessageIfFalse"}, @DeviceProperty(defaultValue = {"test/test/Parser/Attribute1;MessageIfTrue;MessageIfFalse"},
isMandatory = true, isMandatory = true,
description = "List of the attributes and messages to be sent.\n" + description = "List of the attributes and messages to be sent.\n" +
...@@ -64,7 +46,8 @@ public class MessageTrigger implements StateUpdates{ ...@@ -64,7 +46,8 @@ public class MessageTrigger implements StateUpdates{
this.MessageList = MessageList; this.MessageList = MessageList;
} }
// TextTalker
// Property TextTalker
@DeviceProperty(description = "Name/Path of the Text Talker Proxy in the database.\nFor example: test/test/talker", isMandatory = true) @DeviceProperty(description = "Name/Path of the Text Talker Proxy in the database.\nFor example: test/test/talker", isMandatory = true)
private String TextTalkerProxyName; private String TextTalkerProxyName;
...@@ -72,7 +55,8 @@ public class MessageTrigger implements StateUpdates{ ...@@ -72,7 +55,8 @@ public class MessageTrigger implements StateUpdates{
this.TextTalkerProxyName = TextTalkerProxyName; this.TextTalkerProxyName = TextTalkerProxyName;
} }
// PollingPeriod
// Property PollingPeriod
@DeviceProperty(defaultValue = "1000", description = "Polling period in milliseconds.\nMinimum is 100 milliseconds.") @DeviceProperty(defaultValue = "1000", description = "Polling period in milliseconds.\nMinimum is 100 milliseconds.")
private int PollingPeriod; private int PollingPeriod;
...@@ -81,33 +65,29 @@ public class MessageTrigger implements StateUpdates{ ...@@ -81,33 +65,29 @@ public class MessageTrigger implements StateUpdates{
} }
//----------------------------------------------------------------------------------------- // State
// STATE
//-----------------------------------------------------------------------------------------
@State @State
private volatile DeviceState state = DeviceState.INIT; private volatile DeviceState state = DeviceState.INIT;
// This might be accessed by different threads (the trigger task can modify the state) // This might be accessed by different threads (the trigger task can modify the state)
public synchronized DeviceState getState() public synchronized DeviceState getState() {
{
return state; return state;
} }
// This might be accessed by different threads (the trigger task can modify the state) // This might be accessed by different threads (the trigger task can modify the state)
public synchronized void setState(DeviceState state) public synchronized void setState(DeviceState state) {
{
this.state = state; this.state = state;
} }
//----------------------------------------------------------------------------------------- // Status
// STATUS
//-----------------------------------------------------------------------------------------
@Status @Status
private String status = "Initializing Device"; private String status = "Initializing Device";
public static void main(String[] args) {
ServerManager.getInstance().start(args, MessageTrigger.class);
}
// This might be accessed by different threads (the trigger task can modify the status) // This might be accessed by different threads (the trigger task can modify the status)
public synchronized String getStatus() { public synchronized String getStatus() {
return status; return status;
...@@ -118,56 +98,45 @@ public class MessageTrigger implements StateUpdates{ ...@@ -118,56 +98,45 @@ public class MessageTrigger implements StateUpdates{
this.status = status; this.status = status;
} }
//-----------------------------------------------------------------------------------------
// DELETE
//-----------------------------------------------------------------------------------------
// Delete
@Delete @Delete
public void delete() public void delete() {
{ if (triggerTask != null) triggerTask.stop();
if(m_trigger_task!=null) m_trigger_task.stop();
} }
//-----------------------------------------------------------------------------------------
// INIT
//-----------------------------------------------------------------------------------------
// Init
@Init @Init
public void init() public void init() {
{
setState(DeviceState.INIT); setState(DeviceState.INIT);
setStatus("Initializing..."); setStatus("Initializing...");
// Initializing message list // Initializing message list
sentMessageList = new String[MSG_LOG_SIZE]; sentMessagesArray = new MessagesArray();
m_message_array = new MessageListArray(sentMessageList, MSG_LOG_SIZE);
// Checking polling period // Checking polling period
if(PollingPeriod < 100) if (PollingPeriod < 100) {
{ sendFault(DevFailedUtils.newDevFailed("PollingPeriod is not valid"), "Invalid PollingPeriod property! It should be at least 100ms.");
send_fault(DevFailedUtils.newDevFailed("PollingPeriod is not valid"), "Invalid PollingPeriod property! It should be at least 100ms");
return; return;
} }
// Initializing TextTalker device // Initializing TextTalker device
try try {
{ textTalkerDevice = new TangoDevice(TextTalkerProxyName);
m_text_talker = new TangoDevice(TextTalkerProxyName);
} }
catch (DevFailed e) catch (DevFailed e) {
{ sendFault(e, "Cannot reach Text Talker Proxy. Check the property TextTalkerProxyName.");
send_fault(e, "Cannot reach Text Talker Proxy. Check the property TextTalkerProxyName");
return; return;
} }
// Initializing monitored attributes and their devices
m_monitored_attributes_list = new Vector<AttributeParser>(MessageList.length);
m_monitored_devices = new HashMap<String,TangoDevice>();
// Variables for temporary work // Variables for temporary work
AttributeParser attribute; AttributeParser attribute;
String device_name; String device_name;
// Retrieving all attributes from message list // Retrieving all attributes from message list
for(int i=0; i<MessageList.length; i++) for(int i=0; i<MessageList.length; i++)
{ {
...@@ -176,28 +145,28 @@ public class MessageTrigger implements StateUpdates{ ...@@ -176,28 +145,28 @@ public class MessageTrigger implements StateUpdates{
// Create a new attribute // Create a new attribute
attribute = new AttributeParser(MessageList[i]); attribute = new AttributeParser(MessageList[i]);
// Add it to our list // Add it to our list
m_monitored_attributes_list.add(attribute); monitoredAttributesList.add(attribute);
} }
catch (DevFailed e) catch (DevFailed e)
{ {
send_fault(e, "Error when initializing monitored attributes\n" + sendFault(e, "Error when initializing monitored attributes.\n" +
"Check line "+ (i+1) +" of property MessageList"); "Check line "+ (i+1) +" of property MessageList.");
return; return;
} }
// Get the device name of current attribute // Get the device name of current attribute
device_name = attribute.get_device_name().toLowerCase(); device_name = attribute.getDeviceName().toLowerCase();
// If not already retrieved, get the device // If not already retrieved, get the device
if(!m_monitored_devices.containsKey(device_name)) if(!monitoredDevicesMap.containsKey(device_name))
{ {
try try
{ {
m_monitored_devices.put(device_name, new TangoDevice(device_name)); monitoredDevicesMap.put(device_name, new TangoDevice(device_name));
} }
catch (DevFailed e) catch (DevFailed e)
{ {
send_fault(e, "Cannot reach device " + device_name); sendFault(e, "Cannot reach device " + device_name);
return; return;
} }
} }
...@@ -207,81 +176,59 @@ public class MessageTrigger implements StateUpdates{ ...@@ -207,81 +176,59 @@ public class MessageTrigger implements StateUpdates{
// Device should be OFF until it's started. // Device should be OFF until it's started.
setState(DeviceState.OFF); setState(DeviceState.OFF);
setStatus("Ready! Standing by..."); setStatus("Ready! Standing by...");
sendInfo("Successfull init!");
// Starting by default // Starting by default
Start(); Start();
} }
//----------------------------------------------------------------------------------------- // Attribute SentMessageList
// MAIN @Attribute
//----------------------------------------------------------------------------------------- public String[] getSentMessageList() {
return sentMessagesArray.getMessages();
public static void main(String[] args) {
ServerManager.getInstance().start(args, MessageTrigger.class);
}
//-----------------------------------------------------------------------------------------
// ATTRIBUTE sentMessageList
//-----------------------------------------------------------------------------------------
public String[] getSentMessageList()
{
// This variable might be accessed by different threads (the trigger task can update the message list)
synchronized(sentMessageList[0])
{
return sentMessageList;
}
} }
//----------------------------------------------------------------------------------------- // Command Stop
// COMMANDS
//-----------------------------------------------------------------------------------------
@Command(inTypeDesc = "Stops the monitoring service", displayLevel = 1) @Command(inTypeDesc = "Stops the monitoring service", displayLevel = 1)
@StateMachine(deniedStates = {DeviceState.FAULT, DeviceState.OFF, DeviceState.INIT}) @StateMachine(deniedStates = {DeviceState.FAULT, DeviceState.OFF, DeviceState.INIT})
public void Stop() public void Stop() {
{
// Stops the monitoring task // Stops the monitoring task
if(m_trigger_task!=null) m_trigger_task.stop(); if (triggerTask != null) triggerTask.stop();
setStatus("Trigger service stopped!\nDevice standing by..."); setStatus("Trigger service stopped!\nDevice standing by...");
setState(DeviceState.OFF); setState(DeviceState.OFF);
sendInfo("Successfull stop!");
} }
// Command Start
@Command(inTypeDesc = "Starts the monitoring service", displayLevel = 1) @Command(inTypeDesc = "Starts the monitoring service", displayLevel = 1)
@StateMachine(deniedStates = {DeviceState.FAULT, DeviceState.ALARM, DeviceState.ON, DeviceState.INIT}) @StateMachine(deniedStates = {DeviceState.FAULT, DeviceState.ALARM, DeviceState.ON, DeviceState.INIT})
public void Start() public void Start() {
{
// Get the list of monitored attributes to display their names in status // Get the list of monitored attributes to display their names in status
m_monitored_attributes_string = "Monitored attributes:\n"; monitoredAttributesString = "Monitored attributes:\n";
for(int i=0; i<m_monitored_attributes_list.size(); i++) for (int i = 0; i < monitoredAttributesList.size(); i++) {
{ monitoredAttributesString += monitoredAttributesList.get(i).getName();
m_monitored_attributes_string+=m_monitored_attributes_list.get(i).get_name(); monitoredAttributesString += "\n";
m_monitored_attributes_string+="\n";
} }
// Starts the monitoring task // Starts the monitoring task
m_trigger_task = new TriggerPulserTask( PollingPeriod, m_monitored_attributes_list, m_monitored_devices, m_text_talker, m_message_array, this ); triggerTask = new TriggerPulserTask(PollingPeriod, monitoredAttributesList, monitoredDevicesMap, textTalkerDevice, sentMessagesArray, this);
setStatus("Trigger service started!\n\n"+m_monitored_attributes_string); setStatus("Trigger service started!\n\n" + monitoredAttributesString);
setState(DeviceState.ON); setState(DeviceState.ON);
sendInfo("Successfull start!");
} }
// Command ClearMessagesList
@Command(inTypeDesc = "Clear the list of messages") @Command(inTypeDesc = "Clear the list of messages")
@StateMachine(deniedStates = {DeviceState.FAULT}) @StateMachine(deniedStates = {DeviceState.FAULT})
public void ClearMessagesList() public void ClearMessagesList() {
{ sentMessagesArray.clearMessages();
m_message_array.clear_messages();
} }
//-----------------------------------------------------------------------------------------
// METHODS
//-----------------------------------------------------------------------------------------
// FAULT: fatal error: stops the trigger task, lock the device in FAULT state, log the error. // FAULT: fatal error: stops the trigger task, lock the device in FAULT state, log the error.
@Override @Override
public void send_fault(DevFailed e, String desc) { public void sendFault(DevFailed e, String desc) {
if(m_trigger_task!=null) m_trigger_task.stop(); if (triggerTask != null) triggerTask.stop();
logger.error(desc, e); logger.error(desc, e);
logger.error(DevFailedUtils.toString(e)); logger.error(DevFailedUtils.toString(e));
...@@ -291,25 +238,25 @@ public class MessageTrigger implements StateUpdates{ ...@@ -291,25 +238,25 @@ public class MessageTrigger implements StateUpdates{
// ALARM: warning: logs the error and set the device in ALARM state. // ALARM: warning: logs the error and set the device in ALARM state.
@Override @Override
public void send_alarm(DevFailed e, String desc) { public void sendAlarm(DevFailed e, String desc) {
logger.warn(desc, e); logger.warn(desc, e);
logger.warn(DevFailedUtils.toString(e)); logger.warn(DevFailedUtils.toString(e));
setState(DeviceState.ALARM); setState(DeviceState.ALARM);
setStatus("ALARM: " + desc); setStatus("ALARM: " + desc + getStatus());
} }
// INFO: update status and log the event // INFO: update status and log the event
@Override @Override
public void send_info(String desc) { public void sendInfo(String desc) {
logger.info(desc); logger.info(desc);
setStatus("INFO: " + desc + "\n\n" + getStatus()); setStatus("INFO: " + desc + "\n\n" + getStatus());
} }
// Reset the status // Reset the status
@Override @Override
public void clean_status() { public void cleanStatus() {
setState(DeviceState.ON); setState(DeviceState.ON);
setStatus(m_monitored_attributes_string); setStatus(monitoredAttributesString);
} }
} }
\ No newline at end of file
package fr.soleil.tango.server.messagetrigger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayDeque;
import java.util.Date;
import java.util.Queue;
/**
* Class to handle the list of messages as an array of a fixed size
*/
final public class MessagesArray {
private static final int MSG_LOG_SIZE = 2;
private final Queue<String> messageList = new ArrayDeque<String>(MSG_LOG_SIZE);
private Logger logger = LoggerFactory.getLogger(MessagesArray.class);
/**
* Adds a new message to the array
*
* @param message
*/
public synchronized void pushMessage(String message) {
while (messageList.size() >= MSG_LOG_SIZE) {
messageList.poll();
}
// Get today's date
Date date = new Date();
final boolean isInserted = messageList.offer(date.toString() + "\n" + message + "\n");
if (!isInserted) {
logger.debug("{} not inserted in message queue ", message);
}
}
/**
* Clears the array
*/
public synchronized void clearMessages() {
messageList.clear();
}
/**
* Get the message array
*
* @return message Array
*/
public synchronized String[] getMessages() {
return messageList.toArray(new String[0]);
}
}
...@@ -2,13 +2,14 @@ package fr.soleil.tango.server.messagetrigger; ...@@ -2,13 +2,14 @@ package fr.soleil.tango.server.messagetrigger;
import fr.esrf.Tango.DevFailed; import fr.esrf.Tango.DevFailed;
//-----------------------------------------------------------------------------------------
// Interface so that the monitoring task can send errors to the device /**
//----------------------------------------------------------------------------------------- * Interface so that the monitoring task can send errors to the device
*/
public interface StateUpdates public interface StateUpdates
{ {
void clean_status(); void cleanStatus();
void send_fault(DevFailed e, String desc); void sendFault(DevFailed e, String desc);
void send_alarm(DevFailed e, String desc); void sendAlarm(DevFailed e, String desc);
void send_info(String desc); void sendInfo(String desc);
} }
package fr.soleil.tango.server.messagetrigger; package fr.soleil.tango.server.messagetrigger;
import java.util.HashMap;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;
import org.tango.utils.DevFailedUtils;
import fr.esrf.Tango.DevFailed; import fr.esrf.Tango.DevFailed;
import fr.esrf.Tango.DevState; import fr.esrf.Tango.DevState;
import fr.soleil.tango.clientapi.TangoDevice; import fr.soleil.tango.clientapi.TangoDevice;
import org.tango.utils.DevFailedUtils;
import java.util.*;
//----------------------------------------------------------------------------------------- /**
// Task to monitor the attributes * Task to monitor the attributes
//----------------------------------------------------------------------------------------- */
final public class TriggerPulserTask extends TimerTask { final public class TriggerPulserTask extends TimerTask {
// Members // Members
final private Timer m_timer; final private Timer timer;
final private Vector<AttributeParser> m_monitored_attributes_list; final private List<AttributeParser> monitoredAttributesList;
final private HashMap<String, TangoDevice> m_monitored_devices; final private Map<String, TangoDevice> monitoredDevicesMap;
final private TangoDevice m_text_talker; final private TangoDevice textTalkerDevice;
final private MessageListArray m_message_list; final private MessagesArray sentMessagesArray;
final private StateUpdates m_error_handler; final private StateUpdates errorHandler;
// Variables for temporary stockage // Variables for temporary stockage
private String tmp_message; private String tmpMessage;
private DevState tmp_state; private DevState tmpState;
private boolean is_status_clean; private boolean isStatusClean;
//----------------------------------------------------------------------------------------- /**
// Constructor * Constructor
//----------------------------------------------------------------------------------------- */
public TriggerPulserTask( int polling_period, public TriggerPulserTask(int pollingPeriod,
Vector<AttributeParser> monitored_attributes_list, List<AttributeParser> monitoredAttributesList,
HashMap<String, TangoDevice> monitored_devices, Map<String, TangoDevice> monitoredDevicesMap,
TangoDevice text_talker, TangoDevice textTalkerDevice,
MessageListArray message_list, MessagesArray sentMessagesArray,
StateUpdates error_handler ) StateUpdates errorHandler) {
{
// Passing members // Passing members
m_text_talker = text_talker; this.textTalkerDevice = textTalkerDevice;
m_monitored_attributes_list = monitored_attributes_list; this.monitoredAttributesList = monitoredAttributesList;
m_error_handler = error_handler; this.errorHandler = errorHandler;
m_message_list = message_list; this.sentMessagesArray = sentMessagesArray;
m_monitored_devices = monitored_devices; this.monitoredDevicesMap = monitoredDevicesMap;
is_status_clean = false; isStatusClean = false;
// Starting polling // Starting polling
m_timer = new Timer(); timer = new Timer();
m_timer.scheduleAtFixedRate(this , 0, polling_period); timer.scheduleAtFixedRate(this, 0, pollingPeriod);
} }
//----------------------------------------------------------------------------------------- /**
// Stops the task * Stops the task and purge it
//----------------------------------------------------------------------------------------- */
public void stop() public void stop() {
{
// Canceling timer and task // Canceling timer and task
m_timer.cancel(); timer.cancel();
m_timer.purge(); // Flag the timer as ready to be recycled timer.purge(); // Flag the timer as ready to be recycled
this.cancel(); this.cancel();
} }
//----------------------------------------------------------------------------------------- /**
// Polled method * Polled method
//----------------------------------------------------------------------------------------- */
@Override @Override
public void run() { public void run() {
// If status is not clean // If status is not clean
if(!is_status_clean) if (!isStatusClean) {
{
// Reset status // Reset status
m_error_handler.clean_status(); errorHandler.cleanStatus();
is_status_clean = true; isStatusClean = true;
} }
//-----------------------------------------------------------------------------------------
// Checking text talker state // Checking text talker state
//----------------------------------------------------------------------------------------- try {
try tmpState = textTalkerDevice.state();
{ } catch (DevFailed e) {
tmp_state = m_text_talker.state(); errorHandler.sendAlarm(e, "Cannot reach text talker");
} isStatusClean = false;
catch (DevFailed e)
{
m_error_handler.send_fault(e, "Cannot reach text talker");
is_status_clean = false;
return; return;
} }
if(tmp_state == DevState.FAULT || tmp_state == DevState.ALARM) if (tmpState == DevState.FAULT || tmpState == DevState.ALARM) {
{ errorHandler.sendAlarm(DevFailedUtils.newDevFailed("Text Talker Device is not in a valid state!"),
m_error_handler.send_fault(DevFailedUtils.newDevFailed( "Text Talker Device is not in a valid state!"), "Text Talker Device is in " + tmpState.toString() + " state!");
"Text Talker Device is in " + tmp_state.toString() + " state!"); isStatusClean = false;
is_status_clean = false;
return; return;
} }
//-----------------------------------------------------------------------------------------
// Checking states of monitored devices // Checking states of monitored devices
//----------------------------------------------------------------------------------------- for (String device_name : monitoredDevicesMap.keySet()) {
for(String device_name : m_monitored_devices.keySet())
{
// Try to get the state // Try to get the state
try try {
{ tmpState = monitoredDevicesMap.get(device_name).state();
tmp_state = m_monitored_devices.get(device_name).state(); } catch (DevFailed e) {
} errorHandler.sendAlarm(e, "Cannot reach monitored device " + device_name + "!");
catch (DevFailed e) isStatusClean = false;
{
m_error_handler.send_alarm(e, "Cannot reach monitored device "+ device_name+"!");
is_status_clean = false;
return; return;
} }
// Check for invalid states // Check for invalid states
if(tmp_state == DevState.FAULT) if (tmpState == DevState.FAULT) {
{ errorHandler.sendAlarm(DevFailedUtils.newDevFailed("Monitored Device is not in a valid state!"),
m_error_handler.send_fault(DevFailedUtils.newDevFailed( "Monitored Device is not in a valid state!"), "Monitored device is in " + tmpState.toString() + " state!\n" +
"Monitored device is in " + tmp_state.toString() + " state!\n"+
"Device: " + device_name); "Device: " + device_name);
is_status_clean = false; isStatusClean = false;
return; return;
} }
if(tmp_state == DevState.ALARM) if (tmpState == DevState.ALARM) {
{ errorHandler.sendInfo("Monitored device " + device_name + " is in " + tmpState.toString() + " state.");
m_error_handler.send_info("Monitored device " + device_name + " is in " + tmp_state.toString() + " state."); isStatusClean = false;
is_status_clean = false;
} }
} }
//-----------------------------------------------------------------------------------------
// Going through monitored attributes // Going through monitored attributes
//----------------------------------------------------------------------------------------- for (int i = 0; i < monitoredAttributesList.size(); i++) {
for(int i = 0; i<m_monitored_attributes_list.size(); i++)
{
// Try to check the current attribute // Try to check the current attribute
try try {
{ tmpMessage = monitoredAttributesList.get(i).checkAttribute();
tmp_message = m_monitored_attributes_list.get(i).check_attribute(); } catch (DevFailed e) {
} errorHandler.sendFault(e, "Cannot check attribute " + monitoredAttributesList.get(i).getName());
catch (DevFailed e) isStatusClean = false;
{
m_error_handler.send_fault(e, "Cannot check attribute " + m_monitored_attributes_list.get(i).get_name());
is_status_clean = false;
return; return;
} }
// If there is a message to be sent // If there is a message to be sent
if(!(tmp_message.contentEquals("NULL"))) if (!(tmpMessage.contentEquals("NULL"))) {
{
// Try to send the message // Try to send the message
try try {
{ textTalkerDevice.getTangoCommand("DevTalk").execute(String.class, tmpMessage);
m_text_talker.getTangoCommand("DevTalk").execute(String.class, tmp_message); sentMessagesArray.pushMessage(tmpMessage);
m_message_list.push_message(tmp_message); errorHandler.sendInfo("Detected update on attribute: " + monitoredAttributesList.get(i).getName() + "\n" +
m_error_handler.send_info( "Detected update on attribute: " + m_monitored_attributes_list.get(i).get_name()+"\n"+ "Sent message: " + tmpMessage);
"Sent message: " + tmp_message); isStatusClean = false;
is_status_clean = false; } catch (DevFailed e) {
} errorHandler.sendFault(e, "Cannot write message on Text Talker");
catch (DevFailed e) isStatusClean = false;
{
m_error_handler.send_fault(e, "Cannot write message on Text Talker");
is_status_clean = false;
return; return;
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment