
org.bidib.wizard.mvc.booster.controller.BoosterTableController Maven / Gradle / Ivy
package org.bidib.wizard.mvc.booster.controller;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import java.util.List;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import org.apache.commons.collections4.CollectionUtils;
import org.bidib.jbidibc.core.DefaultMessageListener;
import org.bidib.jbidibc.core.Node;
import org.bidib.jbidibc.core.enumeration.BoosterState;
import org.bidib.jbidibc.core.utils.NodeUtils;
import org.bidib.wizard.comm.Communication;
import org.bidib.wizard.comm.CommunicationFactory;
import org.bidib.wizard.comm.listener.CommunicationListener;
import org.bidib.wizard.mvc.booster.model.BoosterModel;
import org.bidib.wizard.mvc.booster.model.BoosterTableModel;
import org.bidib.wizard.mvc.booster.view.BoosterTableView;
import org.bidib.wizard.mvc.common.view.DockKeys;
import org.bidib.wizard.mvc.main.controller.MainControllerInterface;
import org.bidib.wizard.mvc.main.model.listener.DefaultNodeListListener;
import org.bidib.wizard.mvc.main.model.listener.NodeListListener;
import org.bidib.wizard.utils.DockUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.vlsolutions.swing.docking.Dockable;
import com.vlsolutions.swing.docking.DockingConstants;
import com.vlsolutions.swing.docking.DockingDesktop;
import com.vlsolutions.swing.docking.RelativeDockablePosition;
import com.vlsolutions.swing.docking.event.DockableStateChangeEvent;
import com.vlsolutions.swing.docking.event.DockableStateChangeListener;
public class BoosterTableController {
private static final Logger LOGGER = LoggerFactory.getLogger(BoosterTableController.class);
private BoosterTableView boosterTableView;
private BoosterTableModel boosterTableModel;
private DefaultMessageListener messageListener;
private Timer boosterCurrentTimer;
private static final long CURRENT_UPDATE_TIMEOUT = 3000;
public void start(final DockingDesktop desktop, final MainControllerInterface mainController) {
// check if the booster table view is already opened
String searchKey = DockKeys.BOOSTER_TABLE_VIEW;
LOGGER.info("Search for view with key: {}", searchKey);
Dockable view = desktop.getContext().getDockableByKey(searchKey);
if (view != null) {
LOGGER.info("Select the existing booster table view.");
DockUtils.selectWindow(view);
return;
}
LOGGER.info("Create new BoosterTableView.");
boosterTableModel = new BoosterTableModel();
boosterTableView = new BoosterTableView(boosterTableModel);
if (desktop.getDockables().length > 1) {
Dockable dock = desktop.getDockables()[1].getDockable();
// dock.addDockable(boosterTableView, RelativeDockablePosition.RIGHT);
desktop.split(dock, boosterTableView, DockingConstants.SPLIT_BOTTOM);
desktop.setDockableHeight(boosterTableView, 0.2d);
}
else {
desktop.addDockable(boosterTableView, RelativeDockablePosition.RIGHT);
}
// create the nodeList listener
final NodeListListener nodeListListener = new DefaultNodeListListener() {
@Override
public void listNodeAdded(org.bidib.wizard.mvc.main.model.Node node) {
LOGGER.info("The nodelist has a new node: {}", node);
nodeNew(node.getNode());
}
@Override
public void listNodeRemoved(org.bidib.wizard.mvc.main.model.Node node) {
LOGGER.info("The nodelist has a node removed: {}", node);
nodeLost(node.getNode());
}
};
// register as nodeList listener at the main controller
mainController.addNodeListListener(nodeListListener);
try {
CommunicationFactory.addCommunicationListener(new CommunicationListener() {
@Override
public void status(String statusText, int displayDuration) {
}
@Override
public void opened(String port) {
LOGGER.info("The communication was opened.");
}
@Override
public void initialized() {
}
@Override
public void closed(String port) {
LOGGER.info("The communication was closed.");
List boosters = new LinkedList<>(boosterTableModel.getBoosters());
for (BoosterModel booster : boosters) {
boosterTableModel.removeBooster(booster.getBooster());
}
}
});
messageListener = new DefaultMessageListener() {
@Override
public void boosterState(final byte[] address, final BoosterState state) {
LOGGER.debug("Set the booster state: {}", state);
if (SwingUtilities.isEventDispatchThread()) {
boosterTableModel.setBoosterState(address, state);
}
else {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
boosterTableModel.setBoosterState(address, state);
}
});
}
}
@Override
public void boosterCurrent(final byte[] address, final int current) {
if (SwingUtilities.isEventDispatchThread()) {
boosterTableModel.setBoosterCurrent(address, current);
}
else {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
boosterTableModel.setBoosterCurrent(address, current);
}
});
}
}
@Override
public void boosterVoltage(final byte[] address, final int voltage) {
if (SwingUtilities.isEventDispatchThread()) {
boosterTableModel.setBoosterVoltage(address, voltage);
}
else {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
boosterTableModel.setBoosterVoltage(address, voltage);
}
});
}
}
@Override
public void boosterTemperature(final byte[] address, final int temperature) {
if (SwingUtilities.isEventDispatchThread()) {
boosterTableModel.setBoosterTemperature(address, temperature);
}
else {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
boosterTableModel.setBoosterTemperature(address, temperature);
}
});
}
}
};
CommunicationFactory.addMessageListener(messageListener);
final Communication communication = CommunicationFactory.getInstance();
// get the current nodes
List nodes = communication.getNodes();
if (CollectionUtils.isNotEmpty(nodes)) {
for (Node node : nodes) {
LOGGER.info("Initially add node.");
nodeNew(node);
}
}
}
catch (Exception ex) {
LOGGER.warn("Register controller as node listener failed.", ex);
}
desktop.addDockableStateChangeListener(new DockableStateChangeListener() {
@Override
public void dockableStateChanged(DockableStateChangeEvent event) {
if (event.getNewState().getDockable().equals(boosterTableView) && event.getNewState().isClosed()) {
LOGGER.info("BoosterTableView was closed, free resources.");
try {
// remove node listener from communication factory
if (nodeListListener != null) {
mainController.removeNodeListListener(nodeListListener);
}
if (messageListener != null) {
CommunicationFactory.removeMessageListener(messageListener);
}
}
catch (Exception ex) {
LOGGER.warn("Register controller as node listener failed.", ex);
}
// stop the booster current timer
if (boosterCurrentTimer != null) {
LOGGER.info("Stop the booster current timer.");
boosterCurrentTimer.stop();
boosterCurrentTimer = null;
}
}
}
});
try {
// start the booster current timer
boosterCurrentTimer = new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
LOGGER.trace("The booster current timer has elapsed.");
long now = System.currentTimeMillis();
// trigger the model
List boosters = boosterTableModel.getBoosters();
for (BoosterModel boosterModel : boosters) {
if (boosterModel.getCurrent() > 0
&& boosterModel.getLastCurrentUpdate() < (now - CURRENT_UPDATE_TIMEOUT)) {
// the current value is outdated -> clear the value
LOGGER.info("the current value is outdated -> clear the value, booster: {}", boosterModel);
boosterTableModel.setBoosterCurrent(boosterModel.getNodeAddress(), -1);
}
}
}
});
boosterCurrentTimer.setCoalesce(true);
boosterCurrentTimer.start();
}
catch (Exception ex) {
LOGGER.warn("Start the booster current timer failed.", ex);
}
}
private void nodeLost(final Node node) {
if (NodeUtils.hasBoosterFunctions(node.getUniqueId())) {
LOGGER.info("Remove booster from model: {}", node);
if (SwingUtilities.isEventDispatchThread()) {
boosterTableModel.removeBooster(node);
}
else {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
boosterTableModel.removeBooster(node);
}
});
}
}
}
private void nodeNew(final Node node) {
if (NodeUtils.hasBoosterFunctions(node.getUniqueId())) {
LOGGER.info("New booster in system detected: {}", node);
if (SwingUtilities.isEventDispatchThread()) {
internalNewNode(node);
}
else {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
internalNewNode(node);
}
});
}
}
// if the node is a hub then we must get it's subnodes ...
if (NodeUtils.hasSubNodesFunctions(node.getUniqueId())) {
final Communication communication = CommunicationFactory.getInstance();
List subNodes = new LinkedList<>(communication.getSubNodes(node));
if (CollectionUtils.isNotEmpty(subNodes)) {
for (Node subNode : subNodes) {
LOGGER.info("Found a subnode: {}", subNode);
nodeNew(subNode);
}
}
}
}
private void internalNewNode(final Node node) {
boosterTableModel.addBooster(node);
int maxCurrent = CommunicationFactory.getInstance().getBoosterMaximumCurrent(node);
LOGGER.info("Initialize the booster max current: {} mA, uniqueId: {}", maxCurrent,
NodeUtils.getUniqueIdAsString(node.getUniqueId()));
boosterTableModel.setBoosterMaxCurrent(node.getAddr(), maxCurrent);
// trigger the booster state
CommunicationFactory.getInstance().queryBoosterState(node);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy