Skip to content
Snippets Groups Projects
Commit 4c73eebc authored by FrankR's avatar FrankR
Browse files

added README.md for OrderPicker extension and some further documentation

parent 09b93333
No related branches found
No related tags found
No related merge requests found
...@@ -80,6 +80,12 @@ public class MainApp { ...@@ -80,6 +80,12 @@ public class MainApp {
ipos.project.SensorValueIntegration.api.MqttPositionHandler.setInitialized(true); ipos.project.SensorValueIntegration.api.MqttPositionHandler.setInitialized(true);
} }
/**
* IPos-Framework is initialized with data that is suitable for testing the "OrderPicker"-usecase
* This initialization data is contained in configuration file ORDERPICKER_FILE.
* OrderPicker extension is initialized (OFBizOrderPicker.initialize()).
* After initialization the "OrderPicker extension" should be updated by the IPos-FW with all relevant positions
*/
private static void initOp() { private static void initOp() {
ipos.project.SensorValueIntegration.api.MqttPositionHandler.setInitialized(false); ipos.project.SensorValueIntegration.api.MqttPositionHandler.setInitialized(false);
SimpleSceneIntegration.init(ORDERPICKER_FILE); SimpleSceneIntegration.init(ORDERPICKER_FILE);
......
...@@ -8,6 +8,16 @@ public abstract class ECARule { ...@@ -8,6 +8,16 @@ public abstract class ECARule {
protected Condition condition; protected Condition condition;
/**
* This function implements the overall behaviour of each ECARule:
* Determine applicability of the PositionEvent ->
* determine whether the PositionEvent fulfills the current condition and can be accepted ->
* translate the PositionEvent into an action and execute it.
* Remark: If the PositionEvent can not be accepted a no-operation action is created and executed.
* The behaviour of the ECARule at runtime depends on the implementation of the Condition- and
* Action-interface
* @param posEvent
*/
public void apply(IposPositionEvent posEvent){ public void apply(IposPositionEvent posEvent){
if (isApplicable(posEvent)){ if (isApplicable(posEvent)){
Action action = condition.evaluate(posEvent); Action action = condition.evaluate(posEvent);
......
...@@ -22,6 +22,8 @@ import java.io.File; ...@@ -22,6 +22,8 @@ import java.io.File;
* This filter is part of this IPos-FW and is used for the verification. Also, the * This filter is part of this IPos-FW and is used for the verification. Also, the
* frontend application is initialized and updated to allow the operator to track the * frontend application is initialized and updated to allow the operator to track the
* progress of the picker and detect errors. * progress of the picker and detect errors.
*
* The picklist conforms to the datamodel defined in the open-source ERP-system OFBiz.
*/ */
@Component @Component
public class OFBizOrderPicker { public class OFBizOrderPicker {
...@@ -43,6 +45,12 @@ public class OFBizOrderPicker { ...@@ -43,6 +45,12 @@ public class OFBizOrderPicker {
ofbizOpIposExt.setMqttService(mqttService); ofbizOpIposExt.setMqttService(mqttService);
} }
/**
* The OFBizOrderPicker application is an extension of the IPos-FW. Therefore, initialization relies
* on the function "configureIpos", which is provided by the abstract class IPosExtension. Each application-specific
* extension of the IPos-FW, i.e., also the OrderPicker extension, has to derive a concrete class from that class.
* The OrderPicker extension derives the class ipos.project.iposextension.orderpicker.OFBizOrderPickerExt
*/
public static void initialize(){ public static void initialize(){
try { try {
ofbizOpIposExt.configureIpos(new IPosArguments.IPosConfigData() { ofbizOpIposExt.configureIpos(new IPosArguments.IPosConfigData() {
...@@ -53,6 +61,14 @@ public class OFBizOrderPicker { ...@@ -53,6 +61,14 @@ public class OFBizOrderPicker {
} }
} }
/** Function transforms the received picklist into a data format that can be handled
* by the frontend-application (FETable) and publishes the picklist to the
* frontend-application. Moreover, a filter (ECARule) is set up for accepting the
* PositionEvents that are sent from the IPos-FW. The information that is relevant
* for the filter is the zone that the position belongs to.
*
* @param picklist
*/
public static void handlePicklist(Picklist picklist){ public static void handlePicklist(Picklist picklist){
try { try {
FETable feTable = OFBizOrderPickerTrans.transformPicklistIntoFeTable(picklist); FETable feTable = OFBizOrderPickerTrans.transformPicklistIntoFeTable(picklist);
......
...@@ -19,6 +19,9 @@ import java.util.LinkedList; ...@@ -19,6 +19,9 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
/**
* Extension of the IPos-FW specific to the usecase "OrderPicker".
*/
public class OFBizOrderPickerExt extends IPosExtension { public class OFBizOrderPickerExt extends IPosExtension {
private static org.apache.logging.log4j.Logger LOG = LogManager.getLogger(); private static org.apache.logging.log4j.Logger LOG = LogManager.getLogger();
...@@ -39,15 +42,21 @@ public class OFBizOrderPickerExt extends IPosExtension { ...@@ -39,15 +42,21 @@ public class OFBizOrderPickerExt extends IPosExtension {
return zoneIds.substring(0, zoneIds.length()-2); return zoneIds.substring(0, zoneIds.length()-2);
} }
/**
* Function runs through all registered picklists (i.e., all ECARules that have been created) and
* applies the received PositionEvent to it. It is not the responsibility of this function to determine
* whether a given PositionEvent is applicable to a given ECARule. This decision is determined by the ECARule.
* For handling a PositionEvent the classes SeqPicklistRule, SeqPicklistRule, SeqPicklistCondition, and UpdateFrontendAction are relevant.
*
* @param posEvent
* @param _posEvtConf
*/
@Override @Override
public void handlePositionEvent(IposPositionEvent posEvent, IPosArguments.HandlePosEventConf _posEvtConf) { public void handlePositionEvent(IposPositionEvent posEvent, IPosArguments.HandlePosEventConf _posEvtConf) {
LOG.info("OP:"); LOG.info("OP:");
LOG.info("OP:----OFBizOrderPickerExt--------------------------"); LOG.info("OP:----OFBizOrderPickerExt--------------------------");
LOG.info("OP: Received IposPositionEvent for agent " + posEvent.getAgentId() + ". Zones: " + extractZoneIdsAsString(posEvent.getZoneDescriptors()) + "; position: " + logPoint((Point3D) posEvent.getPosition().getPoint())); LOG.info("OP: Received IposPositionEvent for agent " + posEvent.getAgentId() + ". Zones: " + extractZoneIdsAsString(posEvent.getZoneDescriptors()) + "; position: " + logPoint((Point3D) posEvent.getPosition().getPoint()));
try { try {
// String picklistId = readPicklistId(_posEvtConf);
// SeqPicklistRule spRule = getEcaRule(picklistId);
spRules.forEach(spRule -> spRule.apply(posEvent)); spRules.forEach(spRule -> spRule.apply(posEvent));
/* above: lambda-expression, shortform of: /* above: lambda-expression, shortform of:
...@@ -58,8 +67,6 @@ public class OFBizOrderPickerExt extends IPosExtension { ...@@ -58,8 +67,6 @@ public class OFBizOrderPickerExt extends IPosExtension {
} }
}); });
*/ */
// CEFResult cefResult = cef_seq.acceptPositionEvent(posEvent);
// handleCefResult(picklistId, cefResult);
}catch (RuntimeException e){ }catch (RuntimeException e){
LOG.info("OP: PositionEvent could not be handled: " + e.getMessage()); LOG.info("OP: PositionEvent could not be handled: " + e.getMessage());
return; return;
...@@ -98,6 +105,13 @@ public class OFBizOrderPickerExt extends IPosExtension { ...@@ -98,6 +105,13 @@ public class OFBizOrderPickerExt extends IPosExtension {
return picklistId; return picklistId;
} }
*/ */
/**
* Functions prepares a MonitoringRequest that causes the IPos-FW to update the OrderPicker extension with all positions
* relevant for the OrderPicker-usecase.
* @param iposConfigData
* @return
*/
@Override @Override
public SimpleScene.IposConfigWrapper prepareConfigWrapper(IPosArguments.IPosConfigData iposConfigData) { public SimpleScene.IposConfigWrapper prepareConfigWrapper(IPosArguments.IPosConfigData iposConfigData) {
try { try {
...@@ -107,6 +121,14 @@ public class OFBizOrderPickerExt extends IPosExtension { ...@@ -107,6 +121,14 @@ public class OFBizOrderPickerExt extends IPosExtension {
} }
} }
/**
* Function creates an ECARule that is able to detect whether PositionEvents have been received in
* an order that conforms to the order that is specified by the Picklist (see testdata-file testdata_raw_orderpicker_readable.txt).
* The picklist specifies picklistBins and InventoryItems. InventoryItems have to be placed in the picklistBins they belong to.
* Picklistbins have to be handled in the order of their occurence in the textfile. InventoryItems have to be handled
* in the order of their occurence in their picklistbin.
* @param picklist
*/
public void setupECARule(Picklist picklist){ public void setupECARule(Picklist picklist){
String pickerId = extractPickerId(picklist).orElseThrow(() -> new RuntimeException("Picklist did not contain the ID of the picker who is responsible for it")); String pickerId = extractPickerId(picklist).orElseThrow(() -> new RuntimeException("Picklist did not contain the ID of the picker who is responsible for it"));
SeqPicklistRule spRule = new SeqPicklistRule(picklist.getPicklistId(), pickerId); // complex event filter for verifying the picker SeqPicklistRule spRule = new SeqPicklistRule(picklist.getPicklistId(), pickerId); // complex event filter for verifying the picker
......
# OrderPicker extension
## How to run?
1. Preparation
- Make sure that IPos-FW can connect to an MQTT-server
- Verify MQTT-configuration in `src\main\resources\application.yml`
- Check logger configuration in `ipos.project.CustomLoggingFilter`
- Returning `FilterReply.DENY` prevents messages from being logged, `FilterReply.ACCEPT` allows them to be logged
- Logging all messages with relevance for this extension requires accepting all messages that contain the string `OP:`
- Check that the *modules*-submodule has been checked out properly
- folder `models` should not be empty
- if empty, try to clone the repository together with checking out all submodules
- `git clone -b SimpleScene --recurse-submodules https://git-st.inf.tu-dresden.de/ipos/project.git project4`
- additionally: `git status` in folder `models` should return `Head detached`. To fix that: `git checkout main`
- Make sure that an instance of the [frontend-app](https://git-st.inf.tu-dresden.de/ipos/front-end-app) is running and accessible by the IPos-FW
- Remark: This is not necessary if you only want to debug the IPos-FW or examine its logging messages
2. Launch IPos-FW
- main-function: `ipos.project.MainApp.main`
- Console should print an overview of the available comments (if CustomLoggingFilter accepts messages containing string `SHELL:`)
- Console can be made to reprint the overview by entering `help`
3. Enter `init op`
- Initializes both, IPos-FW and OrderPicker extension
- OrderPicker extension sends MonitoringRequest to IPos-FW that causes it to send *Position-Updates* to the OrderPicker that cover all zones relevant for the verification of order-picking
4. Enter `oppl testdata`
- Reads a test-picklist contained in JSON-file `testdata_raw_orderpicker.txt`
- The logger should print the sequence of zones the picker is expected to visit
5. Enter `opevts testdata`
- Reads the JSON-file `testdata_raw_orderpicker_posEvts.txt` containing a sequence of test-messages indicating to the *OrderPicker extension* the presence of the picker in certain zones
- The OrderPicker verifies whether the picker follows the expected sequence.
- The *OrderPicker extension* informs the frontend-app about certain events by sending appropriate messages:
- Picker entered a zone in order
- Picker entered a zone out of order
- The behaviour of the *OrderPicker extension* can be verified by inspecting the (exhaustive) logger-output
- Messages sent are sent to the frontend-app are logged
- Events that have occured but are not indicated to the frontend-app are logged
## Selected positions in source-code
### Execution of the SHELL-commands
- function `ipos.project.MainApp.processCommands`
### Initialization of the *OrderPicker extension*
- starting point: function `ipos.project.MainApp.initOp`
- The MonitoringReqeuest is prepared: function `ipos.project.iposextension.orderpicker.OFBizOrderPickerExt.prepareConfigWrapper`
### Information on the extension-mechanism of the IPos-FW
- see documentation of function `ipos.project.iposextension.orderpicker.OFBizOrderPicker.initialize`
### Information on the general behaviour of the `OrderPicker extension`
- see documentation of class `ipos.project.iposextension.orderpicker.OFBizOrderPicker`
### Testdata processing
- picklist testdata: function `ipos.project.iposextension.orderpicker.OFBizOrderPicker.processPicklistTestData`
- position testdata: function `ipos.project.iposextension.orderpicker.OFBizOrderPicker.processPosEvtTestData`
### Picklist-handling
- function: `ipos.project.iposextension.orderpicker.OFBizOrderPicker.handlePicklist`
- filter-behaviour: see documentation of function `ipos.project.iposextension.orderpicker.OFBizOrderPickerExt.setupECARule`
### Handling a PositionEvent sent from IPos-FW
- function: `ipos.project.iposextension.orderpicker.OFBizOrderPickerExt.handlePositionEvent(ipos.project.DataModellntegration.iPos_Datamodel.IPosDevKit.IposPositionEvent, ipos.project.devkit.iposext.IPosArguments.HandlePosEventConf)`
- overall behaviour of each ECA-rule: `ipos.project.devkit.eca.ECARule.apply`
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment