From dafd6e11d5cb236c5b8e53da03f6d596131b9402 Mon Sep 17 00:00:00 2001 From: dan-du-car Date: Thu, 13 Jun 2024 22:00:42 +0000 Subject: [PATCH 01/10] update --- scripts/momscript_port_drayage.py | 55 ++++++++++++++++++++ src/v2i-hub/PortDrayagePlugin/README.md | 67 +++++++++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 scripts/momscript_port_drayage.py create mode 100644 src/v2i-hub/PortDrayagePlugin/README.md diff --git a/scripts/momscript_port_drayage.py b/scripts/momscript_port_drayage.py new file mode 100644 index 000000000..e293440e4 --- /dev/null +++ b/scripts/momscript_port_drayage.py @@ -0,0 +1,55 @@ +######## 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)) + # Wait 5 second before sending another one + print(f'\n{title}. Sent: {message}') + input("Press enter to send next arrival message.") + time.sleep(1) + +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") diff --git a/src/v2i-hub/PortDrayagePlugin/README.md b/src/v2i-hub/PortDrayagePlugin/README.md new file mode 100644 index 000000000..988c2c64b --- /dev/null +++ b/src/v2i-hub/PortDrayagePlugin/README.md @@ -0,0 +1,67 @@ +## 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. +### Deployment Instructions +Clone V2x-Hub GitHub repos: +``` +git clone https://github.com/usdot-fhwa-OPS/V2X-Hub +``` +Once downloaded, navigate to the configuration directory: +``` +cd ~/V2X-Hub/configuration/ +``` +Create mysql_password and mysql_root_password: +``` +mkdir secrets +nano mysql_password.txt +nano mysql_root_password.txt +``` + +You may make the passwords whatever you like, but you will need to remember them: +``` +Example: ivp +``` + +Launch V2x-Hub and Port Drayage web service +``` +docker-compose up +``` + +Create a V2X Hub UI username and password. +``` +cd mysql +./add_v2xhub_user.bash +``` + +You may make these whatever you’d like, but will need to use them to log into the web UI. Example: +``` +Username: v2xadmin +Password: V2xHub#321 +``` + +You will then need to enter the mysql_password you created in step 5a: +``` +Example: ivp +``` +Insert redefined set of actions into `PORT_DRAYAGE` database: +``` +INSERT INTO `first_action` VALUES ('DOT-80550','CARGO_A',28.1249788,-81.8348897,'PICKUP','4bea1c45-e421-11eb-a8cc-000c29ae389d','32320c8a-e422-11eb-a8cc-000c29ae389d'),('DOT-10004','CARGO_A',28.1249788,-81.8348897,'PICKUP','66bba4a0-52c1-11ec-9105-000145098e4f','66bba4cb-52c1-11ec-9105-000145098e4f'); +``` + +``` + +INSERT INTO `freight` VALUES ('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-10004','CARGO_A',28.1249788,-81.8348897,'PICKUP','66bba4a0-52c1-11ec-9105-000145098e4f','66bba4cb-52c1-11ec-9105-000145098e4f'),('DOT-10004',NULL,28.1232195,-81.8348278,'EXIT_STAGING_AREA','66bba4cb-52c1-11ec-9105-000145098e4f','84f6b797-52c2-11ec-9105-000145098e4f'),('DOT-10004',NULL,28.1128156,-81.8314745,'ENTER_PORT','84f6b797-52c2-11ec-9105-000145098e4f','c9bba171-52c2-11ec-9105-000145098e4f'),('DOT-10004','CARGO_B',28.1232336,-81.8347566,'ENTER_STAGING_AREA','20b546e3-52c6-11ec-9105-000145098e4f','53875eba-52c7-11ec-9105-000145098e4f'); +``` +``` + +INSERT INTO `freight` VALUES ('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'),('DOT-10004',NULL,28.1128156,-81.8314745,'ENTER_PORT','84f6b797-52c2-11ec-9105-000145098e4f','c9bba171-52c2-11ec-9105-000145098e4f'),('DOT-10004','CARGO_A',28.1119763,-81.8312035,'DROPOFF','c9bba171-52c2-11ec-9105-000145098e4f','8e1d456a-52c3-11ec-9105-000145098e4f'),('DOT-10004','CARGO_B',28.1117373,-81.8309654,'PICKUP','8e1d456a-52c3-11ec-9105-000145098e4f','744be658-52c4-11ec-9105-000145098e4f'),('DOT-10004','CARGO_B',28.1120500,-81.8306483,'PORT_CHECKPOINT','744be658-52c4-11ec-9105-000145098e4f','a4b419b9-52c5-11ec-9105-000145098e4f'),('DOT-10004','CARGO_B',28.1138052,-81.8317502,'EXIT_PORT','a4b419b9-52c5-11ec-9105-000145098e4f','20b546e3-52c6-11ec-9105-000145098e4f'),('DOT-10004','CARGO_B',28.1232336,-81.8347566,'ENTER_STAGING_AREA','20b546e3-52c6-11ec-9105-000145098e4f','53875eba-52c7-11ec-9105-000145098e4f'); +``` +Open a browser and land on V2x-Hub plugin management page. Enable `MessageReceiverPlugin` , `PortDrayagePlugin`, and `ImmediateForwardPlugin`. + +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](https://raw.githubusercontent.com/usdot-fhwa-OPS/V2X-Hub/develop/scripts/momscript_port_drayage.py) to send mobility operation message to indicate vehicle arrived at a particular location. +``` +python3 momscript_port_drayage.py +``` + + From feeeb062050975632f8e52dd3d43cc605f6e458a Mon Sep 17 00:00:00 2001 From: dan-du-car Date: Fri, 14 Jun 2024 13:21:41 +0000 Subject: [PATCH 02/10] update --- .../mysql/suntrax}/momscript_port_drayage.py | 0 src/v2i-hub/PortDrayagePlugin/README.md | 18 +++++++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) rename {scripts => configuration/mysql/suntrax}/momscript_port_drayage.py (100%) diff --git a/scripts/momscript_port_drayage.py b/configuration/mysql/suntrax/momscript_port_drayage.py similarity index 100% rename from scripts/momscript_port_drayage.py rename to configuration/mysql/suntrax/momscript_port_drayage.py diff --git a/src/v2i-hub/PortDrayagePlugin/README.md b/src/v2i-hub/PortDrayagePlugin/README.md index 988c2c64b..1070f8c77 100644 --- a/src/v2i-hub/PortDrayagePlugin/README.md +++ b/src/v2i-hub/PortDrayagePlugin/README.md @@ -38,28 +38,32 @@ Username: v2xadmin Password: V2xHub#321 ``` -You will then need to enter the mysql_password you created in step 5a: +You will then need to enter the mysql_password you created: ``` Example: ivp ``` -Insert redefined set of actions into `PORT_DRAYAGE` database: +Insert redefined set of actions into `PORT_DRAYAGE` database. Open terminal and run “mysql -uroot -pivp -h127.0.0.1” ``` -INSERT INTO `first_action` VALUES ('DOT-80550','CARGO_A',28.1249788,-81.8348897,'PICKUP','4bea1c45-e421-11eb-a8cc-000c29ae389d','32320c8a-e422-11eb-a8cc-000c29ae389d'),('DOT-10004','CARGO_A',28.1249788,-81.8348897,'PICKUP','66bba4a0-52c1-11ec-9105-000145098e4f','66bba4cb-52c1-11ec-9105-000145098e4f'); +use PORT_DRAYAGE ``` +``` +INSERT INTO `first_action` VALUES ('DOT-80550','CARGO_A',28.1249788,-81.8348897,'PICKUP','4bea1c45-e421-11eb-a8cc-000c29ae389d','32320c8a-e422-11eb-a8cc-000c29ae389d'); ``` -INSERT INTO `freight` VALUES ('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-10004','CARGO_A',28.1249788,-81.8348897,'PICKUP','66bba4a0-52c1-11ec-9105-000145098e4f','66bba4cb-52c1-11ec-9105-000145098e4f'),('DOT-10004',NULL,28.1232195,-81.8348278,'EXIT_STAGING_AREA','66bba4cb-52c1-11ec-9105-000145098e4f','84f6b797-52c2-11ec-9105-000145098e4f'),('DOT-10004',NULL,28.1128156,-81.8314745,'ENTER_PORT','84f6b797-52c2-11ec-9105-000145098e4f','c9bba171-52c2-11ec-9105-000145098e4f'),('DOT-10004','CARGO_B',28.1232336,-81.8347566,'ENTER_STAGING_AREA','20b546e3-52c6-11ec-9105-000145098e4f','53875eba-52c7-11ec-9105-000145098e4f'); ``` +INSERT INTO `freight` VALUES ('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'); ``` -INSERT INTO `freight` VALUES ('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'),('DOT-10004',NULL,28.1128156,-81.8314745,'ENTER_PORT','84f6b797-52c2-11ec-9105-000145098e4f','c9bba171-52c2-11ec-9105-000145098e4f'),('DOT-10004','CARGO_A',28.1119763,-81.8312035,'DROPOFF','c9bba171-52c2-11ec-9105-000145098e4f','8e1d456a-52c3-11ec-9105-000145098e4f'),('DOT-10004','CARGO_B',28.1117373,-81.8309654,'PICKUP','8e1d456a-52c3-11ec-9105-000145098e4f','744be658-52c4-11ec-9105-000145098e4f'),('DOT-10004','CARGO_B',28.1120500,-81.8306483,'PORT_CHECKPOINT','744be658-52c4-11ec-9105-000145098e4f','a4b419b9-52c5-11ec-9105-000145098e4f'),('DOT-10004','CARGO_B',28.1138052,-81.8317502,'EXIT_PORT','a4b419b9-52c5-11ec-9105-000145098e4f','20b546e3-52c6-11ec-9105-000145098e4f'),('DOT-10004','CARGO_B',28.1232336,-81.8347566,'ENTER_STAGING_AREA','20b546e3-52c6-11ec-9105-000145098e4f','53875eba-52c7-11ec-9105-000145098e4f'); ``` -Open a browser and land on V2x-Hub plugin management page. Enable `MessageReceiverPlugin` , `PortDrayagePlugin`, and `ImmediateForwardPlugin`. +INSERT INTO `freight` VALUES ('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'); +``` + +Open a browser and get certificate in internet browser: Https://127.0.0.1:19760. OPen another tab, navigate to http://127.0.0.1 and land on V2x-Hub plugin management page. Enable `MessageReceiverPlugin` , `PortDrayagePlugin`, and `ImmediateForwardPlugin`. 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](https://raw.githubusercontent.com/usdot-fhwa-OPS/V2X-Hub/develop/scripts/momscript_port_drayage.py) to send mobility operation message to indicate vehicle arrived at a particular location. +Open a terminal, and run [a python script](https://raw.githubusercontent.com/usdot-fhwa-OPS/V2X-Hub/develop/configuration/mysql/suntrax/momscript_port_drayage.py) to send mocked mobility operation message to test each action at a particular location. ``` python3 momscript_port_drayage.py ``` From 3655fb13347b170c83163d4c9df3c3e1d5134369 Mon Sep 17 00:00:00 2001 From: dan-du-car Date: Fri, 14 Jun 2024 13:23:34 +0000 Subject: [PATCH 03/10] remove sleep --- configuration/mysql/suntrax/momscript_port_drayage.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/configuration/mysql/suntrax/momscript_port_drayage.py b/configuration/mysql/suntrax/momscript_port_drayage.py index e293440e4..70d53b247 100644 --- a/configuration/mysql/suntrax/momscript_port_drayage.py +++ b/configuration/mysql/suntrax/momscript_port_drayage.py @@ -36,10 +36,8 @@ def send_messages(messages): continue unhexed = ba.unhexlify(message) sk.sendto(unhexed,(udpip,udpport)) - # Wait 5 second before sending another one print(f'\n{title}. Sent: {message}') input("Press enter to send next arrival message.") - time.sleep(1) if __name__ == '__main__': while True: From c7c985c7d58f51b4cce0be526c057a2213895d53 Mon Sep 17 00:00:00 2001 From: dan-du-car Date: Fri, 14 Jun 2024 13:25:14 +0000 Subject: [PATCH 04/10] fix typo --- src/v2i-hub/PortDrayagePlugin/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/v2i-hub/PortDrayagePlugin/README.md b/src/v2i-hub/PortDrayagePlugin/README.md index 1070f8c77..293728dab 100644 --- a/src/v2i-hub/PortDrayagePlugin/README.md +++ b/src/v2i-hub/PortDrayagePlugin/README.md @@ -59,7 +59,9 @@ INSERT INTO `freight` VALUES ('DOT-80550',NULL,28.1232195,-81.8348278,'EXIT_STAG INSERT INTO `freight` VALUES ('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'); ``` -Open a browser and get certificate in internet browser: Https://127.0.0.1:19760. OPen another tab, navigate to http://127.0.0.1 and land on V2x-Hub plugin management page. Enable `MessageReceiverPlugin` , `PortDrayagePlugin`, and `ImmediateForwardPlugin`. +Open a browser and get certificate in internet browser: Https://127.0.0.1:19760. + +Open another tab, navigate to http://127.0.0.1 and land on V2x-Hub plugin management page. Enable `MessageReceiverPlugin` , `PortDrayagePlugin`, and `ImmediateForwardPlugin`. 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. From ae3222b777f8b4fe129b3cb56429928d25b17246 Mon Sep 17 00:00:00 2001 From: dan-du-car Date: Fri, 14 Jun 2024 14:34:55 -0400 Subject: [PATCH 05/10] update doc format --- .../mysql/suntrax/momscript_port_drayage.py | 79 ++++++++++++------- src/v2i-hub/PortDrayagePlugin/README.md | 6 +- 2 files changed, 57 insertions(+), 28 deletions(-) mode change 100644 => 100755 configuration/mysql/suntrax/momscript_port_drayage.py mode change 100644 => 100755 src/v2i-hub/PortDrayagePlugin/README.md diff --git a/configuration/mysql/suntrax/momscript_port_drayage.py b/configuration/mysql/suntrax/momscript_port_drayage.py old mode 100644 new mode 100755 index 70d53b247..411c79ec8 --- a/configuration/mysql/suntrax/momscript_port_drayage.py +++ b/configuration/mysql/suntrax/momscript_port_drayage.py @@ -1,53 +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) +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'}] +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: + if "HOLDING" in title: hold = input("Move to holding location? (y/n): ") - if hold != 'y': + if hold != "y": continue unhexed = ba.unhexlify(message) - sk.sendto(unhexed,(udpip,udpport)) - print(f'\n{title}. Sent: {message}') + sk.sendto(unhexed, (udpip, udpport)) + print(f"\n{title}. Sent: {message}") input("Press enter to send next arrival message.") -if __name__ == '__main__': + +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': + if area == "1": send_messages(staging_area_messages) - elif area == '2': + elif area == "2": send_messages(port_area_messages) - elif area == '0': + elif area == "0": break else: print("Invalid area. Choose 0 to exit") diff --git a/src/v2i-hub/PortDrayagePlugin/README.md b/src/v2i-hub/PortDrayagePlugin/README.md old mode 100644 new mode 100755 index 293728dab..a85e30a93 --- a/src/v2i-hub/PortDrayagePlugin/README.md +++ b/src/v2i-hub/PortDrayagePlugin/README.md @@ -1,6 +1,8 @@ +# 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. -### Deployment Instructions + +## Configuration/Deployment Clone V2x-Hub GitHub repos: ``` git clone https://github.com/usdot-fhwa-OPS/V2X-Hub @@ -63,6 +65,8 @@ Open a browser and get certificate in internet browser: Https://127.0.0.1:19760. Open another tab, navigate to http://127.0.0.1 and land on V2x-Hub plugin management page. Enable `MessageReceiverPlugin` , `PortDrayagePlugin`, and `ImmediateForwardPlugin`. +## Functionality Testing or Regression 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](https://raw.githubusercontent.com/usdot-fhwa-OPS/V2X-Hub/develop/configuration/mysql/suntrax/momscript_port_drayage.py) to send mocked mobility operation message to test each action at a particular location. From 9fe1d0af3f341abf55b68a7266a98208557a6338 Mon Sep 17 00:00:00 2001 From: dev Date: Mon, 17 Jun 2024 11:35:04 -0400 Subject: [PATCH 06/10] Documentation updates --- src/v2i-hub/PortDrayagePlugin/README.md | 109 +++++++++++------- .../docs/communication_diagram.png | Bin 0 -> 50812 bytes .../PortDrayagePlugin/docs/design_diagram.png | Bin 0 -> 80826 bytes 3 files changed, 65 insertions(+), 44 deletions(-) create mode 100644 src/v2i-hub/PortDrayagePlugin/docs/communication_diagram.png create mode 100644 src/v2i-hub/PortDrayagePlugin/docs/design_diagram.png diff --git a/src/v2i-hub/PortDrayagePlugin/README.md b/src/v2i-hub/PortDrayagePlugin/README.md index a85e30a93..96e278021 100755 --- a/src/v2i-hub/PortDrayagePlugin/README.md +++ b/src/v2i-hub/PortDrayagePlugin/README.md @@ -1,49 +1,79 @@ # 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 + +Plugins related to the Port Drayage functionality. + +### Immediate Forward Plugin + +For RSU Immediate Message Forwarding (IMF) functionality to communicate with freight vehicle. + +### Message Receiver Plugin + +For receiving vehicle communication from freight vehicles. + ## Configuration/Deployment -Clone V2x-Hub GitHub repos: -``` -git clone https://github.com/usdot-fhwa-OPS/V2X-Hub -``` -Once downloaded, navigate to the configuration directory: -``` -cd ~/V2X-Hub/configuration/ -``` -Create mysql_password and mysql_root_password: -``` -mkdir secrets -nano mysql_password.txt -nano mysql_root_password.txt -``` -You may make the passwords whatever you like, but you will need to remember them: -``` -Example: ivp -``` +Plugin default configuration parameters work for docker-compose deployment. The include configuring Port Drayage MySQL server address name and credentials as well as Port Drayage Web Application address. -Launch V2x-Hub and Port Drayage web service -``` -docker-compose up -``` +1) Populate actions in DB (Sample action databases can be found under `configuration/mysql/port_drayage.sql`) +2) Enable Plugin -Create a V2X Hub UI username and password. -``` -cd mysql -./add_v2xhub_user.bash -``` +## Design -You may make these whatever you’d like, but will need to use them to log into the web UI. Example: -``` -Username: v2xadmin -Password: V2xHub#321 -``` +![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 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 this was the Port Drayage Plugin, which is responsible for receiving and 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. + +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 will consist 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. + +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 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 facilitates 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 that is 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 + } -You will then need to enter the mysql_password you created: -``` -Example: ivp ``` + +For the actions with the operations PICKUP (LOADING), DROPOFF (UNLOADING), PORT_CHECKPOINT (INSPECTION), and HOLDING_AREA (INSPECTION) require user input 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) and consists of request/response communication. The file included below it 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. Below is the SQL file used to setup both the freight and first_action tables in the PORT_DRAYAGE MySQL database. + + +## Functionality Testing or Regression 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](https://raw.githubusercontent.com/usdot-fhwa-OPS/V2X-Hub/develop/configuration/mysql/suntrax/momscript_port_drayage.py) to send mocked mobility operation message to test each action at a particular location. + +**TODO Replace mysql commands with sql file volume setup** Insert redefined set of actions into `PORT_DRAYAGE` database. Open terminal and run “mysql -uroot -pivp -h127.0.0.1” ``` use PORT_DRAYAGE @@ -61,15 +91,6 @@ INSERT INTO `freight` VALUES ('DOT-80550',NULL,28.1232195,-81.8348278,'EXIT_STAG INSERT INTO `freight` VALUES ('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'); ``` -Open a browser and get certificate in internet browser: Https://127.0.0.1:19760. - -Open another tab, navigate to http://127.0.0.1 and land on V2x-Hub plugin management page. Enable `MessageReceiverPlugin` , `PortDrayagePlugin`, and `ImmediateForwardPlugin`. - -## Functionality Testing or Regression 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](https://raw.githubusercontent.com/usdot-fhwa-OPS/V2X-Hub/develop/configuration/mysql/suntrax/momscript_port_drayage.py) to send mocked mobility operation message to test each action at a particular location. ``` python3 momscript_port_drayage.py ``` diff --git a/src/v2i-hub/PortDrayagePlugin/docs/communication_diagram.png b/src/v2i-hub/PortDrayagePlugin/docs/communication_diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..6700ee56105cc50af7ff89aeb0c157b6a524e39e GIT binary patch literal 50812 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

