---
# System prepended metadata

title: Porolog entities & topics

---

# 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

![](https://i.imgur.com/s8CTJx2.jpg)

---
## 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=

```