
org.bidib.wizard.simulation.ReadyServo8Simulator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bidibwizard-simulation Show documentation
Show all versions of bidibwizard-simulation Show documentation
jBiDiB BiDiB Wizard Simulation POM
package org.bidib.wizard.simulation;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.collections4.MapUtils;
import org.bidib.jbidibc.messages.BidibLibrary;
import org.bidib.jbidibc.messages.BidibPort;
import org.bidib.jbidibc.messages.Feature;
import org.bidib.jbidibc.messages.LcConfigX;
import org.bidib.jbidibc.messages.enums.InputPortEnum;
import org.bidib.jbidibc.messages.enums.LcOutputType;
import org.bidib.jbidibc.messages.enums.SwitchPortEnum;
import org.bidib.jbidibc.messages.exception.ProtocolException;
import org.bidib.jbidibc.messages.message.BidibMessageInterface;
import org.bidib.jbidibc.messages.message.BidibRequestFactory;
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.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.PortConfigUtils;
import org.bidib.jbidibc.messages.port.PortConfigValue;
import org.bidib.jbidibc.messages.port.ReconfigPortConfigValue;
import org.bidib.jbidibc.messages.utils.ByteUtils;
import org.bidib.jbidibc.messages.utils.NodeUtils;
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.InputPortType;
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.GenericPort;
import org.bidib.wizard.model.ports.InputPort;
import org.bidib.wizard.model.ports.ServoPort;
import org.bidib.wizard.model.ports.SwitchPort;
import org.bidib.wizard.model.status.InputPortStatus;
import org.bidib.wizard.model.status.SwitchPortStatus;
import org.bidib.wizard.simulation.events.InputPortSetStatusEvent;
import org.bidib.wizard.simulation.events.InputPortStatusEvent;
import org.bidib.wizard.simulation.events.PortConfigEvent;
import org.bidib.wizard.simulation.events.ServoPortStatusEvent;
import org.bidib.wizard.simulation.events.SwitchPortStatusEvent;
import org.bidib.wizard.simulation.ports.GenericSimulationPort;
import org.bidib.wizard.simulation.ports.PortListUtils;
import org.bushe.swing.event.EventBus;
import org.bushe.swing.event.annotation.EventSubscriber;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@BidibNodeSimulators({ @BidibNodeSimulator(vid = "251", pid = "232") })
public class ReadyServo8Simulator extends LightControlSimulator implements SwitchingFunctionsNode {
private static final Logger LOGGER = LoggerFactory.getLogger(ReadyServo8Simulator.class);
private static final String SIMULATION_PANEL_CLASS =
"org.bidib.wizard.simulation.client.view.panel.ReadyServo8Panel";
private final Map genericPorts = new HashMap();
public ReadyServo8Simulator(byte[] nodeAddress, long uniqueId, boolean autoAddFeature,
SimulationBidibMessageProcessor messageReceiver, final BidibRequestFactory bidibRequestFactory) {
super(nodeAddress, uniqueId, autoAddFeature, messageReceiver, bidibRequestFactory);
}
@Override
public String getSimulationPanelClass() {
return SIMULATION_PANEL_CLASS;
}
@Override
public void postConstruct() {
super.postConstruct();
Feature feature = getFeature(BidibLibrary.FEATURE_CTRL_PORT_FLAT_MODEL);
if (feature != null && MapUtils.isEmpty(genericPorts)) {
LOGGER.info("The current simulator has the flat model configured. Prepare the generic ports.");
int numPorts = feature.getValue();
LOGGER.info("Create generic ports, numPorts: {}", numPorts);
servoPortCount = 8;
switchPortCount = 8; // GPIO port count
inputPortOffset = switchPortCount;
for (int portNumber = 0; portNumber < numPorts; portNumber++) {
GenericSimulationPort port = new GenericSimulationPort(portNumber);
int mask = 0;
// port 0..7 are servo ports
if (portNumber >= 0 && portNumber < 8) {
port.setPortValue(120);
mask = 1 << BidibLibrary.BIDIB_PORTTYPE_SERVO;
port.setCurrentPortType(LcOutputType.SERVOPORT, mask);
}
else {
// GPIO input and switch port
port
.setPortStatus(portNumber % 2 == 0 ? InputPortStatus.ON.getType().getType()
: InputPortStatus.OFF.getType().getType());
mask = (1 << BidibLibrary.BIDIB_PORTTYPE_INPUT | 1 << BidibLibrary.BIDIB_PORTTYPE_SWITCH);
port.setCurrentPortType(LcOutputType.INPUTPORT, mask);
}
LOGGER.info("Register genericPort, portNumber: {}, port: {}", portNumber, port);
genericPorts.put(portNumber, port);
}
}
else {
LOGGER.info("Skip init the ports because the ports are available already.");
if (MapUtils.isNotEmpty(genericPorts)) {
LOGGER.info("Set the feature FEATURE_CTRL_PORT_FLAT_MODEL to value: {}", genericPorts.size());
features.add(new Feature(BidibLibrary.FEATURE_CTRL_PORT_FLAT_MODEL, genericPorts.size()));
}
}
}
@Override
protected void prepareFeatures() {
LOGGER.info("Prepare the features.");
super.prepareFeatures();
}
@Override
public void start() {
LOGGER.info("Start the simulator for address: {}", getAddress());
super.start();
if (!MapUtils.isEmpty(genericPorts)) {
int index = 0;
for (int portNum = 0; portNum < servoPortCount; portNum++) {
GenericSimulationPort genericPort = genericPorts.get(portNum + index);
genericPort.setCurrentPortType(LcOutputType.SERVOPORT, 0x0004);
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(200)));
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(0)));
genericPort.setPortConfigX(portConfig);
genericPort.setPortValue(ServoPort.getAbsoluteValue((portNum % 4) * 25));
}
index += servoPortCount;
// this is a hack for the ReadyServo8
LOGGER.info("Set the port type for GPIO ports, index: {}, switchPortCount: {}", index, switchPortCount);
for (int portNum = 0; portNum < switchPortCount; portNum++) {
GenericSimulationPort genericPort = genericPorts.get(portNum + index);
int mask = (1 << BidibLibrary.BIDIB_PORTTYPE_SWITCH | 1 << BidibLibrary.BIDIB_PORTTYPE_INPUT);
genericPort.setCurrentPortType(LcOutputType.SWITCHPORT, mask);
LOGGER.info("The current port is configured as INPUT port: {}", genericPort);
Map> portConfig = genericPort.getPortConfigX();
portConfig.remove(BidibLibrary.BIDIB_PCFG_RECONFIG);
portConfig.put(BidibLibrary.BIDIB_PCFG_LOAD_TYPE, new BytePortConfigValue(Byte.valueOf((byte) 0x00)));
portConfig.put(BidibLibrary.BIDIB_PCFG_INPUT_CTRL, new BytePortConfigValue(Byte.valueOf((byte) 0x02)));
portConfig.put(BidibLibrary.BIDIB_PCFG_TICKS, new BytePortConfigValue(Byte.valueOf((byte) 0x1E)));
genericPort.setPortConfigX(portConfig);
}
}
}
@Override
public void stop() {
super.stop();
}
@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_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_PARA_SET:
response = processAccessoryParaSetRequest(bidibMessage);
break;
case BidibLibrary.MSG_ACCESSORY_PARA_GET:
response = processAccessoryParaGetRequest(bidibMessage);
break;
default:
response = super.prepareResponse(bidibMessage);
break;
}
return response;
}
@Override
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();
GenericPort port = genericPorts.get(Integer.valueOf(outputNumber));
BidibPort bidibPort = BidibPort.prepareBidibPort(getPortModel(), outputType, outputNumber);
if (port != null) {
LcStatResponse lcStatResponse = null;
if (port.isMatchingPortType(LcOutputType.SERVOPORT)
|| port.isMatchingPortType(LcOutputType.BACKLIGHTPORT)) {
port.setPortValue(ByteUtils.getInt(outputStatus));
}
else {
port.setPortStatus(outputStatus);
}
lcStatResponse =
new LcStatResponse(bidibMessage.getAddr(), getNextSendNum(), bidibPort,
lcOutputMessage.getOutputStatus());
response = lcStatResponse.getContent();
}
else {
LOGGER.warn("No port available with portNumber: {}", outputNumber);
LcNotAvailableResponse lcNotAvailableResponse =
new LcNotAvailableResponse(bidibMessage.getAddr(), getNextSendNum(), bidibPort);
response = lcNotAvailableResponse.getContent();
}
if (port != null) {
switch (outputType) {
case INPUTPORT:
publishInputPortChange(port);
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 publishSwitchPortChange(GenericPort port) {
SwitchPortStatus status = SwitchPortStatus.valueOf(SwitchPortEnum.valueOf(port.getPortStatus()));
LOGGER.info("The switchport status has changed, notify the listeners, nodeAddress: {}", nodeAddress);
EventBus.publish(new SwitchPortStatusEvent(NodeUtils.formatAddress(nodeAddress), port.getPortNumber(), status));
}
private void publishServoPortChange(GenericPort port) {
Integer value = port.getPortValue();
LOGGER.info("The servoport status has changed, notify the listeners, nodeAddress: {}", nodeAddress);
EventBus.publish(new ServoPortStatusEvent(NodeUtils.formatAddress(nodeAddress), port.getPortNumber(), value));
}
@Override
protected byte[] processLcConfigXSetRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the LcConfigXSet request: {}", bidibMessage);
byte[] response = null;
try {
LcConfigXSetMessage lcConfigXSetMessage = (LcConfigXSetMessage) bidibMessage;
int outputNumber = lcConfigXSetMessage.getPortNumber(getPortModel());
LcOutputType outputType = lcConfigXSetMessage.getPortType(getPortModel());
GenericPort port = null;
port = genericPorts.get(Integer.valueOf(outputNumber));
LOGGER.info("Set LcConfig for output number: {}, port: {}", outputNumber, port);
BidibPort bidibPort = BidibPort.prepareBidibPort(getPortModel(), outputType, outputNumber);
boolean publishConfigChangeEvent = false;
if (port != null) {
Map> currentPortConfig = port.getPortConfigX();
// the problem here is that the BIDIB_PCFG_RECONFIG overwrites the supported port types
LcConfigX lcConfigX = lcConfigXSetMessage.getLcConfigX(messageLogger);
ReconfigPortConfigValue reconfig =
(ReconfigPortConfigValue) lcConfigX.getPortConfig().get(BidibLibrary.BIDIB_PCFG_RECONFIG);
if (reconfig != null) {
// Change of port type is requested, we must keep the supported port types
Integer supportedPortTypes = port.getSupportedPortTypes();
if (supportedPortTypes != null) {
ReconfigPortConfigValue newReconfig =
new ReconfigPortConfigValue(reconfig.getCurrentOutputType().getType(), supportedPortTypes);
LOGGER.info("Prepared BIDIB_PCFG_RECONFIG to replace: {}", newReconfig);
lcConfigX.getPortConfig().put(BidibLibrary.BIDIB_PCFG_RECONFIG, newReconfig);
publishConfigChangeEvent = true;
}
}
for (Entry> entry : lcConfigX.getPortConfig().entrySet()) {
Byte key = entry.getKey();
if (currentPortConfig.containsKey(key)) {
currentPortConfig.remove(key);
}
currentPortConfig.put(key, entry.getValue());
}
port.setPortConfigX(currentPortConfig);
lcConfigX.getPortConfig().clear();
switch (port.getCurrentPortType()) {
case INPUTPORT:
lcConfigX
.getPortConfig().put(BidibLibrary.BIDIB_PCFG_RECONFIG,
currentPortConfig.get(BidibLibrary.BIDIB_PCFG_RECONFIG));
lcConfigX
.getPortConfig().put(BidibLibrary.BIDIB_PCFG_INPUT_CTRL,
currentPortConfig.get(BidibLibrary.BIDIB_PCFG_INPUT_CTRL));
break;
case SWITCHPORT:
lcConfigX.getPortConfig().putAll(currentPortConfig);
lcConfigX.getPortConfig().remove(BidibLibrary.BIDIB_PCFG_INPUT_CTRL);
break;
default:
lcConfigX.getPortConfig().putAll(currentPortConfig);
break;
}
byte[] content = LcConfigX.getCodedPortConfig(null, lcConfigX, getPortModel());
LOGGER.info("Prepared content: {}", ByteUtils.bytesToHex(content));
LcConfigXResponse lcConfigXResponse =
new LcConfigXResponse(bidibMessage.getAddr(), getNextSendNum(), content);
response = lcConfigXResponse.getContent();
if (publishConfigChangeEvent) {
LOGGER.info("Publish the change of port type for port: {}", port);
publishPortConfigChange(port, port.getCurrentPortType());
}
}
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;
}
@Override
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 outputType = lcConfigXGetMessage.getPortType(getPortModel());
GenericPort port = null;
Map> values = new LinkedHashMap<>();
port = genericPorts.get(Integer.valueOf(outputNumber));
BidibPort bidibPort = BidibPort.prepareBidibPort(getPortModel(), outputType, outputNumber);
if (port != null) {
if (outputNumber >= 0 && outputNumber < servoPortCount) { // 4 or 8 servo ports
values
.put(BidibLibrary.BIDIB_PCFG_RECONFIG, new ReconfigPortConfigValue(Integer.valueOf(0x000402)));
}
else if (outputNumber >= 4 && outputNumber < (servoPortCount + 16)) { // 16 power ports
values.putAll(port.getPortConfigX());
}
else { // GPIO are all input ports
values
.put(BidibLibrary.BIDIB_PCFG_RECONFIG, new ReconfigPortConfigValue(Integer.valueOf(0x80010F)));
values.put(BidibLibrary.BIDIB_PCFG_INPUT_CTRL, new BytePortConfigValue(Byte.valueOf((byte) 0x00)));
values.put(BidibLibrary.BIDIB_PCFG_TICKS, new BytePortConfigValue(Byte.valueOf((byte) 0x20)));
}
LOGGER.info("Return config of port: {}", port);
LcConfigX lcConfigX = new LcConfigX(bidibPort, values);
LcConfigXResponse lcConfigXResponse =
new LcConfigXResponse(bidibMessage.getAddr(), getNextSendNum(),
LcConfigX.getCodedPortConfig(null, lcConfigX, getPortModel()));
response = lcConfigXResponse.getContent();
}
else {
LOGGER.warn("No port available with port number: {}", outputNumber);
LcNotAvailableResponse notAvailableResponse =
new LcNotAvailableResponse(bidibMessage.getAddr(), getNextSendNum(), bidibPort);
response = notAvailableResponse.getContent();
}
}
catch (ProtocolException ex) {
LOGGER.warn("Create LcConfigX response failed.", ex);
}
return response;
}
@Override
protected void processLcConfigXGetAllRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the LcConfigXGetAll request: {}", bidibMessage);
try {
LcConfigXGetAllMessage lcConfigXGetAllMessage = (LcConfigXGetAllMessage) bidibMessage;
LcOutputType outputType = lcConfigXGetAllMessage.getPortTypeFrom(getPortModel());
// TODO evaluate port type/range to
Map> values = new HashMap<>();
if (outputType != null) {
LOGGER.info("Get all ports for output type: {}", outputType);
byte[] response = null;
switch (outputType) {
case SERVOPORT:
for (GenericSimulationPort servoPort : PortListUtils
.findPortsByType(genericPorts.values(), LcOutputType.SERVOPORT)) {
values.clear();
values.putAll(servoPort.getPortConfigX());
LOGGER.info("Return config of servo port: {}", servoPort);
BidibPort bidibPort =
BidibPort.prepareBidibPort(getPortModel(), outputType, servoPort.getPortNumber());
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 (GenericSimulationPort switchPort : PortListUtils
.findPortsByType(genericPorts.values(), LcOutputType.SWITCHPORT)) {
values.clear();
values.putAll(switchPort.getPortConfigX());
values.remove(BidibLibrary.BIDIB_PCFG_INPUT_CTRL);
LOGGER.info("Return config of switch port: {}", switchPort);
BidibPort bidibPort =
BidibPort.prepareBidibPort(getPortModel(), outputType, switchPort.getPortNumber());
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 INPUTPORT:
for (GenericSimulationPort inputPort : PortListUtils
.findPortsByType(genericPorts.values(), LcOutputType.INPUTPORT)) {
values.clear();
// values.putAll(inputPort.getPortConfigX());
values
.put(BidibLibrary.BIDIB_PCFG_RECONFIG,
inputPort.getPortConfigX().get(BidibLibrary.BIDIB_PCFG_RECONFIG));
values
.put(BidibLibrary.BIDIB_PCFG_INPUT_CTRL,
inputPort.getPortConfigX().get(BidibLibrary.BIDIB_PCFG_INPUT_CTRL));
LOGGER.info("Return config of input port: {}", inputPort);
BidibPort bidibPort =
BidibPort.prepareBidibPort(getPortModel(), outputType, inputPort.getPortNumber());
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 {
for (GenericPort port : genericPorts.values()) {
int portNumber = port.getPortNumber();
LOGGER.info("Prepare lcConfigXResponse for port number: {}", portNumber);
values.clear();
values.putAll(port.getPortConfigX());
switch (port.getCurrentPortType()) {
case INPUTPORT:
values.remove(BidibLibrary.BIDIB_PCFG_TICKS);
values.remove(BidibLibrary.BIDIB_PCFG_SWITCH_CTRL);
break;
case SWITCHPORT:
values.remove(BidibLibrary.BIDIB_PCFG_INPUT_CTRL);
break;
default:
break;
}
LOGGER.info("Return config of port: {}", port);
BidibPort bidibPort = BidibPort.prepareBidibPort(getPortModel(), outputType, portNumber);
LcConfigX lcConfigX = new LcConfigX(bidibPort, values);
LcConfigXResponse lcConfigXResponse =
new LcConfigXResponse(bidibMessage.getAddr(), getNextSendNum(),
LcConfigX.getCodedPortConfig(null, lcConfigX, getPortModel()));
byte[] response = lcConfigXResponse.getContent();
LOGGER.info("Prepared lcConfigXResponse: {}", ByteUtils.bytesToHex(response));
sendSpontanousResponse(response);
}
}
}
catch (ProtocolException ex) {
LOGGER.warn("Create lcConfigXResponse response failed.", ex);
}
}
private void publishInputPortChange(GenericPort port) {
InputPortStatus status = InputPortStatus.valueOf(InputPortEnum.valueOf(port.getPortStatus()));
LOGGER.info("The inputport status has changed, notify the listeners, nodeAddress: {}", nodeAddress);
EventBus.publish(new InputPortStatusEvent(NodeUtils.formatAddress(nodeAddress), port.getPortNumber(), status));
}
private void publishPortConfigChange(GenericPort port, LcOutputType signalledPortType) {
LOGGER.info("The port config has changed, notify the listeners, nodeAddress: {}", nodeAddress);
final PortConfigEvent portConfigEvent =
new PortConfigEvent(NodeUtils.formatAddress(nodeAddress), port.getPortNumber(), signalledPortType, port);
portConfigEvent.setEnabled(port.isMatchingPortType(signalledPortType));
EventBus.publish(portConfigEvent);
}
@Override
protected byte[] processLcPortQueryRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the LcPortQuery request: {}", bidibMessage);
byte[] response = null;
try {
LcPortQueryMessage lcOutputQueryMessage = (LcPortQueryMessage) bidibMessage;
LcOutputType outputType = lcOutputQueryMessage.getPortType(getPortModel());
int outputNumber = lcOutputQueryMessage.getPortNumber(getPortModel());
GenericPort port = genericPorts.get(Integer.valueOf(outputNumber));
byte portState = 0;
if (port != null) {
if (port.isMatchingPortType(LcOutputType.SERVOPORT)
|| port.isMatchingPortType(LcOutputType.BACKLIGHTPORT)) {
portState = ByteUtils.getLowByte(port.getPortValue());
}
else {
portState = port.getPortStatus();
}
}
else {
LOGGER.warn("No port available with portNumber: {}", outputNumber);
}
BidibPort bidibPort = BidibPort.prepareBidibPort(getPortModel(), outputType, outputNumber);
LcStatResponse lcStatResponse =
new LcStatResponse(bidibMessage.getAddr(), getNextSendNum(), bidibPort, portState);
response = lcStatResponse.getContent();
}
catch (ProtocolException ex) {
LOGGER.warn("Create LcStat response failed.", ex);
}
return response;
}
@Override
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);
for (GenericPort genericPort : genericPorts.values()) {
LcOutputType currentPortType = genericPort.getCurrentPortType();
if (PortConfigUtils.isSupportsPortType(currentPortType, portTypeMask)
&& (genericPort.getPortNumber() >= portRangeFrom && genericPort.getPortNumber() < portRangeTo)) {
try {
byte portStatus = 0;
if (genericPort.isMatchingPortType(LcOutputType.SERVOPORT)
|| genericPort.isMatchingPortType(LcOutputType.BACKLIGHTPORT)) {
portStatus = ByteUtils.getLowByte(genericPort.getPortValue());
}
else {
portStatus = genericPort.getPortStatus();
}
publishPortState(bidibMessage.getAddr(), currentPortType, genericPort.getPortNumber(),
portStatus);
}
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);
}
}
LOGGER.info("Send the terminating LC_NA message.");
publishLcNaResponse(bidibMessage.getAddr());
}
catch (ProtocolException ex) {
LOGGER.warn("Create LcStat response failed.", ex);
}
return response;
}
@Override
public void queryStatus(Class portClass) {
for (GenericSimulationPort port : genericPorts.values()) {
if (portClass == InputPort.class) {
if (port.isMatchingPortType(LcOutputType.INPUTPORT)) {
publishInputPortChange(port);
}
if (port.isSupportsInputPort()) {
publishPortConfigChange(port, LcOutputType.INPUTPORT);
}
}
else if (portClass == SwitchPort.class) {
if (port.isMatchingPortType(LcOutputType.SWITCHPORT)) {
publishSwitchPortChange(port);
}
if (port.isSupportsSwitchPort()) {
publishPortConfigChange(port, LcOutputType.SWITCHPORT);
}
}
else if (portClass == ServoPort.class) {
if (port.isMatchingPortType(LcOutputType.SERVOPORT)) {
publishServoPortChange(port);
}
if (port.isSupportsServoPort()) {
publishPortConfigChange(port, LcOutputType.SERVOPORT);
}
}
else {
LOGGER.warn("Query port status for unsupported port class: {}", portClass);
}
}
}
@Override
public void setPortsConfig(PortType portType) {
if (portType == null) {
return;
}
LOGGER.info("Set the port config: {}", portType);
if (portType instanceof SwitchPortType) {
switchPortCount = portType.getCount();
LOGGER.info("Set the number of switchPorts: {}", switchPortCount);
}
else if (portType instanceof InputPortType) {
inputPortCount = portType.getCount();
inputPortOffset = (portType.getOffset() != null ? portType.getOffset() : 0);
}
else if (portType instanceof ServoPortType) {
servoPortCount = portType.getCount();
}
}
@Override
@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);
}
@Override
protected void changeInputPortStatus(int portNum) {
GenericPort port =
PortListUtils.findPortsByTypeAndPortNumber(genericPorts.values(), LcOutputType.INPUTPORT, portNum);
if (port != null) {
switch (InputPortStatus.valueOf(InputPortEnum.valueOf(port.getPortStatus()))) {
case OFF:
port.setPortStatus(InputPortStatus.ON.getType().getType());
break;
default:
port.setPortStatus(InputPortStatus.OFF.getType().getType());
break;
}
// prepare the request
final LcPortQueryMessage lcPortQueryMessage =
getBidibRequestFactory().createLcPortQuery(getPortModel(), LcOutputType.INPUTPORT, portNum);
lcPortQueryMessage.setAddr(getNodeAddress());
processRequest(lcPortQueryMessage);
publishInputPortChange(port);
}
else {
LOGGER.warn("The requested input port is not available: {}", portNum);
}
}
}