oz@T;&cUQ9srKHcNu1cSpXzs z2#L!}@TK&s52oqt@R(rjtLY-*OscX}__u7mRgg+?2p0(t*uYghzBLIc< z-E;4K=#lGBvK;{ZALngHnpD$L^N=_|8T;>!o6KWC+ZGD{N&Al)dA|_m{89)`X ziH5$Qo?wzO|5U%+=@^kv#V#4#oCdV)MZ8sU8H^QOHSIYuj?K>ly$Qwg2QWA>9#pxH zv<2zx1h{s!khb?EB>37Jf=hb!vEALF2$L>Xev1vBiP34Pp=J(t1w%oRfNyv`*8&x3m zIe51({HFNFQl=>8B00fGgQ#mPDkZ(2Fnyz77`rzn_Ge;blL~uf@a)U#B{`?LDDD*s zt>Wa5C!h6oM0jVo_ow*xt(4zq-ltKkSFpW%DcuW{oFnYic|Ly%!5Hnqdw+zL_Qe~} z_rrfoK_2>4*VdkoOlhF6(dOqf+hMibP<5X6V!A`hb;n?mQOt58Hwz)BIH$-_7=$9* z4h*1zmW%}s1|7=V1AnC`4A8ir_BDm^60_~*u`0kmIi(uXq~U!>p*kT5dyIH~2acZ9 zPAJ#XZ9yGsCC!Q|#`Fk|sw!Xc)g(p?^%coxM4IAdTUPO@tbDU-xRk%*OxaHVN(19@ zS^}Af^WL`j@k}b!pBFSuL>+_={P2RZ@iPNr=19PU+GE5S511soNc@ZR<-;KCQwf2u z+S2<9qDs&{GA*ltXDW*L;uppN$!YpU>D=Q!qF= zryo<3vMivQLj4VEk%p&!hwf;EYkYOAb+p#!PQQE7vMsOdyxkp5hMcSH=AItYb?MKh_r4P9=szwUc=YQ&=V6}B<@cpP!h_r$MHEQK;{JG4K0xZ! zE)u#C4vs>`{mr_n%G7CIoAT9%HP9#XC+3DLP!hgaP+ML? zyZ1NMa+0vw@Rs&s^cdB{rT;pzf&%&CBahaPy*MGTTk=Cy1LCr!z{o&ueSzEpG|uF( zSZWUx;|=fACpV6BBVqgy#vseR3@=mRe})$OZk+Ha9=Y zuoGzE0|C-F`W)4U6k?uSXDNwKfD_6^C2Lz~CeBi+^!Vc?zRaR}+6_iDl=U#g9{Vn? zz;?n=-GEx#u4au`o;~Mh)%+7Lm<$l%I+rEN2)UVFvDT^TT z^aSHzsIJkj59Ye7lyA`}ja@5$lOFYNUDZOYjP>@60yDerA#_Cai3hmPV$p}^^NVW! zV0r~d{1J*xwiC6j_G>P2fR@K{wlMFe^b|zQ=xWp^+b7B)g2er8Ve)2&;zV&@(^-L& zYvAr2%#HZ$Vn!6R2-qcLli?Fsam@oXv3A8Y1zf%H}Ahdi%Yx*w#531buWsvRT~ z>(h{>3P^|DbM_!zC3Xv>p~EN#DWLNqhNN-6hbaUUSlS`$Y?2e`xMVlVY_cg1UA=}| zye-^iXU#(eRxh(sR?%A2R|iQi5wx}@w1WhJ<{sXb#R(cg`~Uj9iGh*;gCPJuNoVuw z*aA-kIr!G~W{pzPuZHi#w{KuFEZ|G>`WWRLwEmt;3lq=HzWd!nl&~$JB$4QFwm6b8^t(JHsF%Vd*3U? z;)X^Aa%R+5U|_@ewo+p}UJE|m+e{<_?&$#uLnzF{b01_v2L+MlY+n5Q6`ZnEZ_YhL z!7azj&R(cW;#MGi?+L93ysIB3o~-J_r+y=OL2UNxGG1Y%5&eOQE5Nj#Q_hWdbWaj}U6B zK|cB1RWeTKA><3)n^-YU#_Fr(`n#dd2zN0l@6MR->{vxUVbs?5xKirprvAxUdDvxB zbClDoPozazjqWwCM_N6_jY{ z?kTYqfiH|DxGJ6Rg+Y7^CuV1Ebjt#DUN`d7#Izt~pdnYLPiZ;gM3`7*m?~(IoJzG7 zkgz*{0w7%pmO!yK^dm^iHH-y-ua=Ws@`j}h0$6;aL);@bHqXWe$+#of3|{?YaS?K; z__Ca4GeB;}(w5g?CpyfSDJIu0dvf=)|0MUxlN81>#Z#YDG2J*iIS<&1ZS#3zp1;TX zOMm&uzms-EM%t8Zk66YI*u#D{Fw`O8(|bCiy7ttQ+ma)mM(HJO#1z#dAcb!Fh56Mf zO&p~aG~}9597f;s@D0-ZjF<)GTIjVn=7uxA-2^c#_K5V&x0%#Y8!sQLMi61wn>qSH z-^lbQV+E|NAC^X_<3fd@GG4T+Shajva0?P!3qqyKr>robEvcmla1TqZJcJydSnki9 z2FY&zTO6tAZUihZhpG!XbAKDeyD4o>tmv-3Mu%1Rk3C2)Vw2GsA*<(dIcEd{D|oF7S5QT>+Qd~rX==w zizenZoYKL;`FRU83B`8D@C63b!=U=dBZ{2BwPCQfr`NFiLnal1&+Hmv#2ei67w&;2 zY5~a@odX2V%vH3)L0ylb| z+hRFO;hH5wu6chD{Dzolaz4@g=#F*7R3_)PnzA7dWJ;fvD`<24TN|*hL)} z{?cRmL8UzSs7`oJb_Q31%&4jcK)VOU#QfVUJBuJ_eA8&!_SgnKCoPks)r{%E2c+x6SsMc zFP@k{NjI+!%>`VK(YUs5fjo1etMrMjiNK@T1Po{w_H@w-qZtr}K$XJu;fp`m{4Z~P zpR)!tNEq@OO|J2D>v4(s7^8lVDN-W@%=+h5&5$r*}HufNEX~iF3C&R>7RopW2^TmKcchPCrda{B?htz}Z6pmAZ zg$R3br^kqsK&bVN*`tOKxDCn)!gqSM(4TAWF@?5O~*3&#d}jx+)XnQlp3 zypmJiAb(UT7*n!<`|EN=YC_1o7KD`GOlTzz+PMShifvHclFnq_sS_moF{dpSLdh4+ zQCAg><~TKix2$+Q{`?qTMi8VEP-=4sw`(fwW5G2kt`k&rL+WC=z+D__$ITT>3C%+W_jfAal*bSICYHg(d3f0 z1B?~V_L6?YxOMHwKmsOqy zMKu>UK(L2wbV`bht*PzgQ(NUpU-{AXi4D!S>o;11dFp(s1pHdhxEWsanDF?W4zH&U zQhd-kF{&d21@=Zt>_Nv1dU6W52$m;gLD7TcXr6-m38GgcsTFAwJo(ZMYbz{*PdwB> z+&RLzowsKsZjCxxeNaaplp{TWv}h&Z3jK$`SPLWxLu}R3*3-Oqv6IiYGk zUXs+XeK?+r)R+-{8868`E$J%&3AInh0!4>O1;k%f>V)Yz4aDqX3^O;Qk$yu&YvFfg zBL03|sGG{E-)=%(!n7ukVy&2VGPQ7$s;3Cv&@qB*H4pJg3xKD7Whb9;i3V#eKVn6)Xd}` z9*pQRU&;R^N||5bY)J9{2xl`wV_3!S`esYVxD$w3kqQfA*mFW_3pHLKNN~Zrt zk$1z#&={QBdZ6mRX=*9E(@2i`Q(pC(?3@Dgl|;Hsx_XTRAPmgrLY# z$o41mEee)=3$IqOI0fw+N3Ba|ERcC zoL^;5w#zwpUFcP0Rh&CsSJU}E!B4moy>Z@Zid8w#?{i1fFHOw(t0MSDA~}e8dUe;g z9CbEh7%gfHB9YZXzLIj+i5+Nhl#-ML31Yjrn&Fp`knnquC6&Mc5!(s^p@{G+b1E}=1;^P-k_dLtt*@A(7O*su*)&)x6M$W%Ir1jt z{!H#k3~|-3J?6GK`{A2%B_Ly(T4BMY3!g2IWNS41O+@ATzTEToGYSpnr4^w}ZE1K}1fSl5OUR2Z7aM+LNz(G2c9-->6;e z+>*XLXhzCz%4tT|JQMoZw4yX~#Jb(b4p+r!fUC8MJ(!yi4U-{ML62N}>qQX)v$C#A5dcuvNd1v)Efbuxo;j5|=gpxL|;;>-hdMp7R z%T8iJzz>pQN1mCXzEqMJ(T%*}s>{3gOM3N6BmSM0FxX?=6zbmNsm0=uQ?1LzW`te{bOemL+~LE-<4R1I0b`Z$4uvQn&Mlq}D`NJLDP)6btU#{j z9Ib7aJ{mn~A*`03S-2(rP(M%tG(tdtEADpD_dOtl=~=7Tc-;e};K3#2Rf*KD0kkL; zy`+%HBT}UDIB}9;l@=LY6sRj?MoX6&Y)zC$W%i%WP%&n%j4Pl~2v5cdgO(oWb@6&X z3L>`gnf2I5r!&n|*!V~ec1+V?qgi?a0%a;_+iRF<&@+KW#KsS97lJcORyU?^(}Y9p z^>B!xU$12}B#2RAn@$0>dPAqSdu-$|ry~deJ}@1WYCE51`D4GyMq6L;z796rkIcry zDe0d=>yNW0j5{&Gt~lAxri@R!)KNoy;re+>2b3}MHwd!N7O1{WIU@Cn`&=c$e!Ba^e z8*U96Y;L?!zuC09|9L6F%RQqTjGccA_@#^OIrezVD2|L*{c-kC$(mk~HYa6D7X4gd zU1Hyxb%(bKf%^1$e2)k@h~kIx^S3JV(hZTuiFD;d$70%xwm3pKDKeyoR=|cgZBc!S zZ^>7oEM*fnhAeE{3w-)L>`8`>qr(u8al$FI)qk_eeOM&$SL0)`gJut7XN@k3CfF zgGow|>L&w3+Lu2%-Yi;8Ge7NG&K&v6lH0AhKtf%$hGqDlgCN)G4a&EYq-&sP`Ys92 z&SE}cZn7t^eu)`t)3>Wp_={u`xFQ$`k%ataI-#2=l4idx>~W`q`sfB>Kk42t>NQ>f zFY5LDKHKHFi)zB)b!DbjY}wC>BRnv|8#*BPIIyQQn_WbPl=h0$mtYuT)G=J&GL|%T zk+>gYQmBKS`Mtp;%0tuVNWk98khK8(@|qtK(ALK;>>G)@+(us@ATLI3;@Rb^Uf^Ck z<3y9Kb)VPmBlm{dtkVUa1O;NkMVkaW<;cy(j`n=7>uwpw;hkB-e1lTYKQc^8V9ZD# z3R)=J$!GM9(T_2Xo&21Z#YPCdEw-Kv>+n} zmgF(J-P+W;9CCh{_l@3@=WP2#olN;lIdh{erNolMVzsX;xgR%mCK(aW6%TIb>iqBQ z_cPQ|snjNgmgSW`4+Wh`GwMAMy2^*ZeoUu(W3}^~#0kBedA2XJTbLz%y;X)rCgJxL zlz`N#1cmt4H}teoD&~TVWdmvB!;*jl^t)jOfN7ziaUVF&Hw19$vYfh?l_^HQ%E`C4 zly%nOIm8TEH&ttqulZv}WM3ZLLU-G(M01#c3_=^zSqUDQLdxkw-an2R>0^)_B6@7d zIbC%)Joky(S<3#6sA6wG!+85=OjYATl(TSGi|U+6VgCeGa}yDktL!D^=atar?3Pq_ zSgpL0ZtpDSECe`wx8nIr3WbnXk}1UCUKi-k6G_ftBEoX$y^Y1wP#f5@{bNs(m`y-D ze&2JS=1tre?emXMRo{QGCMkqqfqFJuO(MD?RuxB7%ix#{h{q!0nv$Fxww4do{mXDc%TqX5d$a!X*P7& zG2oA}TpC+NeBpAM6ej1wz$EO>;JUx>NpP@sx#M4$BkZ^;sZPgvK|ar1Kp_UtLYemq zNn$1ebrU-6B|Q=cU!NiW#P^q_`hx3cMxvM5jinPn!cbkjQq4@g3 zlr<^l^V0xJC+wk!jFU9>Jf&kk;)X+tAf1dxv^YjYkmvSV-hQLTe@N+HDE@-VCPMzz zV><6#XJ}|mEQ15*_)`r&I7cso2JQn9d&~TbdujUV&Rt}OVU_lu2n$JNt`u!9H3n-M zJG0`K5-P(DVN$(~bB~;Y*!zDG2mdo$;{YH_AYAVxQKNhZD1ENfcVBY-tqAa81@&@t zwx(@hR!)D5yK5#a*4^u-pqnm%E6&|bna7((hb$5!Oikf|(Vi__P6Hdj(%+)UW)<_=grX`?J8<&oQVqVxwscENt<}FYPfsY@gKz^X zJu(sB@H+{))F?VImz#0RhTHOmzX;I4fZkMJkTN)8(y#$FsUU|)@M>hpaCVNpmLv71 z)iV1(ly@r-NG7yT|9YPoxeH37O6J5*BwG)uOKFL9O;oL$4zy%%NV0n^Eu94Fp{+(O z_>f*I>#R_aHuW#v{tpy-HAF-mwf*)*`5DrLz$bxz0%9*mVR!(|lctQQ7$zT?*{i^T zf(^rE{{J$T4CEM{R2F(>6_RQqs2Fc90{VdG@Y;}0qNc3{)i4{D&ixtkwua`>mH#*a z1=BBd~G5=>f11tDejiidBeKo8tUzt`^DwHX1(|A|KMOL>5?0W6fP%-_Bk%l|To zzwB!a)EWp_zM3YnL&nml-h>?^BgEt#qc1O$F2DI%oId_29JoJ@`h<+to% zgriuO#uM;Xy&6^O7eEo+BMP)hyEj3lBkRzO(a-3p+FUC&{GTQGVy~T{s8VUeWXRT~ zWabsaNbu{H&3z%3T9}85%*dZK+cQSkHHmDzS~NV2s_#ocbTn|DbK0Vt+JnBux_m5b zcAL!=Q|l!$Y9*=g>J?XOpR={yI2tM8QZ6CXePK5&X^c%;g=$xUsS` z188e-{V$vOrz#c-3L;#}07s4eXoVUg*Oz|W7)g@+xAp$>d4Fvo92odGkuJE6%qZc1 zZ@zzRBZ(el2B6vcsM;v=KdSog-A^6v%W5o{*2t;z{!2pt(#dMaFH>Kh>1e7o`Y$d0 zm+^J|6cltf3g4!e#Qra#{M#4{!hP>XzG@35(#8LO5n+J-MFi&}IYRY6tNic%iB|i| z${QUoD=bt0ABeD!z7YLvmR1z|U%K~CZ+1-b<;@B_Y>Y<#OYi@UsNeSs5k{|e9P|IR zAb;m0jrmuA>mC42ivI^9h`)%iF5(it|33uS3e{X>`sMV)(S`V53P}M}UiWQ!K29DOOfUgp?-BmeG8HbkC zQ2(#d1c_oLA|m0Wss7H)w&=!x>nu@d5|8`9yQ-+OkvUy-D@F1TEkioglpt1s-YL{J*4qN3qt9u~xI zHk<*?0-;GI{~yr{dV?($>A<(fZDkKvihB2v^`nUS%6$X1f&0)m7@A(5;8GRKA^yN3 zkcidgN~*5hDy#_&cho}Xxsz`1sCE0tthYXG4iOZA!2GCuXWkjs7uo3)krJwPrb?MT zNX8f`fI+|(pysl#hf)J+eY*F^&5bPb8(PB!Q^CmrW%tpl3G32L%q3})=l O^^+8p6R8x|^Z!4YQPd0o literal 0 HcmV?d00001 diff --git a/src/v2i-hub/PortDrayagePlugin/docs/design_diagram.png b/src/v2i-hub/PortDrayagePlugin/docs/design_diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..07f2957a28f2c0df2e6a73840610186eb0cbb406 GIT binary patch literal 80826 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 literal 0 HcmV?d00001 From 7a463677ef952178844b3ee6b4c632854b93fb3e Mon Sep 17 00:00:00 2001 From: dan-du-car Date: Mon, 17 Jun 2024 11:43:14 -0400 Subject: [PATCH 07/10] replace SQL statements with SQL file --- configuration/mysql/port_drayage.sql | 4 ++-- src/v2i-hub/PortDrayagePlugin/README.md | 21 +-------------------- 2 files changed, 3 insertions(+), 22 deletions(-) diff --git a/configuration/mysql/port_drayage.sql b/configuration/mysql/port_drayage.sql index eccdb199b..17d04e5ce 100644 --- a/configuration/mysql/port_drayage.sql +++ b/configuration/mysql/port_drayage.sql @@ -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; @@ -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 */; diff --git a/src/v2i-hub/PortDrayagePlugin/README.md b/src/v2i-hub/PortDrayagePlugin/README.md index 96e278021..2e8944c48 100755 --- a/src/v2i-hub/PortDrayagePlugin/README.md +++ b/src/v2i-hub/PortDrayagePlugin/README.md @@ -72,27 +72,8 @@ The final method of communication is SQL (Structure Query Language). To query th 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](https://raw.githubusercontent.com/usdot-fhwa-OPS/V2X-Hub/develop/configuration/mysql/suntrax/momscript_port_drayage.py) to send mocked mobility operation message to test each action at a particular location. - -**TODO Replace mysql commands with sql file volume setup** -Insert redefined set of actions into `PORT_DRAYAGE` database. Open terminal and run “mysql -uroot -pivp -h127.0.0.1” -``` -use PORT_DRAYAGE -``` - -``` -INSERT INTO `first_action` VALUES ('DOT-80550','CARGO_A',28.1249788,-81.8348897,'PICKUP','4bea1c45-e421-11eb-a8cc-000c29ae389d','32320c8a-e422-11eb-a8cc-000c29ae389d'); -``` - -``` -INSERT INTO `freight` VALUES ('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'); -``` - -``` -INSERT INTO `freight` VALUES ('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'); -``` - ``` -python3 momscript_port_drayage.py +./momscript_port_drayage.py ``` From 92b16b9510a2ac5a5005589678acf166eadf8dca Mon Sep 17 00:00:00 2001 From: dan-du-car Date: Mon, 17 Jun 2024 12:03:27 -0400 Subject: [PATCH 08/10] tweak doc --- src/v2i-hub/PortDrayagePlugin/README.md | 26 +++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/v2i-hub/PortDrayagePlugin/README.md b/src/v2i-hub/PortDrayagePlugin/README.md index 2e8944c48..f0fa8fef5 100755 --- a/src/v2i-hub/PortDrayagePlugin/README.md +++ b/src/v2i-hub/PortDrayagePlugin/README.md @@ -6,11 +6,11 @@ The Port Drayage Plugin in V2x-Hub facilitates infrastructure, vehicle and conta ## Related Plugins -Plugins related to the Port Drayage functionality. +A list of plugins related to the Port Drayage functionality. ### Immediate Forward Plugin -For RSU Immediate Message Forwarding (IMF) functionality to communicate with freight vehicle. +For RSU Immediate Message Forwarding (IMF) functionality to communicate with a freight vehicle. ### Message Receiver Plugin @@ -18,7 +18,7 @@ For receiving vehicle communication from freight vehicles. ## Configuration/Deployment -Plugin default configuration parameters work for docker-compose deployment. The include configuring Port Drayage MySQL server address name and credentials as well as Port Drayage Web Application address. +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 @@ -28,19 +28,21 @@ Plugin default configuration parameters work for docker-compose deployment. The ![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. -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 this was the Port Drayage Plugin, which is responsible for receiving and 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. -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 will consist 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. - -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 its next action. The Port Drayage Web Service maintains the state of these actions and hosts the web UI through which input is received. +### 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 facilitates 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 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 that is contained within the Mobility Operation message’s ‘strategy_params’ field. +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": @@ -62,12 +64,12 @@ The Mobility Operation messages used for this plugin, incoming and outgoing, are ``` -For the actions with the operations PICKUP (LOADING), DROPOFF (UNLOADING), PORT_CHECKPOINT (INSPECTION), and HOLDING_AREA (INSPECTION) require user input 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) and consists of request/response communication. The file included below it the OpenAPI API definition, which defines the endpoint, possible requests, possible responses and the JSON objects exchanged between client and service. +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. Below is the SQL file used to setup both the freight and first_action tables in the PORT_DRAYAGE MySQL database. +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 or Regression Testing +## 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. From c75e89d8488e0e96c19e8dd988a656ab2398cb9c Mon Sep 17 00:00:00 2001 From: dan-du-car Date: Mon, 17 Jun 2024 12:04:32 -0400 Subject: [PATCH 09/10] tweak doc --- src/v2i-hub/PortDrayagePlugin/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v2i-hub/PortDrayagePlugin/README.md b/src/v2i-hub/PortDrayagePlugin/README.md index f0fa8fef5..e23fa03a3 100755 --- a/src/v2i-hub/PortDrayagePlugin/README.md +++ b/src/v2i-hub/PortDrayagePlugin/README.md @@ -2,7 +2,7 @@ ## 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. +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 From afc90d2d0a77bfb74954d8b018a616443db7f3e4 Mon Sep 17 00:00:00 2001 From: dan-du-car Date: Mon, 17 Jun 2024 12:11:14 -0400 Subject: [PATCH 10/10] update doc url --- src/v2i-hub/PortDrayagePlugin/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/v2i-hub/PortDrayagePlugin/README.md b/src/v2i-hub/PortDrayagePlugin/README.md index e23fa03a3..3682021ec 100755 --- a/src/v2i-hub/PortDrayagePlugin/README.md +++ b/src/v2i-hub/PortDrayagePlugin/README.md @@ -28,13 +28,13 @@ Port Drayage Plugin default configuration parameters work for docker-compose dep ![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 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 +#### 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 +#### 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 @@ -66,14 +66,14 @@ The Mobility Operation Messages used for this plugin, incoming and outgoing, are 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. +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](https://raw.githubusercontent.com/usdot-fhwa-OPS/V2X-Hub/develop/configuration/mysql/suntrax/momscript_port_drayage.py) to send mocked mobility operation message to test each action at a particular location. +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 ```