Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add README documentation for port drayage #617

Merged
merged 10 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions configuration/mysql/port_drayage.sql
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ CREATE TABLE `first_action` (

LOCK TABLES `first_action` WRITE;
/*!40000 ALTER TABLE `first_action` DISABLE KEYS */;
INSERT INTO `first_action` VALUES ("123",'SOME_CARGO',38.9548890,-77.1481430,'PICKUP','4bea1c45-e421-11eb-a8cc-000c29ae389d','32320c8a-e422-11eb-a8cc-000c29ae389d');
INSERT INTO `first_action` VALUES ("123",'SOME_CARGO',38.9548890,-77.1481430,'PICKUP','4bea1c45-e421-11eb-a8cc-000c29ae389d','32320c8a-e422-11eb-a8cc-000c29ae389d'),('DOT-80550','CARGO_A',28.1249788,-81.8348897,'PICKUP','4bea1c45-e421-11eb-a8cc-000c29ae389d','32320c8a-e422-11eb-a8cc-000c29ae389d');
/*!40000 ALTER TABLE `first_action` ENABLE KEYS */;
UNLOCK TABLES;

Expand Down Expand Up @@ -75,7 +75,7 @@ CREATE TABLE `freight` (

LOCK TABLES `freight` WRITE;
/*!40000 ALTER TABLE `freight` DISABLE KEYS */;
INSERT INTO `freight` VALUES ("123",NULL,38.9549780,-77.1475790,'EXIT_STAGING_AREA','32320c8a-e422-11eb-a8cc-000c29ae389d','4ace39e6-ee36-11eb-9a03-0242ac130003'),("123",'SOME_CARGO',38.9548890,-77.1481430,'PICKUP','4bea1c45-e421-11eb-a8cc-000c29ae389d','32320c8a-e422-11eb-a8cc-000c29ae389d');
INSERT INTO `freight` VALUES ("123",NULL,38.9549780,-77.1475790,'EXIT_STAGING_AREA','32320c8a-e422-11eb-a8cc-000c29ae389d','4ace39e6-ee36-11eb-9a03-0242ac130003'),("123",'SOME_CARGO',38.9548890,-77.1481430,'PICKUP','4bea1c45-e421-11eb-a8cc-000c29ae389d','32320c8a-e422-11eb-a8cc-000c29ae389d'),('DOT-80550',NULL,28.1232195,-81.8348278,'EXIT_STAGING_AREA','32320c8a-e422-11eb-a8cc-000c29ae389d','4ace39e6-ee36-11eb-9a03-0242ac130003'),('DOT-80550','CARGO_A',28.1249788,-81.8348897,'PICKUP','4bea1c45-e421-11eb-a8cc-000c29ae389d','32320c8a-e422-11eb-a8cc-000c29ae389d'),('DOT-80550',NULL,28.1128156,-81.8314745,'ENTER_PORT','4ace39e6-ee36-11eb-9a03-0242ac130003','67eadd3a-38b4-11ec-930a-000145098e4f'),('DOT-80550','CARGO_B',28.1232336,-81.8347566,'ENTER_STAGING_AREA','fc15d52a-3c0c-11ec-b00d-000145098e4f','5ceaab82-515c-11ec-9e2c-000145098e47'),('DOT-80550',NULL,28.1128156,-81.8314745,'ENTER_PORT','4ace39e6-ee36-11eb-9a03-0242ac130003','67eadd3a-38b4-11ec-930a-000145098e4f'),('DOT-80550','CARGO_A',28.1119763,-81.8312035,'DROPOFF','67eadd3a-38b4-11ec-930a-000145098e4f','0bf7ebda-38b5-11ec-930a-000145098e4f'),('DOT-80550','CARGO_B',28.1117373,-81.8309654,'PICKUP','0bf7ebda-38b5-11ec-930a-000145098e4f','9230504d-38b5-11ec-930a-000145098e4f'),('DOT-80550','CARGO_B',28.1120500,-81.8306483,'PORT_CHECKPOINT','9230504d-38b5-11ec-930a-000145098e4f','511ad052-38b6-11ec-930a-000145098e4f'),('DOT-80550','CARGO_B',28.1138052,-81.8317502,'EXIT_PORT','511ad052-38b6-11ec-930a-000145098e4f','fc15d52a-3c0c-11ec-b00d-000145098e4f'),('DOT-80550','CARGO_B',28.1232336,-81.8347566,'ENTER_STAGING_AREA','fc15d52a-3c0c-11ec-b00d-000145098e4f','5ceaab82-515c-11ec-9e2c-000145098e47');
/*!40000 ALTER TABLE `freight` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
Expand Down
78 changes: 78 additions & 0 deletions configuration/mysql/suntrax/momscript_port_drayage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/usr/bin/python3
######## use this block to send message to V2X hub##################
####### The messages hit MessageReceiver Plugin first at port: 26789 ########

import socket
import binascii as ba
import time

udpip = "127.0.0.1"
udpport = 26789


sk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# Send sample MobilityOperation messages
staging_area_messages = [
{
"DOT-80550: Arrival at ENTER_STAGING_AREA location": "00f381093f3cbbb265e57f4e47e797764cbcafe9c98b9edbfa7258b0c183060c183060b583060c16b060c182d60c18305ac183060c183060c183060c5bb170c993866cdab068e5b3766cdcb9431e1e5b70afe1bf974bf93961f3873e531bda0458f6f6bfa722274811449f516b860d5ab044b1022d9bf1e1e9a77ee4481020408102040e907b408b661e9a7a75c99513a40899b85ce5ab568cdbb744b1022d9bf767d3d3ae4ca89d2044b5bb75cc5ab066d19314483eac408b265e7d34eec3d34efdc89d20f68116cc3d34f4eb932a240810204081020748113370b9cb56ac1833708962045b37eecfa7a75c99513a40896b76eb98b470c5cb8668907d588116fe197961e9a77ee44e902245f4"
},
{
"DOT-80550: Arrive at PICKUP location": "00f381583f3cbbb265e57f4e47e797764cbcafe9c98b9edbfa7258b0c183060c183060b583060c16b060c182d60c18305ac183060c183060c183060c5bb170c993968d19b76ce183570dd9b1431e1e5b70afe1bf974bf93961f3873e5483da0458f6f6bfa722274811449f516b860d5ab044b1022c787967df7f4e444e902287069479f7e0a2588116cdf8f0f4d3bf722408102040810207483da045b30f4d3d3ae4ca89d2044cdc2e72d5ab466ddba2588116cdfbb3e9e9d726544e90225addbae62d583368c98a241f562045932f3e9a7761e9a77ee44e907b408b661e9a7a75c9951204081020408103a40899b85ce5ab560c19b844b1022d9bf767d3d3ae4ca89d2044b5bb75cc5a3862e5c334483eac408b7f0cbcb0f4d3bf7227481150930e5d5a08962045871f4d3bf75fd3911204081020408103a4089a62cb858e368d56e568c98ad62c72e25b85c63c6b5830618d939c3959b8739117d0"
},
{
"DOT-80550: Arrive at EXIT_STAGING_AREA location": "00f381623f3cbbb265e57f4e47e797764cbcafe9c98b9edbfa7258b0c183060c183060b583060c16b060c182d60c18305ac183060c183060c183060c5bb170c99396ec1ab970e1a3364e58b1431e1e5b70afe1bf974bf93961f3873e54afda0458f6f6bfa722274811449f516b860d5ab044b1022c787967df7f4e444e902287069479f7e0a2588116cdf8f0f4d3bf722408102040810207483da045b30f4d3d3ae4ca89d2044cdc2e72d5ab466ddba2588116cdfbb3e9e9d726544e90225addbae62d583368c98a241f562045932f3e9a7761e9a77ee44e907b408b661e9a7a75c9951204081020408103a40899b85ce5ab560c19b844b1022d9bf767d3d3ae4ca89d2044b5bb75cc5a3862e5c334483eac408b7f0cbcb0f4d3bf7227481145b126a5fa7520c7933a3df834a2c144b1022c38fa69dfbafe9c88902040810204081d2044cd93364c31b8c2b72b464c96b1639712dc2e31e35ac1830c6c9ce1cacdc39c88be80"
},
]

port_area_messages = [
{
"DOT-80550: Arrive at ENTER_PORT location": "00f3815b3f3cbbb265e57f4e47e797764cbcafe9c98b9edbfa7258b0c183060c183060b583060c16b060c182d60c18305ac183060c183060c183060c5bb170c99396ee59b070e18b860c1ab3431e1e5b70afe1bf974bf93961f3873e5493da0458f6f6bfa722274811449f516b860d5ab044b1022c787967df7f4e444e902287069479f7e0a2588116cdf8f0f4d3bf722408102040810207483da045b30f4d3d3ae4ca89d2044cdc2e72d5ab466ddba2588116cdfbb3e9e9d726544e90225addbae62d583368c98a241f562045932f3e9a7761e9a77ee44e907b408b661e9a7a75c9951204081020408103a40899b85ce5ab560c19b844b1022d9bf767d3d3ae4ca89d2044b5bb75cc5a3862e5c334483eac408b7f0cbcb0f4d3bf72274811459d522d2bf427d2a88962045871f4d3bf75fd3911204081020408103a4089a61c7959b9cad96e5cacdb2d62c72e25ae70b066b583268cb0e362cd83060cd17d"
},
{
"DOT-80550: Arrive at DROPOFF location": "00f381593f3cbbb265e57f4e47e797764cbcafe9c98b9edbfa7258b0c183060c183060b583060c16b060c182d60c18305ac183060c183060c183060c5bb170c993972dd8386cc5bb968d98b9431e1e5b70afe1bf974bf93961f3873e5487da0458f6f6bfa722274811449f516b860d5ab044b1022c787967df7f4e444e902287069479f7e0a2588116cdf8f0f4d3bf722408102040810207483da045b30f4d3d3ae4ca89d2044cdc2e72d5ab466ddba2588116cdfbb3e9e9d726544e90225addbae62d583368c98a241f562045932f3e9a7761e9a77ee44e907b408b661e9a7a75c9951204081020408103a40899b85ce5ab560c19b844b1022d9bf767d3d3ae4ca89d2044b5bb75cc5a3862e5c334483eac408b7f0cbcb0f4d3bf7227481144a53e84f8d1912c408b0e3e9a77eebfa72224081020408102074811366f970e4c8cf0ad66e31345ac58e5c6b5cb361856b060c18b46ac1cb8cad3322fa0"
},
{
"DOT-80550: DOT-80550: Arrive at PICKUP location": "00f381583f3cbbb265e57f4e47e797764cbcafe9c98b9edbfa7258b0c183060c183060b583060c16b060c182d60c18305ac183060c183060c183060c5bb170c99b060e583964d583870c9832431e1e5b70afe1bf974bf93961f3873e5483da0458f6f6bfa722274811449f516b860d5ab044b1022c787967df7f4e444e902287069479f7e122588116cdf8f0f4d3bf722408102040810207483da045b30f4d3d3ae4ca89d2044cdc2e72d5ab466ddba2588116cdfbb3e9e9d726544e90225addbae62d583368c98a241f562045932f3e9a7761e9a77ee44e907b408b661e9a7a75c9951204081020408103a40899b85ce5ab560c19b844b1022d9bf767d3d3ae4ca89d2044b5bb75cc5a3862e5c334483eac408b7f0cbcb0f4d3bf7227481150930e5d5a08962045871f4d3bf75fd3911204081020408103a4089862ccdf2e2c9856b37189aad62c72e35ae59b0c2b583060c5a3560e5c65699917d0"
},
{
"DOT-80550: Arrive at PORT_CHECKPOINT location": "00f381603f3cbbb265e57f4e47e797764cbcafe9c98b9edbfa7258b0c183060c183060b583060c16b060c182d60c18305ac183060c183060c183060c5bb170c99b064d18306ec5a3368e19b3431e1e5b70afe1bf974bf93961f3873e54a7da0458f6f6bfa722274811449f516b860d5ab044b1022c787967df7f4e444e902287069479f7e122588116cdf8f0f4d3bf722408102040810207483da045b30f4d3d3ae4ca89d2044cdc2e72d5ab466ddba2588116cdfbb3e9e9d726544e90225addbae62d583368c98a241f562045932f3e9a7761e9a77ee44e907b408b661e9a7a75c9951204081020408103a40899b85ce5ab560c19b844b1022d9bf767d3d3ae4ca89d2044b5bb75cc5a3862e5c334483eac408b7f0cbcb0f4d3bf72274811509f4aa5f87222c397427c99d5112c408b0e3e9a77eebfa722240810204081020748113964cd83560d322d66e31355ac58e5c6b5cb361856b060c18b46ac1cb8cad3322fa0"
},
{
"DOT-80550: Arrive at HOLDING_AREA location": "00f3815d3f3cbbb265e57f4e47e797764cbcafe9c98b9edbfa7258b0c183060c183060b583060c16b060c182d60c18305ac183060c183060c183060c5bb170c99b068d98b068e1b3472d9cb1431e1e5b70afe1bf974bf93961f3873e549bda0458f6f6bfa722274811449f516b860d5ab044b1022c787967df7f4e444e902287069479f7e122588116cdf8f0f4d3bf722408102040810207483da045b30f4d3d3ae4ca89d2044cdc2e72d5ab466ddba2588116cdfbb3e9e9d726544e90225addbae62d583368c98a241f562045932f3e9a7761e9a77ee44e907b408b661e9a7a75c9951204081020408103a40899b85ce5ab560c19b844b1022d9bf767d3d3ae4ca89d2044b5bb75cc5a3862e5c334483eac408b7f0cbcb0f4d3bf72274811489f322499d1efc1a5160a25881161c7d34efdd7f4e44481020408102040e9022cccdcb370d1c395ac9cb070b58b1cb996b968cb32d60c186364e583170d5b3045f4"
},
{
"DOT-80550: Arrive at EXIT_PORT location": "00f3815b3f3cbbb265e57f4e47e797764cbcafe9c98b9edbfa7258b0c183060c183060b583060c16b060c182d60c18305ac183060c183060c183060c5bb170c99b06ae1bb768e193170e1c33431e1e5b70afe1bf974bf93961f3873e548fda0458f6f6bfa722274811449f516b860d5ab044b1022c787967df7f4e444e902287069479f7e122588116cdf8f0f4d3bf722408102040810207483da045b30f4d3d3ae4ca89d2044cdc2e72d5ab466ddba2588116cdfbb3e9e9d726544e90225addbae62d583368c98a241f562045932f3e9a7761e9a77ee44e907b408b661e9a7a75c9951204081020408103a40899b85ce5ab560c19b844b1022d9bf767d3d3ae4ca89d2044b5bb75cc5a3862e5c334483eac408b7f0cbcb0f4d3bf7227481145b126a5fa13e95444b1022c38fa69dfbafe9c88902040810204081d2044d58b1c39183564b59b8c4d96b163971ad72cd8615ac183062d1ab072e32b4cc8be80"
},
{
"DOT-80550: Arrive at ENTER_STAGING_AREA location": "00f381623f3cbbb265e57f4e47e797764cbcafe9c98b9edbfa7258b0c183060c183060b583060c16b060c182d60c18305ac183060c183060c183060c5bb170c99b06ec1c376ac5bb66cc5cb3431e1e5b70afe1bf974bf93961f3873e54b3da0458f6f6bfa722274811449f516b860d5ab044b1022c787967df7f4e444e902287069479f7e122588116cdf8f0f4d3bf722408102040810207483da045b30f4d3d3ae4ca89d2044cdc2e72d5ab466ddba2588116cdfbb3e9e9d726544e90225addbae62d583368c98a241f562045932f3e9a7761e9a77ee44e907b408b661e9a7a75c9951204081020408103a40899b85ce5ab560c19b844b1022d9bf767d3d3ae4ca89d2044b5bb75cc5a3862e5c334483eac408b7f0cbcb0f4d3bf72274811459d522d2bf4ea418f26747bf06945828962045871f4d3bf75fd3911204081020408103a408b36362d723565856b3c6c31ad62c72e35b89830c8b583060c5a3560e5c65699917d"
},
]


def send_messages(messages):
for message in messages:
title = list(message.keys())[0]
message = list(message.values())[0]
if "HOLDING" in title:
hold = input("Move to holding location? (y/n): ")
if hold != "y":
continue
unhexed = ba.unhexlify(message)
sk.sendto(unhexed, (udpip, udpport))
print(f"\n{title}. Sent: {message}")
input("Press enter to send next arrival message.")


if __name__ == "__main__":
while True:
print("\nAvailable area options:\n\t1: staging\n\t2: port\n\t0: exit\n")
area = input("Choose area: ")
if area == "1":
send_messages(staging_area_messages)
elif area == "2":
send_messages(port_area_messages)
elif area == "0":
break
else:
print("Invalid area. Choose 0 to exit")
81 changes: 81 additions & 0 deletions src/v2i-hub/PortDrayagePlugin/README.md
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally this page should have similar topic to

Port Drayage Plugin Documentation

Introduction

Introduce functionality

Configuration/Deployment

Any plugin specific configuration/deployment steps for plugin.
Example, under recently updated initialization script you must select to enable port drayage functionality when prompted to deploy port drayage plugin(

read -r -p "Enable Port Drayage functionality (TRUE/FALSE, or press Enter to use default as $PORT_DRAYAGE_ENABLED_DEFAULT): " PORT_DRAYAGE_ENABLED
)

Functionality Testing or Regression Testing

How to use your script to test if functionality is deployed correctly

Remember this is for external users that may not be developers so our documentation should always use existing scripts instead of manual commands where possible and be high level enough for less technical people to for their purposes.

Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Port Drayage Plugin Documentation

## Introduction

The Port Drayage Plugin in V2x-Hub facilitates infrastructure, vehicle and container handling equipment (CHE) communication for port drayage operations. The plugin provides and montior drayage actions for a freight truck inside and between a mock port and staging area. The list of actions includes `ENTER_STAGING_AREA`, `PICKUP`, `EXIT_STAGING_AREA`, `ENTER_PORT`, `DROPOFF`, `PORT_CHECKPOINT`, `HOLDING_AREA`, and `EXIT_PORT`.

## Related Plugins

A list of plugins related to the Port Drayage functionality.

### Immediate Forward Plugin

For RSU Immediate Message Forwarding (IMF) functionality to communicate with a freight vehicle.

### Message Receiver Plugin

For receiving vehicle communication from freight vehicles.

## Configuration/Deployment

Port Drayage Plugin default configuration parameters work for docker-compose deployment. The include configuring Port Drayage MySQL server address, database credentials and Port Drayage Web Application address.

1) Populate actions in DB (Sample action databases can be found under `configuration/mysql/port_drayage.sql`)
2) Enable Plugin

## Design

![Alt text](docs/design_diagram.png)

The infrastructure component of the Port Drayage CARMA-Freight Use Case has 3 major actors that all fall under the CARMA-Streets umbrella: V2X-Hub , MySQL Database ,and Port Drayage Web Service.
#### V2X-Hub
V2X-Hub is a message handler that acts as a translator and data aggregator/disseminator for infrastructure components of a connected vehicle deployment. It is built with a plugin architecture, meaning to add new custom functionality, new plugins can be written to consume and produce J2735 messages that are broadcast over DSRC. For the Port Drayage CARMA-Freight Use Case, the Port Drayage Plugin is responsible for receiving/transmitting Mobility Operation messages from a CARMA equipped vehicles and facilitating any necessary communication with CHE or inspection personnel to complete port drayage operations. This includes container pickup, drop off, vehicle inspection and entrance or exit gate interactions at a port or staging area.

#### MySQL database
The MySQL database stores vehicle instructions called actions. V2X-Hub will query this database to provide vehicles actions one by one. Actions consist mainly of a UUID to identify each action, a vehicle ID to identify the recipient for an action, a cargo ID to identify any cargo associated with the action, and an operation to describe the action. MySQL Database that contains two tables. The `first_action` table is used to store vehicles first actions. The `freight` table is used to store all vehicle actions. Each action in the database includes the UUID string action id of the next action to link actions of a single vehicle in sequence. A sequence of actions for a given vehicle consists of a first action stored in the `first_action` table and subsequent linked actions stored in the `freight` table. The first action is provided to the vehicle as a response to initial communication. After completing an action, the vehicle will broadcast the completed action. The Port Drayage Plugin will then attempt to use the completed action to retrieve the next action from the `freight` table.

#### Port Drayage Web Service
The Port Drayage Web Service is a java spring application that contains a REST API server and a web user interface created using java Thyme Leaf. Some port drayage actions require user input from personnel operating CHE or from inspection personnel. The Port Drayage Web Service was created to allow personnel, through a web UI, to interact with actions that require user input. Supported actions that require user input include `LOADING`, `UNLOADING`, and `INSPECTION`. User input actions differ from other actions in that they require user input to be considered completed and therefor also for the vehicle to be provided with its next action. The Port Drayage Web Service maintains the state of these actions and hosts the web UI through which input is received.

### Communication
![Alt text](docs/communication_diagram.png)

The infrastructure software designed for the CARMA-Freight Port Drayage use case contains several different lines of communication. The first and most important, facilitating communication between infrastructure and the vehicle. To communicate, we use SAE J2735 messages broadcast over DSRC. Specifically, in this standard we use the Mobility Operations Message, often used for prototyping messages, since it has a simple string payload and a strategy field to give information to receiving software on how to interpret the string payload.

The Mobility Operation Messages used for this plugin, incoming and outgoing, are designated with the strategy `carma/port_drayage`. Messages from the CMV indicate the CMV’s completion of an action, while messages from V2XHub indicate an instructed operation to the CMV. The sample message below shows the JSON payload contained within the Mobility Operation message’s `strategy_params` field.

```json
// Example Mobility Operation strategy_params JSON payload with message's strategy set to "carma/port_drayage":
{
"cmv_id": "DOT-80550", // [Required from all] string unique identifier for CMV
"operation": "ENTERING_STAGING_AREA", // [Required from all] Enum to indicate the type of action
// NOTE: Possible operations include: PICKUP, DROPOFF, PORT_CHECKPOINT, HOLDING_AREA,
// ENTER_STAGING_AREA, EXIT_STAGING_AREA, ENTER_PORT, EXIT_PORT
"cargo": false, // [Required from all with PICKUP/DROPOFF operation] boolean flag to indicate whether the CMV is loaded with cargo
"cargo_id": "SOME_CARGO", // [Required from all with PICKUP/DROPOFF operation] string unique identifier for cargo
"location": { // [Required from CMV] current location of the CMV
"longitude": 0,
"latitude": 0},
"destination": { // [Required from infrastructure] optional destination for CMV
"longitude": 0,
"latitude": 0},
"action_id": "SOMEUID" // [Required from all] string UUID to identify action
}

```

For the actions with the operations `PICKUP` (`LOADING`), `DROPOFF` (`UNLOADING`), `PORT_CHECKPOINT` (`INSPECTION`), and `HOLDING_AREA` (`INSPECTION`) require user input from container handling equipment (CHE) personnel and inspection personnel. We also use RESTful communication to connect the V2X-Hub Port Drayage Plugin to the Port Drayage Web Service. RESTful communication contains a client (V2X-Hub) and a server (Port Drayage Web Service). The file included below is the OpenAPI API definition, which defines the endpoint, possible requests, possible responses and the JSON objects exchanged between client and service.

The final method of communication is SQL (Structure Query Language). To query the MySQL database for each action in a sequence, the V2X-Hub Port Drayage Plugin uses mysql connecter client library to make SQL queries and receive the results. [A sample SQL file](../../../configuration/mysql/port_drayage.sql) used to setup both the `freight` and `first_action` tables in the PORT_DRAYAGE MySQL database.


## Functionality Testing

Open another tab and type in `localhost:8090` to navigate to port drayage web UI. Click `Staging Area` or `Port Area` button to test V2x-Hub located at staging or port area.

Open a terminal, and run [a python script](../../../configuration/mysql/suntrax/momscript_port_drayage.py) to send mocked mobility operation message to test each action at a particular location.
```
./momscript_port_drayage.py
```


Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading