org.bidib.wizard.server.controllers.MessageActions Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bidibwizard-server Show documentation
Show all versions of bidibwizard-server Show documentation
jBiDiB BiDiB Wizard Server POM
package org.bidib.wizard.server.controllers;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.collections4.CollectionUtils;
import org.bidib.api.json.types.NodeAddress;
import org.bidib.api.json.types.booster.BoostDiagnostic;
import org.bidib.api.json.types.booster.BoosterState;
import org.bidib.api.json.types.booster.BoosterState.BoosterStateType;
import org.bidib.api.json.types.booster.BoosterState.CommandStationStateType;
import org.bidib.api.json.types.occupancy.AbstractPort;
import org.bidib.api.json.types.occupancy.AddressData.EnrailmentDirection;
import org.bidib.api.json.types.occupancy.OccupancyStatusResponse;
import org.bidib.api.json.types.occupancy.PortIdentifier;
import org.bidib.api.json.types.switching.AbstractConfigPort;
import org.bidib.api.json.types.switching.PortConfigResponse;
import org.bidib.api.json.types.switching.PortStatusResponse;
import org.bidib.jbidibc.messages.FeedbackAddressData;
import org.bidib.jbidibc.messages.enums.LcOutputType;
import org.bidib.wizard.api.model.BoosterNodeInterface;
import org.bidib.wizard.api.model.CommandStationNodeInterface;
import org.bidib.wizard.api.model.NodeInterface;
import org.bidib.wizard.api.model.connection.AbstractQueueEvent;
import org.bidib.wizard.api.model.connection.event.AccessoryStateMessageEvent;
import org.bidib.wizard.api.model.connection.event.OccupancyCvMessageEvent;
import org.bidib.wizard.api.model.event.NodeStatusEvent.StatusIdentifier;
import org.bidib.wizard.api.utils.JsonNodeUtils;
import org.bidib.wizard.api.utils.PortListUtils;
import org.bidib.wizard.model.ports.AnalogPort;
import org.bidib.wizard.model.ports.BacklightPort;
import org.bidib.wizard.model.ports.FeedbackPort;
import org.bidib.wizard.model.ports.GenericPort;
import org.bidib.wizard.model.ports.InputPort;
import org.bidib.wizard.model.ports.LightPort;
import org.bidib.wizard.model.ports.MotorPort;
import org.bidib.wizard.model.ports.Port;
import org.bidib.wizard.model.ports.PortTypeAware;
import org.bidib.wizard.model.ports.ServoPort;
import org.bidib.wizard.model.ports.SoundPort;
import org.bidib.wizard.model.ports.SwitchPairPort;
import org.bidib.wizard.model.ports.SwitchPort;
import org.bidib.wizard.model.status.BoosterStatus;
import org.bidib.wizard.model.status.FeedbackPortStatus;
import org.bidib.wizard.server.controllers.actions.BoosterDiagAction;
import org.bidib.wizard.server.controllers.actions.BoosterStatusAction;
import org.bidib.wizard.server.controllers.actions.CommandStationStatusAction;
import org.bidib.wizard.server.controllers.actions.FeedbackPortAction;
import org.bidib.wizard.server.controllers.actions.NodeStatusAction;
import org.bidib.wizard.server.controllers.actions.NodeStringAction;
import org.bidib.wizard.server.controllers.actions.PortConfigAction;
import org.bidib.wizard.server.controllers.actions.PortStatusAction;
import org.bidib.wizard.server.jsontuils.JsonPortMapping;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
enum MessageActions implements MessageConsumer {
BoosterDiagAction {
@Override
public void accept(AbstractQueueEvent messageEvent, NodeInterface node, MessageController controller) {
BoosterDiagAction event = (BoosterDiagAction) messageEvent;
LOGGER.info("Received new booster diag action: {}", event);
NodeAddress nodeAddress = JsonNodeUtils.prepareNodeAddress(node);
final BoosterNodeInterface boosterNode = node.getBoosterNode();
if (boosterNode != null) {
BoostDiagnostic boostDiagnostic =
new BoostDiagnostic(event.getConnectionId(), nodeAddress, boosterNode.getBoosterCurrent(),
boosterNode.getBoosterMaximumCurrent(), boosterNode.getBoosterVoltage(),
boosterNode.getBoosterTemperature());
controller.publishBoostDiagnostic(boostDiagnostic);
}
}
},
BoosterStateAction {
@Override
public void accept(AbstractQueueEvent messageEvent, NodeInterface node, MessageController controller) {
// BoosterStateMessageEvent event = (BoosterStateMessageEvent) messageEvent;
BoosterStatusAction event = (BoosterStatusAction) messageEvent;
LOGGER.info("Received new booster state event: {}", event);
NodeAddress nodeAddress = JsonNodeUtils.prepareNodeAddress(node);
final BoosterNodeInterface boosterNode = node.getBoosterNode();
if (boosterNode != null) {
// prepare the json booster state
BoosterState boosterState =
new BoosterState()
.withBooster(BoosterStateType
.fromValue(boosterNode.getBoosterStatus() != null ? boosterNode.getBoosterStatus().name()
: BoosterStatus.OFF.name()))
.withConnectionId(event.getConnectionId()).withNode(nodeAddress);
// check if the node is a command station, and get the status of the command station
CommandStationNodeInterface commandStationNode = node.getCommandStationNode();
if (commandStationNode != null) {
if (commandStationNode.getCommandStationStatus() != null) {
boosterState
.withDcc(
CommandStationStateType.valueOf(commandStationNode.getCommandStationStatus().name()));
}
else {
boosterState.withDcc(CommandStationStateType.OFF);
}
}
LOGGER.info("Prepare new booster state: {}", boosterState);
controller.publishBoosterState(boosterState);
}
else {
LOGGER.warn("The signalled node is not a booster node: {}", node);
}
}
},
CommandStationStateAction {
@Override
public void accept(AbstractQueueEvent messageEvent, NodeInterface node, MessageController controller) {
CommandStationStatusAction event = (CommandStationStatusAction) messageEvent;
LOGGER.info("Received new command station state event: {}", event);
CommandStationNodeInterface commandStationNode = node.getCommandStationNode();
if (commandStationNode != null) {
NodeAddress nodeAddress = JsonNodeUtils.prepareNodeAddress(node);
BoosterState boosterState =
new BoosterState().withConnectionId(event.getConnectionId()).withNode(nodeAddress);
if (commandStationNode.getCommandStationStatus() != null) {
boosterState
.withDcc(CommandStationStateType.fromValue(commandStationNode.getCommandStationStatus().name()));
}
// check if the node is a booster
final BoosterNodeInterface boosterNode = node.getBoosterNode();
if (boosterNode != null) {
if (boosterNode.getBoosterStatus() != null) {
boosterState.withBooster(BoosterStateType.valueOf(boosterNode.getBoosterStatus().name()));
}
else {
boosterState.withBooster(BoosterStateType.OFF);
}
}
LOGGER.info("Prepare new booster state: {}", boosterState);
controller.publishBoosterState(boosterState);
}
else {
LOGGER.warn("The signalled node is not a commandstation node: {}", node);
}
}
},
PortConfigAction {
@Override
public void accept(AbstractQueueEvent messageEvent, NodeInterface node, MessageController controller) {
PortConfigAction event = (PortConfigAction) messageEvent;
LOGGER
.info("Received new PortConfigAction: {}, isInitialLoadFinished: {}", event,
node.getNodeLoadStatusIdentifier());
if (StatusIdentifier.InitialLoadFinished != node.getNodeLoadStatusIdentifier()) {
LOGGER.info("The initial load has not finished yet. Do not publish the port config.");
return;
}
// publish the change to the client
NodeAddress nodeAddress = JsonNodeUtils.prepareNodeAddress(node);
final PortConfigResponse portConfigResponse =
new PortConfigResponse().withConnectionId(event.getConnectionId()).withNode(nodeAddress);
Port> port = null;
Integer portNumber = event.getPort().getPortNumber();
if (node.getNode().isPortFlatModelAvailable()) {
PortTypeAware genericPort = event.getPort();
LcOutputType currentPortType = genericPort.getPortType();
LOGGER
.info(
"The current node supports the flat port model, get the generic port with portNumber: {}, portType: {}",
portNumber, currentPortType);
// get the port with the current port type
port = PortListUtils.getPort(node, currentPortType, portNumber);
}
else {
// get the port with the current port type
port = (Port>) event.getPort();
}
LOGGER.info("Convert port to jsonPort: {}", port);
AbstractPort jsonPort = JsonPortMapping.toJsonPort(port);
// publish the notification
portConfigResponse.withPort(new PortIdentifier(portNumber, jsonPort.getPortType()));
if (jsonPort instanceof AbstractConfigPort) {
portConfigResponse.withPcfg(((AbstractConfigPort) jsonPort).getPcfg());
}
else {
LOGGER.warn("No config available from jsonPort: {}", jsonPort);
}
try {
controller.publishPortConfig(portConfigResponse);
}
catch (Exception ex) {
LOGGER.warn("Publish the port config failed.", ex);
}
}
},
PortStatusAction {
@Override
public void accept(AbstractQueueEvent messageEvent, NodeInterface node, MessageController controller) {
PortStatusAction event = (PortStatusAction) messageEvent;
LOGGER.info("Received new PortStatusAction: {}", event);
if (StatusIdentifier.InitialLoadFinished != node.getNodeLoadStatusIdentifier()) {
LOGGER.info("The initial load has not finished yet. Do not publish the port status.");
return;
}
// publish the change to the client
NodeAddress nodeAddress = JsonNodeUtils.prepareNodeAddress(node);
Port> port = null;
Integer portNumber = event.getPort().getPortNumber();
if (node.getNode().isPortFlatModelAvailable()) {
LOGGER.info("The current node supports the flat port model, update the generic port.");
PortTypeAware genericPort = event.getPort();
LcOutputType currentPortType = genericPort.getPortType();
// get the port with the current port type
port = PortListUtils.getPort(node, currentPortType, portNumber);
}
else {
// get the port with the current port type
port = (Port>) event.getPort();
if (port == null) {
LOGGER.warn("No port delivered in event: {}", event);
}
}
try {
LcOutputType portType = port.getPortType();
LOGGER.info("Current port type: {}", portType);
final PortStatusResponse portStatusResponse =
JsonPortMapping.toJsonPortStatusResponse(event.getConnectionId(), nodeAddress, port);
try {
controller.publishPortStatus(portStatusResponse);
}
catch (Exception ex) {
LOGGER.warn("Publish the port status failed.", ex);
}
}
catch (Exception ex2) {
LOGGER.warn("Get the port type failed, port: {}", port, ex2);
}
}
},
NodeStatusAction {
@Override
public void accept(AbstractQueueEvent messageEvent, NodeInterface node, MessageController controller) {
NodeStatusAction event = (NodeStatusAction) messageEvent;
LOGGER.info("Received node status action: {}", event);
if (StatusIdentifier.InitialLoadFinished != node.getNodeLoadStatusIdentifier()) {
LOGGER.info("The initial load has not finished yet. Do not publish the port status.");
return;
}
LOGGER.info("Publish the port config and the port status for node: {}", node);
NodeAddress nodeAddress = JsonNodeUtils.prepareNodeAddress(node);
if (node.getNode().isPortFlatModelAvailable()) {
LOGGER.info("The current node supports the flat port model, publish config of the generic port ports.");
List ports = node.getGenericPorts();
for (GenericPort genericPort : ports) {
LOGGER.info("Prepare config data of genericPort: {}", genericPort);
int portNumber = genericPort.getPortNumber();
// get the port with the current port type
Port> port = PortListUtils.getPort(node, genericPort.getCurrentPortType(), portNumber);
if (port == null) {
LOGGER.info("No port available for portNumber: {}", portNumber);
continue;
}
publishPort(event.getConnectionId(), nodeAddress, port, controller);
}
}
else {
// TODO add support for typed-port model
LOGGER.info("Deliver all ports for typed-port model: {}", node);
if (node.hasAnalogPorts()) {
// publish analog ports
for (AnalogPort port : node.getAnalogPorts()) {
publishPort(event.getConnectionId(), nodeAddress, port, controller);
}
}
if (node.hasBacklightPorts()) {
// publish backlight ports
for (BacklightPort port : node.getBacklightPorts()) {
publishPort(event.getConnectionId(), nodeAddress, port, controller);
}
}
if (node.hasInputPorts()) {
// publish input ports
List inputPorts = node.getInputPorts();
LOGGER.info("Node has inputPorts: {}", inputPorts);
for (InputPort port : inputPorts) {
publishPort(event.getConnectionId(), nodeAddress, port, controller);
}
}
else {
LOGGER.info("Node has node inputPorts: {}", node);
}
if (node.hasLightPorts()) {
// publish light ports
List lightPorts = node.getLightPorts();
LOGGER.info("Node has lightPorts: {}", lightPorts);
for (LightPort port : lightPorts) {
publishPort(event.getConnectionId(), nodeAddress, port, controller);
}
}
else {
LOGGER.info("Node has node lightPorts: {}", node);
}
if (node.hasMotorPorts()) {
// publish motor ports
for (MotorPort port : node.getMotorPorts()) {
publishPort(event.getConnectionId(), nodeAddress, port, controller);
}
}
if (node.hasServoPorts()) {
// publish servo ports
for (ServoPort port : node.getServoPorts()) {
publishPort(event.getConnectionId(), nodeAddress, port, controller);
}
}
if (node.hasSoundPorts()) {
// publish sound ports
for (SoundPort port : node.getSoundPorts()) {
publishPort(event.getConnectionId(), nodeAddress, port, controller);
}
}
if (node.hasSwitchPairPorts()) {
// publish switchPair ports
for (SwitchPairPort port : node.getSwitchPairPorts()) {
publishPort(event.getConnectionId(), nodeAddress, port, controller);
}
}
if (node.hasSwitchPorts()) {
// publish switch ports
for (SwitchPort port : node.getSwitchPorts()) {
publishPort(event.getConnectionId(), nodeAddress, port, controller);
}
}
}
}
},
StringAction {
@Override
public void accept(AbstractQueueEvent messageEvent, NodeInterface node, MessageController controller) {
NodeStringAction event = (NodeStringAction) messageEvent;
LOGGER.info("Received node string action: {}", event);
// TODO
}
},
AccessoryStateAction {
@Override
public void accept(AbstractQueueEvent messageEvent, NodeInterface node, MessageController controller) {
AccessoryStateMessageEvent event = (AccessoryStateMessageEvent) messageEvent;
LOGGER.info("Received new AccessoryState event: {}", event);
// TODO publish the change to the client
}
},
OccupancyCvAction {
@Override
public void accept(AbstractQueueEvent messageEvent, NodeInterface node, MessageController controller) {
OccupancyCvMessageEvent event = (OccupancyCvMessageEvent) messageEvent;
LOGGER.info("Received new occupancy CV event: {}", event);
}
},
FeedbackPortAction {
@Override
public void accept(AbstractQueueEvent messageEvent, NodeInterface node, MessageController controller) {
FeedbackPortAction event = (FeedbackPortAction) messageEvent;
LOGGER.info("Received new feedback port action: {}", event);
final FeedbackPort feedbackPort = event.getPort();
if (feedbackPort != null) {
// publish the change to the client
NodeAddress nodeAddress = JsonNodeUtils.prepareNodeAddress(node);
final OccupancyStatusResponse occupancyStatusResponse =
buildOccupancyStatusResponse(event.getConnectionId(), nodeAddress, feedbackPort);
controller.publishOccupancyStatus(occupancyStatusResponse);
}
}
};
private static final Logger LOGGER = LoggerFactory.getLogger(MessageActions.class);
private static OccupancyStatusResponse buildOccupancyStatusResponse(
String connectionId, final NodeAddress nodeAddress, final FeedbackPort feedbackPort) {
final OccupancyStatusResponse occupancyStatusResponse =
new OccupancyStatusResponse().withConnectionId(connectionId).withNode(nodeAddress);
final org.bidib.api.json.types.occupancy.FeedbackPort jsonFeedbackPort =
new org.bidib.api.json.types.occupancy.FeedbackPort().withId(feedbackPort.getId());
occupancyStatusResponse.setPortNum(jsonFeedbackPort.getId());
occupancyStatusResponse
.setPortStatus(
feedbackPort.getStatus() == FeedbackPortStatus.FREE ? OccupancyStatusResponse.FeedbackPortStatus.FREE
: OccupancyStatusResponse.FeedbackPortStatus.OCCUPIED);
if (CollectionUtils.isNotEmpty(feedbackPort.getAddresses())) {
Set addresses = new HashSet<>();
for (FeedbackAddressData addressData : feedbackPort.getAddresses()) {
final org.bidib.api.json.types.occupancy.AddressData jsonAddressData =
new org.bidib.api.json.types.occupancy.AddressData()
.withAddress(addressData.getAddress())
.withEnrailmentDirection(EnrailmentDirection.fromValue(addressData.getType().name()))
.withSpeed(addressData.getSpeed());
addresses.add(jsonAddressData);
}
occupancyStatusResponse.withAddresses(addresses);
}
return occupancyStatusResponse;
}
private static void publishPort(
String connectionId, NodeAddress nodeAddress, Port> port, MessageController controller) {
LOGGER.info("Convert port to jsonPort: {}, status: {}", port, port.getStatus());
AbstractPort jsonPort = JsonPortMapping.toJsonPort(port);
final PortConfigResponse portConfigResponse =
new PortConfigResponse().withConnectionId(connectionId).withNode(nodeAddress);
// publish the notification
portConfigResponse.withPort(new PortIdentifier(port.getPortNumber(), jsonPort.getPortType()));
if (jsonPort instanceof AbstractConfigPort) {
portConfigResponse.withPcfg(((AbstractConfigPort) jsonPort).getPcfg());
}
else {
LOGGER.warn("No config available from jsonPort: {}", jsonPort);
}
try {
controller.publishPortConfig(portConfigResponse);
}
catch (Exception ex) {
LOGGER.warn("Publish the port config failed.", ex);
}
try {
LcOutputType portType = port.getPortType();
LOGGER.info("Current port type: {}", portType);
final PortStatusResponse portStatusResponse =
JsonPortMapping.toJsonPortStatusResponse(connectionId, nodeAddress, port);
controller.publishPortStatus(portStatusResponse);
}
catch (Exception ex) {
LOGGER.warn("Publish the port status failed, port: {}", port, ex);
}
}
}