# Porolog entities & topics
- API documentation: https://fiware-orion.readthedocs.io/en/1.2.3/user/walkthrough_apiv2/index.html
- https://swagger.lab.fiware.org/
## Entities
### **Type Robot**, linked to WarehouseFloor:
```yaml=
{
"id": "urn:ngsi-ld:Robot:1",
"type": "Robot",
"pose": {
"type": "pose",
"x": 0,
"y": 0,
"th": 0
},
"path": {
"type": "list",
"points": []
},
"target": {
"type": "point",
"x": 0.0,
"y": 0.0
},
"targetProduct": {
"type": "productID",
"val": "Product-001"
},
"velocities": {
"type": "vector2d",
"linear": 0.0,
"angular": 0.0
},
"state": {
"type": "enum",
"val": "IDLE"
},
"power": {
"type": "float",
"percentage": 1.0
},
"hearbeat": {
"type": "boolean",
"val": "True"
},
"logs": {
"type": "string",
"val": "I am a buggy log!"
},
"image": {
"type": "string",
"val": ""
}
}
```
### **Type RobotKPIs** linked to Robot
```yaml
{
"id": "urn:ngsi-ld:RobotKPI:1",
"type": "RobotKPI",
"date": {
"type": "Date",
"val": "14/06/2022"
},
"boxesMoved":{
"type": "number",
"val": 1
},
"palletesMoved":{
"type": "number",
"val": 1
},
"distance":{
"type": "number",
"val": 1.2
}
}
```
### **Type Warehouse**
```yaml
{
"id": "urn:ngsi-ld:Warehouse:1",
"type": "Warehouse",
"name": {
"type": "string",
"value": "Bleujour"
},
"georeference": {
"type": "vector",
"value": {
"longitude": 43.5746458,
"lattitude": 1.4514467
},
"metadata": {
"address": {
"type": "postalAddress",
"value": {
"streetAddress": "37 Av. Jules Julien",
"addressRegion": "Toulouse, France",
"addressLocality": "-",
"postalCode": "31400"
}
}
}
},
"blueprint": {
"type": "string",
"value": ""
},
"dimensions": {
"type": "vector",
"value": {
"width": 120,
"height": 80,
"resolution": 0.2
}
},
"annotations": {
"type": "list",
"value": []
}
}
```
### **Type WarehouseKPIs** linked to Warehouse
```yaml
{
"id": "urn:ngsi-ld:WarehouseKPI:1",
"type": "WarehouseKPI",
"date": {
"type": "Date",
"val": "14/06/2022"
},
"palleteStorageDensity":{
"type": "number",
"val": 1
},
"distanceXmassMovedByRobots":{
"type": "number",
"val": 1
},
"distanceXmassMovedByOperators":{
"type": "number",
"val": 1
},
"palletsMoved":{
"type": "number",
"val": 1
},
"parcelsMoved":{
"type": "number",
"val": 1
},
"savedTimeshareForOperator":{
"type": "number",
"val": 1
}
}
```
### **Type Room** linked to Warehouse
```yaml=
{
"id": "urn:ngsi-ld:Room:1",
"type": "Room",
"floor": {
"type": "number",
"value": 0
},
"blueprint": {
"type": "string",
"value": ""
},
"dimensions": {
"type": "vector",
"value": {
"width": 10,
"height": 15.2,
"z": 4.5,
"resolution": 0.2
}
},
"annotations": {
"type": "list",
"value": []
},
"groundType": {
"type": "string",
"value": ""
},
"origin": {
"type": "vector",
"value": {
"x": 230,
"y": 140
}
}
}
```
### **Type Rack** linked to Room
```yaml=
{
"id": "urn:ngsi-ld:Rack:1",
"type": "Rack",
"maxPayload": {
"type": "number",
"value": 300
},
"dimensions": {
"type": "vector",
"value": {
"length": 3,
"width": 1.5,
"height": 0.8,
"orientation": 0
}
},
"origin": {
"type": "vector",
"value": {
"x": 1.2,
"y": 0.6
}
}
}
```
### **Type Shelf** linked to Rack
```yaml=
{
"id": "urn:ngsi-ld:Shelf:1",
"type": "Shelf",
"altitude": {
"type": "number",
"value": 2.5
},
"surfaceNature": {
"type": "string",
"value": ""
}
}
```
### **Type Slot** linked to Shelf
```yaml=
{
"id": "urn:ngsi-ld:Slot:1",
"type": "Slot",
"width": {
"type": "number",
"value": 2.5
},
"originx": {
"type": "number",
"value": 0.5
}
}
```
### **Type Pallet**, reference to Slot
```yaml=
{
"id": "urn:ngsi-ld:Pallet:1",
"type": "Pallet",
"dimensions": {
"type": "vector",
"value": {
"length": 0,
"width": 0,
"height": 0
}
},
"barcode": {
"type": "string",
"value": {
"val": "xxx"
}
},
"material": {
"type": "string",
"value": ""
},
"fragile": {
"type": "bool",
"value": false
}
}
```
### **Type Parcel**, reference to Slot or Pallet
```yaml=
{
"id": "urn:ngsi-ld:Parcel:1",
"type": "Parcel",
"dimensions": {
"type": "vector",
"value": {
"length": 0,
"width": 0,
"height": 0
}
},
"sku": {
"type": "string",
"value": "xxx"
},
"manufacturer": {
"type": "string",
"value": ""
},
"manufDate": {
"type": "Date",
"value": ""
},
"content": {
"type": "string",
"value": ""
},
"mass": {
"type": "number",
"value": 0
},
"price": {
"type": "number",
"value": 0
},
"fragile": {
"type": "bool",
"value": false
},
"itemQuantity": {
"type": "number",
"value": 10
}
}
```
## Fiware entities & links
### Warehouses
- `urn:ngsi-ld:Warehouse:1`
### WarehouseKPIs
- `urn:ngsi-ld:WarehouseKPI:1` **refWarehouse** `urn:ngsi-ld:Warehouse:1`
### Robots
- `urn:ngsi-ld:Robot:1` **refWarehouse** `urn:ngsi-ld:Warehouse:1`
- `urn:ngsi-ld:Robot:2` **refWarehouse** `urn:ngsi-ld:Warehouse:1`
### Robot KPIs
- `urn:ngsi-ld:RobotKPI:1` **refRobot** `urn:ngsi-ld:Robot:1`
- `urn:ngsi-ld:RobotKPI:2` **refRobot** `urn:ngsi-ld:Robot:2`
### Rooms
- `urn:ngsi-ld:Room:1` **refWarehouse** `urn:ngsi-ld:Warehouse:1`
- `urn:ngsi-ld:Room:2` **refWarehouse** `urn:ngsi-ld:Warehouse:1`
### Racks
- `urn:ngsi-ld:Rack:1` **refRoom** `urn:ngsi-ld:Room:1`
- `urn:ngsi-ld:Rack:2` **refRoom** `urn:ngsi-ld:Room:1`
- `urn:ngsi-ld:Rack:3` **refRoom** `urn:ngsi-ld:Room:2`
- `urn:ngsi-ld:Rack:4` **refRoom** `urn:ngsi-ld:Room:2`
### Shelves
- `urn:ngsi-ld:Shelf:1` **refRack** `urn:ngsi-ld:Rack:1`
- `urn:ngsi-ld:Shelf:2` **refRack** `urn:ngsi-ld:Rack:4`
### Slots
- `urn:ngsi-ld:Slot:1` **refShelf** `urn:ngsi-ld:Shelf:2`
- `urn:ngsi-ld:Slot:2` **refShelf** `urn:ngsi-ld:Shelf:2`
### Pallet
- `urn:ngsi-ld:Pallet:1` **refSlot** `urn:ngsi-ld:Slot:2`
### Parcel
- `urn:ngsi-ld:Parcel:1` **refPallet** `urn:ngsi-ld:Pallet:1`
- `urn:ngsi-ld:Parcel:2` **refSlot** `urn:ngsi-ld:Slot:1`
## Components & topics

