package com.roboclub.robobuggy.nodes.baseNodes; import com.roboclub.robobuggy.messages.StateMessage; import com.roboclub.robobuggy.ros.NodeChannel; import com.roboclub.robobuggy.ros.Publisher; import java.util.Timer; import java.util.TimerTask; /** * Base implementation of a Buggy {@link BuggyNode} to be decorated * with {@link BuggyDecoratorNode}s according to the decorator pattern. * The {@link BuggyBaseNode} implements the functionality for health/status * monitoring. * * @author Zachary Dawson */ public class BuggyBaseNode implements BuggyNode { private String name; private static final long WATCHDOG_PERIOD = 2000; private Publisher statePub; private NodeState state; private Long lastUpdate; private Timer timer; /** * Construct a new {@link BuggyBaseNode} * * @param nodeChannel {@link NodeChannel} for the node being created */ public BuggyBaseNode(NodeChannel nodeChannel) { statePub = new Publisher(nodeChannel.getStatePath()); state = NodeState.NOT_IN_USE; lastUpdate = 0L; TimerTask timerTask = new UpdateTask(); timer = new Timer(true); timer.scheduleAtFixedRate(timerTask, 0, WATCHDOG_PERIOD); } /** * {@inheritDoc} */ @Override public boolean startNode() { //Set the state to be on and record the time state = NodeState.ON; lastUpdate = System.currentTimeMillis(); //Return true as the base node can always be started return true; } /** * {@inheritDoc} */ @Override public boolean shutdown() { //Set the state to not in use state = NodeState.NOT_IN_USE; timer.cancel(); //needs to stop the thread from continuing to operate //Return true as the base node can always be shut down return true; } /** * {@inheritDoc} */ @Override public void setNodeState(NodeState state) { this.state = state; lastUpdate = System.currentTimeMillis(); } /** * Task used to call the update method */ private class UpdateTask extends TimerTask { @Override public void run() { if (System.currentTimeMillis() - lastUpdate > WATCHDOG_PERIOD && state == NodeState.ON) { state = NodeState.WATCHDOG_DEAD; } statePub.publish(new StateMessage(state)); } } /** * used for updating the name by which this node is known * * @param newName the new name for this node */ public void setName(String newName) { name = newName; } /** * gives access to the current value of this nodes name * * @return the name of the node */ public String getName() { return name; } }