-
Notifications
You must be signed in to change notification settings - Fork 8
Documentation Single Source of Truth
The goal of Ark Automate is to have multiple interfaces altering/showing the same robot. For each robot, there will be a properties panel to change attributes, a view of the current .robot code and possibly multiple modeling interfaces. The user selects the modeling language he/she prefers and starts modeling the behavior of the robot (at least for now the user has to pre-select the modeling language). At the same time, the user can view/change the .robot code of the bot and/or update attributes via the property panel. To achieve that we need a single-source-of-truth(SSoT) for each robot. In the SSoT all necessary information is saved so that changes can be automatically applied to every interface.
- definitely have to be implemented: BPMN editor, robot framework code editor
- optional (planned) are: Google BLOCKLY
- in the long run we are open for other modelling languages
(We want to support all modelling languages that can be rendered into an edge and node model)
Observation: All frontends that represent "executable program code" can be represented as a graph.
- Linear flow (sequences)
- Branching
- Loops (For+While) Does not support try-catch constructs
The SSoT itself will be stored on the server-side of the product. It will support multiple use cases shown in the following image: With a change of one of the interfaces on the frontend-side (e.g. type in a new name in the side panel) the new data will be sent to the SSoT via HTTP and the SSoT on the server side will be updated. Once the SSoT gets updated all the other interfaces update accordingly as they are dependent on the SSoT data.
- Saving the SSoT - the local SSOT is pushed into the DB in certain time intervals (or trigger like "change tab") - the SSoT stores only the logic behind the modeling interfaces (the visual representation is "rendered" from the graph)
- Only those features of the modelling languages are allowed that are supported by Robot Framework. - Parallelism is not supported - No gateways other than an XOR split are recorded in the SSOT. ( => non-interrupting events are not supported) - Exception handling is not supported (=> therefore we do not support intermediate events in BPMN)
-
Front-end rendering
- requires extensive programming
- may cause the programmer to see his model differently from the way he saved it
- Hard-coded values required for frontend rendering are stored in a
config.json
-
Do we store information about each model in the SSoT or do we "render" each model from the SSoT without having specific model information stored in the SSoT?
- we render each model from our "logical graph".
- no modelling-interface-specific values are therefore stored.
- missing attributes needed to create a modelling visualisation have to be assumed or calculated with default values
- Do we use the XML as SSOT? No, we render the models from the SSOT. For e.g. BPMN we render SSOT to XML to BPMN.
- How do we store the edges from BPMN? Implicitly through the successor/predecessor relationships. The exact waypoints have to be "calculated"
- What are the consequences of not saving modelling attributes for our project? (BPMN specific) - exact arrangement in the interface is not maintained; however: support for adherence to the standard (automatic pretty print) - Logic for updating SSoT after deleting (and adding) is needed. - Config files with sizes, colours, symbols etc. are needed for each modelling interface
**Note: SSoT should be closer to basic programming constructs than to a BPMN model. Therefore: All interfaces are rendered into a graph model where the nodes are defined by the following tags: 'INSTRUCTION', 'BRANCH', 'CASE' and 'MARKER'. These tags represent the basic programming constructs that can also be used in the **Robot Framework**.
SSoT tag | BPMN representation | Code representation | ArkA 0.3 | ArkA 1.0 |
---|---|---|---|---|
INSTRUCTION | Activity | "one line of code" | ✔️ | ✔️ |
CASE | XOR-Gateway | Branching (IF, CASE) | ❌ | ✔️ |
LOOP | XOR-Split & Join (Combination) | Loop (FOR, WHILE) | ❌ | ✔️ |
MARKER | Start & End Event | - | ✔️ | ✔️ |
EXCEPTION | intermediate Event | TRY-CATCH | ❌ | ❌ |
Special features for events: Timers: In the long term, timers are to be represented in BPMN as intermediate events. At the moment, a "sleep event" (to pause execution) is to be defined as an instruction with an RPA action as an example.
Event types: are not stored. Events therefore always appear as "empty circles". They are also not linkable with logic. For example, if an end event is to send a mail, please model this construct as 'Activity: Send Mail' and 'End Event'. No intermediate events are currently supported.
User information about a robot (creator, released for etc.) is stored in an additional file in the database.
SSoT
{
"_id": "6045eccfa9a07940e5763f0b",
"starterId": "exampleID",
"robotName": "exampleRobot",
"elements": [
{
/* Here start the nodes of the graph */
}
]
}
SSoT
{
"type": "INSTRUCTION",
"name": "exampleName",
"id": "exampleId",
"predecessorIds": ["randomId"],
"successorIds": ["randomId"],
"rpaApplication": "e.g. Excel.Files",
"rpaTask": "e.g. Open Workbook"
}
Parameter Object Extending the INSTRUCTION Element
{
"robotId": "604f537ed699a2eb47274184",
"activityId": "Activity_47II",
"outputValue": "exampleId",
"rpaParameters": [
{
"name": "Filename",
"type": "Boolean",
"value": "",
"requireUserInput": true,
"infoText": "The name of the file",
"isRequired": true,
"index": 0
},
{
"name": "Path",
"value": "C:/RPA-folder/",
"type": "Boolean",
"requireUserInput": false,
"infoText": "The path where the file is located on the machine",
"isRequired": true,
"index": 1
}
]
}
attribute object extending the INSTRUCTION:
{
"robotId": "604f537ed699a2eb47274184",
"activityId": "Activity_47II",
"rpaApplication": "Excel.Files",
"rpaTask": "Open Workbook"
}
BPMN requires:
- id ✔️
- label -> name ✔️
- predecessor ✔️
- successor ✔️
-
position-> calculated ✔️ -
size->config.json
✔️ - RPA-Task & Application & Parameters ✔️
By using separate external objects we allow for a more consistent updating of the ssot, since it is only required to carry the information about the name of single elements, as well as their predecessors and successors. Splitting the required information again into parameter and attributes has benefits when working with only one of the both in situations where many of those objects are needed, but only the attribute or parameter information is needed at that point.
SSoT stores
- predecessor node, Successor node
- name, ID
- default successor node
- conditions (for each successor node) = IF condition
{
"type": "CASE",
"name": "",
"id": "exampleId",
"predecessorIds": ["randomId3"],
"successorIds": ["randomId", "randomId2, randomId3"],
"default_successorIds": "randomId",
"conditions": {
"X+1==3": "randomID",
"X-1==3": "randomID2"
}
}
BPMN requires
- predecessor node ✔️
- successor node ✔️
- label (name) ✔️
- default successor node ✔️
- conditions (texts at the Path to each successor node) ✔️
SSoT stores
- id, text (label)
- predecessor and successor nodes of the loop
- loop termination condition
- predecessor node of the loop body end
- successor node of the loop body start
{
"type": "LOOP",
"id": "exampleId",
"loop_condition": "X > 5",
"predecessorIds": ["randomId"],
"successorIds": ["randomId"],
"loop_body_predecessorIds": ["randomId"],
"loop_body_successorIds": ["randomId"]
}
SSoT stores
- id, text (label)
- predecessor node
- successor node
{
"type": "MARKER",
"id": "exampleId",
"name": "Wait 5 seconds",
"predecessorIds": ["randomId"],
"successorIds": ["randomId"]
}
BPMN requires
- label ✔️
- event type1: Start, End ✔️
- start = Event without incoming edge
- end = Event without outgoing edge
- event type2: timer event, message event etc. 💭
- all events are always rendered as "neutral events" (empty circle).
Modelled process
BPMN Json | SSOT |
{
"_declaration": {
"_attributes": {
"version": "1.0",
"encoding": "UTF-8"
}
},
"bpmn2:definitions": {
"_attributes": {
"xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
"xmlns:bpmn2": "http://www.omg.org/spec/BPMN/20100524/MODEL",
"xmlns:bpmndi": "http://www.omg.org/spec/BPMN/20100524/DI",
"xmlns:dc": "http://www.omg.org/spec/DD/20100524/DC",
"xmlns:arkRPA": "http://magic",
"xmlns:di": "http://www.omg.org/spec/DD/20100524/DI",
"id": "sample-diagram",
"targetNamespace": "http://bpmn.io/schema/bpmn",
"xsi:schemaLocation": "http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd"
},
"bpmn2:collaboration": {
"_attributes": {
"id": "Collaboration_0czsqyr"
},
"bpmn2:participant": {
"_attributes": {
"id": "Participant_0cyhvx8",
"processRef": "Process_1"
}
}
},
"bpmn2:process": {
"_attributes": {
"id": "Process_1",
"isExecutable": "false"
},
"bpmn2:task": [
{
"_attributes": {
"id": "Activity_0a128t6",
"name": "#+# First activity"
},
"bpmn2:incoming": {
"_text": "Flow_1bewk1i"
},
"bpmn2:outgoing": {
"_text": "Flow_0sg07kn"
}
},
{
"_attributes": {
"id": "Activity_0ascvdr",
"name": "#+#+# RPA Activity"
},
"bpmn2:incoming": {
"_text": "Flow_0sg07kn"
},
"bpmn2:outgoing": {
"_text": "Flow_1hwcghk"
}
}
],
"bpmn2:sequenceFlow": [
{
"_attributes": {
"id": "Flow_1bewk1i",
"sourceRef": "StartEvent_1",
"targetRef": "Activity_0a128t6"
}
},
{
"_attributes": {
"id": "Flow_0sg07kn",
"sourceRef": "Activity_0a128t6",
"targetRef": "Activity_0ascvdr"
}
},
{
"_attributes": {
"id": "Flow_1hwcghk",
"sourceRef": "Activity_0ascvdr",
"targetRef": "Event_0wghmrz"
}
}
],
"bpmn2:endEvent": {
"_attributes": {
"id": "Event_0wghmrz"
},
"bpmn2:incoming": {
"_text": "Flow_1hwcghk"
}
},
"bpmn2:startEvent": {
"_attributes": {
"id": "StartEvent_1"
},
"bpmn2:outgoing": {
"_text": "Flow_1bewk1i"
}
}
},
"bpmndi:BPMNDiagram": {
"_attributes": {
"id": "BPMNDiagram_1"
},
"bpmndi:BPMNPlane": {
"_attributes": {
"id": "BPMNPlane_1",
"bpmnElement": "Collaboration_0czsqyr"
},
"bpmndi:BPMNShape": [
{
"_attributes": {
"id": "Participant_0cyhvx8_di",
"bpmnElement": "Participant_0cyhvx8",
"isHorizontal": "true"
},
"dc:Bounds": {
"_attributes": {
"x": "130",
"y": "220",
"width": "710",
"height": "250"
}
}
},
{
"_attributes": {
"id": "Activity_0a128t6_di",
"bpmnElement": "Activity_0a128t6"
},
"dc:Bounds": {
"_attributes": {
"x": "340",
"y": "280",
"width": "100",
"height": "80"
}
}
},
{
"_attributes": {
"id": "Activity_0ascvdr_di",
"bpmnElement": "Activity_0ascvdr"
},
"dc:Bounds": {
"_attributes": {
"x": "500",
"y": "280",
"width": "100",
"height": "80"
}
}
},
{
"_attributes": {
"id": "Event_0wghmrz_di",
"bpmnElement": "Event_0wghmrz"
},
"dc:Bounds": {
"_attributes": {
"x": "662",
"y": "392",
"width": "36",
"height": "36"
}
}
},
{
"_attributes": {
"id": "_BPMNShape_StartEvent_2",
"bpmnElement": "StartEvent_1"
},
"dc:Bounds": {
"_attributes": {
"x": "212",
"y": "302",
"width": "36",
"height": "36"
}
}
}
],
"bpmndi:BPMNEdge": [
{
"_attributes": {
"id": "Flow_1bewk1i_di",
"bpmnElement": "Flow_1bewk1i"
},
"di:waypoint": [
{
"_attributes": {
"x": "248",
"y": "320"
}
},
{
"_attributes": {
"x": "340",
"y": "320"
}
}
]
},
{
"_attributes": {
"id": "Flow_0sg07kn_di",
"bpmnElement": "Flow_0sg07kn"
},
"di:waypoint": [
{
"_attributes": {
"x": "440",
"y": "320"
}
},
{
"_attributes": {
"x": "500",
"y": "320"
}
}
]
},
{
"_attributes": {
"id": "Flow_1hwcghk_di",
"bpmnElement": "Flow_1hwcghk"
},
"di:waypoint": [
{
"_attributes": {
"x": "600",
"y": "320"
}
},
{
"_attributes": {
"x": "631",
"y": "320"
}
},
{
"_attributes": {
"x": "631",
"y": "410"
}
},
{
"_attributes": {
"x": "662",
"y": "410"
}
}
]
}
]
}
}
}
} |
"_id": "6045eccfa9a07940e5763f0b",
"starterId": "exampleID",
"robotName": "exampleRobot",
"elements": [
{
"type": "MARKER",
"name": "",
"id": "StartEvent_1",
"predecessorIds": [],
"successorIds": ["Activity_0a128t6"],
},
// first activity
{
"type": "INSTRUCTION",
"name": "#+# First activity",
"id": "Activity_0a128t6",
"predecessorIds": ["StartEvent_1"],
"successorIds": ["Activity_0ascvdr"]
},
// second activity
{
"type": "INSTRUCTION",
"name": "#+#+# RPA Activity",
"id": "Activity_0ascvdr",
"predecessorIds": ["Activity_0a128t6"],
"successorIds": ["Event_0wghmrz"]
},
// Endevent
{
"type": "MARKER",
"name": "",
"id": "Event_0wghmrz",
"predecessorIds": ["Activity_0a128t6"],
"successorIds": [],
}
]
} |
Back to the Wiki Home
-
About Ark Automate
- Pitch
- Architecture
- Interaction with our Software until the summer of 2021
-
Documentation