---
## Todo
RESTeeFi
- Robot
- GET
- KPIs by date to check if it exists
- KPIs (cold state)
- POST
- Create KPI entity + link with robot
---
Common code for **Commlib initialization** (this will exist in Robot):
```python=
from commlib.transports.mqtt import ConnectionParameters, MQTTProtocolType, Credentials
from commlib.node import Node, TransportType
MOSQUITTO_HOST = "155.207.33.189"
MOSQUITTO_PORT = 1893
MOSQUITTO_USERNAME = "porolog"
MOSQUITTO_PASSWORD = "fiware"
API_KEY = "1234"
if __name__ == "__main__":
creds = Credentials(
username=MOSQUITTO_USERNAME,
password=MOSQUITTO_PASSWORD
)
params = ConnectionParameters(
host=MOSQUITTO_HOST,
port=MOSQUITTO_PORT,
creds=creds
)
node = Node(
transport_type=TransportType.MQTT,
connection_params=params,
debug=True
)
```
Type **Robot** Commlib samples (this will exist in Robot):
```python=
ENTITY_TYPE = "Robot"
ENTITY_ID = "001"
BASE_TOPIC = f"/{API_KEY}/{ENTITY_TYPE}{ENTITY_ID}/attrs"
# Publishers
pose_pub = node.create_publisher(topic=BASE_TOPIC + "/pose")
path_pub = node.create_publisher(topic=BASE_TOPIC + "/path")
target_pub = node.create_publisher(topic=BASE_TOPIC + "/target")
target_product_pub = node.create_publisher(
topic=BASE_TOPIC + "/targetProduct")
velocities_pub = node.create_publisher(topic=BASE_TOPIC + "/velocities")
state_pub = node.create_publisher(topic=BASE_TOPIC + "/state")
power_pub = node.create_publisher(topic=BASE_TOPIC + "/power")
heartbeat_pub = node.create_publisher(topic=BASE_TOPIC + "/heartbeat")
logs_pub = node.create_publisher(topic=BASE_TOPIC + "/logs")
image_pub = node.create_publisher(topic=BASE_TOPIC + "/image")
teleop_pub = node.create_publisher(topic=BASE_TOPIC + "/teleop/commands")
# ==================== Publish calls ===============
pose_pub.publish({
"x": 1.0,
"y": 2.0,
"th": 90
})
path_pub.publish({
"points": [[x, x] for x in range(10)]
})
target_pub.publish({
"x": 10.0,
"y": 10.0
})
target_product_pub.publish({
"val": "Product-X"
})
velocities_pub.publish({
"linear": 5.35,
"angular": 0.0
})
state_pub.publish({
"val": "Moving"
})
power_pub.publish({
"percentage": 0.89
})
heartbeat_pub.publish({
"val": True
})
logs_pub.publish({
"val": "Everything works perfectly!"
})
image_pub.publish({
"val": "This is an image base64 - encoded string!"
})
# ================== Callback functions =================
def target_cb(msg):
print(f"Received new Robot TARGET: {msg}")
def state_cb(msg):
print(f"Received new Robot STATE: {msg}")
def teleop_comm_cb(msg):
print(f"Received new Robot TELEOP: {msg}")
# ===================== Subscribers =====================
target_sub = node.create_subscriber(
topic=BASE_TOPIC + "/target",
on_message=target_cb
)
target_sub.run()
state_sub = node.create_subscriber(
topic=BASE_TOPIC + "/state",
on_message=state_cb
)
state_sub.run()
teleop_comm_sub = node.create_subscriber(
topic=BASE_TOPIC + "/teleop/commands",
on_message=teleop_comm_cb
)
teleop_comm_sub.run()
# ================== Test Subscribers ==================
teleop_commands = ["Stop", "Lift", "Release",
"Forward", "Backwards", "Left", "Right"]
try:
for command in teleop_commands:
print(f"Publishing teleop command: {command}")
teleop_pub.publish({
"command": command
})
time.sleep(0.2)
except KeyboardInterrupt as e:
print("Bey!")
```
Type **RobotKPI** Commlib samples (this will exist in Robot):
```python=
ENTITY_TYPE = "RobotKPI"
ENTITY_ID = "001"
BASE_TOPIC = f"/{API_KEY}/{ENTITY_TYPE}{ENTITY_ID}/attrs"
# Publishers
date_pub = node.create_publisher(topic=BASE_TOPIC + "/date")
boxes_moved_pub = node.create_publisher(topic=BASE_TOPIC + "/boxesMoved")
palletes_moved_pub = node.create_publisher(
topic=BASE_TOPIC + "/palletesMoved")
distance_pub = node.create_publisher(
topic=BASE_TOPIC + "/distance")
# ==================== Publish data ====================
date_pub.publish({
"val": datetime.now().strftime("%d/%m/%y")
})
boxes_moved_pub.publish({
"val": 856
})
palletes_moved_pub.publish({
"val": 36
})
distance_pub.publish({
"val": 53647.0
})
```
Type Robot RESTeeFi samples (this will exist in Robot):
```python=
```