org.bidib.wizard.gateway.service.ProxyNetBidibConnectionAdapter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bidibwizard-gateway Show documentation
Show all versions of bidibwizard-gateway Show documentation
jBiDiB BiDiB Wizard Gateway POM
package org.bidib.wizard.gateway.service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.IterableUtils;
import org.bidib.api.json.types.NodeAddress;
import org.bidib.jbidibc.messages.AccessoryState;
import org.bidib.jbidibc.messages.BidibLibrary;
import org.bidib.jbidibc.messages.BidibPort;
import org.bidib.jbidibc.messages.Feature;
import org.bidib.jbidibc.messages.FeedbackConfidenceData;
import org.bidib.jbidibc.messages.FeedbackTimestampData;
import org.bidib.jbidibc.messages.HostAdapter;
import org.bidib.jbidibc.messages.LcConfigX;
import org.bidib.jbidibc.messages.LcMacro;
import org.bidib.jbidibc.messages.Node;
import org.bidib.jbidibc.messages.ProtocolVersion;
import org.bidib.jbidibc.messages.SoftwareVersion;
import org.bidib.jbidibc.messages.StringData;
import org.bidib.jbidibc.messages.enums.CommandStationState;
import org.bidib.jbidibc.messages.enums.InputPortEnum;
import org.bidib.jbidibc.messages.enums.LcOutputType;
import org.bidib.jbidibc.messages.enums.LightPortEnum;
import org.bidib.jbidibc.messages.enums.OccupationState;
import org.bidib.jbidibc.messages.enums.PortModelEnum;
import org.bidib.jbidibc.messages.enums.SwitchPortEnum;
import org.bidib.jbidibc.messages.exception.ProtocolException;
import org.bidib.jbidibc.messages.message.AccessoryGetMessage;
import org.bidib.jbidibc.messages.message.AccessoryParaGetMessage;
import org.bidib.jbidibc.messages.message.BidibMessage;
import org.bidib.jbidibc.messages.message.BidibMessageInterface;
import org.bidib.jbidibc.messages.message.BidibResponseFactory;
import org.bidib.jbidibc.messages.message.CommandStationSetStateMessage;
import org.bidib.jbidibc.messages.message.FeatureGetAllMessage;
import org.bidib.jbidibc.messages.message.FeatureNotAvailableResponse;
import org.bidib.jbidibc.messages.message.FeatureResponse;
import org.bidib.jbidibc.messages.message.FeatureSetMessage;
import org.bidib.jbidibc.messages.message.FeedbackGetRangeMessage;
import org.bidib.jbidibc.messages.message.LcConfigXGetAllMessage;
import org.bidib.jbidibc.messages.message.LcConfigXResponse;
import org.bidib.jbidibc.messages.message.LcConfigXSetMessage;
import org.bidib.jbidibc.messages.message.LcMacroGetMessage;
import org.bidib.jbidibc.messages.message.LcMacroParaGetMessage;
import org.bidib.jbidibc.messages.message.LcOutputMessage;
import org.bidib.jbidibc.messages.message.LcPortQueryAllMessage;
import org.bidib.jbidibc.messages.message.NodeTabCountResponse;
import org.bidib.jbidibc.messages.message.NodeTabResponse;
import org.bidib.jbidibc.messages.message.StringGetMessage;
import org.bidib.jbidibc.messages.message.StringResponse;
import org.bidib.jbidibc.messages.port.PortConfigUtils;
import org.bidib.jbidibc.messages.port.PortConfigValue;
import org.bidib.jbidibc.messages.utils.ByteUtils;
import org.bidib.jbidibc.messages.utils.NodeUtils;
import org.bidib.jbidibc.messages.utils.ThreadFactoryBuilder;
import org.bidib.wizard.api.model.Accessory;
import org.bidib.wizard.api.model.Macro;
import org.bidib.wizard.api.model.MacroRepeatDay;
import org.bidib.wizard.api.model.MacroRepeatTime;
import org.bidib.wizard.api.model.NodeInterface;
import org.bidib.wizard.api.model.StartCondition;
import org.bidib.wizard.api.model.TimeStartCondition;
import org.bidib.wizard.api.model.connection.AbstractMessageEvent;
import org.bidib.wizard.api.model.connection.event.AccessoryStateMessageEvent;
import org.bidib.wizard.api.model.connection.event.BoosterDiagMessageEvent;
import org.bidib.wizard.api.model.connection.event.BoosterStateMessageEvent;
import org.bidib.wizard.api.model.connection.event.CommandStationStateMessageEvent;
import org.bidib.wizard.api.model.connection.event.LcConfigXMessageEvent;
import org.bidib.wizard.api.model.connection.event.LcNaMessageEvent;
import org.bidib.wizard.api.model.connection.event.LcStatMessageEvent;
import org.bidib.wizard.api.model.connection.event.NodeLostMessageEvent;
import org.bidib.wizard.api.model.connection.event.NodeNewMessageEvent;
import org.bidib.wizard.api.model.connection.event.OccupancyStateMessageEvent;
import org.bidib.wizard.api.model.connection.event.StringMessageEvent;
import org.bidib.wizard.api.model.connection.event.SysMagicMessageEvent;
import org.bidib.wizard.api.model.connection.event.SysProtocolVersionMessageEvent;
import org.bidib.wizard.api.model.connection.event.SysSoftwareVersionMessageEvent;
import org.bidib.wizard.api.model.event.NodeStatusEvent.StatusIdentifier;
import org.bidib.wizard.api.model.function.Function;
import org.bidib.wizard.api.model.function.SystemFunction;
import org.bidib.wizard.api.service.node.BoosterService;
import org.bidib.wizard.api.service.node.CommandStationService;
import org.bidib.wizard.api.service.node.NodeService;
import org.bidib.wizard.api.service.node.SwitchingNodeService;
import org.bidib.wizard.api.utils.JsonNodeUtils;
import org.bidib.wizard.api.utils.PortListUtils;
import org.bidib.wizard.gateway.model.connection.ProxyBidibConnection;
import org.bidib.wizard.gateway.model.node.ProxyInterfaceNode;
import org.bidib.wizard.gateway.model.node.ProxyNode;
import org.bidib.wizard.model.ports.BacklightPort;
import org.bidib.wizard.model.ports.FeedbackPort;
import org.bidib.wizard.model.ports.GenericPort;
import org.bidib.wizard.model.ports.InputPort;
import org.bidib.wizard.model.ports.LightPort;
import org.bidib.wizard.model.ports.Port;
import org.bidib.wizard.model.ports.ServoPort;
import org.bidib.wizard.model.ports.SwitchPairPort;
import org.bidib.wizard.model.ports.SwitchPort;
import org.bidib.wizard.model.status.BidibStatus;
import org.bidib.wizard.model.status.BoosterStatus;
import org.bidib.wizard.model.status.CommandStationStatus;
import org.bidib.wizard.model.status.FeedbackConfidenceStatus;
import org.bidib.wizard.model.status.InputPortStatus;
import org.bidib.wizard.model.status.LightPortStatus;
import org.bidib.wizard.model.status.SwitchPortStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
/**
* The {@code ProxyNetBidibConnectionAdapter} is used to transform the bidib messages to calls on the
* {@code ProxyBidibConnection} that will call the backend.
*/
public class ProxyNetBidibConnectionAdapter implements ProxyConnectionAdapter {
private static final Logger LOGGER = LoggerFactory.getLogger(ProxyNetBidibConnectionAdapter.class);
private static final Logger LOGGER_LCCONFIGX = LoggerFactory.getLogger(LcConfigX.class);
private final BidibResponseFactory responseFactory;
@Autowired
private NodeService nodeService;
@Autowired
private SwitchingNodeService switchingNodeService;
@Autowired
private CommandStationService commandStationService;
@Autowired
private BoosterService boosterService;
private boolean mimicGateway = true;
private final org.bidib.jbidibc.messages.logger.Logger messageLogger;
private final ScheduledExecutorService serviceWorker;
public ProxyNetBidibConnectionAdapter(final BidibResponseFactory responseFactory) {
this.responseFactory = responseFactory;
this.messageLogger = new org.bidib.jbidibc.messages.logger.Logger() {
@Override
public void debug(String format, Object... arguments) {
LOGGER_LCCONFIGX.debug(format, arguments);
}
@Override
public void info(String format, Object... arguments) {
LOGGER_LCCONFIGX.info(format, arguments);
}
@Override
public void warn(String format, Object... arguments) {
LOGGER_LCCONFIGX.warn(format, arguments);
}
@Override
public void error(String format, Object... arguments) {
LOGGER_LCCONFIGX.error(format, arguments);
}
};
this.serviceWorker =
Executors
.newScheduledThreadPool(1,
new ThreadFactoryBuilder().setNameFormat("proxyConnectionServiceWorkers-thread-%d").build());
}
@Override
public void processBidibMessageFromGuest(
final ProxyBidibConnection bidibProxyConnection,
final HostAdapter distributedHostAdapter, final BidibMessageInterface bidibMessage)
throws ProtocolException {
LOGGER.info("Process the bidibMessage: {}", bidibMessage);
try {
int messageType = ByteUtils.getInt(bidibMessage.getType());
doProcessBidibMessageFromGuest(bidibProxyConnection, distributedHostAdapter, bidibMessage, messageType);
}
catch (Exception ex) {
LOGGER.warn("Process bidibMessage failed: {}", bidibMessage, ex);
throw new ProtocolException("Process message failed.");
}
}
private void doProcessBidibMessageFromGuest(
final ProxyBidibConnection bidibProxyConnection,
final HostAdapter distributedHostAdapter, final BidibMessageInterface bidibMessage,
int messageType) throws ProtocolException {
try {
// get the node by address
final NodeInterface node =
Optional
.ofNullable(bidibProxyConnection.getNodeProvider().findNodeByAddress(bidibMessage.getAddr()))
.orElseThrow(() -> new ProtocolException(
"No node available with address: " + NodeUtils.formatAddress(bidibMessage.getAddr())));
final ProxyNode proxyNode = ProxyNode.getProxyNode(node);
switch (messageType) {
case BidibLibrary.MSG_SYS_GET_UNIQUE_ID:
Long uniqueId = proxyNode.getUniqueId();
BidibMessageInterface sysUniqueIdResponse =
responseFactory.createSysUniqueIdResponse(bidibMessage.getAddr(), 0, uniqueId);
distributedHostAdapter.forwardMessageToGuest(proxyNode, sysUniqueIdResponse);
break;
case BidibLibrary.MSG_SYS_GET_MAGIC:
Integer magic = proxyNode.getNode().getMagic();
LOGGER.info("Current magic of node: {}", magic);
if (mimicGateway) {
magic = BidibLibrary.BIDIB_GATEWAY_MAGIC;
LOGGER.info("Changed current magic of node to BIDIB_GATEWAY_MAGIC: {}", magic);
}
if (magic != null) {
BidibMessageInterface sysMagicResponse =
responseFactory.createSysMagicResponse(bidibMessage.getAddr(), 0, magic);
distributedHostAdapter.forwardMessageToGuest(proxyNode, sysMagicResponse);
}
else {
LOGGER.warn("No magic available for node: {}", proxyNode);
}
break;
case BidibLibrary.MSG_SYS_ENABLE:
processSysEnableOrDisableRequest(bidibProxyConnection.getConnectionId(), bidibMessage, proxyNode,
true);
break;
case BidibLibrary.MSG_SYS_DISABLE:
processSysEnableOrDisableRequest(bidibProxyConnection.getConnectionId(), bidibMessage, proxyNode,
false);
break;
case BidibLibrary.MSG_SYS_GET_SW_VERSION:
SoftwareVersion softwareVersion = proxyNode.getNode().getSoftwareVersion();
LOGGER.info("Current software version of node: {}", softwareVersion);
if (softwareVersion != null) {
BidibMessageInterface sysSwVersionResponse =
responseFactory.createSysSwVersionResponse(bidibMessage.getAddr(), 0, softwareVersion);
distributedHostAdapter.forwardMessageToGuest(proxyNode, sysSwVersionResponse);
}
else {
LOGGER.warn("No software version available for node: {}", proxyNode);
}
break;
case BidibLibrary.MSG_SYS_GET_P_VERSION:
ProtocolVersion protocolVersion = proxyNode.getNode().getProtocolVersion();
LOGGER.info("Current protocol version of node: {}", protocolVersion);
if (protocolVersion != null) {
BidibMessageInterface sysProtocolVersionResponse =
responseFactory
.createSysProtocolVersionResponse(bidibMessage.getAddr(), 0, protocolVersion);
distributedHostAdapter.forwardMessageToGuest(proxyNode, sysProtocolVersionResponse);
}
else {
LOGGER.warn("No protocol version available for node: {}", proxyNode);
}
break;
case BidibLibrary.MSG_FEATURE_GETALL:
processFeatureGetAllRequest(distributedHostAdapter, bidibMessage, proxyNode);
break;
case BidibLibrary.MSG_FEATURE_GETNEXT:
processFeatureGetNextRequest(distributedHostAdapter, bidibMessage, proxyNode);
break;
case BidibLibrary.MSG_FEATURE_SET:
processFeatureSetRequest(bidibProxyConnection.getConnectionId(), distributedHostAdapter,
bidibMessage, proxyNode);
break;
case BidibLibrary.MSG_NODETAB_GETALL:
processNodetabGetAllRequest(bidibProxyConnection, distributedHostAdapter, bidibMessage, proxyNode);
break;
case BidibLibrary.MSG_NODETAB_GETNEXT:
processNodetabGetNextRequest(bidibProxyConnection, distributedHostAdapter, bidibMessage, proxyNode);
break;
case BidibLibrary.MSG_STRING_GET:
processStringGetRequest(distributedHostAdapter, bidibMessage, proxyNode);
break;
case BidibLibrary.MSG_CS_SET_STATE:
processCommandStationSetStateRequest(bidibProxyConnection.getConnectionId(), distributedHostAdapter,
bidibMessage, proxyNode);
break;
case BidibLibrary.MSG_BOOST_QUERY:
processBoosterQueryRequest(bidibProxyConnection.getConnectionId(), distributedHostAdapter,
bidibMessage, proxyNode);
break;
case BidibLibrary.MSG_BOOST_OFF:
case BidibLibrary.MSG_BOOST_ON:
processBoosterStateRequest(bidibProxyConnection.getConnectionId(), distributedHostAdapter,
bidibMessage, proxyNode);
break;
case BidibLibrary.MSG_BM_GET_RANGE:
processFeedbackGetRangeRequest(bidibProxyConnection.getConnectionId(), distributedHostAdapter,
bidibMessage, proxyNode);
break;
case BidibLibrary.MSG_BM_GET_CONFIDENCE:
processFeedbackGetConfidenceRequest(bidibProxyConnection.getConnectionId(), distributedHostAdapter,
bidibMessage, proxyNode);
break;
case BidibLibrary.MSG_BM_ADDR_GET_RANGE:
processFeedbackAddressGetRangeRequest(bidibProxyConnection.getConnectionId(), bidibMessage,
proxyNode);
break;
case BidibLibrary.MSG_LOCAL_PING:
// TODO forward the local ping to the real node
// bidibProxyConnection.
break;
case BidibLibrary.MSG_NODE_CHANGED_ACK:
LOGGER.warn("The message MSG_NODE_CHANGED_ACK is not signaled to the proxy connection");
break;
case BidibLibrary.MSG_LC_PORT_QUERY_ALL:
processLcPortQueryAllRequest(bidibProxyConnection.getConnectionId(), distributedHostAdapter,
bidibMessage, proxyNode);
break;
case BidibLibrary.MSG_LC_CONFIGX_GET_ALL:
processLcConfigXGetAllRequest(bidibProxyConnection.getConnectionId(), distributedHostAdapter,
bidibMessage, proxyNode);
break;
case BidibLibrary.MSG_LC_CONFIGX_SET:
processLcConfigXSetRequest(bidibProxyConnection.getConnectionId(), distributedHostAdapter,
bidibMessage, proxyNode);
break;
case BidibLibrary.MSG_LC_OUTPUT:
processLcOutputRequest(bidibProxyConnection.getConnectionId(), distributedHostAdapter, bidibMessage,
proxyNode);
break;
case BidibLibrary.MSG_LC_MACRO_GET:
processLcMacroGetRequest(bidibProxyConnection.getConnectionId(), distributedHostAdapter,
bidibMessage, proxyNode);
break;
case BidibLibrary.MSG_LC_MACRO_PARA_GET:
processLcMacroParaGetRequest(bidibProxyConnection.getConnectionId(), distributedHostAdapter,
bidibMessage, proxyNode);
break;
case BidibLibrary.MSG_ACCESSORY_PARA_GET:
processAccessoryParaGetRequest(bidibProxyConnection.getConnectionId(), distributedHostAdapter,
bidibMessage, proxyNode);
break;
case BidibLibrary.MSG_ACCESSORY_GET:
processAccessoryGetRequest(bidibProxyConnection.getConnectionId(), distributedHostAdapter,
bidibMessage, proxyNode);
break;
default:
LOGGER.warn("Unsupported message detected: {}", bidibMessage);
break;
}
}
catch (Exception ex) {
LOGGER.warn("Process bidibMessage failed: {}", bidibMessage, ex);
throw new ProtocolException("Process message failed.");
}
}
@Override
public void handleMessageEventFromBus(
final ProxyBidibConnection bidibProxyConnection,
final HostAdapter distributedHostAdapter, final AbstractMessageEvent event) {
LOGGER.info("Handle the message event: {}", event);
try {
final NodeInterface node =
Optional
.ofNullable(bidibProxyConnection.getNodeProvider().findNodeByAddress(event.getAddress()))
.orElseThrow(() -> new ProtocolException(
"No node available with address: " + NodeUtils.formatAddress(event.getAddress())));
final ProxyNode proxyNode = ProxyNode.getProxyNode(node);
switch (event.getMessageType()) {
case BidibLibrary.MSG_CS_STATE:
final CommandStationStateMessageEvent commandStationStateMessageEvent =
(CommandStationStateMessageEvent) event;
final CommandStationState csState = commandStationStateMessageEvent.getCommandStationState();
// TODO we must synchronize the access to the sending
final BidibMessage csStateResponse =
responseFactory.createCommandStationStateResponse(event.getAddress(), 0, csState);
LOGGER
.info(">>> MSG_CS_STATE: Current messageContent: {}",
ByteUtils.bytesToHex(csStateResponse.getMessageContent()));
distributedHostAdapter.forwardMessageToGuest(proxyNode, csStateResponse);
break;
case BidibLibrary.MSG_BM_FREE:
case BidibLibrary.MSG_BM_OCC:
if (!proxyNode.isEnabled()) {
LOGGER.info("Discard the occupancy message because the node is not enabled: {}", proxyNode);
break;
}
LOGGER.info("Current message event: {}", event);
OccupancyStateMessageEvent occupancyStateMessageEvent = (OccupancyStateMessageEvent) event;
int detectorNumber = occupancyStateMessageEvent.getDetectorNumber();
OccupationState occupationState = occupancyStateMessageEvent.getOccupationState();
Integer timestamp = occupancyStateMessageEvent.getTimestamp();
final BidibMessage feedbackStateResponse =
responseFactory
.createOccupancyStateResponse(event.getAddress(), 0, detectorNumber, occupationState,
timestamp);
LOGGER
.info(">>> MSG_BM_FREE/MSG_BM_OCC: Current messageContent: {}",
ByteUtils.bytesToHex(feedbackStateResponse.getMessageContent()));
distributedHostAdapter.forwardMessageToGuest(proxyNode, feedbackStateResponse);
break;
case BidibLibrary.MSG_BM_CONFIDENCE:
case BidibLibrary.MSG_BM_MULTIPLE:
if (!proxyNode.isEnabled()) {
LOGGER.info("Discard the occupancy message because the node is not enabled: {}", proxyNode);
break;
}
LOGGER.info("Current message event: {}", event);
// TODO
break;
case BidibLibrary.MSG_BOOST_STAT:
final BoosterStateMessageEvent boosterStateMessageEvent = (BoosterStateMessageEvent) event;
final BidibMessage boosterStateResponse =
responseFactory
.createBoosterStateResponse(event.getAddress(), 0,
boosterStateMessageEvent.getBoosterState());
LOGGER
.info(">>> MSG_BOOST_STAT: Current messageContent: {}",
ByteUtils.bytesToHex(boosterStateResponse.getMessageContent()));
distributedHostAdapter.forwardMessageToGuest(proxyNode, boosterStateResponse);
break;
case BidibLibrary.MSG_BOOST_DIAGNOSTIC:
if (!proxyNode.isEnabled()) {
LOGGER.info("Discard the booster diag message because the node is not enabled: {}", proxyNode);
break;
}
final BoosterDiagMessageEvent boosterDiagMessageEvent = (BoosterDiagMessageEvent) event;
final BidibMessage boosterDiagResponse =
responseFactory
.createBoosterDiagnosticResponse(event.getAddress(), 0,
boosterDiagMessageEvent.getCurrent(), boosterDiagMessageEvent.getVoltage(),
boosterDiagMessageEvent.getTemperature());
LOGGER
.info(">>> MSG_BOOST_DIAGNOSTIC: Current messageContent: {}",
ByteUtils.bytesToHex(boosterDiagResponse.getMessageContent()));
distributedHostAdapter.forwardMessageToGuest(proxyNode, boosterDiagResponse);
break;
case BidibLibrary.MSG_LOCAL_PONG:
// final LocalPongMessageEvent localPongMessageEvent = (LocalPongMessageEvent) event;
final BidibMessage localPongResponse = responseFactory.createLocalPongResponse(event.getAddress());
LOGGER
.info(">>> MSG_LOCAL_PONG: Current messageContent: {}",
ByteUtils.bytesToHex(localPongResponse.getMessageContent()));
distributedHostAdapter.forwardMessageToGuest(proxyNode, localPongResponse);
break;
case BidibLibrary.MSG_NODE_NEW:
final NodeNewMessageEvent nodeNewMessageEvent = (NodeNewMessageEvent) event;
final Node newCoreNode = nodeNewMessageEvent.getNode();
try {
byte[] addr = newCoreNode.getAddr();
int localAddr = addr[addr.length - 1];
long uniqueId = newCoreNode.getUniqueId();
LOGGER
.info("handle nodeNewMessageEvent: {}, proxyNode: {}, coreNode: {}, localAddr: {}",
nodeNewMessageEvent, proxyNode, newCoreNode, localAddr);
final BidibMessage nodeNewResponse =
responseFactory
.createNodeNewResponse(event.getAddress(), 0, newCoreNode.getVersion(), localAddr,
uniqueId);
distributedHostAdapter.forwardMessageToGuest(proxyNode, nodeNewResponse);
}
catch (Exception ex) {
LOGGER
.warn("Forward NodeNewResponse to guest failed. Current nodeNewMessageEvent: {}",
nodeNewMessageEvent, ex);
}
break;
case BidibLibrary.MSG_NODE_LOST:
final NodeLostMessageEvent nodeLostMessageEvent = (NodeLostMessageEvent) event;
final Node lostCoreNode = nodeLostMessageEvent.getNode();
try {
byte[] addr = lostCoreNode.getAddr();
int localAddr = addr[addr.length - 1];
long uniqueId = lostCoreNode.getUniqueId();
LOGGER
.info("handle nodeLostMessageEvent: {}, proxyNode: {}, coreNode: {}, localAddr: {}",
nodeLostMessageEvent, proxyNode, lostCoreNode, localAddr);
final BidibMessage nodeLostResponse =
responseFactory
.createNodeLostResponse(event.getAddress(), 0, lostCoreNode.getVersion(), localAddr,
uniqueId);
distributedHostAdapter.forwardMessageToGuest(proxyNode, nodeLostResponse);
}
catch (Exception ex) {
LOGGER
.warn("Forward NodeLostResponse to guest failed. Current nodeLostMessageEvent: {}",
nodeLostMessageEvent, ex);
}
break;
case BidibLibrary.MSG_SYS_MAGIC:
final SysMagicMessageEvent sysMagicMessageEvent = (SysMagicMessageEvent) event;
int magic = sysMagicMessageEvent.getMagic();
final BidibMessage sysMagicResponse =
responseFactory.createSysMagicResponse(event.getAddress(), 0, magic);
LOGGER.info("Publish the sysMagicResponse: {}", sysMagicResponse);
distributedHostAdapter.forwardMessageToGuest(proxyNode, sysMagicResponse);
break;
case BidibLibrary.MSG_SYS_SW_VERSION:
final SysSoftwareVersionMessageEvent sysSoftwareVersionMessageEvent =
(SysSoftwareVersionMessageEvent) event;
SoftwareVersion softwareVersion = sysSoftwareVersionMessageEvent.getSoftwareVersion();
final BidibMessage sysSoftwareVersionResponse =
responseFactory.createSysSwVersionResponse(event.getAddress(), 0, softwareVersion);
LOGGER.info("Publish the sysSoftwareVersionResponse: {}", sysSoftwareVersionResponse);
distributedHostAdapter.forwardMessageToGuest(proxyNode, sysSoftwareVersionResponse);
break;
case BidibLibrary.MSG_SYS_P_VERSION:
final SysProtocolVersionMessageEvent sysProtocolVersionMessageEvent =
(SysProtocolVersionMessageEvent) event;
ProtocolVersion protocolVersion = sysProtocolVersionMessageEvent.getProtocolVersion();
final BidibMessage sysProtocolVersionResponse =
responseFactory.createSysProtocolVersionResponse(event.getAddress(), 0, protocolVersion);
LOGGER.info("Publish the sysProtocolVersionResponse: {}", sysProtocolVersionResponse);
distributedHostAdapter.forwardMessageToGuest(proxyNode, sysProtocolVersionResponse);
break;
case BidibLibrary.MSG_STRING:
final StringMessageEvent stringMessageEvent = (StringMessageEvent) event;
final StringData stringData = stringMessageEvent.getStringData();
final BidibMessage stringResponse =
responseFactory.createStringResponse(event.getAddress(), 0, stringData);
distributedHostAdapter.forwardMessageToGuest(proxyNode, stringResponse);
break;
case BidibLibrary.MSG_LC_CONFIGX:
final LcConfigXMessageEvent lcConfigXMessageEvent = (LcConfigXMessageEvent) event;
final LcConfigX lcConfigX = lcConfigXMessageEvent.getLcConfigX();
final PortModelEnum portModelEnum = PortModelEnum.getPortModel(node.getNode());
LOGGER.info("Publish lcConfigX: {}", lcConfigX);
final BidibMessage lcConfigXResponse =
responseFactory.createLcConfigXResponse(event.getAddress(), 0, lcConfigX, portModelEnum);
distributedHostAdapter.forwardMessageToGuest(proxyNode, lcConfigXResponse);
break;
case BidibLibrary.MSG_LC_STAT:
final LcStatMessageEvent lcStatMessageEvent = (LcStatMessageEvent) event;
try {
final BidibPort bidibPort = lcStatMessageEvent.getBidibPort();
final int portStatus = lcStatMessageEvent.getPortStatus();
final BidibMessage lcStatResponse =
responseFactory.createLcStatResponse(event.getAddress(), 0, bidibPort, portStatus);
distributedHostAdapter.forwardMessageToGuest(proxyNode, lcStatResponse);
}
catch (Exception ex) {
LOGGER
.warn("Forward LcStatResponse to guest failed. Current lcStatMessageEvent: {}",
lcStatMessageEvent, ex);
}
break;
case BidibLibrary.MSG_LC_NA:
final LcNaMessageEvent lcNaMessageEvent = (LcNaMessageEvent) event;
final BidibPort bidibPort = lcNaMessageEvent.getBidibPort();
final BidibMessage lcNaResponse =
responseFactory.createLcNaResponse(event.getAddress(), 0, bidibPort);
distributedHostAdapter.forwardMessageToGuest(proxyNode, lcNaResponse);
break;
case BidibLibrary.MSG_ACCESSORY_STATE:
final AccessoryStateMessageEvent accessoryStateMessageEvent = (AccessoryStateMessageEvent) event;
final AccessoryState accessoryState = accessoryStateMessageEvent.getAccessoryState();
int accessoryNumber = accessoryState.getAccessoryNumber();
Integer aspect = accessoryState.getActiveAspect();
byte[] value =
new byte[] { accessoryState.getTotal(), accessoryState.getExecute(),
ByteUtils.getLowByte(accessoryState.getWait()) };
final BidibMessage accessoryStateResponse =
responseFactory
.createAccessoryStateResponse(event.getAddress(), 0, accessoryNumber, aspect, value);
distributedHostAdapter.forwardMessageToGuest(proxyNode, accessoryStateResponse);
break;
default:
LOGGER.info("Unprocessed event: {}", event);
break;
}
}
catch (ProtocolException ex) {
LOGGER.warn("Publish message from event failed: {}", event, ex);
}
}
private void processFeatureGetAllRequest(
final HostAdapter distributedHostAdapter, final BidibMessageInterface bidibMessage,
final NodeInterface node) throws ProtocolException {
FeatureGetAllMessage featureGetAllMessage = (FeatureGetAllMessage) bidibMessage;
Integer startStreaming = featureGetAllMessage.getStartStreaming();
ProxyNode proxyNode = ProxyNode.getProxyNode(node);
if (StatusIdentifier.InitialLoadFinished == proxyNode.getNodeLoadStatusIdentifier()) {
// reset the feature
proxyNode.setCurrentFeature(0);
int featureCount = node.getNode().getFeatures().size();
if (startStreaming == null || startStreaming.intValue() == 0) {
BidibMessageInterface featureCountResponse =
responseFactory.createFeatureCountResponse(bidibMessage.getAddr(), 0, featureCount, 0);
distributedHostAdapter.forwardMessageToGuest(proxyNode, featureCountResponse);
}
else {
LOGGER.info("Provide streaming support for features. Current featureCount: {}", featureCount);
BidibMessageInterface featureCountResponse =
responseFactory.createFeatureCountResponse(bidibMessage.getAddr(), 0, featureCount, 1);
distributedHostAdapter.forwardMessageToGuest(proxyNode, featureCountResponse);
// stream features
for (Feature feature : node.getNode().getFeatures()) {
FeatureResponse featureResponse =
new FeatureResponse(bidibMessage.getAddr(), 0, feature.getType(), feature.getValue());
distributedHostAdapter.forwardMessageToGuest(proxyNode, featureResponse);
}
// terminating
FeatureNotAvailableResponse featureResponse =
new FeatureNotAvailableResponse(bidibMessage.getAddr(), 0, 255);
distributedHostAdapter.forwardMessageToGuest(proxyNode, featureResponse);
}
}
else {
LOGGER.warn("The initial load has not finished for node: {}. Set the publish features marker.", proxyNode);
proxyNode.setPublishFeatures(true);
// TODO evaluate the streaming support
}
}
private void processFeatureGetNextRequest(
final HostAdapter distributedHostAdapter, final BidibMessageInterface bidibMessage,
final NodeInterface node) {
int featureCount = node.getNode().getFeatures().size();
ProxyNode proxyNode = ProxyNode.getProxyNode(node);
int currentFeature = proxyNode.getNextFeature();
if (currentFeature >= featureCount) {
try {
FeatureNotAvailableResponse featureResponse =
new FeatureNotAvailableResponse(bidibMessage.getAddr(), 0, 255);
distributedHostAdapter.forwardMessageToGuest(proxyNode, featureResponse);
}
catch (ProtocolException ex) {
LOGGER.warn("Create feature N/A response failed.", ex);
}
}
else {
try {
Feature feature = IterableUtils.get(node.getNode().getFeatures(), currentFeature);
FeatureResponse featureResponse =
new FeatureResponse(bidibMessage.getAddr(), 0, feature.getType(), feature.getValue());
distributedHostAdapter.forwardMessageToGuest(proxyNode, featureResponse);
}
catch (ProtocolException ex) {
LOGGER.warn("Create feature response failed.", ex);
}
catch (Exception ex) {
LOGGER.warn("Create feature response failed.", ex);
}
}
}
private void processFeatureSetRequest(
String connectionId, final HostAdapter distributedHostAdapter,
final BidibMessageInterface bidibMessage, final NodeInterface node) {
FeatureSetMessage featureSetMessage = (FeatureSetMessage) bidibMessage;
LOGGER.info("Write feature to node: {}", featureSetMessage);
ProxyNode proxyNode = ProxyNode.getProxyNode(node);
// write feature to node
final NodeAddress nodeAddress = JsonNodeUtils.prepareNodeAddress(proxyNode);
List features =
Arrays.asList(new Feature(featureSetMessage.getNumber(), featureSetMessage.getValue()));
nodeService.setFeatures(connectionId, nodeAddress, features);
}
private void processNodetabGetAllRequest(
final ProxyBidibConnection bidibProxyConnection,
final HostAdapter distributedHostAdapter, final BidibMessageInterface bidibMessage,
final NodeInterface node) throws ProtocolException {
ProxyNode proxyNode = ProxyNode.getProxyNode(node);
int subNodeCount = 1;
if (proxyNode instanceof ProxyInterfaceNode) {
ProxyInterfaceNode proxyInterfaceNode = (ProxyInterfaceNode) proxyNode;
proxyInterfaceNode.resetSubNodeIndex();
List subNodes =
Optional
.ofNullable(bidibProxyConnection.getNodeProvider().findSubNodes(proxyNode))
.orElseThrow(() -> new ProtocolException(
"No subnodes available with address: " + NodeUtils.formatAddress(proxyNode.getAddr())));
subNodeCount = subNodes.size() + 1;
}
LOGGER.info("Return subNodeCount: {}", subNodeCount);
NodeTabCountResponse nodeTabCountResponse =
new NodeTabCountResponse(bidibMessage.getAddr(), 0, ByteUtils.getLowByte(subNodeCount));
distributedHostAdapter.forwardMessageToGuest(proxyNode, nodeTabCountResponse);
}
private void processNodetabGetNextRequest(
final ProxyBidibConnection bidibProxyConnection,
final HostAdapter distributedHostAdapter, final BidibMessageInterface bidibMessage,
final NodeInterface node) throws ProtocolException {
ProxyNode proxyNode = ProxyNode.getProxyNode(node);
NodeTabResponse nodeTabResponse = null;
if (proxyNode instanceof ProxyInterfaceNode) {
ProxyInterfaceNode proxyInterfaceNode = (ProxyInterfaceNode) proxyNode;
int subNodeIndex = proxyInterfaceNode.getNextSubNodeIndex();
List subNodes =
Optional
.ofNullable(bidibProxyConnection.getNodeProvider().findSubNodes(proxyNode))
.orElseThrow(() -> new ProtocolException(
"No subnodes available with address: " + NodeUtils.formatAddress(proxyNode.getAddr())));
// add the interface node itself
subNodes.add(0, proxyNode);
NodeInterface subNode = subNodes.get(subNodeIndex);
byte[] address = subNode.getAddr();
int localAddress = address[0];
LOGGER
.info("Return subNode: {}, address: {}, localAddress: {}", subNode, ByteUtils.bytesToHex(address),
localAddress);
nodeTabResponse =
new NodeTabResponse(bidibMessage.getAddr(), 0, proxyNode.getNodeTabVersion(), localAddress,
subNode.getUniqueId());
}
else {
nodeTabResponse =
new NodeTabResponse(bidibMessage.getAddr(), 0, proxyNode.getNodeTabVersion(),
proxyNode.getLocalAddress(), node.getUniqueId());
}
distributedHostAdapter.forwardMessageToGuest(proxyNode, nodeTabResponse);
}
private void processStringGetRequest(
final HostAdapter distributedHostAdapter, final BidibMessageInterface bidibMessage,
final NodeInterface node) throws ProtocolException {
StringGetMessage stringGetMessage = (StringGetMessage) bidibMessage;
ProxyNode proxyNode = ProxyNode.getProxyNode(node);
String stringData = null;
switch (stringGetMessage.getNamespace()) {
case StringData.NAMESPACE_NODE:
stringData = proxyNode.getNode().getStoredString(stringGetMessage.getStringId());
break;
case StringData.NAMESPACE_DEBUG:
break;
default:
break;
}
if (stringData != null) {
StringResponse stringResponse =
new StringResponse(bidibMessage.getAddr(), 0, ByteUtils.getLowByte(stringGetMessage.getNamespace()),
ByteUtils.getLowByte(stringGetMessage.getStringId()), stringData);
distributedHostAdapter.forwardMessageToGuest(proxyNode, stringResponse);
}
}
private void processLcPortQueryAllRequest(
String connectionId, final HostAdapter distributedHostAdapter,
final BidibMessageInterface bidibMessage, final NodeInterface node) throws ProtocolException {
final LcPortQueryAllMessage lcPortQueryAllMessage = (LcPortQueryAllMessage) bidibMessage;
final ProxyNode proxyNode = ProxyNode.getProxyNode(node);
final PortModelEnum portModel = PortModelEnum.getPortModel(proxyNode.getNode());
int portRangeFrom = lcPortQueryAllMessage.getPortRangeFrom(portModel);
int portRangeTo = lcPortQueryAllMessage.getPortRangeTo(portModel);
int portTypeMask = lcPortQueryAllMessage.getPortTypeMask();
LOGGER
.info("Query all port states, portRangeFrom: {}, portRangeTo: {}, portModel: {}, portTypeMask: {}",
portRangeFrom, portRangeTo, portModel, portTypeMask);
if (proxyNode.isFlatPortModel()) {
if (!proxyNode.isGenericPortsSet()) {
queryAndApplyGenericPortsToNode(connectionId, proxyNode);
}
List genericPorts = new LinkedList<>();
genericPorts.addAll(proxyNode.getGenericPorts());
for (GenericPort genericPort : genericPorts) {
LcOutputType currentPortType = genericPort.getCurrentPortType();
LOGGER.info("Current currentPortType: {}", currentPortType);
if (PortConfigUtils.isSupportsPortType(currentPortType, portTypeMask)
&& (genericPort.getPortNumber() >= portRangeFrom && genericPort.getPortNumber() < portRangeTo)) {
try {
byte portValue = 0;
switch (genericPort.getCurrentPortType()) {
case BACKLIGHTPORT:
case SERVOPORT:
Integer portVal = genericPort.getPortValue();
if (portVal != null) {
portValue = ByteUtils.getLowByte(portVal.intValue());
}
break;
default:
portValue = genericPort.getPortStatus();
break;
}
// byte portStatus = genericPort.getPortStatus();
publishPortState(proxyNode, distributedHostAdapter, bidibMessage, currentPortType,
genericPort.getPortNumber(), portValue, portModel);
}
catch (Exception ex) {
LOGGER.warn("Publish port state failed for port: {}", genericPort, ex);
}
}
else {
LOGGER.info("Skip current port that is out of port range or wrong port type: {}", genericPort);
}
}
}
else {
List> nodePorts = node.getPorts();
if (nodePorts.isEmpty()) {
queryAndApplyTypedPortsToNode(connectionId, proxyNode);
}
if (PortConfigUtils.isSupportsInputPort(portTypeMask)) {
List inputPorts = node.getInputPorts();
if (CollectionUtils.isNotEmpty(inputPorts)) {
for (InputPort inputPort : inputPorts) {
if (inputPort.getId() >= portRangeFrom && inputPort.getId() < portRangeTo) {
try {
InputPortStatus inputPortStatus = inputPort.getStatus();
byte portStatus = inputPortStatus.getType().getType();
publishPortState(proxyNode, distributedHostAdapter, bidibMessage,
LcOutputType.INPUTPORT, inputPort.getId(), portStatus, portModel);
}
catch (Exception ex) {
LOGGER.warn("Publish port state failed for port: {}", inputPort, ex);
}
}
else {
LOGGER.info("Skip input port that is out of port range: {}", inputPort);
}
}
}
}
if (PortConfigUtils.isSupportsLightPort(portTypeMask)) {
List lightPorts = node.getLightPorts();
if (CollectionUtils.isNotEmpty(lightPorts)) {
for (LightPort lightPort : lightPorts) {
if (lightPort.getId() >= portRangeFrom && lightPort.getId() < portRangeTo) {
try {
LightPortStatus lightPortStatus = lightPort.getStatus();
byte portStatus = lightPortStatus.getType().getType();
publishPortState(proxyNode, distributedHostAdapter, bidibMessage,
LcOutputType.LIGHTPORT, lightPort.getId(), portStatus, portModel);
}
catch (Exception ex) {
LOGGER.warn("Publish port state failed for port: {}", lightPort, ex);
}
}
else {
LOGGER.info("Skip light port that is out of port range: {}", lightPort);
}
}
}
}
if (PortConfigUtils.isSupportsSwitchPort(portTypeMask)) {
List switchPorts = node.getSwitchPorts();
if (CollectionUtils.isNotEmpty(switchPorts)) {
for (SwitchPort switchPort : switchPorts) {
if (switchPort.getId() >= portRangeFrom && switchPort.getId() < portRangeTo) {
try {
SwitchPortStatus switchPortStatus = switchPort.getStatus();
byte portStatus = switchPortStatus.getType().getType();
publishPortState(proxyNode, distributedHostAdapter, bidibMessage,
LcOutputType.SWITCHPORT, switchPort.getId(), portStatus, portModel);
}
catch (Exception ex) {
LOGGER.warn("Publish port state failed for port: {}", switchPort, ex);
}
}
else {
LOGGER.info("Skip switch port that is out of port range: {}", switchPort);
}
}
}
}
if (PortConfigUtils.isSupportsSwitchPairPort(portTypeMask)) {
List switchPairPorts = node.getSwitchPairPorts();
if (CollectionUtils.isNotEmpty(switchPairPorts)) {
for (SwitchPairPort switchPairPort : switchPairPorts) {
if (switchPairPort.getId() >= portRangeFrom && switchPairPort.getId() < portRangeTo) {
try {
SwitchPortStatus switchPortStatus = switchPairPort.getStatus();
byte portStatus = switchPortStatus.getType().getType();
publishPortState(proxyNode, distributedHostAdapter, bidibMessage,
LcOutputType.SWITCHPAIRPORT, switchPairPort.getId(), portStatus, portModel);
}
catch (Exception ex) {
LOGGER.warn("Publish port state failed for port: {}", switchPairPort, ex);
}
}
else {
LOGGER.info("Skip switchPair port that is out of port range: {}", switchPairPort);
}
}
}
}
if (PortConfigUtils.isSupportsServoPort(portTypeMask)) {
List servoPorts = node.getServoPorts();
if (CollectionUtils.isNotEmpty(servoPorts)) {
for (ServoPort servoPort : servoPorts) {
if (servoPort.getId() >= portRangeFrom && servoPort.getId() < portRangeTo) {
try {
byte portStatus = ByteUtils.getLowByte(servoPort.getValue());
// ServoPortStatus servoPortStatus = servoPort.getStatus();
// byte portStatus = servoPortStatus.getType().getType();
publishPortState(proxyNode, distributedHostAdapter, bidibMessage,
LcOutputType.SERVOPORT, servoPort.getId(), portStatus, portModel);
}
catch (Exception ex) {
LOGGER.warn("Publish port state failed for port: {}", servoPort, ex);
}
}
else {
LOGGER.info("Skip servo port that is out of port range: {}", servoPort);
}
}
}
}
}
// publish end of status
publishEndOfPortList(proxyNode, distributedHostAdapter, bidibMessage);
}
private void publishEndOfPortList(
final ProxyNode proxyNode, final HostAdapter distributedHostAdapter,
final BidibMessageInterface bidibMessage) throws ProtocolException {
final BidibPort bidibPort = BidibPort.prepareBidibPortNa();
final BidibMessage lcNaResponse = responseFactory.createLcNaResponse(bidibMessage.getAddr(), 0, bidibPort);
LOGGER.info("Prepared LcNaResponse: {}", lcNaResponse);
distributedHostAdapter.forwardMessageToGuest(proxyNode, lcNaResponse);
}
private void publishPortState(
final ProxyNode proxyNode, final HostAdapter distributedHostAdapter,
final BidibMessageInterface bidibMessage, LcOutputType outputType, int outputNumber, byte portStatus,
final PortModelEnum portModel) throws ProtocolException {
final BidibPort bidibPort = prepareBidibPort(portModel, outputType, outputNumber);
final BidibMessage lcStatResponse =
responseFactory.createLcStatResponse(bidibMessage.getAddr(), 0, bidibPort, portStatus);
LOGGER.info("Prepared LcStatResponse: {}", lcStatResponse);
distributedHostAdapter.forwardMessageToGuest(proxyNode, lcStatResponse);
}
private void processLcConfigXGetAllRequest(
final String connectionId, final HostAdapter distributedHostAdapter,
final BidibMessageInterface bidibMessage, final NodeInterface node) throws ProtocolException {
final LcConfigXGetAllMessage lcConfigXGetAllMessage = (LcConfigXGetAllMessage) bidibMessage;
final ProxyNode proxyNode = ProxyNode.getProxyNode(node);
final PortModelEnum portModel = PortModelEnum.getPortModel(proxyNode.getNode());
LOGGER.info("processLcConfigXGetAllRequest, current portModel: {}", portModel);
LcOutputType outputType = lcConfigXGetAllMessage.getPortTypeFrom(portModel);
int rangeFrom = lcConfigXGetAllMessage.getPortRangeFrom(portModel);
int rangeTo = lcConfigXGetAllMessage.getPortRangeTo(portModel);
LOGGER.info("Get the configX for type: {}, rangeFrom: {}, rangeTo: {}", outputType, rangeFrom, rangeTo);
if (portModel == PortModelEnum.type) {
// TODO fix the missing types
if (outputType == null) {
LOGGER.warn("Set the requested LcOutputType to INPUTPORT because none is requested.");
LcOutputType[] outputTypes =
new LcOutputType[] { LcOutputType.BACKLIGHTPORT, LcOutputType.INPUTPORT, LcOutputType.LIGHTPORT,
LcOutputType.MOTORPORT, LcOutputType.SERVOPORT, LcOutputType.SOUNDPORT, LcOutputType.SWITCHPORT,
LcOutputType.SWITCHPAIRPORT };
for (LcOutputType currentOutputType : outputTypes) {
publishLcConfigXResponse(connectionId, distributedHostAdapter, bidibMessage.getAddr(), proxyNode,
currentOutputType, portModel);
}
}
else {
publishLcConfigXResponse(connectionId, distributedHostAdapter, bidibMessage.getAddr(), proxyNode,
outputType, portModel);
}
}
else {
// handle flat port model
outputType = LcOutputType.SWITCHPORT;
if (!proxyNode.isGenericPortsSet()) {
queryAndApplyGenericPortsToNode(connectionId, proxyNode);
}
final List genericPorts = proxyNode.getGenericPorts();
try {
for (GenericPort port : genericPorts) {
int portNumber = port.getPortNumber();
LOGGER.info("Prepare lcConfigXResponse for port number: {}, port: {}", portNumber, port);
BidibPort bidibPort = prepareBidibPort(portModel, outputType, portNumber);
LcConfigX lcConfigX = new LcConfigX(bidibPort, port.getPortConfigX());
LcConfigXResponse lcConfigXResponse =
new LcConfigXResponse(bidibMessage.getAddr(), 0,
LcConfigX.getCodedPortConfig(messageLogger, lcConfigX, portModel));
LOGGER.info("Publish lcConfigXResponse: {}", lcConfigXResponse);
distributedHostAdapter.forwardMessageToGuest(proxyNode, lcConfigXResponse);
}
}
catch (ProtocolException ex) {
LOGGER.warn("Create LcConfigXResponse response failed.", ex);
}
}
}
private void publishLcConfigXResponse(
final String connectionId, final HostAdapter distributedHostAdapter, byte[] nodeAddr,
final ProxyNode proxyNode, final LcOutputType outputType, final PortModelEnum portModel)
throws ProtocolException {
final List> ports = new LinkedList<>();
// TODO implement
switch (outputType) {
case BACKLIGHTPORT:
ports.addAll(proxyNode.getBacklightPorts());
if (ports.isEmpty()) {
queryAndApplyTypedPortsToNode(connectionId, proxyNode);
ports.addAll(proxyNode.getBacklightPorts());
}
break;
case INPUTPORT:
ports.addAll(proxyNode.getInputPorts());
if (ports.isEmpty()) {
queryAndApplyTypedPortsToNode(connectionId, proxyNode);
ports.addAll(proxyNode.getInputPorts());
}
break;
case LIGHTPORT:
ports.addAll(proxyNode.getLightPorts());
if (ports.isEmpty()) {
queryAndApplyTypedPortsToNode(connectionId, proxyNode);
ports.addAll(proxyNode.getLightPorts());
}
break;
case SERVOPORT:
ports.addAll(proxyNode.getServoPorts());
if (ports.isEmpty()) {
queryAndApplyTypedPortsToNode(connectionId, proxyNode);
ports.addAll(proxyNode.getServoPorts());
}
break;
case SWITCHPORT:
ports.addAll(proxyNode.getSwitchPorts());
if (ports.isEmpty()) {
queryAndApplyTypedPortsToNode(connectionId, proxyNode);
ports.addAll(proxyNode.getSwitchPorts());
}
break;
case SWITCHPAIRPORT:
ports.addAll(proxyNode.getSwitchPairPorts());
if (ports.isEmpty()) {
queryAndApplyTypedPortsToNode(connectionId, proxyNode);
ports.addAll(proxyNode.getSwitchPairPorts());
}
break;
default:
break;
}
LOGGER.info("Process the ports, outputType: {}, ports: {}", outputType, ports);
for (Port> port : ports) {
Map> portConfigX = port.getPortConfigX();
BidibPort bidibPort = prepareBidibPort(portModel, outputType, port.getId());
LcConfigX lcConfigX = new LcConfigX(bidibPort, portConfigX);
final BidibMessage lcConfigXResponse =
responseFactory.createLcConfigXResponse(nodeAddr, 0, lcConfigX, portModel);
LOGGER.info("Publish lcConfigXResponse: {}", lcConfigXResponse);
distributedHostAdapter.forwardMessageToGuest(proxyNode, lcConfigXResponse);
}
}
private void processLcConfigXSetRequest(
String connectionId, final HostAdapter distributedHostAdapter,
final BidibMessageInterface bidibMessage, final NodeInterface node) throws ProtocolException {
final LcConfigXSetMessage lcConfigXSetMessage = (LcConfigXSetMessage) bidibMessage;
final ProxyNode proxyNode = ProxyNode.getProxyNode(node);
final PortModelEnum portModel = PortModelEnum.getPortModel(proxyNode.getNode());
LOGGER.info("processLcConfigXSetRequest, current portModel: {}, proxyNode: {}", portModel, proxyNode);
final LcConfigX lcConfigX = lcConfigXSetMessage.getLcConfigX(this.messageLogger);
final Map> values = lcConfigX.getPortConfig();
final LcOutputType portType = lcConfigX.getOutputType(portModel);
int portNumber = lcConfigX.getOutputNumber(portModel);
final NodeAddress nodeAddress = JsonNodeUtils.prepareNodeAddress(proxyNode);
switchingNodeService.setPortConfig(connectionId, nodeAddress, portType, portNumber, null, values);
}
private void processLcOutputRequest(
String connectionId, final HostAdapter distributedHostAdapter,
final BidibMessageInterface bidibMessage, final NodeInterface node) throws ProtocolException {
final LcOutputMessage lcOutputMessage = (LcOutputMessage) bidibMessage;
final ProxyNode proxyNode = ProxyNode.getProxyNode(node);
final PortModelEnum portModel = PortModelEnum.getPortModel(proxyNode.getNode());
LOGGER.info("processLcOutputRequest, current portModel: {}, proxyNode: {}", portModel, proxyNode);
final LcOutputType portType = lcOutputMessage.getOutputType(portModel);
int portNumber = lcOutputMessage.getOutputNumber(portModel);
byte outputStatus = lcOutputMessage.getOutputStatus();
final NodeAddress nodeAddress = JsonNodeUtils.prepareNodeAddress(proxyNode);
Port> port = getPortInstance(proxyNode, portModel, portType, portNumber, outputStatus);
switchingNodeService.setPortStatus(connectionId, nodeAddress, port);
}
private Port> getPortInstance(
final ProxyNode proxyNode, final PortModelEnum portModel, LcOutputType portType, int portNumber,
byte outputStatus) {
if (proxyNode.isFlatPortModel()) {
// get the current port type
GenericPort genericPort =
PortListUtils.findGenericPortByPortNumber(proxyNode.getGenericPorts(), portNumber);
portType = genericPort.getCurrentPortType();
LOGGER.info("Changed the port type from the generic port to: {}", portType);
}
Port> port = null;
switch (portType) {
case BACKLIGHTPORT:
BacklightPort backlightPort = new BacklightPort();
backlightPort.setId(portNumber);
backlightPort.setValue(ByteUtils.getInt(outputStatus));
port = backlightPort;
break;
case INPUTPORT:
InputPort inputPort = new InputPort();
inputPort.setId(portNumber);
inputPort.setStatus(InputPortStatus.valueOf(InputPortEnum.valueOf(outputStatus)));
port = inputPort;
break;
case LIGHTPORT:
LightPort lightPort = new LightPort();
lightPort.setId(portNumber);
lightPort.setStatus(LightPortStatus.valueOf(LightPortEnum.valueOf(outputStatus)));
port = lightPort;
break;
case SERVOPORT:
ServoPort servoPort = new ServoPort();
servoPort.setId(portNumber);
servoPort.setValue(ByteUtils.getInt(outputStatus));
port = servoPort;
break;
case SWITCHPORT:
SwitchPort switchPort = new SwitchPort();
switchPort.setId(portNumber);
switchPort.setStatus(SwitchPortStatus.valueOf(SwitchPortEnum.valueOf(outputStatus)));
port = switchPort;
break;
case SWITCHPAIRPORT:
SwitchPairPort switchPairPort = new SwitchPairPort();
switchPairPort.setId(portNumber);
switchPairPort.setStatus(SwitchPortStatus.valueOf(SwitchPortEnum.valueOf(outputStatus)));
port = switchPairPort;
break;
default:
LOGGER.warn("Unsupported port type detected: {}, portNumber: {}", portType, portNumber);
break;
}
return port;
}
private void queryAndApplyGenericPortsToNode(String connectionId, final ProxyNode proxyNode) {
final NodeAddress nodeAddress = JsonNodeUtils.prepareNodeAddress(proxyNode);
List sourceGenericPorts = switchingNodeService.queryAllGenericPorts(connectionId, nodeAddress);
LOGGER.info("queryAndApplyGenericPortsToNode, genericPorts: {}", sourceGenericPorts);
List genericPorts = new LinkedList<>();
for (GenericPort sgp : sourceGenericPorts) {
// @formatter:off
GenericPort genericPort =
GenericPort
.builder().withPortNumber(sgp.getPortNumber())
.withConfigStatus(sgp.getConfigStatus())
.withIsInactive(sgp.isInactive())
.withKnownPortConfigKeys(sgp.getKnownPortConfigKeys())
.withPairedPortMaster(sgp.getPairedPortMaster())
.withPortConfig(sgp.getPortConfigX())
.withPortConfigErrorCode(sgp.getPortConfigErrorCode())
.withPortStatus(sgp.getPortStatus())
.withPortValue(sgp.getPortValue())
.build();
// @formatter:on
genericPorts.add(genericPort);
}
proxyNode.setGenericPorts(genericPorts);
}
private void queryAndApplyTypedPortsToNode(String connectionId, final ProxyNode proxyNode) {
final NodeAddress nodeAddress = JsonNodeUtils.prepareNodeAddress(proxyNode);
if (proxyNode.isFlatPortModel()) {
List ports = switchingNodeService.queryAllGenericPorts(connectionId, nodeAddress);
proxyNode.setGenericPorts(ports);
}
else {
List> ports = switchingNodeService.queryAllPorts(connectionId, nodeAddress);
LOGGER.info("queryAndApplyPortsToNode, ports: {}", ports);
List sourceInputPorts =
ports
.stream().filter(p -> p.getPortType() == LcOutputType.INPUTPORT).map(p -> (InputPort) p)
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(sourceInputPorts)) {
List inputPorts = new LinkedList<>();
for (InputPort ip : sourceInputPorts) {
InputPort inputPort = InputPort.clonePort(ip);
inputPorts.add(inputPort);
}
proxyNode.setInputPorts(inputPorts);
}
List sourceServoPorts =
ports
.stream().filter(p -> p.getPortType() == LcOutputType.SERVOPORT).map(p -> (ServoPort) p)
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(sourceServoPorts)) {
List servoPorts = new LinkedList<>();
for (ServoPort sp : sourceServoPorts) {
ServoPort servoPort = ServoPort.clonePort(sp);
servoPorts.add(servoPort);
}
proxyNode.setServoPorts(servoPorts);
}
List sourceBacklightPorts =
ports
.stream().filter(p -> p.getPortType() == LcOutputType.BACKLIGHTPORT).map(p -> (BacklightPort) p)
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(sourceBacklightPorts)) {
List backlightPorts = new LinkedList<>();
for (BacklightPort bp : sourceBacklightPorts) {
BacklightPort backlightPort = BacklightPort.clonePort(bp);
backlightPorts.add(backlightPort);
}
proxyNode.setBacklightPorts(backlightPorts);
}
List sourceLightPorts =
ports
.stream().filter(p -> p.getPortType() == LcOutputType.LIGHTPORT).map(p -> (LightPort) p)
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(sourceLightPorts)) {
List lightPorts = new LinkedList<>();
for (LightPort lp : sourceLightPorts) {
LightPort lightPort = LightPort.clonePort(lp);
lightPorts.add(lightPort);
}
proxyNode.setLightPorts(lightPorts);
}
List sourceSwitchPorts =
ports
.stream().filter(p -> p.getPortType() == LcOutputType.SWITCHPORT).map(p -> (SwitchPort) p)
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(sourceSwitchPorts)) {
List switchPorts = new LinkedList<>();
for (SwitchPort sp : sourceSwitchPorts) {
SwitchPort switchPort = SwitchPort.clonePort(sp);
switchPorts.add(switchPort);
}
proxyNode.setSwitchPorts(switchPorts);
}
List sourceSwitchPairPorts =
ports
.stream().filter(p -> p.getPortType() == LcOutputType.SWITCHPAIRPORT).map(p -> (SwitchPairPort) p)
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(sourceSwitchPairPorts)) {
List switchPairPorts = new LinkedList<>();
for (SwitchPairPort sp : sourceSwitchPairPorts) {
SwitchPairPort switchPairPort = SwitchPairPort.clonePort(sp);
switchPairPorts.add(switchPairPort);
}
proxyNode.setSwitchPairPorts(switchPairPorts);
}
}
}
private BidibPort prepareBidibPort(PortModelEnum portModelEnum, LcOutputType lcOutputType, int port) {
BidibPort bidibPort = null;
if (portModelEnum == PortModelEnum.type) {
bidibPort = new BidibPort(new byte[] { lcOutputType.getType(), ByteUtils.getLowByte(port) });
}
else {
bidibPort = new BidibPort(new byte[] { ByteUtils.getLowByte(port), ByteUtils.getHighByte(port) });
}
return bidibPort;
}
private void processLcMacroGetRequest(
String connectionId, final HostAdapter distributedHostAdapter,
final BidibMessageInterface bidibMessage, final NodeInterface node) throws ProtocolException {
final LcMacroGetMessage lcMacroGetMessage = (LcMacroGetMessage) bidibMessage;
final ProxyNode proxyNode = ProxyNode.getProxyNode(node);
int macroNumber = lcMacroGetMessage.getMacroNumber();
int stepNumber = lcMacroGetMessage.getStep();
LOGGER.info("Get the macro for macro id: {}, step: {}", macroNumber, stepNumber);
if (CollectionUtils.isEmpty(node.getMacros())) {
queryAndApplyMacrosToNode(connectionId, proxyNode);
}
BidibMessageInterface lcMacroResponse = null;
final Macro macro =
proxyNode.getMacros().stream().filter(m -> m.getId() == macroNumber).findFirst().orElse(null);
if (macro != null) {
Function> function = macro.getFunction(stepNumber);
LcMacro lcMacro = null;
// TODO prepare the macro for the transfer
LOGGER.warn("Loading the macro is not implemented yet!");
// function.getAction();
// int delay = 0;
if (function instanceof SystemFunction) {
SystemFunction systemFunction = (SystemFunction) function;
// int delay = delay = 0xFF;
// TODO
// lcMacro = new LcMacro(macroNumber, stepNumber, delay, outputType, portNumber, value);
}
// function.
// LcMacro lcMacro = new LcMacro();
lcMacro = new LcMacro(macroNumber, stepNumber, 0xFF, BidibLibrary.BIDIB_MSYS_END_OF_MACRO, 0x00, 0x00);
lcMacroResponse =
responseFactory.createLcMacroResponse(bidibMessage.getAddr(), 0, macroNumber, stepNumber, lcMacro);
}
LOGGER.info("Publish lcMacroResponse: {}", lcMacroResponse);
distributedHostAdapter.forwardMessageToGuest(proxyNode, lcMacroResponse);
}
private void processLcMacroParaGetRequest(
String connectionId, final HostAdapter distributedHostAdapter,
final BidibMessageInterface bidibMessage, final NodeInterface node) throws ProtocolException {
final LcMacroParaGetMessage lcMacroParaGetMessage = (LcMacroParaGetMessage) bidibMessage;
final ProxyNode proxyNode = ProxyNode.getProxyNode(node);
int macroNumber = lcMacroParaGetMessage.getMacroNumber();
int parameterIndex = lcMacroParaGetMessage.getParameterIndex();
LOGGER.info("Get the macro parameter for macro id: {}, paramIndex: {}", macroNumber, parameterIndex);
if (CollectionUtils.isEmpty(node.getMacros())) {
queryAndApplyMacrosToNode(connectionId, proxyNode);
}
// LOGGER.warn("processLcMacroParaGetRequest: Not implemented!");
BidibMessageInterface lcMacroParaResponse = null;
byte[] macroParam =
new byte[] { ByteUtils.getLowByte(0xFF), ByteUtils.getLowByte(0xFF), ByteUtils.getLowByte(0xFF),
ByteUtils.getLowByte(0xFF) };
final Macro macro =
proxyNode.getMacros().stream().filter(m -> m.getId() == macroNumber).findFirst().orElse(null);
if (macro != null) {
switch (parameterIndex) {
case BidibLibrary.BIDIB_MACRO_PARA_REPEAT:
int cycles = macro.getCycles();
macroParam[0] = ByteUtils.getLowByte(cycles);
break;
case BidibLibrary.BIDIB_MACRO_PARA_SLOWDOWN:
int speed = macro.getSpeed();
macroParam[0] = ByteUtils.getLowByte(speed);
break;
case BidibLibrary.BIDIB_MACRO_PARA_START_CLK:
Collection startConditions = macro.getStartConditions();
if (CollectionUtils.isNotEmpty(startConditions)) {
TimeStartCondition timeStartCondition =
startConditions
.stream().filter(sc -> sc instanceof TimeStartCondition)
.map(sc -> (TimeStartCondition) sc).findFirst().orElse(null);
if (timeStartCondition != null) {
// TODO
MacroRepeatDay repeatDay = timeStartCondition.getRepeatDay();
MacroRepeatTime repeatTime = timeStartCondition.getRepeatTime();
final Calendar cal = timeStartCondition.getTime();
int minute = cal.get(Calendar.MINUTE);
int hour = cal.get(Calendar.HOUR_OF_DAY);
int day = 0;
if (repeatTime != null) {
switch (repeatTime) {
case WORKING_HOURLY:
hour = 25;
break;
case HOURLY:
hour = 24;
break;
case MINUTELY:
minute = 60;
break;
case HALF_HOURLY:
minute = 61;
break;
case QUARTER_HOURLY:
minute = 62;
break;
default:
break;
}
}
if (repeatDay != null) {
day = repeatDay.getValue();
}
macroParam[0] = ByteUtils.getLowByte(minute);
macroParam[1] = ByteUtils.getLowByte(hour);
macroParam[2] = ByteUtils.getLowByte(day);
}
}
break;
default:
break;
}
lcMacroParaResponse =
responseFactory
.createLcMacroParaResponse(bidibMessage.getAddr(), 0, macroNumber, parameterIndex, macroParam);
}
else {
LOGGER.warn("No macro available, macroNumber: {}", macroNumber);
lcMacroParaResponse =
responseFactory
.createLcMacroParaResponse(bidibMessage.getAddr(), 0, macroNumber, parameterIndex, macroParam);
}
LOGGER.info("Publish lcMacroParaResponse: {}", lcMacroParaResponse);
distributedHostAdapter.forwardMessageToGuest(proxyNode, lcMacroParaResponse);
}
private void queryAndApplyMacrosToNode(String connectionId, final ProxyNode proxyNode) {
final NodeAddress nodeAddress = JsonNodeUtils.prepareNodeAddress(proxyNode);
List macros = switchingNodeService.queryAllMacros(connectionId, nodeAddress);
LOGGER.info("queryAndApplyMacrosToNode, macros: {}", macros);
// TODO clone the data from the macros
proxyNode.setMacros(macros);
}
private void processAccessoryGetRequest(
String connectionId, final HostAdapter distributedHostAdapter,
final BidibMessageInterface bidibMessage, final NodeInterface node) throws ProtocolException {
final AccessoryGetMessage accessoryGetMessage = (AccessoryGetMessage) bidibMessage;
final ProxyNode proxyNode = ProxyNode.getProxyNode(node);
int accessoryNumber = accessoryGetMessage.getAccessoryNumber();
LOGGER.info("Get the accessory for accessory id: {}", accessoryNumber);
if (CollectionUtils.isEmpty(node.getAccessories())) {
queryAndApplyAccessoriesToNode(connectionId, proxyNode);
}
BidibMessageInterface accessoryResponse = null;
final Accessory accessory =
proxyNode.getAccessories().stream().filter(acc -> acc.getId() == accessoryNumber).findFirst().orElse(null);
if (accessory != null && accessory.getAccessoryState() != null) {
final AccessoryState accessoryState = accessory.getAccessoryState();
Integer aspect = accessoryState.getActiveAspect();
byte[] value =
new byte[] { accessoryState.getTotal(), accessoryState.getExecute(),
ByteUtils.getLowByte(accessoryState.getWait()) };
accessoryResponse =
responseFactory.createAccessoryStateResponse(bidibMessage.getAddr(), 0, accessoryNumber, aspect, value);
}
if (accessoryResponse != null) {
LOGGER.info("Publish accessoryResponse: {}", accessoryResponse);
distributedHostAdapter.forwardMessageToGuest(proxyNode, accessoryResponse);
}
else {
LOGGER.warn("No accessory available with accessory id: {}", accessoryNumber);
}
}
private void processAccessoryParaGetRequest(
String connectionId, final HostAdapter distributedHostAdapter,
final BidibMessageInterface bidibMessage, final NodeInterface node) throws ProtocolException {
final AccessoryParaGetMessage accessoryParaGetMessage = (AccessoryParaGetMessage) bidibMessage;
final ProxyNode proxyNode = ProxyNode.getProxyNode(node);
int accessoryNumber = accessoryParaGetMessage.getAccessoryNumber();
int paramNumber = accessoryParaGetMessage.getParaNumber();
LOGGER.info("Get the accessory parameter for accessory id: {}, paramNumber: {}", accessoryNumber, paramNumber);
if (CollectionUtils.isEmpty(node.getAccessories())) {
queryAndApplyAccessoriesToNode(connectionId, proxyNode);
}
else {
LOGGER.info("Use existing accessories: {}", node.getAccessories());
}
BidibMessageInterface accessoryParaResponse = null;
final Accessory accessory =
proxyNode.getAccessories().stream().filter(acc -> acc.getId() == accessoryNumber).findFirst().orElse(null);
if (accessory != null) {
// prepare the response
int[] accessoryParam = accessory.getParam(paramNumber);
if (accessoryParam != null && accessoryParam.length > 0) {
LOGGER
.info("Prepare AccessoryParaResponse for accessoryNumber: {}, paramNumber: {}, accessoryParam: {}",
accessoryNumber, paramNumber, accessoryParam);
accessoryParaResponse =
responseFactory
.createAccessoryParaResponse(bidibMessage.getAddr(), 0, accessoryNumber, paramNumber,
accessoryParam);
}
else {
LOGGER
.warn("No accessory params available for accessoryNumber: {}, paramNumber: {}", accessoryNumber,
paramNumber);
}
}
else {
LOGGER.warn("No accessory available for accessoryNumber: {}", accessoryNumber);
}
if (accessoryParaResponse == null) {
accessoryParaResponse =
responseFactory
.createAccessoryParaResponse(bidibMessage.getAddr(), 0, accessoryNumber,
BidibLibrary.BIDIB_ACCESSORY_PARA_NOTEXIST, new int[] { paramNumber });
}
LOGGER.info("Publish accessoryParaResponse: {}", accessoryParaResponse);
distributedHostAdapter.forwardMessageToGuest(proxyNode, accessoryParaResponse);
}
private void queryAndApplyAccessoriesToNode(String connectionId, final ProxyNode proxyNode) {
final NodeAddress nodeAddress = JsonNodeUtils.prepareNodeAddress(proxyNode);
List accessories = switchingNodeService.queryAllAccessories(connectionId, nodeAddress);
LOGGER.info("queryAndApplyAccessoriesToNode, accessories: {}", accessories);
// TODO clone the data from the accessories
proxyNode.setAccessories(accessories);
}
private void processCommandStationSetStateRequest(
String connectionId, final HostAdapter distributedHostAdapter,
final BidibMessageInterface bidibMessage, final NodeInterface node) throws ProtocolException {
final CommandStationSetStateMessage commandStationSetStateMessage =
(CommandStationSetStateMessage) bidibMessage;
final ProxyNode proxyNode = ProxyNode.getProxyNode(node);
CommandStationState state = commandStationSetStateMessage.getState();
LOGGER.info("The requested command station state is: {}", state);
final NodeAddress nodeAddress = JsonNodeUtils.prepareNodeAddress(proxyNode);
switch (state) {
case OFF:
case STOP:
case SOFTSTOP:
case GO:
case GO_IGN_WD:
case PROG:
serviceWorker.schedule(() -> {
LOGGER.info("Set the new command station state: {}", state);
commandStationService
.setCommandStationState(connectionId, nodeAddress, CommandStationStatus.valueOf(state));
}, 5, TimeUnit.MILLISECONDS);
break;
case QUERY:
serviceWorker.schedule(() -> {
LOGGER.warn("Query command station state requested");
commandStationService.queryCommandStationState(connectionId, nodeAddress);
}, 5, TimeUnit.MILLISECONDS);
break;
default:
LOGGER.warn("Unprocessed command station state: {}", state);
break;
}
}
private void processBoosterQueryRequest(
String connectionId, final HostAdapter distributedHostAdapter,
final BidibMessageInterface bidibMessage, final NodeInterface node) throws ProtocolException {
LOGGER.info("Query the booster state.");
ProxyNode proxyNode = ProxyNode.getProxyNode(node);
final NodeAddress nodeAddress = JsonNodeUtils.prepareNodeAddress(proxyNode);
serviceWorker.schedule(() -> {
LOGGER.info("Query the new booster state");
boosterService.queryBoosterState(connectionId, nodeAddress);
}, 5, TimeUnit.MILLISECONDS);
}
private void processBoosterStateRequest(
String connectionId, final HostAdapter distributedHostAdapter,
final BidibMessageInterface bidibMessage, final NodeInterface node) throws ProtocolException {
BoosterStatus boosterState = null;
switch (ByteUtils.getInt(bidibMessage.getType())) {
case BidibLibrary.MSG_BOOST_OFF:
boosterState = BoosterStatus.OFF;
break;
case BidibLibrary.MSG_BOOST_ON:
boosterState = BoosterStatus.ON;
break;
}
final BoosterStatus boosterStatus = boosterState;
LOGGER.info("Set the booster state: {}", boosterStatus);
ProxyNode proxyNode = ProxyNode.getProxyNode(node);
final NodeAddress nodeAddress = JsonNodeUtils.prepareNodeAddress(proxyNode);
serviceWorker.schedule(() -> {
// LOGGER.info("Set the new booster state: {}", boosterStatus);
boosterService.setBoosterState(connectionId, nodeAddress, boosterStatus);
}, 5, TimeUnit.MILLISECONDS);
}
private void processSysEnableOrDisableRequest(
String connectionId, final BidibMessageInterface bidibMessage, final NodeInterface node, boolean enableNode)
throws ProtocolException {
LOGGER.info("Enable/Disable the node: {}, enableNode: {}", node, enableNode);
ProxyNode proxyNode = ProxyNode.getProxyNode(node);
if (enableNode != proxyNode.isEnabled()) {
proxyNode.setEnabled(enableNode);
final NodeAddress nodeAddress = JsonNodeUtils.prepareNodeAddress(proxyNode);
serviceWorker.schedule(() -> {
LOGGER.info("Enable the node: {}", node);
if (enableNode) {
nodeService.enable(connectionId, nodeAddress);
}
else {
// TODO prevent disable spontaneous events from the node
// nodeService.disable(connectionId, nodeAddress);
}
}, 5, TimeUnit.MILLISECONDS);
}
}
private void processFeedbackGetRangeRequest(
String connectionId, final HostAdapter distributedHostAdapter,
BidibMessageInterface bidibMessage, NodeInterface node) throws ProtocolException {
LOGGER.info("Get feedback state, node: {}", node);
FeedbackGetRangeMessage feedbackGetRangeMessage = (FeedbackGetRangeMessage) bidibMessage;
final ProxyNode proxyNode = ProxyNode.getProxyNode(node);
final NodeAddress nodeAddress = JsonNodeUtils.prepareNodeAddress(proxyNode);
if (CollectionUtils.isEmpty(proxyNode.getFeedbackPorts())) {
// set the feedback ports on the proxy node
LOGGER.info("Get the feedback ports.");
List nodeFeedbackPorts = nodeService.queryAllOccupancyPorts(connectionId, nodeAddress);
List ports = new ArrayList<>();
for (FeedbackPort nodeFeedbackPort : nodeFeedbackPorts) {
FeedbackPort feedbackPort = new FeedbackPort();
feedbackPort.setId(nodeFeedbackPort.getId());
feedbackPort.setEnabled(nodeFeedbackPort.isEnabled());
feedbackPort.setConfigStatus(nodeFeedbackPort.getConfigStatus());
feedbackPort.setStatus(nodeFeedbackPort.getStatus());
FeedbackTimestampData feedbackTimestampData = nodeFeedbackPort.getTimestamp();
if (feedbackTimestampData != null) {
feedbackPort.setTimestamp(new FeedbackTimestampData(feedbackTimestampData.getTimestamp()));
}
FeedbackConfidenceData confidenceData = nodeFeedbackPort.getConfidence();
if (confidenceData != null) {
feedbackPort
.setConfidence(new FeedbackConfidenceData(confidenceData.isInvalid(), confidenceData.isFreeze(),
confidenceData.isNoSignal()));
}
ports.add(feedbackPort);
}
LOGGER.info("Prepared the feedback ports for the proxyNode: {}", ports);
proxyNode.setFeedbackPorts(ports);
}
// nodeService
// .queryFeedbackPortStatus(connectionId, nodeAddress, feedbackGetRangeMessage.getBeginRange(),
// feedbackGetRangeMessage.getEndRange());
// TODO publish the MSG_BM_MULTIPLE
final List feedbackPorts = proxyNode.getFeedbackPorts();
int baseAddress = feedbackGetRangeMessage.getBeginRange();
int end = feedbackGetRangeMessage.getEndRange();
int feedbackSize = feedbackGetRangeMessage.getEndRange() - feedbackGetRangeMessage.getBeginRange();
byte value = 0x00;
int index = 0;
int feedbackByteSize = feedbackSize / 8 + (feedbackSize % 8 > 0 ? 1 : 0);
byte[] feedbackMultiple = new byte[feedbackByteSize];
int position = feedbackMultiple.length;
for (int portNum = end; portNum > baseAddress; portNum--) {
value = (byte) ((value & 0xFF) << 1);
FeedbackPort fbp = PortListUtils.findPortByPortNumber(feedbackPorts, portNum - 1);
byte status = 0;
if (fbp != null) {
status = ByteUtils.getLowByte(fbp.getStatus().getType().getType(), 0x01);
}
value |= status;
feedbackMultiple[position - 1] = value;
index++;
if (index > 7) {
value = 0;
index = 0;
position--;
}
}
LOGGER.info("Prepared feedback multiple: {}", ByteUtils.bytesToHex(feedbackMultiple));
final BidibMessage occupancyMultipleResponse =
responseFactory
.createOccupancyMultipleResponse(bidibMessage.getAddr(), 0, baseAddress, feedbackSize,
feedbackMultiple);
LOGGER.info("Publish occupancyMultipleResponse: {}", occupancyMultipleResponse);
distributedHostAdapter.forwardMessageToGuest(proxyNode, occupancyMultipleResponse);
}
private void processFeedbackGetConfidenceRequest(
String connectionId, final HostAdapter distributedHostAdapter,
BidibMessageInterface bidibMessage, NodeInterface node) throws ProtocolException {
LOGGER.info("Get feedback confidence, node: {}", node);
// FeedbackGetConfidenceMessage feedbackGetConfidenceMessage = (FeedbackGetConfidenceMessage) bidibMessage;
ProxyNode proxyNode = ProxyNode.getProxyNode(node);
FeedbackConfidenceStatus feedbackConfidenceStatus = proxyNode.getFeedbackPortGroupConfidence();
// final NodeAddress nodeAddress = JsonNodeUtils.prepareNodeAddress(proxyNode);
// nodeService.queryFeedbackConfidence(connectionId, nodeAddress);
int valid = feedbackConfidenceStatus.getInvalid();
int freeze = feedbackConfidenceStatus.getFreeze();
int signal = feedbackConfidenceStatus.getNoSignal();
final BidibMessage occupancyConfidenceResponse =
responseFactory.createOccupancyConfidenceResponse(bidibMessage.getAddr(), 0, valid, freeze, signal);
LOGGER.info("Publish occupancyConfidenceResponse: {}", occupancyConfidenceResponse);
distributedHostAdapter.forwardMessageToGuest(proxyNode, occupancyConfidenceResponse);
}
private void processFeedbackAddressGetRangeRequest(
String connectionId, BidibMessageInterface bidibMessage, NodeInterface node) {
LOGGER.info("Get feedback addresses, node: {}", node);
// TODO Auto-generated method stub
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy