
org.bidib.wizard.simulation.OneHubSimulator Maven / Gradle / Ivy
package org.bidib.wizard.simulation;
import java.util.HashMap;
import java.util.Map;
import org.bidib.jbidibc.core.BidibLibrary;
import org.bidib.jbidibc.core.BidibPort;
import org.bidib.jbidibc.core.Feature;
import org.bidib.jbidibc.core.enumeration.LcOutputType;
import org.bidib.jbidibc.core.exception.ProtocolException;
import org.bidib.jbidibc.core.message.BidibCommand;
import org.bidib.jbidibc.core.message.LcKeyMessage;
import org.bidib.jbidibc.core.message.LcKeyResponse;
import org.bidib.jbidibc.core.message.NodeLostResponse;
import org.bidib.jbidibc.core.message.NodeNewResponse;
import org.bidib.jbidibc.core.message.NodeTabCountResponse;
import org.bidib.jbidibc.core.message.NodeTabResponse;
import org.bidib.jbidibc.core.node.MacroFunctionsNode;
import org.bidib.jbidibc.core.utils.ByteUtils;
import org.bidib.jbidibc.core.utils.NodeUtils;
import org.bidib.jbidibc.simulation.InterfaceNode;
import org.bidib.jbidibc.simulation.SimulatorNode;
import org.bidib.jbidibc.simulation.SimulatorRegistry;
import org.bidib.jbidibc.simulation.SwitchingFunctionsNode;
import org.bidib.jbidibc.simulation.events.NodeAvailableEvent;
import org.bidib.jbidibc.simulation.events.NodeLostEvent;
import org.bidib.jbidibc.simulation.net.SimulationBidibMessageProcessor;
import org.bidib.jbidibc.simulation.nodes.DefaultNodeSimulator;
import org.bidib.jbidibc.simulation.nodes.InputPortType;
import org.bidib.jbidibc.simulation.nodes.PortType;
import org.bidib.wizard.comm.InputPortStatus;
import org.bidib.wizard.mvc.main.model.InputPort;
import org.bidib.wizard.mvc.main.model.Port;
import org.bidib.wizard.simulation.events.InputPortStatusEvent;
import org.bushe.swing.event.EventBus;
import org.bushe.swing.event.annotation.AnnotationProcessor;
import org.bushe.swing.event.annotation.EventSubscriber;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class OneHubSimulator extends DefaultNodeSimulator
implements InterfaceNode, SwitchingFunctionsNode, MacroFunctionsNode {
private static final Logger LOGGER = LoggerFactory.getLogger(OneHubSimulator.class);
// TODO change
private static final String SIMULATION_PANEL_CLASS = "org.bidib.wizard.mvc.simulation.view.panel.LightControlPanel";
private byte localAddrIndex;
private final Map inputPorts = new HashMap();
private int inputPortCount;
public OneHubSimulator(byte[] nodeAddress, long uniqueId, boolean autoAddFeature,
SimulationBidibMessageProcessor messageReceiver) {
super(nodeAddress, uniqueId, autoAddFeature, messageReceiver);
// TODO Auto-generated constructor stub
if (!NodeUtils.hasSubNodesFunctions(uniqueId)) {
LOGGER.warn("The configured Hub has no subnode functions defined in the uniqueId!");
}
}
@Override
protected void prepareFeatures() {
LOGGER.info("Prepare the features.");
super.prepareFeatures();
features.add(new Feature(BidibLibrary.FEATURE_CTRL_INPUT_COUNT, inputPortCount));
features.add(new Feature(BidibLibrary.FEATURE_CTRL_INPUT_NOTIFY, 1));
}
@Override
protected void prepareCVs() {
super.prepareCVs();
}
/**
* @return the subNodes
*/
public Map getSubNodes() {
return subNodes;
}
/**
* Add a new subnode.
*
* @param simulator
* the simulator
*/
@Override
public void addSubNode(SimulatorNode simulator) {
String nodeAddress = simulator.getLocalAddress().trim();
LOGGER.info("Add new subnode, address: {}, simulator: {}", nodeAddress, simulator);
subNodes.put(nodeAddress, simulator);
}
@Override
public String getSimulationPanelClass() {
return SIMULATION_PANEL_CLASS;
}
@Override
public void start() {
LOGGER.info("Start the simulator for address: {}", getAddress());
AnnotationProcessor.process(this);
// prepare the input ports
setupInputPorts();
super.start();
}
@Override
public void stop() {
AnnotationProcessor.unprocess(this);
super.stop();
}
private void setupInputPorts() {
for (int id = 0; id < inputPortCount; id++) {
InputPort port = new InputPort();
port.setId(id);
port.setStatus(id % 2 == 0 ? InputPortStatus.ON : InputPortStatus.OFF);
inputPorts.put(id, port);
}
}
@Override
protected byte[] prepareResponse(BidibCommand bidibMessage) {
byte[] response = null;
switch (ByteUtils.getInt(bidibMessage.getType())) {
case BidibLibrary.MSG_LC_KEY_QUERY:
response = processLcKeyQueryRequest(bidibMessage);
break;
default:
response = super.prepareResponse(bidibMessage);
break;
}
return response;
}
protected byte[] processLcKeyQueryRequest(BidibCommand bidibMessage) {
LOGGER.info("Process the LcKeyQuery request: {}", bidibMessage);
byte[] response = null;
byte keyState = 0;
Port> port = null;
try {
LcKeyMessage lcKeyMessage = (LcKeyMessage) bidibMessage;
int keyNumber = lcKeyMessage.getKeyNumber();
port = inputPorts.get(keyNumber);
keyState = port.getStatus().getType().getType();
LcKeyResponse lcKeyResponse =
new LcKeyResponse(bidibMessage.getAddr(), getNextSendNum(), ByteUtils.getLowByte(lcKeyMessage
.getKeyNumber()), keyState);
response = lcKeyResponse.getContent();
}
catch (ProtocolException ex) {
LOGGER.warn("Create LcKey response failed.", ex);
}
if (port != null) {
publishInputPortChange(port);
}
return response;
}
protected byte[] processNodeTabGetAllRequest(BidibCommand bidibMessage) {
// reset the local addr
localAddrIndex = 0;
byte tabCount = (byte) subNodes.size();
LOGGER.info("Return number of nodeTabs in current node: {}", tabCount);
byte[] response = null;
try {
NodeTabCountResponse nodeTabCountResponse =
new NodeTabCountResponse(bidibMessage.getAddr(), getNextSendNum(), tabCount);
response = nodeTabCountResponse.getContent();
}
catch (ProtocolException ex) {
LOGGER.warn("Create nodeTabCount response failed.", ex);
}
return response;
}
protected byte[] processNodeTabGetNextRequest(BidibCommand bidibMessage) {
// 02.01.2014 14:50:11.961: send NodeTabGetAllMessage[num=4,type=11,data=[]] : FE 03 00 04 0B 93 FE
// 02.01.2014 14:50:11.974: receive NodeTabCountResponse[[0],num=1,type=136,data=[2]] : 04 00 01 88 02
// 02.01.2014 14:50:11.977: send NodeTabGetNextMessage[num=5,type=12,data=[]] : FE 03 00 05 0C D4 FE
// 02.01.2014 14:50:11.990: receive NodeTabResponse[[0],num=2,type=137,data=[1, 0, 210, 0, 13, 104, 0, 0, 54]] :
// 0C 00 02 89 01 00 D2 00 0D 68 00 00 36
// 02.01.2014 14:50:11.994: send SysMagicMessage[num=6,type=1,data=[]] : FE 03 00 06 01 7C FE
// 02.01.2014 14:50:12.006: receive SysMagicResponse[[0],num=0,type=129,data=[254, 175]] : 05 00 00 81 FE AF
// 02.01.2014 14:50:12.008: send NodeTabGetNextMessage[num=7,type=12,data=[]] : FE 03 00 07 0C 45 FE
// 02.01.2014 14:50:12.022: receive NodeTabResponse[[0],num=1,type=137,data=[1, 1, 5, 0, 13, 107, 0, 105, 234]]
// : 0C 00 01 89 01 01 05 00 0D 6B 00 69 EA
// 02.01.2014 14:50:12.031: send SysMagicMessage[num=0,type=1,data=[]] : FE 04 01 00 00 01 CE FE
// 02.01.2014 14:50:12.038: receive SysMagicResponse[[1],num=0,type=129,data=[254, 175]] : 06 01 00 00 81 FE AF
byte[] response = null;
byte nodeTabVersion = 1;
byte localAddr = localAddrIndex;
LOGGER.info("get the simulator with local address: {}", localAddr);
String[] nodeAddresses = subNodes.keySet().toArray(new String[0]);
byte addr = ByteUtils.getLowByte(Integer.parseInt(nodeAddresses[localAddr], 16));
SimulatorNode simulator = subNodes.get(nodeAddresses[localAddr]);
long uniqueId = simulator.getUniqueId();
LOGGER.info("localAddr: {}, nodeAddr: {}, uniqueId: {}", localAddr, addr, uniqueId);
try {
NodeTabResponse nodeTabResponse =
new NodeTabResponse(bidibMessage.getAddr(), getNextSendNum(), nodeTabVersion, addr, uniqueId);
response = nodeTabResponse.getContent();
LOGGER.info("Prepared nodeTab response: {}", ByteUtils.bytesToHex(response));
}
catch (ProtocolException ex) {
LOGGER.warn("Create nodeTab response failed.", ex);
}
localAddrIndex++;
return response;
}
private void publishInputPortChange(Port> port) {
InputPort inputPort = (InputPort) port;
InputPortStatus status = inputPort.getStatus();
LOGGER.info("The inputport status has changed, notify the listeners, nodeAddress: {}", nodeAddress);
EventBus.publish(new InputPortStatusEvent(ByteUtils.bytesToHex(nodeAddress), inputPort.getId(), status));
}
@Override
public void queryStatus(Class> portClass) {
if (InputPort.class.equals(portClass)) {
for (InputPort inputPort : inputPorts.values()) {
publishInputPortChange(inputPort);
}
}
}
@Override
public void setPortsConfig(PortType portType) {
if (portType == null) {
return;
}
if (portType instanceof InputPortType) {
inputPortCount = portType.getCount();
}
}
@EventSubscriber(eventClass = NodeLostEvent.class)
public void nodeLostEvent(NodeLostEvent nodeLostEvent) {
byte[] nodeAddr = nodeLostEvent.getNodeAddr();
// check if the node is a subnode of this node
if (!NodeUtils.isSubNode(nodeAddress, nodeAddr)) {
return;
}
final byte nodeLocalAddress = nodeAddr[nodeAddr.length - 1];
long uniqueId = nodeLostEvent.getUniqueId();
LOGGER
.info("The node lost event was requested, nodeLocalAddress: {}, uniqueId: {}", nodeLocalAddress, uniqueId);
// publish event
byte[] response = null;
byte nodeTabVersion = ByteUtils.getLowByte(SimulatorRegistry.getInstance().getNextNodeTabVersion());
try {
byte addr = nodeLocalAddress;
NodeLostResponse nodeLostResponse =
new NodeLostResponse(nodeAddress, getNextSendNum(), nodeTabVersion, addr, uniqueId);
response = nodeLostResponse.getContent();
LOGGER.info("Prepared nodeLost response: {}", ByteUtils.bytesToHex(response));
}
catch (ProtocolException ex) {
LOGGER.warn("Create nodeLost response failed.", ex);
}
LOGGER.info("Publish the current response: {}", response);
publishResponse(response);
}
@EventSubscriber(eventClass = NodeAvailableEvent.class)
public void nodeAvailableEvent(NodeAvailableEvent nodeAvailableEvent) {
byte[] nodeAddr = nodeAvailableEvent.getNodeAddr();
// check if the node is a subnode of this node
if (!NodeUtils.isSubNode(nodeAddress, nodeAddr)) {
return;
}
final byte nodeLocalAddress = nodeAddr[nodeAddr.length - 1];
long uniqueId = nodeAvailableEvent.getUniqueId();
LOGGER.info("The node available event was requested, nodeLocalAddress: {}, uniqueId: {}", nodeLocalAddress,
uniqueId);
// publish event
byte[] response = null;
byte nodeTabVersion = ByteUtils.getLowByte(SimulatorRegistry.getInstance().getNextNodeTabVersion());
try {
byte addr = nodeLocalAddress;
NodeNewResponse nodeNewResponse =
new NodeNewResponse(nodeAddress, getNextSendNum(), nodeTabVersion, addr, uniqueId);
response = nodeNewResponse.getContent();
LOGGER.info("Prepared nodeNew response: {}", ByteUtils.bytesToHex(response));
}
catch (ProtocolException ex) {
LOGGER.warn("Create nodeNew response failed.", ex);
}
LOGGER.info("Publish the current response: {}", response);
publishResponse(response);
}
@Override
public boolean isPortFlatModelAvailable() {
return false;
}
@Override
public LcOutputType getPortType(BidibPort bidibPort) {
return null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy