org.bidib.wizard.simulation.LedIo24Simulator 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.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
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.LightPortEnum;
import org.bidib.jbidibc.messages.enums.PortConfigStatus;
import org.bidib.jbidibc.messages.enums.PortModelEnum;
import org.bidib.jbidibc.messages.exception.ProtocolException;
import org.bidib.jbidibc.messages.message.AccessoryParaGetMessage;
import org.bidib.jbidibc.messages.message.AccessoryParaResponse;
import org.bidib.jbidibc.messages.message.AccessorySetMessage;
import org.bidib.jbidibc.messages.message.AccessoryStateResponse;
import org.bidib.jbidibc.messages.message.BidibMessageInterface;
import org.bidib.jbidibc.messages.message.BidibRequestFactory;
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.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.FlatBacklightPortType;
import org.bidib.jbidibc.simulation.nodes.FlatInputPortType;
import org.bidib.jbidibc.simulation.nodes.FlatLightPortType;
import org.bidib.jbidibc.simulation.nodes.FlatPortType;
import org.bidib.jbidibc.simulation.nodes.FlatServoPortType;
import org.bidib.jbidibc.simulation.nodes.FlatSwitchPortType;
import org.bidib.jbidibc.simulation.nodes.InputPortParamsType;
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.PortParamsType;
import org.bidib.jbidibc.simulation.nodes.PortType;
import org.bidib.wizard.model.ports.GenericPort;
import org.bidib.wizard.model.ports.InputPort;
import org.bidib.wizard.model.ports.LightPort;
import org.bidib.wizard.model.status.InputPortStatus;
import org.bidib.wizard.model.status.LightPortStatus;
import org.bidib.wizard.model.status.SwitchPortStatus;
import org.bidib.wizard.simulation.events.InputPortStatusEvent;
import org.bidib.wizard.simulation.events.LightPortStatusEvent;
import org.bidib.wizard.simulation.ports.GenericSimulationPort;
import org.bushe.swing.event.EventBus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@BidibNodeSimulators({ @BidibNodeSimulator(vid = "13", pid = "126"), @BidibNodeSimulator(vid = "13", pid = "127") })
public class LedIo24Simulator extends LightControlSimulator implements SwitchingFunctionsNode {
private static final Logger LOGGER = LoggerFactory.getLogger(LedIo24Simulator.class);
private static final String SIMULATION_PANEL_CLASS = "org.bidib.wizard.simulation.client.view.panel.LedIo24Panel";
private final Map genericPorts = new HashMap();
protected final ScheduledExecutorService inputWorker = Executors.newScheduledThreadPool(1);
protected final ScheduledExecutorService simulationWorker = Executors.newScheduledThreadPool(1);
public LedIo24Simulator(byte[] nodeAddress, long uniqueId, boolean autoAddFeature,
SimulationBidibMessageProcessor messageReceiver, final BidibRequestFactory bidibRequestFactory) {
super(nodeAddress, uniqueId, autoAddFeature, messageReceiver, bidibRequestFactory);
}
@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);
for (int portNumber = 0; portNumber < numPorts; portNumber++) {
GenericSimulationPort port = new GenericSimulationPort(portNumber);
port.setPortValue(250);
port
.setPortStatus(portNumber % 2 == 0 ? InputPortStatus.ON.getType().getType()
: InputPortStatus.OFF.getType().getType());
int mask =
(1 << BidibLibrary.BIDIB_PORTTYPE_INPUT | 1 << BidibLibrary.BIDIB_PORTTYPE_LIGHT
| 1 << BidibLibrary.BIDIB_PORTTYPE_SERVO);
port.setCurrentPortType(LcOutputType.INPUTPORT, mask);
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();
features.remove(new Feature(BidibLibrary.FEATURE_ACCESSORY_MACROMAPPED, 2));
features.add(new Feature(BidibLibrary.FEATURE_ACCESSORY_MACROMAPPED, 8));
}
@Override
protected void prepareCVs() {
super.prepareCVs();
configurationVariables.put("String 8", "TEST result");
}
@Override
public void start() {
LOGGER.info("Start the simulator for address: {}", getAddress());
super.start();
if (!MapUtils.isEmpty(genericPorts)) {
int index = 0;
// prepare the light ports
for (int portNum = 0; portNum < lightPortCount; portNum++) {
GenericSimulationPort genericPort = genericPorts.get(portNum + index);
final ReconfigPortConfigValue reconfigPortConfigValue =
(ReconfigPortConfigValue) genericPort.getPortConfigX().get(BidibLibrary.BIDIB_PCFG_RECONFIG);
genericPort.setCurrentPortType(LcOutputType.LIGHTPORT, reconfigPortConfigValue.getPortMap());
// genericPort.setCurrentPortType(LcOutputType.LIGHTPORT, 0x8002);
if (portNum == 0) {
genericPort.setInactive(true);
}
Map> values = new LinkedHashMap<>();
values
.put(BidibLibrary.BIDIB_PCFG_RECONFIG,
new ReconfigPortConfigValue(reconfigPortConfigValue.getValue()));
// values.put(BidibLibrary.BIDIB_PCFG_RECONFIG, new ReconfigPortConfigValue(Integer.valueOf(0x800201)));
// values.putAll(genericPort.getPortConfigX());
LightPort lightPort = lightPorts.get(portNum);
if (lightPort != null && lightPort.getConfigStatus() == PortConfigStatus.CONFIG_PASSED) {
LOGGER.info("Do not initialize the port because the configuration is set already: {}", genericPort);
values
.put(BidibLibrary.BIDIB_PCFG_LEVEL_PORT_OFF,
new BytePortConfigValue(ByteUtils.getLowByte(lightPort.getPwmMin())));
values
.put(BidibLibrary.BIDIB_PCFG_LEVEL_PORT_ON,
new BytePortConfigValue(ByteUtils.getLowByte(lightPort.getPwmMax())));
values
.put(BidibLibrary.BIDIB_PCFG_DIMM_DOWN,
new BytePortConfigValue(ByteUtils.getLowByte(lightPort.getDimMin())));
values
.put(BidibLibrary.BIDIB_PCFG_DIMM_UP,
new BytePortConfigValue(ByteUtils.getLowByte(lightPort.getDimMax())));
}
else {
values
.put(BidibLibrary.BIDIB_PCFG_LEVEL_PORT_OFF,
new BytePortConfigValue(Byte.valueOf((byte) 0x00)));
values
.put(BidibLibrary.BIDIB_PCFG_LEVEL_PORT_ON, new BytePortConfigValue(Byte.valueOf((byte) 0xFF)));
values.put(BidibLibrary.BIDIB_PCFG_DIMM_DOWN, new BytePortConfigValue(Byte.valueOf((byte) 0x0F)));
values.put(BidibLibrary.BIDIB_PCFG_DIMM_UP, new BytePortConfigValue(Byte.valueOf((byte) 0x3F)));
// TODO RGB
// values.put(BidibLibrary.BIDIB_PCFG_RGB, new RgbPortConfigValue(Integer.valueOf(3)));
}
values.put(BidibLibrary.BIDIB_PCFG_SERVO_ADJ_L, new BytePortConfigValue(ByteUtils.getLowByte(20)));
values.put(BidibLibrary.BIDIB_PCFG_SERVO_ADJ_H, new BytePortConfigValue(ByteUtils.getLowByte(150)));
values.put(BidibLibrary.BIDIB_PCFG_SERVO_SPEED, new BytePortConfigValue(ByteUtils.getLowByte(4)));
genericPort.setPortConfigX(values);
lightPort = new LightPort(genericPort);
lightPorts.put(portNum, lightPort);
}
// TODO this is a hack for the OneControl
index = lightPortCount;
// prepare the input ports
LOGGER.info("Set the port type for input ports, index: {}", index);
for (int portNum = 0; portNum < inputPortCount; portNum++) {
GenericSimulationPort genericPort = genericPorts.get(portNum + index);
final ReconfigPortConfigValue reconfigPortConfigValue =
(ReconfigPortConfigValue) genericPort.getPortConfigX().get(BidibLibrary.BIDIB_PCFG_RECONFIG);
genericPort.setCurrentPortType(LcOutputType.INPUTPORT, reconfigPortConfigValue.getPortMap());
// genericPort.setCurrentPortType(LcOutputType.INPUTPORT, 0x8002);
// input ports do support remapping
Map> values = new LinkedHashMap<>();
values
.put(BidibLibrary.BIDIB_PCFG_RECONFIG,
new ReconfigPortConfigValue(reconfigPortConfigValue.getValue()));
// values.put(BidibLibrary.BIDIB_PCFG_RECONFIG, new ReconfigPortConfigValue(Integer.valueOf(0x80020F)));
InputPort inputPort = inputPorts.get(portNum);
if (inputPort != null && inputPort.getConfigStatus() == PortConfigStatus.CONFIG_PASSED) {
LOGGER.info("Do not initialize the port because the configuration is set already: {}", genericPort);
values
.put(BidibLibrary.BIDIB_PCFG_INPUT_CTRL,
new BytePortConfigValue(inputPort.getInputBehaviour().getType()));
values
.put(BidibLibrary.BIDIB_PCFG_TICKS,
new BytePortConfigValue(ByteUtils.getLowByte(inputPort.getTicks())));
}
else {
values.put(BidibLibrary.BIDIB_PCFG_INPUT_CTRL, new BytePortConfigValue(Byte.valueOf((byte) 0x00)));
values.put(BidibLibrary.BIDIB_PCFG_TICKS, new BytePortConfigValue(Byte.valueOf((byte) 0x0F)));
}
values.put(BidibLibrary.BIDIB_PCFG_SERVO_ADJ_L, new BytePortConfigValue(ByteUtils.getLowByte(20)));
values.put(BidibLibrary.BIDIB_PCFG_SERVO_ADJ_H, new BytePortConfigValue(ByteUtils.getLowByte(150)));
values.put(BidibLibrary.BIDIB_PCFG_SERVO_SPEED, new BytePortConfigValue(ByteUtils.getLowByte(4)));
genericPort.setPortConfigX(values);
inputPort = new InputPort(genericPort);
inputPorts.put(portNum, inputPort);
}
}
}
@Override
public void stop() {
LOGGER.info("Stop the LED-IO-24 simulator.");
if (futureTriggerInputMessage != null) {
LOGGER.info("Stop the input message trigger.");
boolean success = futureTriggerInputMessage.cancel(false);
LOGGER.info("Stopped the input message trigger, success: {}", success);
futureTriggerInputMessage = null;
}
super.stop();
}
@Override
public String getSimulationPanelClass() {
return SIMULATION_PANEL_CLASS;
}
private ScheduledFuture> futureTriggerInputMessage;
@Override
protected void processSysEnableRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the sysEnable request: {}", bidibMessage);
super.processSysEnableRequest(bidibMessage);
// use executor to send response
if (futureTriggerInputMessage == null) {
LOGGER.info("Schedule the input message trigger");
int interval = 15;
futureTriggerInputMessage = inputWorker.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
LOGGER.info("Trigger input response");
// try {
// triggerInputResponse();
// }
// catch (Exception ex) {
// LOGGER.warn("Trigger the input response failed.", ex);
// }
LOGGER.info("Trigger input response has finished.");
}
}, 15, interval, TimeUnit.SECONDS);
}
}
@Override
protected void processSysDisableRequest(BidibMessageInterface bidibMessage) {
super.processSysDisableRequest(bidibMessage);
if (futureTriggerInputMessage != null) {
LOGGER.info("Stop the input message trigger.");
boolean success = futureTriggerInputMessage.cancel(false);
LOGGER.info("Stopped the input message trigger, success: {}", success);
futureTriggerInputMessage = null;
}
}
protected void triggerInputResponse() {
int maxPortId = 1;
Random generator = new Random();
int portNum = generator.nextInt(maxPortId);
portNum += 24;
LOGGER.info("Trigger change input status, current portNum: {}", portNum);
try {
changeInputPortStatus(portNum);
}
catch (Exception ex) {
LOGGER.warn("Publish input status failed for portNum: {}", portNum, ex);
}
}
@Override
protected byte[] processLcConfigXSetRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the LcConfigXSet request: {}", bidibMessage);
byte[] response = null;
if (getFlatPortModelPortCount() > 0) {
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 = prepareBidibPort(getPortModel(), outputType, outputNumber);
if (port != null) {
// 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) {
// 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);
}
}
// set the current port configuration
port.setPortConfigX(lcConfigX.getPortConfig());
Map> updatedValues = port.getPortConfigX();
LOGGER.info("Return config of port: {}", port);
lcConfigX = new LcConfigX(bidibPort, updatedValues);
byte[] content = LcConfigX.getCodedPortConfig(null, lcConfigX, getPortModel());
// TODO remove this test
if (outputNumber == 5) {
content = new byte[] { 0x00, 0x05, 0x00, 0x0C };
}
LcConfigXResponse lcConfigXResponse =
new LcConfigXResponse(bidibMessage.getAddr(), getNextSendNum(), content);
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);
}
}
else {
response = super.processLcConfigXSetRequest(bidibMessage);
}
return response;
}
@Override
protected byte[] processLcConfigXGetRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the LcConfigXGet request: {}", bidibMessage);
byte[] response = null;
if (getFlatPortModelPortCount() > 0) {
try {
LcConfigXGetMessage lcConfigXGetMessage = (LcConfigXGetMessage) bidibMessage;
int outputNumber = lcConfigXGetMessage.getPortNumber(getPortModel());
LcOutputType outputType = lcConfigXGetMessage.getPortType(getPortModel());
GenericPort port = null;
port = genericPorts.get(Integer.valueOf(outputNumber));
BidibPort bidibPort = prepareBidibPort(getPortModel(), outputType, outputNumber);
if (port != null) {
Map> values = port.getPortConfigX();
// TODO remove this test
if (outputNumber == 2) {
values.put(BidibLibrary.BIDIB_PCFG_NONE, new BytePortConfigValue((byte) 12));
}
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);
}
}
else {
response = super.processLcConfigXGetRequest(bidibMessage);
}
return response;
}
@Override
protected void processLcConfigXGetAllRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the LcConfigXGetAll request: {}", bidibMessage);
if (getFlatPortModelPortCount() > 0) {
LcOutputType outputType = LcOutputType.SWITCHPORT;
Map> values = new LinkedHashMap<>();
try {
for (GenericPort port : genericPorts.values()) {
int portNumber = port.getPortNumber();
LOGGER.info("Prepare lcConfigXResponse for port number: {}", portNumber);
values.clear();
// if (portNumber >= 0 && portNumber < lightPortCount) { // 24 light ports
// values
// .put(BidibLibrary.BIDIB_PCFG_RECONFIG,
// new ReconfigPortConfigValue(Integer.valueOf(0x800201)));
//
// values
// .put(BidibLibrary.BIDIB_PCFG_LEVEL_PORT_OFF,
// new BytePortConfigValue(Byte.valueOf((byte) 0x00)));
// values
// .put(BidibLibrary.BIDIB_PCFG_LEVEL_PORT_ON,
// new BytePortConfigValue(Byte.valueOf((byte) 0xFF)));
// values
// .put(BidibLibrary.BIDIB_PCFG_DIMM_DOWN, new BytePortConfigValue(Byte.valueOf((byte) 0x0F)));
// values.put(BidibLibrary.BIDIB_PCFG_DIMM_UP, new BytePortConfigValue(Byte.valueOf((byte) 0x3F)));
//
// // TODO RGB
// // values.put(BidibLibrary.BIDIB_PCFG_RGB, new RgbPortConfigValue(Integer.valueOf(3)));
//
// }
// else { // input ports do not support remapping
//
// int currentPortType = ByteUtils.getInt(port.getCurrentPortType().getType());
//
// values
// .put(BidibLibrary.BIDIB_PCFG_RECONFIG,
// // be careful, the constructor is different ...
// new ReconfigPortConfigValue(currentPortType, 0x8000));
//
// values
// .put(BidibLibrary.BIDIB_PCFG_INPUT_CTRL,
// new BytePortConfigValue(Byte.valueOf((byte) 0x00)));
// values.put(BidibLibrary.BIDIB_PCFG_TICKS, new BytePortConfigValue(Byte.valueOf((byte) 0x00)));
// }
values.putAll(port.getPortConfigX());
// TODO remove this test
// if (portNumber == 6) {
// values.put(BidibLibrary.BIDIB_PCFG_NONE, new BytePortConfigValue((byte) 12));
// }
// if (port.isInactive()) {
// values
// .put(BidibLibrary.BIDIB_PCFG_ERR_PORT_INACTIVE,
// new BytePortConfigValue(Byte.valueOf((byte) 0x00)));
// }
LOGGER.info("Return config of port: {}", port);
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);
}
}
else {
super.processLcConfigXGetAllRequest(bidibMessage);
}
}
@Override
protected byte[] processLcPortQueryRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the LcOutputQuery request: {}", bidibMessage);
byte[] response = null;
if (getFlatPortModelPortCount() > 0) {
byte portState = 0;
try {
LcPortQueryMessage lcOutputQueryMessage = (LcPortQueryMessage) bidibMessage;
LcOutputType outputType = lcOutputQueryMessage.getPortType(getPortModel());
int outputNumber = lcOutputQueryMessage.getPortNumber(getPortModel());
GenericPort port = genericPorts.get(Integer.valueOf(outputNumber));
BidibPort bidibPort = prepareBidibPort(getPortModel(), outputType, outputNumber);
if (port != null) {
portState = ByteUtils.getLowByte(0xFF);
}
else {
LOGGER.warn("No port available with portNumber: {}", outputNumber);
}
LcStatResponse lcStatResponse =
new LcStatResponse(bidibMessage.getAddr(), getNextSendNum(), bidibPort, portState);
response = lcStatResponse.getContent();
}
catch (ProtocolException ex) {
LOGGER.warn("Create LcStat response failed.", ex);
}
}
else {
response = super.processLcPortQueryRequest(bidibMessage);
}
return response;
}
@Override
protected byte[] processLcPortQueryAllRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the PortQueryAll request: {}", bidibMessage);
if (getFlatPortModelPortCount() > 0) {
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 = 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;
}
else {
LOGGER
.info(
"The LedIo24Simulator is configured as type-oriented port model! Delegate evaluation to LightControlSimulator.");
return super.processLcPortQueryAllRequest(bidibMessage);
}
}
@Override
protected byte[] processLcKeyQueryRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the LcKeyQuery request: {}", bidibMessage);
byte[] response = null;
if (getFlatPortModelPortCount() > 0) {
byte keyState = 0;
GenericSimulationPort port = null;
try {
LcKeyMessage lcKeyMessage = (LcKeyMessage) bidibMessage;
// int portNumber = lcKeyMessage.getKeyNumber();
int portNumber = lcKeyMessage.getBidibPort().getPortNumber(PortModelEnum.type);
port = genericPorts.get(Integer.valueOf(portNumber));
if (port != null) {
keyState = port.getPortStatus();
}
else {
LOGGER.warn("No port available with portNumber: {}", portNumber);
}
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);
}
}
else {
response = super.processLcKeyQueryRequest(bidibMessage);
}
return response;
}
@Override
protected byte[] processLcOutputRequest(BidibMessageInterface bidibMessage) {
LOGGER.info("Process the LcOutput request: {}", bidibMessage);
byte[] response = null;
if (getFlatPortModelPortCount() > 0) {
GenericSimulationPort port = null;
try {
LcOutputMessage lcOutputMessage = (LcOutputMessage) bidibMessage;
LcOutputType outputType = lcOutputMessage.getOutputType(getPortModel());
int portNumber = lcOutputMessage.getOutputNumber(getPortModel());
byte outputStatus = lcOutputMessage.getOutputStatus();
port = genericPorts.get(Integer.valueOf(portNumber));
BidibPort bidibPort = prepareBidibPort(getPortModel(), outputType, portNumber);
if (port != null) {
port.setPortStatus(outputStatus);
LcStatResponse lcStatResponse =
new LcStatResponse(bidibMessage.getAddr(), getNextSendNum(), bidibPort,
lcOutputMessage.getOutputStatus());
response = lcStatResponse.getContent();
}
else {
LcNotAvailableResponse lcNotAvailableResponse =
new LcNotAvailableResponse(bidibMessage.getAddr(), getNextSendNum(), bidibPort);
response = lcNotAvailableResponse.getContent();
}
if (port != null) {
switch (port.getCurrentPortType()) {
case LIGHTPORT:
publishLightPortChange(port);
break;
default:
break;
}
}
}
catch (ProtocolException ex) {
LOGGER.warn("Create LcStat response failed.", ex);
}
}
return response;
}
private void publishLightPortChange(GenericSimulationPort port) {
LightPortStatus status = LightPortStatus.valueOf(LightPortEnum.valueOf(port.getPortStatus()));
LOGGER.info("The lightport status has changed, notify the listeners, nodeAddress: {}", nodeAddress);
EventBus.publish(new LightPortStatusEvent(NodeUtils.formatAddress(nodeAddress), port.getPortNumber(), status));
}
@Override
protected byte[] processAccessorySetRequest(final 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 };
if (accessoryNumber == 1 && aspect == 1) {
LOGGER.warn("Adding simulated error to accessory state response");
value = new byte[] { 2, 1, 20 };
final AccessoryResponseHandler callable =
new AccessoryResponseHandler(bidibMessage.getAddr(), accessoryNumber, aspect);
ScheduledFuture> future =
simulationWorker.scheduleWithFixedDelay(callable, 1500, 1500, TimeUnit.MILLISECONDS);
callable.setFuture(future);
}
// send accessory state response
AccessoryStateResponse accessoryStateResponse =
new AccessoryStateResponse(bidibMessage.getAddr(), getNextSendNum(),
ByteUtils.getLowByte(accessoryNumber), ByteUtils.getLowByte(aspect), value);
response = accessoryStateResponse.getContent();
}
catch (ProtocolException ex) {
LOGGER.warn("Create AccessoryState response failed.", ex);
}
return response;
}
private final class AccessoryResponseHandler implements Runnable {
private List accessoryResponseList = new ArrayList<>();
private final byte[] nodeAddress;
private ScheduledFuture> future;
public AccessoryResponseHandler(byte[] nodeAddress, int accessoryNumber, int aspect) {
this.nodeAddress = nodeAddress;
// add the remaining response values
accessoryResponseList.add(accessoryNumber + "," + aspect + ",2,128,7");
accessoryResponseList.add(accessoryNumber + ",255,2,129,7");
accessoryResponseList.add(accessoryNumber + ",255,2,0,0");
}
public void setFuture(ScheduledFuture> future) {
LOGGER.info("Set the future: {}", future);
this.future = future;
}
@Override
public void run() {
LOGGER.info("The AccessoryResponseHandler is executed.");
if (!accessoryResponseList.isEmpty()) {
String accessoryResponse = accessoryResponseList.remove(0);
if (StringUtils.isNotBlank(accessoryResponse)) {
LOGGER.info("Send response: {}", accessoryResponse);
// parse
String[] parts = accessoryResponse.split(",");
byte[] value = new byte[parts.length];
int index = 0;
for (String part : parts) {
int val = Integer.parseInt(part);
value[index] = ByteUtils.getLowByte(val);
index++;
}
try {
AccessoryStateResponse accessoryStateResponse =
new AccessoryStateResponse(nodeAddress, 0, /* accessoryNumber */value[0],
/* aspect */value[1], ByteUtils.subArray(value, 2));
byte[] response = accessoryStateResponse.getContent();
LOGGER.info("Prepared accessoryStateResponse: {}", accessoryStateResponse);
LedIo24Simulator.this.sendSpontanousResponse(response);
}
catch (ProtocolException ex) {
LOGGER.warn("Create AccessoryState response failed.", ex);
}
}
}
if (accessoryResponseList.isEmpty()) {
LOGGER.info("No more entries in accessoryResponseList. Cancel the future.");
if (future != null) {
try {
future.cancel(false);
}
catch (Exception ex) {
LOGGER.warn("Cancel the future failed.", ex);
}
}
}
}
}
// //////
@Override
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();
if (paraNumber == BidibLibrary.BIDIB_ACCESSORY_SWITCH_TIME) {
LOGGER.info("The param BIDIB_ACCESSORY_SWITCH_TIME is known for accessory 0 and 1!");
// TODO provide the correct data here ...
byte[] value = null;
switch (accessoryNumber) {
case 0:
value = new byte[] { ByteUtils.getLowByte(0x87) };
break;
case 1:
value = new byte[] { ByteUtils.getLowByte(0x77) };
break;
default:
value = new byte[] { ByteUtils.getLowByte(paraNumber) };
paraNumber = BidibLibrary.BIDIB_ACCESSORY_PARA_NOTEXIST;
break;
}
AccessoryParaResponse accessoryParaResponse =
new AccessoryParaResponse(bidibMessage.getAddr(), getNextSendNum(),
ByteUtils.getLowByte(accessoryNumber), ByteUtils.getLowByte(paraNumber), value);
response = accessoryParaResponse.getContent();
}
else {
response = super.processAccessoryParaGetRequest(bidibMessage);
}
}
catch (ProtocolException ex) {
LOGGER.warn("Create AccessoryPara response failed.", ex);
}
return response;
}
//////////
private void publishInputPortChange(GenericSimulationPort 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));
}
@Override
protected void changeInputPortStatus(int portNum) {
GenericSimulationPort port = genericPorts.get(portNum);
if (port != null) {
InputPortStatus portStatus = InputPortStatus.valueOf(InputPortEnum.valueOf(port.getPortStatus()));
switch (portStatus) {
case OFF:
port.setPortStatus(InputPortStatus.ON.getType().getType());
break;
default:
port.setPortStatus(InputPortStatus.OFF.getType().getType());
break;
}
try {
BidibPort bidibPort = prepareBidibPort(getPortModel(), LcOutputType.INPUTPORT, portNum);
LcStatResponse lcStatResponse =
new LcStatResponse(nodeAddress, getNextSendNum(), bidibPort, port.getPortStatus());
byte[] response = lcStatResponse.getContent();
sendSpontanousResponse(response);
}
catch (ProtocolException ex) {
LOGGER.warn("Create LcStat response failed.", ex);
}
publishInputPortChange(port);
}
else {
LOGGER.warn("The requested input port is not available: {}", portNum);
}
}
@Override
public void setPortsConfig(FlatPortType flatPortType) {
if (flatPortType == null) {
return;
}
LOGGER.info("Set the ports config: {}", flatPortType);
if (CollectionUtils.isNotEmpty(flatPortType.getBACKLIGHTOrLIGHTOrINPUT())) {
for (PortParamsType flatPortParamsType : flatPortType.getBACKLIGHTOrLIGHTOrINPUT()) {
if (flatPortParamsType instanceof FlatInputPortType) {
// add input port
prepareInutPortFromConfig((FlatInputPortType) flatPortParamsType);
}
else if (flatPortParamsType instanceof FlatLightPortType) {
// add light port
prepareLightPortFromConfig((FlatLightPortType) flatPortParamsType);
}
else if (flatPortParamsType instanceof FlatBacklightPortType) {
// add backlight port
prepareBacklightPortFromConfig((FlatBacklightPortType) flatPortParamsType);
}
else if (flatPortParamsType instanceof FlatServoPortType) {
// add servo port
prepareServoPortFromConfig((FlatServoPortType) flatPortParamsType);
}
else if (flatPortParamsType instanceof FlatSwitchPortType) {
// add switch port
prepareSwitchPortFromConfig((FlatSwitchPortType) flatPortParamsType);
}
else {
LOGGER.warn("Unsupported flatPortParamsType detected: {}", flatPortParamsType);
}
}
}
}
@Override
public void setPortsConfig(PortType portType) {
if (portType == null) {
return;
}
LOGGER.info("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);
}
prepareLightPortFromConfig(lightPortType);
}
else if (portType instanceof InputPortType) {
InputPortType inputPortType = (InputPortType) portType;
inputPortCount = inputPortType.getCount();
inputPortOffset = (inputPortType.getOffset() != null ? inputPortType.getOffset() : lightPortCount);
LOGGER.info("Configured number of input ports: {}", inputPortCount);
// prepare initial lightports
for (int portId = 0; portId < inputPortCount; portId++) {
InputPort inputPort = new InputPort();
inputPort.setId(portId);
// add the unconfigured inputport
inputPorts.put(portId, inputPort);
}
prepareInputPortFromConfig(inputPortType);
}
}
protected void prepareLightPortFromConfig(final LightPortType lightPortType) {
// overwrite configured ports
if (CollectionUtils.isNotEmpty(lightPortType.getPort())) {
// 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);
}
// use the number of configured ports
lightPortCount = lightPorts.size();
}
}
protected void prepareBacklightPortFromConfig(final FlatBacklightPortType lightPortType) {
// TODO overwrite configured ports
LOGGER.warn("prepareBacklightPortFromConfig is not implemented yet!");
}
protected void prepareServoPortFromConfig(final FlatServoPortType servoPortType) {
// overwrite configured ports
int portNumber = servoPortType.getPortId();
GenericSimulationPort servoPort = new GenericSimulationPort(portNumber);
int portTypeMap = getPortTypeMap(servoPortType.getPortTypeMap());
servoPort.setCurrentPortType(LcOutputType.SERVOPORT, portTypeMap);
Map> portConfig = new LinkedHashMap<>();
portConfig
.put(BidibLibrary.BIDIB_PCFG_SERVO_SPEED,
new BytePortConfigValue(ByteUtils.getLowByte(servoPortType.getSpeed())));
portConfig
.put(BidibLibrary.BIDIB_PCFG_SERVO_ADJ_L,
new BytePortConfigValue(ByteUtils.getLowByte(servoPortType.getAdjustLow())));
portConfig
.put(BidibLibrary.BIDIB_PCFG_SERVO_ADJ_H,
new BytePortConfigValue(ByteUtils.getLowByte(servoPortType.getAdjustHigh())));
servoPort.setPortConfigX(portConfig);
servoPort.setConfigStatus(PortConfigStatus.CONFIG_PASSED);
servoPort.setPortValue(servoPortType.getValue());
LOGGER.info("Add configured serbvo port: {}", servoPort);
// add the configured port
genericPorts.put(servoPort.getPortNumber(), servoPort);
}
protected void prepareSwitchPortFromConfig(final FlatSwitchPortType switchPortType) {
// overwrite configured ports
int portNumber = switchPortType.getPortId();
GenericSimulationPort switchPort = new GenericSimulationPort(portNumber);
int portTypeMap = getPortTypeMap(switchPortType.getPortTypeMap());
switchPort.setCurrentPortType(LcOutputType.SWITCHPORT, portTypeMap);
Map> portConfig = new LinkedHashMap<>();
portConfig
.put(BidibLibrary.BIDIB_PCFG_TICKS,
new BytePortConfigValue(ByteUtils.getLowByte(switchPortType.getTicks())));
switchPort.setPortConfigX(portConfig);
switchPort.setConfigStatus(PortConfigStatus.CONFIG_PASSED);
switchPort.setPortStatus(SwitchPortStatus.ON.getType().getType());
LOGGER.info("Add configured switch port: {}", switchPort);
// add the configured port
genericPorts.put(switchPort.getPortNumber(), switchPort);
}
protected void prepareLightPortFromConfig(final FlatLightPortType lightPortType) {
// overwrite configured ports
int portNumber = lightPortType.getPortId();
GenericSimulationPort lightPort = new GenericSimulationPort(portNumber);
int portTypeMap = getPortTypeMap(lightPortType.getPortTypeMap());
lightPort.setCurrentPortType(LcOutputType.LIGHTPORT, portTypeMap);
lightPort.setPortNumber(lightPortType.getPortId());
Map> portConfig = new LinkedHashMap<>();
portConfig
.put(BidibLibrary.BIDIB_PCFG_LEVEL_PORT_OFF,
new BytePortConfigValue(ByteUtils.getLowByte(lightPortType.getIntensityOff())));
portConfig
.put(BidibLibrary.BIDIB_PCFG_LEVEL_PORT_ON,
new BytePortConfigValue(ByteUtils.getLowByte(lightPortType.getIntensityOn())));
portConfig
.put(BidibLibrary.BIDIB_PCFG_DIMM_DOWN,
new BytePortConfigValue(ByteUtils.getLowByte(lightPortType.getDimSlopeDown())));
portConfig
.put(BidibLibrary.BIDIB_PCFG_DIMM_UP,
new BytePortConfigValue(ByteUtils.getLowByte(lightPortType.getDimSlopeUp())));
// TODO RGB
// values.put(BidibLibrary.BIDIB_PCFG_RGB, new RgbPortConfigValue(Integer.valueOf(3)));
if (lightPortType.getTransitionTime() != null) {
portConfig
.put(BidibLibrary.BIDIB_PCFG_TRANSITION_TIME,
new BytePortConfigValue(ByteUtils.getLowByte(lightPortType.getTransitionTime())));
}
lightPort.setPortConfigX(portConfig);
lightPort.setConfigStatus(PortConfigStatus.CONFIG_PASSED);
lightPort.setPortStatus(LightPortStatus.OFF.getType().getType());
LOGGER.info("Add configured light port: {}", lightPort);
// add the configured port
genericPorts.put(lightPort.getPortNumber(), lightPort);
}
protected void prepareInutPortFromConfig(final FlatInputPortType inputPortType) {
int portNumber = inputPortType.getPortId();
GenericSimulationPort inputPort = new GenericSimulationPort(portNumber);
int portTypeMap = getPortTypeMap(inputPortType.getPortTypeMap());
inputPort.setCurrentPortType(LcOutputType.INPUTPORT, portTypeMap);
Map> portConfig = new LinkedHashMap<>();
portConfig
.put(BidibLibrary.BIDIB_PCFG_TICKS,
new BytePortConfigValue(ByteUtils.getLowByte(inputPortType.getTicks())));
inputPort.setPortConfigX(portConfig);
inputPort.setConfigStatus(PortConfigStatus.CONFIG_PASSED);
inputPort.setPortStatus(InputPortStatus.ON.getType().getType());
LOGGER.info("Add configured input port: {}", inputPort);
// add the configured port
genericPorts.put(inputPort.getPortNumber(), inputPort);
}
protected void prepareInputPortFromConfig(final InputPortType inputPortType) {
// overwrite configured ports
if (CollectionUtils.isNotEmpty(inputPortType.getPort())) {
// evaluate the configured ports
for (InputPortParamsType portParams : inputPortType.getPort()) {
InputPort inputPort = new InputPort();
inputPort.setId(portParams.getPortId());
inputPort.setSwitchOffTime(portParams.getTicks());
inputPort.setConfigStatus(PortConfigStatus.CONFIG_PASSED);
LOGGER.info("Add configured port: {}", inputPort);
// add the configured port
inputPorts.put(inputPort.getId(), inputPort);
}
// use the number of configured ports
inputPortCount = inputPorts.size();
}
}
}