Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.bidib.wizard.simulation.LightControlSimulator Maven / Gradle / Ivy
package org.bidib.wizard.simulation;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.bidib.jbidibc.messages.AddressData;
import org.bidib.jbidibc.messages.BidibLibrary;
import org.bidib.jbidibc.messages.BidibPort;
import org.bidib.jbidibc.messages.Feature;
import org.bidib.jbidibc.messages.FeedbackAddressData;
import org.bidib.jbidibc.messages.LcConfigX;
import org.bidib.jbidibc.messages.LcMacro;
import org.bidib.jbidibc.messages.ProtocolVersion;
import org.bidib.jbidibc.messages.enums.AddressTypeEnum;
import org.bidib.jbidibc.messages.enums.EnrailmentDirectionEnum;
import org.bidib.jbidibc.messages.enums.FeatureEnum;
import org.bidib.jbidibc.messages.enums.IoBehaviourSwitchEnum;
import org.bidib.jbidibc.messages.enums.LcMacroOperationCode;
import org.bidib.jbidibc.messages.enums.LcMacroState;
import org.bidib.jbidibc.messages.enums.LcOutputType;
import org.bidib.jbidibc.messages.enums.LightPortEnum;
import org.bidib.jbidibc.messages.enums.PortConfigStatus;
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.AccessoryParaResponse;
import org.bidib.jbidibc.messages.message.AccessoryParaSetMessage;
import org.bidib.jbidibc.messages.message.AccessorySetMessage;
import org.bidib.jbidibc.messages.message.AccessoryStateResponse;
import org.bidib.jbidibc.messages.message.BidibMessage;
import org.bidib.jbidibc.messages.message.BidibMessageInterface;
import org.bidib.jbidibc.messages.message.BidibRequestFactory;
import org.bidib.jbidibc.messages.message.FeedbackAddressResponse;
import org.bidib.jbidibc.messages.message.FeedbackConfidenceResponse;
import org.bidib.jbidibc.messages.message.FeedbackFreeResponse;
import org.bidib.jbidibc.messages.message.FeedbackGetRangeMessage;
import org.bidib.jbidibc.messages.message.FeedbackMultipleResponse;
import org.bidib.jbidibc.messages.message.FeedbackOccupiedResponse;
import org.bidib.jbidibc.messages.message.FeedbackSpeedResponse;
import org.bidib.jbidibc.messages.message.LcConfigGetMessage;
import org.bidib.jbidibc.messages.message.LcConfigResponse;
import org.bidib.jbidibc.messages.message.LcConfigSetMessage;
import org.bidib.jbidibc.messages.message.LcConfigXGetAllMessage;
import org.bidib.jbidibc.messages.message.LcConfigXGetMessage;
import org.bidib.jbidibc.messages.message.LcConfigXResponse;
import org.bidib.jbidibc.messages.message.LcConfigXSetMessage;
import org.bidib.jbidibc.messages.message.LcKeyMessage;
import org.bidib.jbidibc.messages.message.LcKeyResponse;
import org.bidib.jbidibc.messages.message.LcMacroGetMessage;
import org.bidib.jbidibc.messages.message.LcMacroHandleMessage;
import org.bidib.jbidibc.messages.message.LcMacroParaGetMessage;
import org.bidib.jbidibc.messages.message.LcMacroParaResponse;
import org.bidib.jbidibc.messages.message.LcMacroParaSetMessage;
import org.bidib.jbidibc.messages.message.LcMacroResponse;
import org.bidib.jbidibc.messages.message.LcMacroSetMessage;
import org.bidib.jbidibc.messages.message.LcMacroStateResponse;
import org.bidib.jbidibc.messages.message.LcNotAvailableResponse;
import org.bidib.jbidibc.messages.message.LcOutputMessage;
import org.bidib.jbidibc.messages.message.LcPortQueryAllMessage;
import org.bidib.jbidibc.messages.message.LcPortQueryMessage;
import org.bidib.jbidibc.messages.message.LcStatResponse;
import org.bidib.jbidibc.messages.port.BytePortConfigValue;
import org.bidib.jbidibc.messages.port.Int16PortConfigValue;
import org.bidib.jbidibc.messages.port.PortConfigUtils;
import org.bidib.jbidibc.messages.port.PortConfigValue;
import org.bidib.jbidibc.messages.port.RgbPortConfigValue;
import org.bidib.jbidibc.messages.utils.ByteUtils;
import org.bidib.jbidibc.messages.utils.MacroUtils;
import org.bidib.jbidibc.messages.utils.NodeUtils;
import org.bidib.jbidibc.messages.utils.ThreadFactoryBuilder;
import org.bidib.jbidibc.simulation.SimulationBidibMessageProcessor;
import org.bidib.jbidibc.simulation.SwitchingFunctionsNode;
import org.bidib.jbidibc.simulation.annotation.BidibNodeSimulator;
import org.bidib.jbidibc.simulation.annotation.BidibNodeSimulators;
import org.bidib.jbidibc.simulation.nodes.DefaultNodeSimulator;
import org.bidib.jbidibc.simulation.nodes.FlatPortType;
import org.bidib.jbidibc.simulation.nodes.InputPortType;
import org.bidib.jbidibc.simulation.nodes.LightPortParamsType;
import org.bidib.jbidibc.simulation.nodes.LightPortType;
import org.bidib.jbidibc.simulation.nodes.PortType;
import org.bidib.jbidibc.simulation.nodes.ServoPortType;
import org.bidib.jbidibc.simulation.nodes.SwitchPortType;
import org.bidib.wizard.model.ports.FeedbackPort;
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.SwitchPort;
import org.bidib.wizard.model.status.FeedbackPortStatus;
import org.bidib.wizard.model.status.InputPortStatus;
import org.bidib.wizard.model.status.LightPortStatus;
import org.bidib.wizard.model.status.ServoPortStatus;
import org.bidib.wizard.model.status.SwitchPortStatus;
import org.bidib.wizard.simulation.events.FeedbackConfidenceSetEvent;
import org.bidib.wizard.simulation.events.FeedbackConfidenceStatusEvent;
import org.bidib.wizard.simulation.events.FeedbackPortSetStatusEvent;
import org.bidib.wizard.simulation.events.FeedbackPortStatusEvent;
import org.bidib.wizard.simulation.events.InputPortSetStatusEvent;
import org.bidib.wizard.simulation.events.InputPortStatusEvent;
import org.bidib.wizard.simulation.events.LightPortStatusEvent;
import org.bidib.wizard.simulation.events.ServoPortStatusEvent;
import org.bidib.wizard.simulation.events.SwitchPortStatusEvent;
import org.bidib.wizard.simulation.macro.MacroContainer;
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;
@BidibNodeSimulators({ @BidibNodeSimulator(vid = "13", pid = "107"), @BidibNodeSimulator(vid = "13", pid = "204") })
public class LightControlSimulator extends DefaultNodeSimulator implements SwitchingFunctionsNode {
private static final Logger LOGGER = LoggerFactory.getLogger(LightControlSimulator.class);
private static final String SIMULATION_PANEL_CLASS =
"org.bidib.wizard.simulation.client.view.panel.LightControlPanel";
protected static final int MAX_NUM_OF_FEEDBACK_PORTS = 8;
protected final Map inputPorts = new HashMap();
protected final Map lightPorts = new HashMap();
protected final Map switchPorts = new HashMap();
protected final Map servoPorts = new HashMap();
protected final Map macros = new HashMap();
protected int inputPortCount;
protected int inputPortOffset;
protected int lightPortCount;
protected int servoPortCount;
protected int switchPortCount;
private final Map feedbackPorts = new HashMap();
private final AtomicBoolean statusFreeze = new AtomicBoolean();
private final AtomicBoolean statusValid = new AtomicBoolean();
private final AtomicBoolean statusSignal = new AtomicBoolean();
private boolean startFeedbackWorker = false;
protected final ScheduledExecutorService feedbackAddrWorker;
public LightControlSimulator(byte[] nodeAddress, long uniqueId, boolean autoAddFeature,
SimulationBidibMessageProcessor messageReceiver, final BidibRequestFactory bidibRequestFactory) {
super(nodeAddress, uniqueId, autoAddFeature, messageReceiver, bidibRequestFactory);
final ThreadFactory namedThreadFactory =
new ThreadFactoryBuilder().setNameFormat("feedbackAddrWorkers-thread-%d").build();
feedbackAddrWorker = Executors.newScheduledThreadPool(1, namedThreadFactory);
}
@Override
protected void prepareFeatures() {
LOGGER.info("Prepare the features.");
super.prepareFeatures();
// features.add(new Feature(BidibLibrary.FEATURE_BM_SIZE, MAX_NUM_OF_FEEDBACK_PORTS));
features.add(new Feature(BidibLibrary.FEATURE_CTRL_PORT_QUERY_AVAILABLE, 1));
features.add(new Feature(BidibLibrary.FEATURE_SWITCH_CONFIG_AVAILABLE, 1));
features.add(new Feature(BidibLibrary.FEATURE_CTRL_INPUT_NOTIFY, 1));
features.add(new Feature(BidibLibrary.FEATURE_CTRL_MAC_COUNT, 40));
features.add(new Feature(BidibLibrary.FEATURE_CTRL_MAC_SIZE, 38));
features.add(new Feature(BidibLibrary.FEATURE_CTRL_MAC_SAVE, 40));
features.add(new Feature(BidibLibrary.FEATURE_CTRL_MAC_LEVEL, 2));
features.add(new Feature(BidibLibrary.FEATURE_ACCESSORY_COUNT, 20));
features.add(new Feature(BidibLibrary.FEATURE_ACCESSORY_SURVEILLED, 0));
features.add(new Feature(BidibLibrary.FEATURE_ACCESSORY_MACROMAPPED, 2));
}
@Override
public void postConstruct() {
super.postConstruct();
if (inputPortCount > 0) {
features.add(new Feature(BidibLibrary.FEATURE_CTRL_INPUT_COUNT, inputPortCount));
}
else if (Feature.findFeature(features, BidibLibrary.FEATURE_CTRL_INPUT_COUNT) != null) {
Integer inputPortCountVal = Feature.getIntegerFeatureValue(features, FeatureEnum.FEATURE_CTRL_INPUT_COUNT);
if (inputPortCountVal != null) {
inputPortCount = inputPortCountVal.intValue();
}
}
if (lightPortCount > 0) {
features.add(new Feature(BidibLibrary.FEATURE_CTRL_LIGHT_COUNT, lightPortCount));
}
else if (Feature.findFeature(features, BidibLibrary.FEATURE_CTRL_LIGHT_COUNT) != null) {
Integer lightPortCountVal = Feature.getIntegerFeatureValue(features, FeatureEnum.FEATURE_CTRL_LIGHT_COUNT);
if (lightPortCountVal != null) {
lightPortCount = lightPortCountVal.intValue();
}
}
if (servoPortCount > 0) {
features.add(new Feature(BidibLibrary.FEATURE_CTRL_SERVO_COUNT, servoPortCount));
}
else if (Feature.findFeature(features, BidibLibrary.FEATURE_CTRL_SERVO_COUNT) != null) {
Integer servoPortCountVal = Feature.getIntegerFeatureValue(features, FeatureEnum.FEATURE_CTRL_SERVO_COUNT);
if (servoPortCountVal != null) {
servoPortCount = servoPortCountVal.intValue();
}
}
if (switchPortCount > 0) {
features.add(new Feature(BidibLibrary.FEATURE_CTRL_SWITCH_COUNT, switchPortCount));
}
else if (Feature.findFeature(features, BidibLibrary.FEATURE_CTRL_SWITCH_COUNT) != null) {
Integer switchPortCountVal =
Feature.getIntegerFeatureValue(features, FeatureEnum.FEATURE_CTRL_SWITCH_COUNT);
if (switchPortCountVal != null) {
switchPortCount = switchPortCountVal.intValue();
}
}
}
@Override
protected void prepareCVs() {
super.prepareCVs();
configurationVariables.put("2", "0");
configurationVariables.put("90", "191");
}
@Override
public String getSimulationPanelClass() {
return SIMULATION_PANEL_CLASS;
}
private int interval = 3000;
private int currentLocoPosition = -1;
@Override
public void start() {
LOGGER.info("Start the simulator for address: {}", getAddress());
AnnotationProcessor.process(this);
// prepare the input ports
setupInputPorts();
// prepare the light ports
setupLightPorts();
// prepare the switch ports
setupSwitchPorts();
// prepare the servo ports
setupServoPorts();
// prepare the feedback ports
setupFeedbackPorts();
super.start();
Feature bmSize = NodeUtils.getFeature(FeatureEnum.FEATURE_BM_SIZE, features);
Feature bmOn = NodeUtils.getFeature(FeatureEnum.FEATURE_BM_ON, features);
if (bmSize != null && bmSize.getValue() > 0 && bmOn != null && bmOn.getValue() > 0) {
this.startFeedbackWorker = true;
LOGGER.info("Start the feedback worker.");
}
if (startFeedbackWorker) {
feedbackAddrWorker.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
try {
int portNum = currentLocoPosition;
LOGGER.info("Trigger feedback address, portNum: {}", portNum);
FeedbackPortSetStatusEvent evtFree = null;
if (portNum > -1) {
portNum = currentLocoPosition;
if (portNum < 0) {
portNum = MAX_NUM_OF_FEEDBACK_PORTS - 1;
}
// make the active position occupied
evtFree = new FeedbackPortSetStatusEvent(getAddress(), portNum, FeedbackPortStatus.FREE);
}
currentLocoPosition++;
if (currentLocoPosition >= MAX_NUM_OF_FEEDBACK_PORTS) {
currentLocoPosition = 0;
}
FeedbackPortSetStatusEvent evtOcc =
new FeedbackPortSetStatusEvent(getAddress(), currentLocoPosition,
FeedbackPortStatus.OCCUPIED);
// TODO
setFeedbackPortStatus(evtOcc);
triggerFeedbackAddressResponse(currentLocoPosition);
Thread.sleep(500);
if (evtFree != null) {
// send the free event
setFeedbackPortStatus(evtFree);
triggerFeedbackAddressResponse(evtFree.getPortNum());
}
int delayValue = ThreadLocalRandom.current().nextInt(300, 4000);
LOGGER.info("Wait for next execution, delayValue: {}", delayValue);
Thread.sleep(delayValue);
}
catch (Exception ex) {
LOGGER.warn("Trigger the feedback address failed.", ex);
}
LOGGER.info("Trigger feedback address has finished.");
}
}, 5000, interval, TimeUnit.MILLISECONDS);
}
}
@Override
public void stop() {
AnnotationProcessor.unprocess(this);
if (feedbackAddrWorker != null) {
LOGGER.info("Stop the booster diag worker.");
feedbackAddrWorker.shutdownNow();
}
super.stop();
}
private void setupFeedbackPorts() {
for (int id = 0; id < MAX_NUM_OF_FEEDBACK_PORTS; id++) {
FeedbackPort port = new FeedbackPort();
port.setId(id);
// port.setStatus(id % 3 == 0 ? FeedbackPortStatus.FREE : FeedbackPortStatus.OCCUPIED);
port.setStatus(FeedbackPortStatus.FREE);
feedbackPorts.put(id, port);
}
}
protected void setupInputPorts() {
if (CollectionUtils.isNotEmpty(inputPorts.values())) {
LOGGER.info("InputPorts are set externally already.");
return;
}
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);
}
}
protected void setupLightPorts() {
if (CollectionUtils.isNotEmpty(lightPorts.values())) {
LOGGER.info("LightPorts are set externally already.");
return;
}
for (int id = 0; id < lightPortCount; id++) {
LightPort port = new LightPort();
port.setId(id);
port.setStatus(id % 3 == 0 ? LightPortStatus.ON : LightPortStatus.OFF);
lightPorts.put(id, port);
}
}
protected void setupSwitchPorts() {
if (CollectionUtils.isNotEmpty(switchPorts.values())) {
LOGGER.info("SwitchPorts are set externally already.");
return;
}
for (int id = 0; id < switchPortCount; id++) {
SwitchPort port = new SwitchPort();
port.setId(id);
port.setStatus(SwitchPortStatus.OFF);
// set some default values
port.setOutputBehaviour(IoBehaviourSwitchEnum.HIGH);
port.setSwitchOffTime(15);
switchPorts.put(id, port);
}
}
protected void setupServoPorts() {
if (CollectionUtils.isNotEmpty(servoPorts.values())) {
LOGGER.info("ServoPorts are set externally already.");
return;
}
boolean useConfigX = getProtocolVersion().isHigherThan(ProtocolVersion.VERSION_0_5);
LOGGER.info("Create servoPorts, count: {}, useConfigX: {}", servoPortCount, useConfigX);
for (int id = 0; id < servoPortCount; id++) {
ServoPort port = new ServoPort();
port.setId(id);
port.setRelativeValue((id % 4) * 25);
if (useConfigX) {
// Map> portConfig = new LinkedHashMap<>();
// portConfig.put(BidibLibrary.BIDIB_PCFG_SERVO_ADJ_L, new
// BytePortConfigValue(ByteUtils.getLowByte(20)));
// portConfig.put(BidibLibrary.BIDIB_PCFG_SERVO_ADJ_H, new
// BytePortConfigValue(ByteUtils.getLowByte(150)));
// portConfig.put(BidibLibrary.BIDIB_PCFG_SERVO_SPEED, new
// BytePortConfigValue(ByteUtils.getLowByte(4)));
//
// portConfig.put(BidibLibrary.BIDIB_PCFG_SERVO_EXTRA, new
// BytePortConfigValue(ByteUtils.getLowByte(0)));
// portConfig.put(BidibLibrary.BIDIB_PCFG_MOVE_TYPE, new
// BytePortConfigValue(ByteUtils.getLowByte(0x12)));
//
// port.setPortConfigX(portConfig);
configureServoPort(port);
}
else {
byte[] portConfig = new byte[] { 0x30, 0x7B, 0x08 };
port.setPortConfig(portConfig);
}
servoPorts.put(id, port);
}
}
protected void configureServoPort(final ServoPort port) {
Map> portConfig = new LinkedHashMap<>();
portConfig.put(BidibLibrary.BIDIB_PCFG_SERVO_ADJ_L, new BytePortConfigValue(ByteUtils.getLowByte(20)));
portConfig.put(BidibLibrary.BIDIB_PCFG_SERVO_ADJ_H, new BytePortConfigValue(ByteUtils.getLowByte(150)));
portConfig.put(BidibLibrary.BIDIB_PCFG_SERVO_SPEED, new BytePortConfigValue(ByteUtils.getLowByte(4)));
// portConfig.put(BidibLibrary.BIDIB_PCFG_SERVO_EXTRA, new BytePortConfigValue(ByteUtils.getLowByte(0)));
// portConfig.put(BidibLibrary.BIDIB_PCFG_MOVE_TYPE, new BytePortConfigValue(ByteUtils.getLowByte(0x12)));
port.setPortConfigX(portConfig);
}
@EventSubscriber(eventClass = InputPortSetStatusEvent.class)
public void inputPortSetStatus(InputPortSetStatusEvent setStatusEvent) {
LOGGER.info("The change of the input port was requested.");
String nodeAddress = setStatusEvent.getNodeAddr();
// check if the node is addressed
if (!isAddressEqual(nodeAddress)) {
LOGGER.trace("Another node is addressed.");
return;
}
int portNum = setStatusEvent.getPortNum();
changeInputPortStatus(portNum);
}
protected void changeInputPortStatus(int portNum) {
InputPort port = inputPorts.get(portNum);
if (port != null) {
switch (port.getStatus()) {
case OFF:
port.setStatus(InputPortStatus.ON);
break;
default:
port.setStatus(InputPortStatus.OFF);
break;
}
// prepare the request
final LcKeyMessage lcKeyMessage = new LcKeyMessage(portNum) {
@Override
public byte[] getAddr() {
return getNodeAddress();
}
};
processRequest(lcKeyMessage);
}
else {
LOGGER.warn("The requested light port is not available: {}", portNum);
}
}
@Override
protected byte[] prepareResponse(BidibMessageInterface bidibMessage) {
byte[] response = null;
switch (ByteUtils.getInt(bidibMessage.getType())) {
case BidibLibrary.MSG_LC_OUTPUT:
response = processLcOutputRequest(bidibMessage);
break;
case BidibLibrary.MSG_LC_CONFIG_GET:
response = processLcConfigGetRequest(bidibMessage);
break;
case BidibLibrary.MSG_LC_CONFIG_SET:
response = processLcConfigSetRequest(bidibMessage);
break;
case BidibLibrary.MSG_LC_KEY_QUERY:
response = processLcKeyQueryRequest(bidibMessage);
break;
case BidibLibrary.MSG_LC_PORT_QUERY:
response = processLcPortQueryRequest(bidibMessage);
break;
case BidibLibrary.MSG_LC_CONFIGX_SET:
response = processLcConfigXSetRequest(bidibMessage);
break;
case BidibLibrary.MSG_LC_CONFIGX_GET:
response = processLcConfigXGetRequest(bidibMessage);
break;
case BidibLibrary.MSG_LC_CONFIGX_GET_ALL:
processLcConfigXGetAllRequest(bidibMessage);
break;
case BidibLibrary.MSG_LC_PORT_QUERY_ALL:
processLcPortQueryAllRequest(bidibMessage);
break;
case BidibLibrary.MSG_LC_MACRO_HANDLE:
response = processLcMacroHandleRequest(bidibMessage);
break;
case BidibLibrary.MSG_LC_MACRO_PARA_GET:
response = processLcMacroParaGetRequest(bidibMessage);
break;
case BidibLibrary.MSG_LC_MACRO_PARA_SET:
response = processLcMacroParaSetRequest(bidibMessage);
break;
case BidibLibrary.MSG_LC_MACRO_GET:
response = processLcMacroGetRequest(bidibMessage);
break;
case BidibLibrary.MSG_LC_MACRO_SET:
response = processLcMacroSetRequest(bidibMessage);
break;
case BidibLibrary.MSG_ACCESSORY_SET:
response = processAccessorySetRequest(bidibMessage);
break;
case BidibLibrary.MSG_ACCESSORY_GET:
response = processAccessoryGetRequest(bidibMessage);
break;
case BidibLibrary.MSG_ACCESSORY_GETALL:
response = processAccessoryGetAllRequest(bidibMessage);
break;
case BidibLibrary.MSG_ACCESSORY_PARA_SET:
response = processAccessoryParaSetRequest(bidibMessage);
break;
case BidibLibrary.MSG_ACCESSORY_PARA_GET:
response = processAccessoryParaGetRequest(bidibMessage);
break;
case BidibLibrary.MSG_BM_GET_RANGE:
response = processBmGetRangeRequest(bidibMessage);
break;
case BidibLibrary.MSG_BM_MIRROR_MULTIPLE:
processBmMirrorMultipleRequest(bidibMessage);
break;
case BidibLibrary.MSG_BM_MIRROR_OCC:
processBmMirrorOccupiedRequest(bidibMessage);
break;
case BidibLibrary.MSG_BM_MIRROR_FREE:
processBmMirrorFreeRequest(bidibMessage);
break;
case BidibLibrary.MSG_BM_GET_CONFIDENCE:
response = processBmGetConfidenceRequest(bidibMessage);
break;
default:
response = super.prepareResponse(bidibMessage);
break;
}
return response;
}
private boolean fakePortStatus;
protected byte[] processLcOutputRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the LcOutput request: {}", bidibMessage);
byte[] response = null;
try {
LcOutputMessage lcOutputMessage = (LcOutputMessage) bidibMessage;
LcOutputType outputType = lcOutputMessage.getOutputType(getPortModel());
int outputNumber = lcOutputMessage.getOutputNumber(getPortModel());
byte outputStatus = lcOutputMessage.getOutputStatus();
Port> port = null;
switch (outputType) {
case LIGHTPORT:
LightPort lightPort = lightPorts.get(Integer.valueOf(outputNumber));
lightPort.setStatus(LightPortStatus.valueOf(LightPortEnum.valueOf(outputStatus)));
port = lightPort;
if (outputNumber == 2) {
if (!fakePortStatus) {
LOGGER.warn("Fake LC_NA");
port = null;
fakePortStatus = true;
}
else {
fakePortStatus = false;
}
}
break;
case SWITCHPORT:
SwitchPort switchPort = switchPorts.get(Integer.valueOf(outputNumber));
switchPort.setStatus(SwitchPortStatus.valueOf(SwitchPortEnum.valueOf(outputStatus)));
port = switchPort;
if (outputNumber == 2) {
if (!fakePortStatus) {
LOGGER.warn("Fake LC_NA");
port = null;
fakePortStatus = true;
}
else {
fakePortStatus = false;
}
}
break;
case SERVOPORT:
ServoPort servoPort = servoPorts.get(Integer.valueOf(outputNumber));
servoPort.setValue(ByteUtils.getInteger(outputStatus));
port = servoPort;
break;
default:
LOGGER.warn("LcOutput request for unsupported port type detected: {}", outputType);
break;
}
BidibPort bidibPort = prepareBidibPort(getPortModel(), outputType, outputNumber);
if (port != null) {
LcStatResponse lcStatResponse =
new LcStatResponse(bidibMessage.getAddr(), getNextSendNum(), bidibPort,
lcOutputMessage.getOutputStatus());
response = lcStatResponse.getContent();
sendSpontanousResponse(response);
response = null;
}
else {
LcNotAvailableResponse lcNotAvailableResponse =
new LcNotAvailableResponse(bidibMessage.getAddr(), getNextSendNum(), bidibPort);
response = lcNotAvailableResponse.getContent();
}
if (port != null) {
switch (outputType) {
case LIGHTPORT:
publishLightPortChange(port);
// if (outputNumber == 2) {
// LOGGER.warn("Fake LC_NA");
//
// bidibPort = prepareBidibPort(getPortModel(), outputType, 4);
//
// LcNotAvailableResponse lcNotAvailableResponse =
// new LcNotAvailableResponse(bidibMessage.getAddr(), getNextSendNum(), bidibPort);
// response = lcNotAvailableResponse.getContent();
// }
break;
case SWITCHPORT:
publishSwitchPortChange(port);
break;
case SERVOPORT:
publishServoPortChange(port);
break;
default:
break;
}
}
}
catch (ProtocolException ex) {
LOGGER.warn("Create LcStat response failed.", ex);
}
return response;
}
private void publishLightPortChange(Port> port) {
LightPort lightPort = (LightPort) port;
LightPortStatus status = lightPort.getStatus();
LOGGER.info("The lightport status has changed, notify the listeners, nodeAddress: {}", nodeAddress);
EventBus.publish(new LightPortStatusEvent(NodeUtils.formatAddress(nodeAddress), lightPort.getId(), status));
}
private void publishSwitchPortChange(Port> port) {
SwitchPort switchPort = (SwitchPort) port;
SwitchPortStatus status = switchPort.getStatus();
LOGGER.info("The switchport status has changed, notify the listeners, nodeAddress: {}", nodeAddress);
EventBus.publish(new SwitchPortStatusEvent(NodeUtils.formatAddress(nodeAddress), switchPort.getId(), status));
}
private void publishServoPortChange(Port> port) {
ServoPort servoPort = (ServoPort) port;
Integer value = servoPort.getValue();
LOGGER.info("The servoport status has changed, notify the listeners, nodeAddress: {}", nodeAddress);
EventBus.publish(new ServoPortStatusEvent(NodeUtils.formatAddress(nodeAddress), servoPort.getId(), value));
}
protected byte[] processLcConfigGetRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the LcConfigGet request: {}", bidibMessage);
byte[] response = null;
try {
LcConfigGetMessage lcConfigGetMessage = (LcConfigGetMessage) bidibMessage;
LcOutputType outputType = lcConfigGetMessage.getPortType(getPortModel());
int outputNumber = lcConfigGetMessage.getPortNumber(getPortModel());
Port> port = null;
switch (outputType) {
case LIGHTPORT:
port = lightPorts.get(Integer.valueOf(outputNumber));
break;
case SWITCHPORT:
port = switchPorts.get(Integer.valueOf(outputNumber));
break;
case SERVOPORT:
// if (outputNumber != 1) { // testing
port = servoPorts.get(Integer.valueOf(outputNumber));
// }
break;
case INPUTPORT:
port = inputPorts.get(Integer.valueOf(outputNumber));
break;
default:
LOGGER.warn("LcConfigGet request for unsupported port type detected: {}", outputType);
break;
}
BidibPort bidibPort = prepareBidibPort(getPortModel(), outputType, outputNumber);
if (port != null) {
LcConfigResponse lcConfigResponse =
new LcConfigResponse(bidibMessage.getAddr(), getNextSendNum(), bidibPort, port.getPortConfig());
response = lcConfigResponse.getContent();
}
else {
LOGGER.warn("No port assigned!");
LcNotAvailableResponse lcNotAvailableResponse =
new LcNotAvailableResponse(bidibMessage.getAddr(), getNextSendNum(), bidibPort);
response = lcNotAvailableResponse.getContent();
}
}
catch (ProtocolException ex) {
LOGGER.warn("Create LcConfig response failed.", ex);
}
return response;
}
protected byte[] processLcConfigSetRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the LcConfigSet request: {}", bidibMessage);
byte[] response = null;
try {
LcConfigSetMessage lcConfigSetMessage = (LcConfigSetMessage) bidibMessage;
LcOutputType outputType = lcConfigSetMessage.getPortType(getPortModel());
int outputNumber = lcConfigSetMessage.getPortNumber(getPortModel());
Port> port = null;
switch (outputType) {
case LIGHTPORT:
LightPort lightPort = lightPorts.get(Integer.valueOf(outputNumber));
if (lightPort != null) {
lightPort.setPortConfig(lcConfigSetMessage.getPortConfig());
port = lightPort;
}
else {
LOGGER.warn("Lightport not available, outputNumber: {}", outputNumber);
}
break;
case SWITCHPORT:
SwitchPort switchPort = switchPorts.get(Integer.valueOf(outputNumber));
if (switchPort != null) {
switchPort.setPortConfig(lcConfigSetMessage.getPortConfig());
port = switchPort;
}
else {
LOGGER.warn("Switchport not available, outputNumber: {}", outputNumber);
}
break;
case SERVOPORT:
ServoPort servoPort = servoPorts.get(Integer.valueOf(outputNumber));
if (servoPort != null /* && outputNumber != 1 */) {
servoPort.setPortConfig(lcConfigSetMessage.getPortConfig());
port = servoPort;
}
else {
LOGGER.warn("Servoport not available, outputNumber: {}", outputNumber);
}
break;
case INPUTPORT:
InputPort inputPort = inputPorts.get(Integer.valueOf(outputNumber));
if (inputPort != null) {
LOGGER.warn("The input port has no config to set.");
port = inputPort;
}
else {
LOGGER.warn("Inputport not available, outputNumber: {}", outputNumber);
}
break;
default:
LOGGER.warn("LcConfigSet request for unsupported port type detected: {}", outputType);
break;
}
BidibPort bidibPort = prepareBidibPort(getPortModel(), outputType, outputNumber);
if (port != null) {
LcConfigResponse lcConfigResponse =
new LcConfigResponse(bidibMessage.getAddr(), getNextSendNum(), bidibPort, port.getPortConfig());
response = lcConfigResponse.getContent();
}
else {
LOGGER.warn("No port assigned!");
LcNotAvailableResponse lcNotAvailableResponse =
new LcNotAvailableResponse(bidibMessage.getAddr(), getNextSendNum(), bidibPort);
response = lcNotAvailableResponse.getContent();
}
}
catch (ProtocolException ex) {
LOGGER.warn("Create LcStat response failed.", ex);
}
return response;
}
protected byte[] processLcConfigXSetRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the LcConfigXSet request: {}", bidibMessage);
byte[] response = null;
try {
LcConfigXSetMessage lcConfigXSetMessage = (LcConfigXSetMessage) bidibMessage;
LcOutputType outputType = lcConfigXSetMessage.getPortType(getPortModel());
int outputNumber = lcConfigXSetMessage.getPortNumber(getPortModel());
Port> port = null;
switch (outputType) {
case INPUTPORT:
InputPort inputPort = inputPorts.get(Integer.valueOf(outputNumber));
if (inputPort != null) {
inputPort.setPortConfigX(lcConfigXSetMessage.getLcConfigX(messageLogger).getPortConfig());
port = inputPort;
}
else {
LOGGER.warn("Inputport not available, outputNumber: {}", outputNumber);
}
break;
case LIGHTPORT:
LightPort lightPort = lightPorts.get(Integer.valueOf(outputNumber));
if (lightPort != null) {
lightPort.setPortConfigX(lcConfigXSetMessage.getLcConfigX(messageLogger).getPortConfig());
port = lightPort;
}
else {
LOGGER.warn("Lightport not available, outputNumber: {}", outputNumber);
}
break;
case SWITCHPORT:
SwitchPort switchPort = switchPorts.get(Integer.valueOf(outputNumber));
if (switchPort != null) {
switchPort.setPortConfigX(lcConfigXSetMessage.getLcConfigX(messageLogger).getPortConfig());
port = switchPort;
}
else {
LOGGER.warn("Switchport not available, outputNumber: {}", outputNumber);
}
break;
case SERVOPORT:
ServoPort servoPort = servoPorts.get(Integer.valueOf(outputNumber));
if (servoPort != null) {
servoPort.setPortConfigX(lcConfigXSetMessage.getLcConfigX(messageLogger).getPortConfig());
port = servoPort;
}
else {
LOGGER.warn("Servoport not available, outputNumber: {}", outputNumber);
}
break;
default:
LOGGER.warn("LcConfigSet request for unsupported port type detected: {}", outputType);
break;
}
BidibPort bidibPort = prepareBidibPort(getPortModel(), outputType, outputNumber);
if (port != null) {
LcConfigX lcConfigX =
new LcConfigX(bidibPort, lcConfigXSetMessage.getLcConfigX(messageLogger).getPortConfig());
LcConfigXResponse lcConfigXResponse =
new LcConfigXResponse(bidibMessage.getAddr(), getNextSendNum(),
LcConfigX.getCodedPortConfig(null, lcConfigX, getPortModel()));
response = lcConfigXResponse.getContent();
}
else {
LOGGER.warn("No port assigned!");
LcNotAvailableResponse magicResponse =
new LcNotAvailableResponse(bidibMessage.getAddr(), getNextSendNum(), bidibPort);
response = magicResponse.getContent();
}
}
catch (ProtocolException ex) {
LOGGER.warn("Create LcConfigX response failed.", ex);
}
return response;
}
protected byte[] processLcConfigXGetRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the LcConfigXGet request: {}", bidibMessage);
byte[] response = null;
try {
LcConfigXGetMessage lcConfigXGetMessage = (LcConfigXGetMessage) bidibMessage;
int outputNumber = lcConfigXGetMessage.getPortNumber(getPortModel());
LcOutputType lcOutputType = lcConfigXGetMessage.getPortType(getPortModel());
Port> port = null;
// byte[] portConfig = null;
Map> values = new LinkedHashMap<>();
switch (lcOutputType) {
case LIGHTPORT:
port = lightPorts.get(Integer.valueOf(outputNumber));
// portConfig = port.getPortConfig();
LightPort lightPort = (LightPort) port;
values
.put(BidibLibrary.BIDIB_PCFG_LEVEL_PORT_ON,
new BytePortConfigValue(ByteUtils.getLowByte(lightPort.getPwmMax())));
values
.put(BidibLibrary.BIDIB_PCFG_LEVEL_PORT_OFF,
new BytePortConfigValue(ByteUtils.getLowByte(lightPort.getPwmMin())));
values
.put(BidibLibrary.BIDIB_PCFG_DIMM_UP,
new BytePortConfigValue(ByteUtils.getLowByte(lightPort.getDimMax())));
values
.put(BidibLibrary.BIDIB_PCFG_DIMM_DOWN,
new BytePortConfigValue(ByteUtils.getLowByte(lightPort.getDimMin())));
// RGB
if (lightPort.getRgbValue() != null) {
values.put(BidibLibrary.BIDIB_PCFG_RGB, new RgbPortConfigValue(lightPort.getRgbValue()));
}
// transition time
if (lightPort.getTransitionTime() != null) {
values
.put(BidibLibrary.BIDIB_PCFG_TRANSITION_TIME,
new Int16PortConfigValue(lightPort.getTransitionTime()));
}
// simulate BIDIB_PCFG_NONE
if (simulateTestErrors && outputNumber == 2) {
values.put(BidibLibrary.BIDIB_PCFG_NONE, new BytePortConfigValue((byte) 12));
}
break;
case SWITCHPORT:
port = switchPorts.get(Integer.valueOf(outputNumber));
SwitchPort switchPort = (SwitchPort) port;
values
.put(BidibLibrary.BIDIB_PCFG_SWITCH_CTRL,
new BytePortConfigValue(ByteUtils.getLowByte(switchPort.getOutputBehaviour().getType())));
values
.put(BidibLibrary.BIDIB_PCFG_TICKS,
new BytePortConfigValue(ByteUtils.getLowByte(switchPort.getSwitchOffTime())));
break;
case SERVOPORT:
port = servoPorts.get(Integer.valueOf(outputNumber));
ServoPort servoPort = (ServoPort) port;
values
.put(BidibLibrary.BIDIB_PCFG_SERVO_SPEED,
new BytePortConfigValue(ByteUtils.getLowByte(servoPort.getSpeed())));
values
.put(BidibLibrary.BIDIB_PCFG_SERVO_ADJ_L,
new BytePortConfigValue(ByteUtils.getLowByte(servoPort.getTrimDown())));
values
.put(BidibLibrary.BIDIB_PCFG_SERVO_ADJ_H,
new BytePortConfigValue(ByteUtils.getLowByte(servoPort.getTrimUp())));
break;
default:
LOGGER.warn("LcConfigGet request for unsupported port type detected: {}", lcOutputType);
break;
}
LOGGER.info("Return config of port: {}", port);
BidibPort bidibPort = prepareBidibPort(getPortModel(), lcOutputType, outputNumber);
LcConfigX lcConfigX = new LcConfigX(bidibPort, values);
LcConfigXResponse lcConfigXResponse =
new LcConfigXResponse(bidibMessage.getAddr(), getNextSendNum(),
LcConfigX.getCodedPortConfig(null, lcConfigX, getPortModel()));
response = lcConfigXResponse.getContent();
}
catch (ProtocolException ex) {
LOGGER.warn("Create LcConfigX response failed.", ex);
}
return response;
}
private boolean simulateTestErrors;
protected void processLcConfigXGetAllRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the LcConfigXGetAll request: {}", bidibMessage);
byte[] response = null;
try {
LcConfigXGetAllMessage lcConfigXGetAllMessage = (LcConfigXGetAllMessage) bidibMessage;
LcOutputType outputType = lcConfigXGetAllMessage.getPortTypeFrom(getPortModel());
// TODO evaluate port type/range to
Map> values = new LinkedHashMap<>();
if (outputType != null) {
LOGGER.info("Get all ports for output type: {}", outputType);
// TODO check the range
switch (outputType) {
case SERVOPORT:
for (ServoPort servoPort : servoPorts.values()) {
values.clear();
values
.put(BidibLibrary.BIDIB_PCFG_SERVO_SPEED,
new BytePortConfigValue(ByteUtils.getLowByte(servoPort.getSpeed())));
values
.put(BidibLibrary.BIDIB_PCFG_SERVO_ADJ_L,
new BytePortConfigValue(ByteUtils.getLowByte(servoPort.getTrimDown())));
values
.put(BidibLibrary.BIDIB_PCFG_SERVO_ADJ_H,
new BytePortConfigValue(ByteUtils.getLowByte(servoPort.getTrimUp())));
LOGGER.info("Return config of servo port: {}", servoPort);
BidibPort bidibPort = prepareBidibPort(getPortModel(), outputType, servoPort.getId());
LcConfigX lcConfigX = new LcConfigX(bidibPort, values);
LcConfigXResponse lcConfigXResponse =
new LcConfigXResponse(bidibMessage.getAddr(), getNextSendNum(),
LcConfigX.getCodedPortConfig(null, lcConfigX, getPortModel()));
response = lcConfigXResponse.getContent();
LOGGER.info("Prepared lcConfigXResponse: {}", ByteUtils.bytesToHex(response));
sendSpontanousResponse(response);
response = null;
}
break;
case SWITCHPORT:
for (SwitchPort switchPort : switchPorts.values()) {
values.clear();
values
.put(BidibLibrary.BIDIB_PCFG_SWITCH_CTRL, new BytePortConfigValue(
ByteUtils.getLowByte(switchPort.getOutputBehaviour().getType())));
values
.put(BidibLibrary.BIDIB_PCFG_TICKS,
new BytePortConfigValue(ByteUtils.getLowByte(switchPort.getSwitchOffTime())));
LOGGER.info("Return config of switch port: {}", switchPort);
BidibPort bidibPort = prepareBidibPort(getPortModel(), outputType, switchPort.getId());
LcConfigX lcConfigX = new LcConfigX(bidibPort, values);
LcConfigXResponse lcConfigXResponse =
new LcConfigXResponse(bidibMessage.getAddr(), getNextSendNum(),
LcConfigX.getCodedPortConfig(null, lcConfigX, getPortModel()));
response = lcConfigXResponse.getContent();
LOGGER.info("Prepared lcConfigXResponse: {}", ByteUtils.bytesToHex(response));
sendSpontanousResponse(response);
response = null;
}
break;
case LIGHTPORT:
if (!lightPorts.isEmpty()) {
for (LightPort lightPort : lightPorts.values()) {
values.clear();
values
.put(BidibLibrary.BIDIB_PCFG_LEVEL_PORT_ON,
new BytePortConfigValue(ByteUtils.getLowByte(lightPort.getPwmMax())));
// simulate missing param
if (simulateTestErrors && lightPort.getId() == 3) {
LOGGER.warn("No BIDIB_PCFG_LEVEL_PORT_OFF for light port 3!");
}
else {
values
.put(BidibLibrary.BIDIB_PCFG_LEVEL_PORT_OFF,
new BytePortConfigValue(ByteUtils.getLowByte(lightPort.getPwmMin())));
}
values
.put(BidibLibrary.BIDIB_PCFG_DIMM_UP,
new BytePortConfigValue(ByteUtils.getLowByte(lightPort.getDimMax())));
// simulate missing param
if (simulateTestErrors && lightPort.getId() == 3) {
LOGGER.warn("No BIDIB_PCFG_DIMM_DOWN for light port 3!");
}
else {
values
.put(BidibLibrary.BIDIB_PCFG_DIMM_DOWN,
new BytePortConfigValue(ByteUtils.getLowByte(lightPort.getDimMin())));
}
// return RGB if available
if (lightPort.getRgbValue() != null) {
values
.put(BidibLibrary.BIDIB_PCFG_RGB,
new RgbPortConfigValue(lightPort.getRgbValue()));
}
// return transition time if available
if (lightPort.getTransitionTime() != null) {
values
.put(BidibLibrary.BIDIB_PCFG_TRANSITION_TIME,
new Int16PortConfigValue(lightPort.getTransitionTime()));
}
LOGGER.info("Return config of light port: {}", lightPort);
BidibPort bidibPort = prepareBidibPort(getPortModel(), outputType, lightPort.getId());
LcConfigX lcConfigX = new LcConfigX(bidibPort, values);
LcConfigXResponse lcConfigXResponse =
new LcConfigXResponse(bidibMessage.getAddr(), getNextSendNum(),
LcConfigX.getCodedPortConfig(null, lcConfigX, getPortModel()));
response = lcConfigXResponse.getContent();
LOGGER.info("Prepared lcConfigXResponse: {}", ByteUtils.bytesToHex(response));
sendSpontanousResponse(response);
response = null;
}
}
else {
LOGGER.warn("No lightPorts configured.");
// MSG_LC_NA ?
}
break;
case INPUTPORT:
for (InputPort inputPort : inputPorts.values()) {
values.clear();
LOGGER.info("Return config of input port: {}", inputPort);
BidibPort bidibPort = prepareBidibPort(getPortModel(), outputType, inputPort.getId());
LcConfigX lcConfigX = new LcConfigX(bidibPort, values);
LcConfigXResponse lcConfigXResponse =
new LcConfigXResponse(bidibMessage.getAddr(), getNextSendNum(),
LcConfigX.getCodedPortConfig(null, lcConfigX, getPortModel()));
response = lcConfigXResponse.getContent();
LOGGER.info("Prepared lcConfigXResponse: {}", ByteUtils.bytesToHex(response));
sendSpontanousResponse(response);
response = null;
}
break;
default:
LOGGER.warn("Unsupported port type requested: {}", outputType);
break;
}
}
else {
// deliver servo ports
for (ServoPort servoPort : servoPorts.values()) {
values.clear();
LOGGER.info("Return config of servo port: {}", servoPort);
BidibPort bidibPort = prepareBidibPort(getPortModel(), LcOutputType.SERVOPORT, servoPort.getId());
LcConfigX lcConfigX = new LcConfigX(bidibPort, values);
LcConfigXResponse lcConfigXResponse =
new LcConfigXResponse(bidibMessage.getAddr(), getNextSendNum(),
LcConfigX.getCodedPortConfig(null, lcConfigX, getPortModel()));
response = lcConfigXResponse.getContent();
LOGGER.info("Prepared lcConfigXResponse: {}", ByteUtils.bytesToHex(response));
sendSpontanousResponse(response);
response = null;
}
// deliver switch ports
for (SwitchPort switchPort : switchPorts.values()) {
values.clear();
LOGGER.info("Return config of switch port: {}", switchPort);
values = switchPort.getPortConfigX();
BidibPort bidibPort = prepareBidibPort(getPortModel(), LcOutputType.SWITCHPORT, switchPort.getId());
LcConfigX lcConfigX = new LcConfigX(bidibPort, values);
LcConfigXResponse lcConfigXResponse =
new LcConfigXResponse(bidibMessage.getAddr(), getNextSendNum(),
LcConfigX.getCodedPortConfig(null, lcConfigX, getPortModel()));
response = lcConfigXResponse.getContent();
LOGGER.info("Prepared lcConfigXResponse: {}", ByteUtils.bytesToHex(response));
sendSpontanousResponse(response);
response = null;
}
// deliver input ports
for (InputPort inputPort : inputPorts.values()) {
values.clear();
LOGGER.info("Return config of input port: {}", inputPort);
BidibPort bidibPort = prepareBidibPort(getPortModel(), LcOutputType.INPUTPORT, inputPort.getId());
LcConfigX lcConfigX = new LcConfigX(bidibPort, values);
LcConfigXResponse lcConfigXResponse =
new LcConfigXResponse(bidibMessage.getAddr(), getNextSendNum(),
LcConfigX.getCodedPortConfig(null, lcConfigX, getPortModel()));
response = lcConfigXResponse.getContent();
LOGGER.info("Prepared lcConfigXResponse: {}", ByteUtils.bytesToHex(response));
sendSpontanousResponse(response);
response = null;
}
// deliver light ports
for (LightPort lightPort : lightPorts.values()) {
values.clear();
LOGGER.info("Return config of light port: {}", lightPort);
BidibPort bidibPort = prepareBidibPort(getPortModel(), LcOutputType.LIGHTPORT, lightPort.getId());
LcConfigX lcConfigX = new LcConfigX(bidibPort, values);
LcConfigXResponse lcConfigXResponse =
new LcConfigXResponse(bidibMessage.getAddr(), getNextSendNum(),
LcConfigX.getCodedPortConfig(null, lcConfigX, getPortModel()));
response = lcConfigXResponse.getContent();
LOGGER.info("Prepared lcConfigXResponse: {}", ByteUtils.bytesToHex(response));
sendSpontanousResponse(response);
response = null;
}
}
}
catch (ProtocolException ex) {
LOGGER.warn("Create lcConfigXResponse response failed.", ex);
}
}
protected byte[] processLcKeyQueryRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the LcKeyQuery request: {}", bidibMessage);
byte[] response = null;
byte keyState = 0;
Port> port = null;
try {
LcKeyMessage lcKeyMessage = (LcKeyMessage) bidibMessage;
int portNumber = lcKeyMessage.getBidibPort().getPortNumber(PortModelEnum.type);
port = inputPorts.get(portNumber);
keyState = port.getStatus().getType().getType();
LcKeyResponse lcKeyResponse =
new LcKeyResponse(bidibMessage.getAddr(), getNextSendNum(), ByteUtils.getLowByte(portNumber), keyState);
response = lcKeyResponse.getContent();
}
catch (ProtocolException ex) {
LOGGER.warn("Create LcKey response failed.", ex);
}
if (port != null) {
publishInputPortChange(port);
}
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(NodeUtils.formatAddress(nodeAddress), inputPort.getId(), status));
}
protected byte[] processLcPortQueryRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the LcOutputQuery request: {}", bidibMessage);
byte[] response = null;
byte portState = 0;
try {
final LcPortQueryMessage lcPortQueryMessage = (LcPortQueryMessage) bidibMessage;
LcOutputType outputType = lcPortQueryMessage.getPortType(getPortModel());
int portNumber = lcPortQueryMessage.getPortNumber(getPortModel());
switch (outputType) {
case INPUTPORT:
portState = inputPorts.get(portNumber).getStatus().getType().getType();
break;
case LIGHTPORT:
portState = lightPorts.get(portNumber).getStatus().getType().getType();
break;
case SWITCHPORT:
portState = switchPorts.get(portNumber).getStatus().getType().getType();
break;
case SERVOPORT:
portState = ByteUtils.getLowByte(servoPorts.get(portNumber).getValue());
break;
default:
LOGGER.warn("LcOutputQuery for unsupported port type detected: {}", outputType);
break;
}
BidibPort bidibPort = prepareBidibPort(getPortModel(), outputType, portNumber);
LcStatResponse lcStatResponse =
new LcStatResponse(bidibMessage.getAddr(), getNextSendNum(), bidibPort, portState);
response = lcStatResponse.getContent();
}
catch (ProtocolException ex) {
LOGGER.warn("Create LcStat response failed.", ex);
}
return response;
}
protected byte[] processLcPortQueryAllRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the PortQueryAll request: {}", bidibMessage);
byte[] response = null;
try {
LcPortQueryAllMessage portQueryAllMessage = (LcPortQueryAllMessage) bidibMessage;
int portRangeFrom = portQueryAllMessage.getPortRangeFrom(getPortModel());
int portRangeTo = portQueryAllMessage.getPortRangeTo(getPortModel());
int portTypeMask = portQueryAllMessage.getPortTypeMask();
LOGGER
.info("Query all port states, portRangeFrom: {}, portRangeTo: {}, portModel: {}, portTypeMask: {}",
portRangeFrom, portRangeTo, getPortModel(), portTypeMask);
if (PortConfigUtils.isSupportsInputPort(portTypeMask) && MapUtils.isNotEmpty(inputPorts)) {
for (InputPort inputPort : inputPorts.values()) {
if (inputPort.getId() >= portRangeFrom && inputPort.getId() < portRangeTo) {
try {
InputPortStatus inputPortStatus = inputPort.getStatus();
if (inputPortStatus == null) {
inputPort.setStatus(InputPortStatus.OFF);
inputPortStatus = inputPort.getStatus();
}
byte portStatus = inputPortStatus.getType().getType();
publishPortState(bidibMessage.getAddr(), LcOutputType.INPUTPORT, inputPort.getId(),
portStatus);
}
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) && MapUtils.isNotEmpty(lightPorts)) {
for (LightPort lightPort : lightPorts.values()) {
if (lightPort.getId() >= portRangeFrom && lightPort.getId() < portRangeTo) {
try {
LightPortStatus lightPortStatus = lightPort.getStatus();
if (lightPortStatus == null) {
lightPort.setStatus(LightPortStatus.OFF);
lightPortStatus = lightPort.getStatus();
}
byte portStatus = lightPortStatus.getType().getType();
publishPortState(bidibMessage.getAddr(), LcOutputType.LIGHTPORT, lightPort.getId(),
portStatus);
}
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) && MapUtils.isNotEmpty(switchPorts)) {
for (SwitchPort switchPort : switchPorts.values()) {
if (switchPort.getId() >= portRangeFrom && switchPort.getId() < portRangeTo) {
try {
SwitchPortStatus switchPortStatus = switchPort.getStatus();
if (switchPortStatus == null) {
switchPort.setStatus(SwitchPortStatus.OFF);
switchPortStatus = switchPort.getStatus();
}
byte portStatus = switchPortStatus.getType().getType();
publishPortState(bidibMessage.getAddr(), LcOutputType.SWITCHPORT, switchPort.getId(),
portStatus);
}
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.isSupportsServoPort(portTypeMask) && MapUtils.isNotEmpty(servoPorts)) {
for (ServoPort servoPort : servoPorts.values()) {
if (servoPort.getId() >= portRangeFrom && servoPort.getId() < portRangeTo) {
try {
ServoPortStatus servoPortStatus = servoPort.getStatus();
if (servoPortStatus == null) {
servoPort.setStatus(ServoPortStatus.START);
servoPortStatus = servoPort.getStatus();
}
byte portStatus = servoPortStatus.getType().getType();
publishPortState(bidibMessage.getAddr(), LcOutputType.SERVOPORT, servoPort.getId(),
portStatus);
}
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);
}
}
}
LOGGER.info("Send the terminating LC_NA message.");
publishLcNaResponse(bidibMessage.getAddr());
}
catch (ProtocolException ex) {
LOGGER.warn("Create LcStat response failed.", ex);
}
return response;
}
protected void publishPortState(byte[] address, LcOutputType outputType, int outputNumber, byte portStatus)
throws ProtocolException {
BidibPort bidibPort = prepareBidibPort(getPortModel(), outputType, outputNumber);
LcStatResponse lcStatResponse = new LcStatResponse(address, getNextSendNum(), bidibPort, portStatus);
LOGGER.info("Prepared LcStatResponse: {}", lcStatResponse);
byte[] response = lcStatResponse.getContent();
sendSpontanousResponse(response);
}
protected void publishLcNaResponse(byte[] address) throws ProtocolException {
BidibPort bidibPort = new BidibPort(new byte[] { ByteUtils.getLowByte(0xFF), ByteUtils.getLowByte(0xFF) });
LcNotAvailableResponse lcNotAvailableResponse =
new LcNotAvailableResponse(address, getNextSendNum(), bidibPort);
LOGGER.info("Prepared LcNotAvailableResponse: {}", lcNotAvailableResponse);
byte[] response = lcNotAvailableResponse.getContent();
sendSpontanousResponse(response);
}
protected byte[] processLcMacroParaGetRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the LcMacroParaGet request: {}", bidibMessage);
byte[] response = null;
try {
LcMacroParaGetMessage lcMacroParaGetMessage = (LcMacroParaGetMessage) bidibMessage;
int macroNumber = lcMacroParaGetMessage.getMacroNumber();
int paramId = lcMacroParaGetMessage.getParameterIndex();
LOGGER.info("Process macroNumber: {}, paramId: {}", macroNumber, paramId);
// return the stored parameter value
MacroContainer container = macros.get(macroNumber);
if (container == null) {
LOGGER.info("Create new MacroContainer for macro number: {}", macroNumber);
// initialize a new macro container
container = new MacroContainer(macroNumber);
macros.put(macroNumber, container);
}
byte[] parameter = container.getMacroParameter(paramId);
LcMacroParaResponse lcMacroParaResponse =
new LcMacroParaResponse(bidibMessage.getAddr(), getNextSendNum(), (byte) macroNumber, (byte) paramId,
parameter);
response = lcMacroParaResponse.getContent();
}
catch (ProtocolException ex) {
LOGGER.warn("Create LcMacroPara response failed.", ex);
}
return response;
}
protected byte[] processLcMacroParaSetRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the LcMacroParaSet request: {}", bidibMessage);
byte[] response = null;
try {
LcMacroParaSetMessage lcMacroParaSetMessage = (LcMacroParaSetMessage) bidibMessage;
int macroNumber = lcMacroParaSetMessage.getMacroNumber();
int paramId = lcMacroParaSetMessage.getParameterIndex();
byte[] parameter = lcMacroParaSetMessage.getValue();
// store the parameter value
MacroContainer container = macros.get(macroNumber);
if (container == null) {
// initialize a new macro container
container = new MacroContainer(macroNumber);
macros.put(macroNumber, container);
}
container.setMacroParameter(paramId, parameter);
LcMacroParaResponse lcMacroParaResponse =
new LcMacroParaResponse(bidibMessage.getAddr(), getNextSendNum(), (byte) macroNumber, (byte) paramId,
parameter);
response = lcMacroParaResponse.getContent();
}
catch (ProtocolException ex) {
LOGGER.warn("Create LcMacroPara response failed.", ex);
}
return response;
}
protected byte[] processLcMacroHandleRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the LcMacroHandle request: {}", bidibMessage);
byte[] response = null;
try {
LcMacroHandleMessage lcMacroHandleMessage = (LcMacroHandleMessage) bidibMessage;
Integer macroNumber = lcMacroHandleMessage.getMacroNumber();
LcMacroOperationCode lcMacroOperationCode = lcMacroHandleMessage.getMacroOperationCode();
LOGGER
.info("Handle macro request, macroNumber: {}, lcMacroOperationCode: {}", macroNumber,
lcMacroOperationCode);
// TODO store the macro state value
LcMacroState macroState = null;
switch (lcMacroOperationCode) {
case START:
macroState = LcMacroState.RUNNING;
break;
case DELETE:
macroState = LcMacroState.DELETE;
LOGGER.info("Remove macro with number: {}", macroNumber);
macros.remove(macroNumber);
break;
case OFF:
macroState = LcMacroState.OFF;
break;
case RESTORE:
macroState = LcMacroState.RESTORE;
break;
case SAVE:
macroState = LcMacroState.SAVE;
break;
default:
macroState = LcMacroState.NOTEXIST;
break;
}
LcMacroStateResponse lcMacroStateResponse =
new LcMacroStateResponse(bidibMessage.getAddr(), getNextSendNum(), ByteUtils.getLowByte(macroNumber),
macroState);
response = lcMacroStateResponse.getContent();
}
catch (ProtocolException ex) {
LOGGER.warn("Create LcMacroState response failed.", ex);
}
return response;
}
protected byte[] processLcMacroGetRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the LcMacroGet request: {}", bidibMessage);
byte[] response = null;
try {
LcMacroGetMessage lcMacroGetMessage = (LcMacroGetMessage) bidibMessage;
Integer macroNumber = lcMacroGetMessage.getMacroNumber();
int stepNumber = lcMacroGetMessage.getStep();
// fetch the macro content and test if the macro is available
MacroContainer container = macros.get(macroNumber);
if (container == null) {
// initialize a new macro container
container = new MacroContainer(macroNumber);
macros.put(macroNumber, container);
}
LcMacro macroStep = container.getMacroStep(stepNumber);
LcMacro value = macroStep;
LcMacroResponse lcMacroResponse =
new LcMacroResponse(bidibMessage.getAddr(), getNextSendNum(), ByteUtils.getLowByte(macroNumber),
ByteUtils.getLowByte(stepNumber), value);
response = lcMacroResponse.getContent();
}
catch (ProtocolException ex) {
LOGGER.warn("Create LcMacro response failed.", ex);
}
return response;
}
protected byte[] processLcMacroSetRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the LcMacroSet request: {}", bidibMessage);
byte[] response = null;
try {
LcMacroSetMessage lcMacroSetMessage = (LcMacroSetMessage) bidibMessage;
int macroNumber = lcMacroSetMessage.getMacroNumber();
int stepNumber = lcMacroSetMessage.getStep();
LcMacro macroStep = MacroUtils.getMacro(lcMacroSetMessage.getData());
LOGGER.info("Current macroNumber: {}, stepNumber: {}, macroStep: {}", macroNumber, stepNumber, macroStep);
// fetch the macro content and test if the macro container is available
MacroContainer container = macros.get(macroNumber);
if (container == null) {
container = new MacroContainer(macroNumber);
macros.put(macroNumber, container);
}
container.setMacroStep(stepNumber, macroStep);
try {
LcMacroResponse lcMacroResponse =
new LcMacroResponse(bidibMessage.getAddr(), getNextSendNum(), ByteUtils.getLowByte(macroNumber),
ByteUtils.getLowByte(stepNumber), macroStep);
response = lcMacroResponse.getContent();
}
catch (NullPointerException npe) {
LOGGER.warn("create response failed.", npe);
}
}
catch (ProtocolException ex) {
LOGGER.warn("Create LcMacro response failed.", ex);
}
return response;
}
protected byte[] processAccessorySetRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the AccessorySet request: {}", bidibMessage);
byte[] response = null;
try {
AccessorySetMessage accessorySetMessage = (AccessorySetMessage) bidibMessage;
int accessoryNumber = accessorySetMessage.getAccessoryNumber();
int aspect = accessorySetMessage.getAspect();
byte[] value = new byte[] { 0, 0, 0 };
AccessoryStateResponse accessoryStateResponse =
new AccessoryStateResponse(bidibMessage.getAddr(), getNextSendNum(), (byte) accessoryNumber,
(byte) aspect, value);
response = accessoryStateResponse.getContent();
}
catch (ProtocolException ex) {
LOGGER.warn("Create AccessoryState response failed.", ex);
}
return response;
}
protected byte[] processAccessoryGetRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the AccessoryGet request: {}", bidibMessage);
byte[] response = null;
try {
AccessoryGetMessage accessoryGetMessage = (AccessoryGetMessage) bidibMessage;
int accessoryNumber = accessoryGetMessage.getAccessoryNumber();
int aspect = 0;
byte[] value = new byte[] { 3 /* total */, 0 /* execute */, 0 /* wait */ };
Feature featureAccessoryMacroMapped =
Feature.findFeature(features, BidibLibrary.FEATURE_ACCESSORY_MACROMAPPED);
if (featureAccessoryMacroMapped != null && featureAccessoryMacroMapped.getValue() > 0) {
value[0] = 0; // no aspects by default if macro-mapped
if (accessoryNumber == 2) {
value[0] = 8; // 8 non-macro mapped aspects for accessory number 2
aspect = 2; // aspect 2 is active
}
}
AccessoryStateResponse accessoryStateResponse =
new AccessoryStateResponse(bidibMessage.getAddr(), getNextSendNum(), (byte) accessoryNumber,
(byte) aspect, value);
response = accessoryStateResponse.getContent();
}
catch (ProtocolException ex) {
LOGGER.warn("Create AccessoryState response failed.", ex);
}
return response;
}
protected byte[] processAccessoryGetAllRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the AccessoryGetAll request: {}", bidibMessage);
byte[] response = null;
try {
Feature featureAccessoryCount = Feature.findFeature(features, BidibLibrary.FEATURE_ACCESSORY_COUNT);
int accessoryCount = featureAccessoryCount.getValue();
int aspect = 0;
for (int accessoryNumber = 0; accessoryNumber < accessoryCount; accessoryNumber++) {
byte[] value = new byte[] { 3 /* total */, 0 /* execute */, 0 /* wait */ };
Feature featureAccessoryMacroMapped =
Feature.findFeature(features, BidibLibrary.FEATURE_ACCESSORY_MACROMAPPED);
if (featureAccessoryMacroMapped != null && featureAccessoryMacroMapped.getValue() > 0) {
value[0] = 0; // no aspects by default if macro-mapped
if (accessoryNumber == 2) {
value[0] = 8; // 8 non-macro mapped aspects for accessory number 2
aspect = 2; // aspect 2 is active
}
}
LOGGER.info("Return data for accessory: {}, data: {}", accessoryNumber, ByteUtils.bytesToHex(value));
AccessoryStateResponse accessoryStateResponse =
new AccessoryStateResponse(bidibMessage.getAddr(), getNextSendNum(), (byte) accessoryNumber,
(byte) aspect, value);
response = accessoryStateResponse.getContent();
sendSpontanousResponse(response);
}
}
catch (ProtocolException ex) {
LOGGER.warn("Create AccessoryState response failed.", ex);
}
return null;
}
protected byte[] processAccessoryParaSetRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the AccessoryParaSet request: {}", bidibMessage);
byte[] response = null;
try {
AccessoryParaSetMessage accessoryParaSetMessage = (AccessoryParaSetMessage) bidibMessage;
int accessoryNumber = accessoryParaSetMessage.getAccessoryNumber();
int paraNumber = accessoryParaSetMessage.getParaNumber();
byte[] value = accessoryParaSetMessage.getValue();
if (accessoryNumber == 3 && paraNumber == BidibLibrary.BIDIB_ACCESSORY_PARA_MACROMAP) {
LOGGER.info("Do not allow change PARA_MACROMAP for accessory number 3!");
value = new byte[] { 0, 1, 2, 3 };
}
AccessoryParaResponse accessoryParaResponse =
new AccessoryParaResponse(bidibMessage.getAddr(), getNextSendNum(),
ByteUtils.getLowByte(accessoryNumber), ByteUtils.getLowByte(paraNumber), value);
response = accessoryParaResponse.getContent();
}
catch (ProtocolException ex) {
LOGGER.warn("Create AccessoryPara response failed.", ex);
}
return response;
}
protected byte[] processAccessoryParaGetRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the AccessoryParaGet request: {}", bidibMessage);
byte[] response = null;
try {
AccessoryParaGetMessage accessoryParaGetMessage = (AccessoryParaGetMessage) bidibMessage;
int accessoryNumber = accessoryParaGetMessage.getAccessoryNumber();
int paraNumber = accessoryParaGetMessage.getParaNumber();
// TODO provide the correct data here ...
byte[] value = new byte[] { 0, 0, 0, 0 };
if (paraNumber == BidibLibrary.BIDIB_ACCESSORY_SWITCH_TIME) {
LOGGER.info("The param is not known currently!");
value = new byte[] { ByteUtils.getLowByte(paraNumber) };
paraNumber = BidibLibrary.BIDIB_ACCESSORY_PARA_NOTEXIST;
}
else if (paraNumber == BidibLibrary.BIDIB_ACCESSORY_PARA_MACROMAP) {
value = new byte[] { 0, 1, 2, 3 };
}
if (accessoryNumber == 2 && paraNumber == BidibLibrary.BIDIB_ACCESSORY_PARA_MACROMAP) {
LOGGER.info("Do not signal PARA_MACROMAP for accessory number 2!");
value = new byte[] { ByteUtils.getLowByte(paraNumber) };
paraNumber = BidibLibrary.BIDIB_ACCESSORY_PARA_NOTEXIST;
}
if (accessoryNumber == 2 && paraNumber == BidibLibrary.BIDIB_ACCESSORY_PARA_STARTUP) {
LOGGER.info("PARA_STARTUP == 2 for accessory number 2!");
// aspect 2 is startup aspect
value = new byte[] { ByteUtils.getLowByte(2) };
}
AccessoryParaResponse accessoryParaResponse =
new AccessoryParaResponse(bidibMessage.getAddr(), getNextSendNum(),
ByteUtils.getLowByte(accessoryNumber), ByteUtils.getLowByte(paraNumber), value);
response = accessoryParaResponse.getContent();
}
catch (ProtocolException ex) {
LOGGER.warn("Create AccessoryPara response failed.", ex);
}
return response;
}
protected byte[] processBmGetRangeRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the FeedbackGetRangeMessage: {}", bidibMessage);
byte[] response = null;
try {
FeedbackGetRangeMessage feedbackGetRangeMessage = (FeedbackGetRangeMessage) bidibMessage;
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 = feedbackPorts.get(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));
FeedbackMultipleResponse feedbackMultipleResponse =
new FeedbackMultipleResponse(bidibMessage.getAddr(), getNextSendNum(),
ByteUtils.getLowByte(baseAddress), ByteUtils.getLowByte(feedbackSize), feedbackMultiple);
response = feedbackMultipleResponse.getContent();
}
catch (ProtocolException ex) {
LOGGER.warn("Create feedbackMultiple response failed.", ex);
}
return response;
}
protected void processBmMirrorMultipleRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the FeedbackMirrorMultipleMessage: {}, do nothing ...", bidibMessage);
}
protected void processBmMirrorOccupiedRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the processBmMirrorOccupiedRequest: {}, do nothing ...", bidibMessage);
}
protected void processBmMirrorFreeRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the processBmMirrorFreeRequest: {}, do nothing ...", bidibMessage);
}
@Override
public void queryStatus(Class> portClass) {
if (InputPort.class.equals(portClass)) {
for (InputPort inputPort : inputPorts.values()) {
publishInputPortChange(inputPort);
}
}
else if (LightPort.class.equals(portClass)) {
for (LightPort lightPort : lightPorts.values()) {
publishLightPortChange(lightPort);
}
}
else if (SwitchPort.class.equals(portClass)) {
for (SwitchPort switchPort : switchPorts.values()) {
publishSwitchPortChange(switchPort);
}
}
else if (ServoPort.class.equals(portClass)) {
for (ServoPort servoPort : servoPorts.values()) {
publishServoPortChange(servoPort);
}
}
else if (FeedbackPort.class.equals(portClass)) {
for (FeedbackPort feedbackPort : feedbackPorts.values()) {
publishFeedbackPortChange(feedbackPort);
}
// publish the confidence
publishFeedbackConfidenceStatusEvent(statusValid.get(), statusFreeze.get(), statusSignal.get());
}
}
@Override
public void setPortsConfig(FlatPortType portType) {
}
@Override
public void setPortsConfig(PortType portType) {
if (portType == null) {
return;
}
LOGGER.debug("Set the ports config: {}", portType);
if (portType instanceof LightPortType) {
LightPortType lightPortType = (LightPortType) portType;
lightPortCount = lightPortType.getCount();
LOGGER.info("Total number of lightports: {}", lightPortCount);
lightPorts.clear();
// prepare initial lightports
for (int portId = 0; portId < lightPortCount; portId++) {
LightPort lightPort = new LightPort();
lightPort.setId(portId);
// add the unconfigured lightport
lightPorts.put(portId, lightPort);
}
prepareLightPortCvValuesFromConfig(lightPortType);
}
else if (portType instanceof SwitchPortType) {
switchPortCount = portType.getCount();
LOGGER.info("Configured number of switch ports: {}", switchPortCount);
}
else if (portType instanceof InputPortType) {
inputPortCount = portType.getCount();
inputPortOffset = (portType.getOffset() != null ? portType.getOffset() : 0);
LOGGER.info("Configured number of input ports: {}", inputPortCount);
}
else if (portType instanceof ServoPortType) {
servoPortCount = portType.getCount();
}
}
protected void prepareLightPortCvValuesFromConfig(final LightPortType lightPortType) {
// overwrite configured ports
if (CollectionUtils.isNotEmpty(lightPortType.getPort())) {
final int cvBaseOffset = 215 /* offset */;
// evaluate the configured ports
for (LightPortParamsType portParams : lightPortType.getPort()) {
LightPort lightPort = new LightPort();
lightPort.setId(portParams.getPortId());
lightPort.setDimMin(portParams.getDimSlopeDown());
lightPort.setDimMax(portParams.getDimSlopeUp());
lightPort.setPwmMax(portParams.getIntensityOn());
lightPort.setPwmMin(portParams.getIntensityOff());
if (portParams.getRgbValue() != null) {
try {
Integer rgbValue = Integer.parseInt(portParams.getRgbValue(), 16);
lightPort.setRgbValue(rgbValue);
}
catch (Exception ex) {
LOGGER.warn("Parse RGB value failed: {}", portParams.getRgbValue(), ex);
lightPort.setRgbValue(null);
}
}
if (portParams.getTransitionTime() != null) {
lightPort.setTransitionTime(portParams.getTransitionTime());
}
lightPort.setConfigStatus(PortConfigStatus.CONFIG_PASSED);
lightPort.setStatus(LightPortStatus.OFF);
LOGGER.info("Add configured port: {}", lightPort);
// add the configured port
lightPorts.put(lightPort.getId(), lightPort);
// prepare the CVs
int cvOffset = cvBaseOffset + portParams.getPortId() * 7 /* next */;
configurationVariables.put(String.valueOf(cvOffset), String.valueOf(-1));
configurationVariables.put(String.valueOf(cvOffset + 1), String.valueOf(lightPort.getPwmMin()));
configurationVariables.put(String.valueOf(cvOffset + 2), String.valueOf(lightPort.getPwmMax()));
configurationVariables
.put(String.valueOf(cvOffset + 3), String.valueOf(ByteUtils.getLowByte(lightPort.getDimMin())));
configurationVariables
.put(String.valueOf(cvOffset + 4), String.valueOf(ByteUtils.getHighByte(lightPort.getDimMin())));
configurationVariables
.put(String.valueOf(cvOffset + 5), String.valueOf(ByteUtils.getLowByte(lightPort.getDimMax())));
configurationVariables
.put(String.valueOf(cvOffset + 6), String.valueOf(ByteUtils.getHighByte(lightPort.getDimMax())));
}
// use the number of configured ports
lightPortCount = lightPorts.size();
}
}
public int getInputPortOffset() {
return inputPortOffset;
}
protected void setFeedbackPortStatus(FeedbackPortSetStatusEvent statusEvent) throws ProtocolException {
int portNum = statusEvent.getPortNum();
FeedbackPort port = feedbackPorts.get(portNum);
if (port != null) {
BidibMessage response = null;
// BidibMessage responsePosition = null;
switch (statusEvent.getStatus()) {
case OCCUPIED:
port.setStatus(FeedbackPortStatus.OCCUPIED);
if (hasTimestampFeature()) {
response =
new FeedbackOccupiedResponse(getNodeAddress(), getNextSendNum(), portNum, getTimestamp());
}
else {
response = new FeedbackOccupiedResponse(getNodeAddress(), getNextSendNum(), portNum);
}
break;
default:
port.setStatus(FeedbackPortStatus.FREE);
response = new FeedbackFreeResponse(getNodeAddress(), getNextSendNum(), portNum);
break;
}
LOGGER.info("Prepared the FeedbackFreeResponse: {}", response);
sendSpontanousResponse(response.getContent());
publishFeedbackPortChange(port);
}
else {
LOGGER.warn("The requested feedback port is not available: {}", portNum);
}
}
private void publishFeedbackPortChange(Port> port) {
FeedbackPort feedbackPort = (FeedbackPort) port;
FeedbackPortStatus status = feedbackPort.getStatus();
LOGGER.info("The feedbackport status has changed, notify the listeners, nodeAddress: {}", nodeAddress);
EventBus.publish(new FeedbackPortStatusEvent(NodeUtils.formatAddress(nodeAddress), port.getId(), status));
}
private int timestamp;
private int getTimestamp() {
timestamp += 10;
if (timestamp > 65000) {
timestamp = 0;
}
return timestamp;
}
private boolean hasTimestampFeature() {
Feature feature = Feature.findFeature(features, BidibLibrary.FEATURE_BM_TIMESTAMP_ON);
return (feature != null && feature.getValue() > 0);
}
protected byte[] processBmGetConfidenceRequest(BidibMessageInterface bidibMessage) {
byte[] response = null;
try {
byte valid = (byte) (statusValid.get() ? 1 : 0);
byte freeze = (byte) (statusFreeze.get() ? 1 : 0);
byte signal = (byte) (statusSignal.get() ? 1 : 0);
// TODO if more than a single GBM16T is attached we must set more bits? See 4.7.4. Uplink: Nachrichten für
// Belegtmelder --> MSG_BM_CONFIDENCE
// Test with real system: See MainMessageListener.confidence()
FeedbackConfidenceResponse feedbackConfidenceResponse =
new FeedbackConfidenceResponse(bidibMessage.getAddr(), getNextSendNum(), valid, freeze, signal);
response = feedbackConfidenceResponse.getContent();
}
catch (ProtocolException ex) {
LOGGER.warn("Create feedbackConfidence response failed.", ex);
}
return response;
}
private void triggerFeedbackAddressResponse(int portNum) {
LOGGER.info("Trigger the feedback address repsonse, portNum: {}", portNum);
byte[] response = null;
List addresses = new LinkedList();
byte lowByte = 3;
byte highByte = ByteUtils.getLowByte(0x80);
int address = ByteUtils.getWord(lowByte, (byte) (highByte & 0x3F));
AddressData addressDataIn = new AddressData(address, AddressTypeEnum.valueOf((byte) ((highByte & 0xC0) >> 6)));
addresses.add(new FeedbackAddressData(addressDataIn.getAddress(), EnrailmentDirectionEnum.LOCOMOTIVE_RIGHT));
// }
try {
FeedbackPort feedbackPort = feedbackPorts.get(portNum);
int detectorNumber = feedbackPort.getId();
List bidibAddresses = new ArrayList<>();
if (FeedbackPortStatus.OCCUPIED == feedbackPort.getStatus()) {
// port is occupied -> add the addresses
if (CollectionUtils.isNotEmpty(addresses)) {
for (FeedbackAddressData addressData : addresses) {
final EnrailmentDirectionEnum enrailmentDirection = addressData.getType();
AddressTypeEnum addressType = null;
switch (enrailmentDirection) {
case LOCOMOTIVE_LEFT:
case LOCOMOTIVE_RIGHT:
addressType = AddressTypeEnum.LOCOMOTIVE_FORWARD;
break;
case BASIC_ACCESSORY:
addressType = AddressTypeEnum.ACCESSORY;
break;
case EXTENDED_ACCESSORY:
addressType = AddressTypeEnum.EXTENDED_ACCESSORY;
break;
default:
break;
}
AddressData bidibAddress = new AddressData(addressData.getAddress(), addressType);
bidibAddresses.add(bidibAddress);
}
}
}
FeedbackAddressResponse feedbackAddressResponse =
new FeedbackAddressResponse(nodeAddress, getNextSendNum(), detectorNumber, bidibAddresses);
response = feedbackAddressResponse.getContent();
sendSpontanousResponse(response);
if (FeedbackPortStatus.OCCUPIED == feedbackPort.getStatus()) {
int speedValue = ThreadLocalRandom.current().nextInt(2, 100);
FeedbackSpeedResponse feedbackSpeedResponse =
new FeedbackSpeedResponse(nodeAddress, getNextSendNum(), address, speedValue);
sendSpontanousResponse(feedbackSpeedResponse.getContent());
}
}
catch (ProtocolException ex) {
LOGGER.warn("Create FeedbackAddressResponse failed.", ex);
}
}
@EventSubscriber(eventClass = FeedbackConfidenceSetEvent.class)
public void feedbackConfidenceSetEvent(FeedbackConfidenceSetEvent feedbackConfidenceEvent) {
String nodeAddress = feedbackConfidenceEvent.getNodeAddr();
LOGGER.info("The change of the feedback confidence was requested, nodeAddress: {}", nodeAddress);
// check if the node is addressed
if (!isAddressEqual(nodeAddress)) {
LOGGER.trace("Another node is addressed.");
return;
}
statusValid.set(feedbackConfidenceEvent.getValid());
statusFreeze.set(feedbackConfidenceEvent.getFreeze());
statusSignal.set(feedbackConfidenceEvent.getSignal());
byte valid = (byte) (statusValid.get() ? 1 : 0);
byte freeze = (byte) (statusFreeze.get() ? 1 : 0);
byte signal = (byte) (statusSignal.get() ? 1 : 0);
try {
FeedbackConfidenceResponse feedbackConfidenceResponse =
new FeedbackConfidenceResponse(this.nodeAddress, getNextSendNum(), valid, freeze, signal);
LOGGER.info("Prepared feedbackConfidenceResponse: {}", feedbackConfidenceResponse);
sendSpontanousResponse(feedbackConfidenceResponse.getContent());
}
catch (ProtocolException ex) {
LOGGER.warn("Send feedbackConfidenceResponse failed.", ex);
}
publishFeedbackConfidenceStatusEvent(statusValid.get(), statusFreeze.get(), statusSignal.get());
}
private void publishFeedbackConfidenceStatusEvent(boolean valid, boolean freeze, boolean signal) {
LOGGER
.info("The feedbackport confidence status has changed, notify the listeners, nodeAddress: {}", nodeAddress);
EventBus
.publish(new FeedbackConfidenceStatusEvent(NodeUtils.formatAddress(nodeAddress), valid, freeze, signal));
}
}