diff --git a/src/main/java/org/opentcs/commadapter/vehicle/vda5050/v1_1/CommAdapterImpl.java b/src/main/java/org/opentcs/commadapter/vehicle/vda5050/v1_1/CommAdapterImpl.java index 6f498d7..56072a6 100644 --- a/src/main/java/org/opentcs/commadapter/vehicle/vda5050/v1_1/CommAdapterImpl.java +++ b/src/main/java/org/opentcs/commadapter/vehicle/vda5050/v1_1/CommAdapterImpl.java @@ -58,6 +58,7 @@ import org.opentcs.customizations.kernel.KernelExecutor; import org.opentcs.data.model.Triple; import org.opentcs.data.model.Vehicle; +import org.opentcs.data.notification.UserNotification; import org.opentcs.data.order.DriveOrder; import org.opentcs.data.order.TransportOrder; import org.opentcs.drivers.vehicle.BasicVehicleCommAdapter; @@ -206,9 +207,8 @@ public CommAdapterImpl(@Assisted Vehicle vehicle, this.getName(), this::sendOrder, this::sendInstantAction, - orderAssociation -> { - movementCommandManager.enqueue(orderAssociation); - } + this::orderAccepted, + this::orderRejected ); vehicleSerialNumber = vehicle.getProperty(PROPKEY_VEHICLE_SERIAL_NUMBER); @@ -625,4 +625,17 @@ private void sendMessage(Header messageObject, String topic) { } } + private void orderAccepted(OrderAssociation order) { + movementCommandManager.enqueue(order); + } + + private void orderRejected(OrderAssociation order) { + getProcessModel().publishUserNotification(new UserNotification( + getProcessModel().getName(), + String.format("Vehicle rejected VDA5050 order (ID: %s, update ID: %s)", + order.getOrder().getOrderId(), + order.getOrder().getOrderUpdateId()), + UserNotification.Level.IMPORTANT + )); + } } diff --git a/src/main/java/org/opentcs/commadapter/vehicle/vda5050/v1_1/MessageResponseMatcher.java b/src/main/java/org/opentcs/commadapter/vehicle/vda5050/v1_1/MessageResponseMatcher.java index dda56d9..7933b2b 100644 --- a/src/main/java/org/opentcs/commadapter/vehicle/vda5050/v1_1/MessageResponseMatcher.java +++ b/src/main/java/org/opentcs/commadapter/vehicle/vda5050/v1_1/MessageResponseMatcher.java @@ -50,6 +50,10 @@ public class MessageResponseMatcher { * The callback for when an order is accepted by the vehicle. */ private final Consumer orderAcceptedCallback; + /** + * The callback for when an order was rejected by the vehicle. + */ + private final Consumer orderRejectedCallback; /** * Creates a new OrderResponseMatcher. @@ -58,16 +62,19 @@ public class MessageResponseMatcher { * @param sendOrderCallback The callback for sending the next order. * @param sendInstantActionsCallback The callback for sending instant actions. * @param orderAcceptedCallback The callback for when the order is accepted by the vehicle. + * @param orderRejectedCallback The callback for when the vehicle rejects an order. */ public MessageResponseMatcher(@Nonnull String commAdapterName, @Nonnull Consumer sendOrderCallback, @Nonnull Consumer sendInstantActionsCallback, - @Nonnull Consumer orderAcceptedCallback) { + @Nonnull Consumer orderAcceptedCallback, + @Nonnull Consumer orderRejectedCallback) { this.commAdapterName = requireNonNull(commAdapterName, "commAdapterName"); this.sendOrderCallback = requireNonNull(sendOrderCallback, "sendOrderCallback"); this.sendInstantActionsCallback = requireNonNull(sendInstantActionsCallback, "sendInstantActionsCallback"); this.orderAcceptedCallback = requireNonNull(orderAcceptedCallback, "orderAcceptedCallback"); + this.orderRejectedCallback = requireNonNull(orderRejectedCallback, "orderRejectedCallback"); } public void enqueueCommand(Order order, MovementCommand command) { @@ -106,9 +113,14 @@ public void onStateMessage(@Nonnull State state) { return; } if (vehicleRejectedOrder(state)) { + Object request = requests.peek(); + if (request instanceof OrderAssociation) { + orderRejectedCallback.accept((OrderAssociation) request); + } + LOG.warn("{}: Vehicle indicates order rejection. Last request sent to it was: {}", commAdapterName, - requests.peek()); + request); return; } diff --git a/src/main/java/org/opentcs/commadapter/vehicle/vda5050/v2_0/CommAdapterImpl.java b/src/main/java/org/opentcs/commadapter/vehicle/vda5050/v2_0/CommAdapterImpl.java index 12d2d79..f2ba1e5 100644 --- a/src/main/java/org/opentcs/commadapter/vehicle/vda5050/v2_0/CommAdapterImpl.java +++ b/src/main/java/org/opentcs/commadapter/vehicle/vda5050/v2_0/CommAdapterImpl.java @@ -58,6 +58,7 @@ import org.opentcs.customizations.kernel.KernelExecutor; import org.opentcs.data.model.Triple; import org.opentcs.data.model.Vehicle; +import org.opentcs.data.notification.UserNotification; import org.opentcs.data.order.DriveOrder; import org.opentcs.data.order.TransportOrder; import org.opentcs.drivers.vehicle.BasicVehicleCommAdapter; @@ -206,9 +207,8 @@ public CommAdapterImpl(@Assisted Vehicle vehicle, this.getName(), this::sendOrder, this::sendInstantAction, - orderAssociation -> { - movementCommandManager.enqueue(orderAssociation); - } + this::orderAccepted, + this::orderRejected ); vehicleSerialNumber = vehicle.getProperty(PROPKEY_VEHICLE_SERIAL_NUMBER); @@ -630,4 +630,17 @@ private void sendMessage(Header messageObject, String topic) { } } + private void orderAccepted(OrderAssociation order) { + movementCommandManager.enqueue(order); + } + + private void orderRejected(OrderAssociation order) { + getProcessModel().publishUserNotification(new UserNotification( + getProcessModel().getName(), + String.format("Vehicle rejected VDA5050 order (ID: %s, update ID: %s)", + order.getOrder().getOrderId(), + order.getOrder().getOrderUpdateId()), + UserNotification.Level.IMPORTANT + )); + } } diff --git a/src/main/java/org/opentcs/commadapter/vehicle/vda5050/v2_0/MessageResponseMatcher.java b/src/main/java/org/opentcs/commadapter/vehicle/vda5050/v2_0/MessageResponseMatcher.java index 659e716..1a3939b 100644 --- a/src/main/java/org/opentcs/commadapter/vehicle/vda5050/v2_0/MessageResponseMatcher.java +++ b/src/main/java/org/opentcs/commadapter/vehicle/vda5050/v2_0/MessageResponseMatcher.java @@ -50,6 +50,10 @@ public class MessageResponseMatcher { * The callback for when an order is accepted by the vehicle. */ private final Consumer orderAcceptedCallback; + /** + * The callback for when an order was rejected by the vehicle. + */ + private final Consumer orderRejectedCallback; /** * Creates a new OrderResponseMatcher. @@ -58,16 +62,19 @@ public class MessageResponseMatcher { * @param sendOrderCallback The callback for sending the next order. * @param sendInstantActionsCallback The callback for sending instant actions. * @param orderAcceptedCallback The callback for when the order is accepted by the vehicle. + * @param orderRejectedCallback The callback for when the vehicle rejects an order. */ public MessageResponseMatcher(@Nonnull String commAdapterName, @Nonnull Consumer sendOrderCallback, @Nonnull Consumer sendInstantActionsCallback, - @Nonnull Consumer orderAcceptedCallback) { + @Nonnull Consumer orderAcceptedCallback, + @Nonnull Consumer orderRejectedCallback) { this.commAdapterName = requireNonNull(commAdapterName, "commAdapterName"); this.sendOrderCallback = requireNonNull(sendOrderCallback, "sendOrderCallback"); this.sendInstantActionsCallback = requireNonNull(sendInstantActionsCallback, "sendInstantActionsCallback"); this.orderAcceptedCallback = requireNonNull(orderAcceptedCallback, "orderAcceptedCallback"); + this.orderRejectedCallback = requireNonNull(orderRejectedCallback, "orderRejectedCallback"); } public void enqueueCommand(Order order, MovementCommand command) { @@ -106,9 +113,14 @@ public void onStateMessage(@Nonnull State state) { return; } if (vehicleRejectedOrder(state)) { + Object request = requests.peek(); + if (request instanceof OrderAssociation) { + orderRejectedCallback.accept((OrderAssociation) request); + } + LOG.warn("{}: Vehicle indicates order rejection. Last request sent to it was: {}", commAdapterName, - requests.peek()); + request); return; } diff --git a/src/test/java/org/opentcs/commadapter/vehicle/vda5050/v1_1/MessageResponseMatcherTest.java b/src/test/java/org/opentcs/commadapter/vehicle/vda5050/v1_1/MessageResponseMatcherTest.java index e68f851..07b1b73 100644 --- a/src/test/java/org/opentcs/commadapter/vehicle/vda5050/v1_1/MessageResponseMatcherTest.java +++ b/src/test/java/org/opentcs/commadapter/vehicle/vda5050/v1_1/MessageResponseMatcherTest.java @@ -51,6 +51,7 @@ public class MessageResponseMatcherTest { private Consumer sendOrderCallback; private Consumer sendInstantActionsCallback; private Consumer orderAcceptedCallback; + private Consumer orderRejectedCallback; private MovementCommand dummyCommand; @@ -60,10 +61,13 @@ public void setUp() { sendOrderCallback = mock(Consumer.class); sendInstantActionsCallback = mock(Consumer.class); orderAcceptedCallback = mock(Consumer.class); + orderRejectedCallback = mock(Consumer.class); messageResponseMatcher = new MessageResponseMatcher("test", sendOrderCallback, sendInstantActionsCallback, - orderAcceptedCallback); + orderAcceptedCallback, + orderRejectedCallback + ); dummyCommand = new DummyMovementCommand(); } diff --git a/src/test/java/org/opentcs/commadapter/vehicle/vda5050/v2_0/MessageResponseMatcherTest.java b/src/test/java/org/opentcs/commadapter/vehicle/vda5050/v2_0/MessageResponseMatcherTest.java index c03b8d5..2ef65df 100644 --- a/src/test/java/org/opentcs/commadapter/vehicle/vda5050/v2_0/MessageResponseMatcherTest.java +++ b/src/test/java/org/opentcs/commadapter/vehicle/vda5050/v2_0/MessageResponseMatcherTest.java @@ -51,6 +51,8 @@ public class MessageResponseMatcherTest { private Consumer sendOrderCallback; private Consumer sendInstantActionsCallback; private Consumer orderAcceptedCallback; + private Consumer orderRejectedCallback; + private Consumer actionRejectedCallback; private MovementCommand dummyCommand; @@ -60,10 +62,13 @@ public void setUp() { sendOrderCallback = mock(Consumer.class); sendInstantActionsCallback = mock(Consumer.class); orderAcceptedCallback = mock(Consumer.class); + orderRejectedCallback = mock(Consumer.class); messageResponseMatcher = new MessageResponseMatcher("test", sendOrderCallback, sendInstantActionsCallback, - orderAcceptedCallback); + orderAcceptedCallback, + orderRejectedCallback + ); dummyCommand = new DummyMovementCommand(); }