メインコンテンツまでスキップ

Webhookとクライアント通知

リアルタイム運用に関連するSWATシステムとサービスは、メッセージキューを使用して消費者のリアルタイム通知を実装しています。メッセージには次のものが含まれます。

  • 受信予約メッセージ
  • 車両の動きのメッセージ
  • オファー
  • スケジューラからのメッセージ
  • その他の種類

メッセージングシステムを活用するために、クライアントはWebhookを使用してメッセージングシステムにサブスクライブできます。

メッセージへのサブスクライブ

危険

オブジェクトを更新する場合、特にdataフィールドには注意してください。これはモデルに関連付けられていない任意のJSONであるためです。以下のようなリクエストを送信すると、dataプロパティの他のすべての値が消去されます。dataプロパティに新しい値を追加するには、現在の値を取得し、必要なフィールドを更新または追加してから、完全なペイロード(つまり、既存の値と新しい値のマージ)でPATCHします。

Webhookへのサブスクリプションは、クライアントがリッスンしたいメッセージのWebhookアドレスとフィルターを設定することにより、(シミュレーション

)のレベルでクライアントが管理できます。

これを実現するには、リクエストを介してシミュレーションにパッチを適用するか、代わりにsimulation templateを使用できます。

PATCH https://<base_url>/api/v2/simulation/<simulation_id>

simulation.dataオブジェクトのWebhookサブスクリプション
{
"data": {
"messaging_webhook_url": "https://<webhook_url>",
"messaging_webhook_message_types": ["<message filter>"]
// リストからのメッセージタイプ
// ['assignment',
// 'bookings',
// 'bookings_cancellation',
// 'fail_to_board',
// 'offers',
// 'no_offer',
// 'node_status',
// 'offer_accepted',
// 'offer_rejected',
// 'vehicle_arrival',
// 'vehicle_state_changed']
}
}
警告

現在、Webhookは認証をサポートしていません。Webhookを保護する唯一の方法は、Webhookを発行するSWATバックエンドサービスのIPアドレスをホワイトリストに登録することです。

Webhookメッセージの例

vehicleエージェントからのノードステータスメッセージ
{
"simulation_id": 158066,
"agent_type": "vehicle",
"message_type": "node_status",
"data": {
"node_uid": "cc90ed77-88c3-4f79-9aa6-b61d78d5ca44",
"status": "completed",
"vehicle_id": 1854644,
"node_id": 12648517,
"node_type": "pickup",
"booking_uid": "aa082b4c-e8b3-4caf-a9f2-aba007bdde63",
"booking_id": 6478565,
"action_data": {
"action_type": "pickup_success",
"lat": -43.5481311,
"lon": 172.6854358,
"driver_uid": null,
"image_urls": [],
"data": {
"driver_note": {
"additional_note": "notes"
}
}
},
"is_confirmation": true
},
"current_sim_ts": "2025-04-01T14:18:18.293000+13:00",
"server_ts": "2025-04-01T01:18:18.659211+00:00",
"transmit_to_websocket": false,
"agent_id": "3fb96457-6e43-48a9-a678-d47bd398500d",
"user_id": 13529
}
vehicleエージェントからの車両到着メッセージ
{
"simulation_id": 158066,
"agent_type": "vehicle",
"message_type": "vehicle_arrival",
"data": {
"booking_id": 6478565,
"booking_uid": "aa082b4c-e8b3-4caf-a9f2-aba007bdde63",
"node_id": 12648518,
"node_uid": "89bfed3c-6ec2-43de-b399-2767319aacb3",
"node_type": "dropoff",
"estimated_earliest_arrival_ts": "2025-04-01T00:45:55.302476+00:00",
"estimated_scheduled_ts": "2025-04-01T07:00:00+00:00",
"scheduled_ts": "2025-04-01T07:00:00+00:00",
"vehicle_id": 1854644,
"vehicle_agent_id": "884a43a2-cea7-4f42-b705-5fa2bc42bf54"
},
"current_sim_ts": "2025-04-01T00:39:04.002476+00:00",
"server_ts": "2025-04-01T00:39:04.002476+00:00",
"transmit_to_websocket": false,
"agent_id": null,
"user_id": null
}
vehicleエージェントからの車両状態変更メッセージ
{
"simulation_id": 158066,
"agent_type": "vehicle",
"message_type": "vehicle_state_changed",
"data": {
"vehicle_id": 1854644,
"instance_changed": true,
"nodes_changed": true,
"update": {
"path": "_fvpAmbtaeEbE{ErG_HnToUvTkV~BtBk[h^iKhLiNxO{DnE]^eAlA_FzE{CkCe@c@o@g@sOgMsT_LuJoEaEkBaDmAiLkEqFcBiL}CmHcC{IqBiK_BwCWwDc@{f@eBy{AcGkNr@uCn@wC|@{BvAsB~BoAjD[tC@jDp@xCnAtCtAbBfBnApC|@bCZjCJbCU~Cw@bCiAlCcCdDaDtAyBbCkUj@kRYuO?eOoBuOaB_Yq@cU_@}M]_Ms@uSMcSn@sZ^yXDoHLqGNiW@sI?uH?wFAiDIeFe@yX?wBOwIWoOR}LdAuIjA{HnAsG|@eGp@_Ep@aDV_Ad@gAv@mAdA}@jAs@p@Wp@YjBu@vBw@|F_BjUmFrgBab@z~@iKjYkFp_@uFt_@qDdDSdEQpe@cAvYi@l]u@lUk@|~@Yzq@kAdQc@tj@mA`LGfhBeClkBChFcCjDQ|CLlETtJU`Kw@tCs@"
}
},
"current_sim_ts": "2025-04-01T00:34:04.045211+00:00",
"server_ts": "2025-04-01T00:34:04.045211+00:00",
"transmit_to_websocket": false,
"agent_id": null,
"user_id": null
}
schedulerエージェントからの予約拒否(オファーなし)メッセージとno_offerメッセージタイプ
{
"simulation_id": 158066,
"agent_type": "scheduler",
"message_type": "no_offer",
"data": {
"booking_ids": [
6478566
],
"booking_uids": [
"aa082b4c-e8b3-4caf-a9f2-aba007bdde66"
]
},
"current_sim_ts": "2025-04-01T00:32:45.043985+00:00",
"server_ts": "2025-04-01T00:33:16.168066+00:00",
"transmit_to_websocket": true,
"agent_id": null,
"user_id": null
}
vehicle_groupエージェントとmessage_type assignmentを介した車両メッセージへの予約(ノード)の割り当て
  {
"simulation_id": 158064,
"agent_type": "vehicle_group",
"message_type": "assignment",
"data": {
"vehicle_id": 1854642,
"vehicle_agent_id": "6a955d42-706a-4b54-9562-391bc74fbd01",
"polyline5": "uodGwuzxRRUX[dAgAdAkAJJyAbBg@j@q@r@QTC@EFUTOMCACCu@m@eAi@c@SSKOGi@SWIk@O]Ka@Kg@IOAQC_CIgHYq@DMBODKFKLGNAN?PBLFNHHHFLDL@L@JANELGLKNOHMJeAD}@Cu@?s@Iu@IqAEgAAo@Ck@CaAA_ABwABsA?]@[@mA?a@?]?W?QAUCsA?KAa@As@@m@Fa@F_@FYDYBSDO@EBGDGDEFEBADAHEJEXGfAWlIoBjEg@tAWfBWfBQNARAzBEtAC~AEfAClEC`DEx@CjCGh@AnIKzI?TMPAN@R@d@Ad@ENE",
"polyline6": "_fvpAmbtaeEbE{ErG_HnToUvTkV~BtBk[h^iKhLiNxO{DnE]^eAlA_FzE{CkCe@c@o@g@sOgMsT_LuJoEaEkBaDmAiLkEqFcBiL}CmHcC{IqBiK_BwCWwDc@{f@eBy{AcGkNr@uCn@wC|@{BvAsB~BoAjD[tC@jDp@xCnAtCtAbBfBnApC|@bCZjCJbCU~Cw@bCiAlCcCdDaDtAyBbCkUj@kRYuO?eOoBuOaB_Yq@cU_@}M]_Ms@uSMcSn@sZ^yXDoHLqGNiW@sI?uH?wFAiDIeFe@yX?wBOwIWoOR}LdAuIjA{HnAsG|@eGp@_Ep@aDV_Ad@gAv@mAdA}@jAs@p@Wp@YjBu@vBw@|F_BjUmFrgBab@z~@iKjYkFp_@uFt_@qDdDSdEQpe@cAvYi@l]u@lUk@|~@Yzq@kAdQc@tj@mA`LGfhBeClkBChFcCjDQ|CLlETtJU`Kw@tCs@",
"nodes": [
{
"id": 12648515,
"created_at": "2025-03-31T23:23:24.761384+00:00",
"modified_at": "2025-03-31T23:23:24.961358+00:00",
"uid": "4c6ed49d-fe30-4243-9683-8e20ff60546d",
"lat": 1.339019,
"lon": 103.852623,
"h3": "0040062440662254514161",
"location_name": "Hub",
"location_code": "",
"display_name": "Hub",
"booking_uid": "aa082b4c-e8b3-4caf-a9f2-aba007bdde63",
"booking_id": 6478564,
"customer_id": null,
"open_time_ts": "2026-02-05T03:00:00+00:00",
"close_time_ts": "2026-02-05T05:00:00+00:00",
"close_time_ts_dynamic": "2026-02-05T05:00:00+00:00",
"service_time": 0,
"demand": {
"sample": 1
},
"status": "assigned",
"node_type": "pickup",
"assigned_vehicle_id": 1854642,
"simulation_id": 158064,
"assignment_order": 0,
"scheduled_ts": "2026-02-05T03:00:00+00:00",
"visited_at_ts": null,
"completed_service_at": null,
"started_service_at_ts": null,
"walking_time_to_node": 0,
"walking_distance_to_node": 0,
"min_trip_duration": null,
"max_trip_duration": 36000,
"fixed_route_walk_time": null,
"fixed_route_ride_time": null,
"fixed_route_wait_time": null,
"fixed_route_journey_time": null,
"fixed_route_is_unreachable": false,
"cancelled_at_ts": null,
"penalty": 10000000,
"lifo_order_check": false,
"lifo_order_penalty": null,
"groups": [],
"matrix_timestamp": "2026-02-05T03:00:00+00:00",
"geofence_ids": [],
"geofence_id": null,
"transit_stop_id": null,
"transit_stop_street": null,
"transit_stop_type": null,
"transfer_type": "depart_at",
"weight": null,
"trip_cost": 0,
"initial_open_time_ts": null,
"initial_max_trip_duration": null,
"initial_close_time_ts": null,
"initial_close_time_ts_dynamic": null,
"max_slack": null,
"slack": 14002.3,
"data": {},
"boarding_pass": "900",
"partial_route_index": null,
"finalization_type": "min",
"allow_jump": false,
"estimated_earliest_arrival_ts": null,
"estimated_scheduled_ts": null,
"vehicle_characteristics": {},
"offer_should_be_auto_accepted": null,
"dynamic_break": null,
"user_accepted_offer_at": null,
"is_invalidated": null,
"time_windows": null
},
{
"id": 12648516,
"created_at": "2025-03-31T23:23:24.761601+00:00",
"modified_at": "2025-03-31T23:23:24.961358+00:00",
"uid": "9eb83008-7c5e-45d0-9743-73d62ede782a",
"lat": 1.329019,
"lon": 103.862623,
"h3": "0040062440662066236013",
"location_name": "254 Some Ave, Some city, some country, 00000",
"location_code": "",
"display_name": "254 Some Ave, Some city, some country, 00000",
"booking_uid": "aa082b4c-e8b3-4caf-a9f2-aba007bdde63",
"booking_id": 6478564,
"customer_id": null,
"open_time_ts": "2026-02-05T07:00:00+00:00",
"close_time_ts": "2026-02-05T13:00:00+00:00",
"close_time_ts_dynamic": "2026-02-05T13:00:00+00:00",
"service_time": 300,
"demand": {
"sample": -1
},
"status": "assigned",
"node_type": "dropoff",
"assigned_vehicle_id": 1854642,
"simulation_id": 158064,
"assignment_order": 1,
"scheduled_ts": "2026-02-05T07:00:00+00:00",
"visited_at_ts": null,
"completed_service_at": null,
"started_service_at_ts": null,
"walking_time_to_node": 0,
"walking_distance_to_node": 0,
"min_trip_duration": null,
"max_trip_duration": 36000,
"fixed_route_walk_time": null,
"fixed_route_ride_time": null,
"fixed_route_wait_time": null,
"fixed_route_journey_time": null,
"fixed_route_is_unreachable": false,
"cancelled_at_ts": null,
"penalty": 10000000,
"lifo_order_check": false,
"lifo_order_penalty": null,
"groups": [],
"matrix_timestamp": "2026-02-05T13:00:00+00:00",
"geofence_ids": [],
"geofence_id": null,
"transit_stop_id": null,
"transit_stop_street": null,
"transit_stop_type": null,
"transfer_type": "depart_at",
"weight": null,
"trip_cost": 0,
"initial_open_time_ts": null,
"initial_max_trip_duration": null,
"initial_close_time_ts": null,
"initial_close_time_ts_dynamic": null,
"max_slack": null,
"slack": 0,
"data": {},
"boarding_pass": "863",
"partial_route_index": null,
"finalization_type": "min",
"allow_jump": false,
"estimated_earliest_arrival_ts": null,
"estimated_scheduled_ts": null,
"vehicle_characteristics": {},
"offer_should_be_auto_accepted": null,
"dynamic_break": null,
"user_accepted_offer_at": null,
"is_invalidated": null,
"time_windows": null
}
],
"edges": [
{
"from_node_id": 12648515,
"to_node_id": 12648516,
"polyline5": "uodGwuzxRRUX[dAgAdAkAJJyAbBg@j@q@r@QTC@EFUTOMCACCu@m@eAi@c@SSKOGi@SWIk@O]Ka@Kg@IOAQC_CIgHYq@DMBODKFKLGNAN?PBLFNHHHFLDL@L@JANELGLKNOHMJeAD}@Cu@?s@Iu@IqAEgAAo@Ck@CaAA_ABwABsA?]@[@mA?a@?]?W?QAUCsA?KAa@As@@m@Fa@F_@FYDYBSDO@EBGDGDEFEBADAHEJEXGfAWlIoBjEg@tAWfBWfBQNARAzBEtAC~AEfAClEC`DEx@CjCGh@AnIKzI?TMPAN@R@d@Ad@ENE",
"edge_type": "between_nodes"
}
]
},
"current_sim_ts": "2025-03-31T23:23:24.808778+00:00",
"server_ts": "2025-03-31T23:23:55.838428+00:00",
"transmit_to_websocket": true,
"agent_id": null,
"user_id": null
}

メッセージの種類とスキーマ

Webhookを介したすべてのメッセージの基本スキーマ
{
"simulation_id": Integer simulation identity,
"agent_type": String agent type, [scheduler, vehicle_group, other],
"message_type": String about message type,
"agent_id": String agent_id, # optional key
"data": {}, dictionary, meaningful data.
"current_sim_ts": simulation timestamp (in real operations, current time),
"server_ts": server timestamp,
"transmit_to_websocket": whether to transmit to websocket this message
}

サポートされているメッセージフィルターの種類

メッセージを生成できるエージェント:

Agent types:
#: Event publisher - publishes different independent events.
EVENT_PUBLISHER = 'event_publisher'
#: Scheduler - schedules tasks for the vehicle groups (batch calculator).
SCHEDULER = 'scheduler'
#: State consumer - consumes events from system. And can do something,
for example, dump them into database.
STATE_CONSUMER = 'state_consumer'
#: Vehicle agent.
VEHICLE = 'vehicle'
#: Vehicle group is a collection of vehicles.
VEHICLE_GROUP = 'vehicle_group'

イベントパブリッシャーエージェント

新規予約メッセージ

{
'simulation_id': id,
'agent_type': 'event_publisher',
'message_type': 'bookings',
'agent_id': String agent_id, # optional key
'data': {
'bookings': [array of booking objects]
},
'current_sim_ts': simulation timestamp,
'server_ts': server timestamp,
'transmit_to_websocket': whether to transmit to sgerp websocket this message
}

予約キャンセルメッセージ

{
'simulation_id': id,
'agent_type': 'event_publisher',
'message_type': 'bookings_cancellation',
'agent_id': String agent_id, # optional key
'data': {
'booking_ids': [array of booking ids integers]
},
'current_sim_ts': simulation timestamp,
'server_ts': server timestamp,
'transmit_to_websocket': whether to transmit to sgerp websocket this message
}

オファー承諾メッセージ

{
'simulation_id': id,
'agent_type': 'event_publisher',
'agent_id': String agent_id, # optional key
'message_type': 'offer_accepted',
'data': {
'offer_id': offer_id
},
'current_sim_ts': simulation timestamp,
'server_ts': server timestamp,
'transmit_to_websocket': whether to transmit to sgerp websocket this message
}

オファー拒否メッセージ

{
'simulation_id': id,
'agent_type': 'event_publisher' or 'scheduler',
'message_type': 'offer_rejected',
'agent_id': String agent_id, # optional key
'data': {
'offer_id': offer_id
},
'current_sim_ts': simulation timestamp,
'server_ts': server timestamp,
'transmit_to_websocket': whether to transmit to sgerp websocket this message
}

スケジューラエージェント

スケジューラ計算開始メッセージ

{
'simulation_id': id,
'agent_type': 'scheduler',
'message_type': 'calc_started',
'agent_id': String agent_id,
'data': {
'booking_ids': [int], # list of sgerp booking ids
'booking_uids': [str], # list of lakhesis booking uids
},
'current_sim_ts': simulation timestamp,
'server_ts': server timestamp,
'transmit_to_websocket': whether to transmit to sgerp websocket this message
}

スケジューラ計算結果メッセージ

{
'simulation_id': id,
'agent_type': 'scheduler',
'message_type': 'scheduler_result', // only calculated nodes, nothing assigned
'agent_id': String agent_id, # optional key
'data': {
'nodes': [array of node objects],
'vehicle_id': vehicle.id, [ID of the vehicle which receives assignments],
},
'current_sim_ts': simulation timestamp,
'server_ts': server timestamp,
'transmit_to_websocket': whether to transmit to sgerp websocket this message
}

確認済み割り当てメッセージ

特定のvehicle_idメッセージの場合。車両はこの割り当てに従う必要があります。

{
'simulation_id': simulation.id,
'agent_type': 'scheduler',
'message_type': 'assignment', // this assignment has been assigned to a vehicle
'agent_id': String agent_id, # optional key, scheduler's agent_id
'data': {
'assignment_id': assignment ID,
'nodes': [array of node objects],
'edges': [
{
"from_node_id": null, // because of type vehicle_to_first
"to_node_id": 1,
"polyline5": "encoded_polyline", // with precision 5
"edge_type": "vehicle_to_first"
},
{
"from_node_id": 1,
"to_node_id": 2,
"polyline5": "encoded_polyline", // with precision 5
"edge_type": "between_nodes"
}
],
'vehicle_id': vehicle.id, [ID of the vehicle which receives assignments],
'vehicle_agent_id': vehicle.agent_id,
'polyline5': 'wqeqwewq5', # polyline of complete route with precision 5
'polyline6': 'wqeqwewq6' # polyline of complete route with precision 6
},
'current_sim_ts': simulation timestamp,
'server_ts': server timestamp,
'transmit_to_websocket': whether to transmit to sgerp websocket this message
}

特定の予約の生成されたオファー

{
"simulation_id": 3622,
"agent_type": "event_publisher",
"message_type": "offers",
"data": {
"offer_ids": [
60201
],
"offers": [
{
"id": 60201,
"uid": "fc57f35c-f254-4831-93fd-b987907eb1ad",
"service_session_id": "78a0034a-dbf1-4f37-8d93-7e97aada432f",
"booking_id": "8d191c2a-2371-4111-9d81-328d20be0e5c",
"vehicle_id": "69b751c0-9b35-46a9-943d-73b68eb76b63",
"offer_pickup_location_lat": 35.705422,
"offer_pickup_location_lon": 139.562104,
"offer_pickup_location_type": "bus_stop",
"offer_pickup_location_info": "かたらいの道",
"offer_pickup_display_name": "かたらいの道 #Tokyo_Demo_21",
"offer_pickup_location_street_name": "都武蔵野市中町2丁目11−9",
"streetview_pickup_position_lat": 35.705422,
"streetview_pickup_position_lon": 139.562104,
"streetview_pickup_bearing": 0,
"streetview_pickup_pitch": 0,
"pickup_stop_id": 1109949, # can be null for waypoint-less operations. See H3 index also.
"pickup_walking_distance": 120,
"pickup_walking_time": 120,
"pickup_walking_route": "cr|xEamyrYDMECGGAJ[jAaAfDOG",
"estimated_pickup_time": "2020-07-25T02:13:10.993305+00:00",
"min_pickup_time": "2020-07-25T02:12:38.185137+00:00",
"max_pickup_time": "2020-07-25T02:25:37.915305+00:00",
"boarding_pass": "677",
"offer_dropoff_location_lat": 35.705833,
"offer_dropoff_location_lon": 139.560521,
"offer_dropoff_location_type": "bus_stop",
"offer_dropoff_location_info": "武蔵野警察署前",
"offer_dropoff_display_name": "武蔵野警察署前 #Tokyo_Demo_22",
"offer_dropoff_location_street_name": "都武蔵野市中町1丁目11",
"streetview_dropoff_position_lat": 35.705833,
"streetview_dropoff_position_lon": 139.560521,
"streetview_dropoff_bearing": 0,
"streetview_dropoff_pitch": 0,
"dropoff_stop_id": 1109950, # can be null for waypoint-less operations. See H3 index also.
"dropoff_walking_distance": 69,
"dropoff_walking_time": 69,
"dropoff_walking_route": "mx|xEg|xrYGA@Il@eCB@",
"estimated_dropoff_time": "2020-07-25T02:17:08.393305+00:00",
"min_dropoff_time": "2020-07-25T02:10:37.915305+00:00",
"max_dropoff_time": "2020-07-25T02:41:24.097582+00:00",
"min_trip_duration": 115,
"max_trip_duration": 825,
"demand": {
"passenger": 1
},
"pickup_h3": "0040054340320265516504", // H3 index of the pickup node. Introduced in March 2021
"dropoff_h3": "0040054340320265516504" // H3 index of the dropoff node. Introduced in March 2021
}
]
},
"current_sim_ts": "2020-07-25T02:10:50.244417+00:00",
"server_ts": "2020-07-25T02:10:50.244417+00:00",
"transmit_to_websocket": false,
"agent_id": null
}

オファーなしメッセージ

{
'simulation_id': id,
'agent_type': 'scheduler',
'message_type': 'no_offer',
'agent_id': String agent_id, # scheduler agent_id
'data': {
'booking_ids': [booking.id], # array of booking ids from sgerp
'booking_uids': [booking.uid], # array of booking string uids from lakhesis
},
'current_sim_ts': simulation timestamp,
'server_ts': server timestamp,
'transmit_to_websocket': whether to transmit to sgerp websocket this message
}

GPSデータイベント

(API(またはモバイルデバイス)からの位置情報イベント)

{
"simulation_id": id,
"agent_type": "vehicle",
'agent_id': String agent_id, # optional key
"data": {
"vehicle_event": "gps_data",
"vehicle_id": 1756,
"fleetman_vehicle_id": 10, # fleetman vehicle ID (physical vehicle) optional
"lat": 1.3,
"lon": 103.88,
"bearing": 100,
"speed": 9.8
"device_ts": datetime
},
"current_sim_ts": simulation timestamp,
"transmit_to_websocket": whether to transmit to sgerp websocket this message
}

車両エージェント

車両状態メッセージ

{
'simulation_id': simulation_id,
'message_type': 'vehicle_states',
'agent_type': 'vehicle',
'agent_id': String agent_id, # optional key
'data': {
'vehicle_states': [
'id': self.id,
'capacity': self.capacity,
'lat': self.lat,
'lon': self.lon,
'speed': self.speed,
'bearing': self.bearing,
'current_route': self.current_route,
'routing_engine_settings': self.routing_engine_settings,
'routing_engine_url': self.routing_engine_settings.get('url', ''),
'routing_engine_name': self.routing_engine_settings['routing_engine_name'],
'last_assignment_ts': self.last_assignment_ts,
'should_reach_for': self.should_reach_for,
'should_reach_at': self.should_reach_at,
'should_wait_until': self.should_wait_until,
'ts': timezone.now(),
'status': self.status.value,
'total_mileage': self.total_mileage if self.total_mileage else 0,
'path': self.path,fail_to_deliver
'vehicle_cost': self.vehicle_cost,
'lifo_order_check': self.lifo_order_check,
'physical_vehicle_id': self.physical_vehicle_id,
'agent_type': 'vehicle',
'agent_id': self.agent_id,
'completed_nodes': [], # always an empty array now
'assigned_nodes': [node.to_dict() for node in self.assigned_nodes],
'next_waypoint_node': self.next_waypoint_node.to_dict() if self.next_waypoint_node else None,
'total_mileage': self.total_mileage if self.total_mileage else 0,
'ts': timezone.now(),
]
},
'current_sim_ts': current_sim_ts,
'transmit_to_websocket': whether to transmit_to_websocket
}

ノードステータスの更新

{
'simulation_id': id,
'agent_type': 'vehicle',
'message_type': 'node_status',
'agent_id': sender messaging agent id,
'data': {
'node_id': id of the node,
'node_uid': uid of the node,
'status': 'completed', # or 'in_service' for more precise use cases
'vehicle_id': integer vehicle id,
'node_type': 'pickup', 'dropoff', 'point'; optional field
'booking_uid': UUID of the node.booking_uid,
'booking_id': integer booking ID for additional reference
},
'current_sim_ts': timestamp of the event,
'server_ts': server timestamp,
'transmit_to_websocket': whether to transmit_to_websocket
}

予約搭乗失敗メッセージ

{
'simulation_id': id,
'agent_type': 'vehicle',
'message_type': 'fail_to_board',
'agent_id': String agent_id, # optional key
'data': {
'booking_ids': [array of booking ids integers who had no-show],
'booking_uids': [array of booking uids UUIDs who had no-show]
},
'current_sim_ts': simulation timestamp,
'server_ts': server timestamp,
'transmit_to_websocket': whether to transmit to sgerp websocket this message
}

車両スケジューリングユーザビリティイベント

現在のスケジューリングで車両を有効/無効にする必要がある場合にイベントをトリガーできます

{
'simulation_id': id,
'agent_type': 'vehicle',
'message_type': 'vehicle_use',
'agent_id': String agent_id, # optional key
'data': {
'vehicle_id': integer vehicle id
'action': 'enabled' or 'disabled' # disable is, for example, for vehicle breakdown
},
'current_sim_ts': simulation timestamp,
'server_ts': server timestamp,
'transmit_to_websocket': whether to transmit to sgerp websocket this message
}

車両到着メッセージ

車両到着メッセージは、performance_tracker_enabled属性がtrueに設定された実際の運用シミュレーション用に生成されます。 simulation.performance_tracker_enabled: true

その後、システムは定期的に(システム設定に応じて、約5分に1回)次のメッセージを生成します。

{
'simulation_id': id,
'agent_type': 'vehicle',
'message_type': 'vehicle_arrival',
'agent_id': String agent_id, # optional key
'data': {
'vehicle_id': integer vehicle id
'vehicle_agent_id': UUID Vehicle.agent_id
'booking_id': integer SGERP booking ID
'booking_uid': UUID booking UID
'node_id': integer node ID
'node_uid': node UID
'estimated_earliest_arrival_ts': possible earliest arrival (not taking into account service times along the route and earliness, so less precise)
'estimated_scheduled_ts': estimated time of starting servicing the node** (taking into account service times along the route and earliness, so **more precise**)
'scheduled_ts': scheduled timestamp, so client can easy compare scheduled and ETA in single message
},
'current_sim_ts': simulation timestamp,
'server_ts': server timestamp,
'transmit_to_websocket': whether to transmit to sgerp websocket this message
}

車両到着グループ化メッセージ

車両到着グループ化メッセージは、vehicle_idでグループ化された車両到着メッセージのリストです。

{
"simulation_id": 1,
"agent_type": "vehicle",
"message_type": "vehicle_arrival_grouped",
"data": {
"vehicle_id": 1,
"vehicle_agent_id": "12345",
"arrivals": [
{
"vehicle_id": 1,
"vehicle_agent_id": "12345",
"booking_id": 1,
"booking_uid": "c565534f-29a5-4ed7-9556-8c819e0b6265",
"node_id": 1,
"node_uid": "73f466b4-3162-42f7-b696-a034af3f63c8",
"estimated_earliest_arrival_ts": "2021-02-19T15:27:24.514985+00:00",
"estimated_scheduled_ts": "2021-02-19T15:27:24.514985+00:00",
"scheduled_ts": "2021-02-03T08:17:09.920827+00:00"
},
{
"vehicle_id": 1,
"vehicle_agent_id": "12345",
"booking_id": 1,
"booking_uid": "c565534f-29a5-4ed7-9556-8c819e0b6265",
"node_id": 2,
"node_uid": "a97048d2-f509-41ec-a1fc-2258c3a05003",
"estimated_earliest_arrival_ts": "2021-02-19T15:27:24.514985+00:00",
"estimated_scheduled_ts": "2021-02-19T15:27:24.514985+00:00",
"scheduled_ts": "2021-02-03T08:27:09.925693+00:00"
}
]
},
"current_sim_ts": "2021-02-03T08:17:09.942437+00:00",
"server_ts": "2021-02-03T08:17:09.942437+00:00",
"transmit_to_websocket": false,
"agent_id": null
}

車両グループエージェント

車両状態変更メッセージ

VehicleStateChangedMessageには車両IDのみが含まれます。これは、車両の状態に何かが変更されたことを示すシグナルです。たとえば、新しいルートがある場合があります。

{
'simulation_id': id,
'agent_type': 'vehicle_group',
'message_type': 'vehicle_arrival',
'agent_id': String agent_id, # optional key
'data': {
'vehicle_id': integer vehicle id
},
'current_sim_ts': simulation timestamp,
'server_ts': server timestamp,
'transmit_to_websocket': whether to transmit to sgerp websocket this message
}

需要変更メッセージ

{
"simulation_id": simulation_id,
"agent_type": "vehicle_group",
"message_type": "demand_modification",
"agent_id": String agent_id, # optional key
"data": {
"vehicle_id": integer vehicle id,
"node_id": integer node id
"tickets": [{"demand": 1, "ticket_type": "passenger"}]
},
"current_sim_ts": simulation timestamp,
"server_ts": server timestamp,
"transmit_to_websocket': whether to transmit to sgerp websocket this message
}

Webhookのテスト

Webhookのテストは、Webhookリクエストを他の場所にプロキシできるサードパーティサービスを使用して可能です。 プロセスは次のようになります。

  • 「新しいチャネルを開始」をクリックして、https://smee.io/を使用してWebhookプロキシURLを作成します
  • Run In Postmanコレクションを使用して、選択したシミュレーションのWebhookを構成します。webhook_urlフィールドにhttps://smee.io/<your_token>を入力し、Webhookフィルターを設定します
  • smeeの指示に従ってnodejsとnpmをインストールします。コンソールでsmee -u https://smee.io/<your_token> -p 3001を使用して、smeeプロキシをlocalhostにリダイレクトするように設定します
  • smee Webブラウザウィンドウを使用して着信メッセージ(配信)を表示するか、代わりに、
  • 別のコンソールでノードスクリプトを使用してコンソールにメッセージをダンプするようにnodejsプロキシを実行します
ローカルnodejsプロキシ
node -e "const h = require('http');const s = h.createServer();const l = console.log;s.on('request', (rq, rs) => {let b = [];rq.on('data', (c) => {b.push(c);}).on('end', () => {b = Buffer.concat(b).toString();l('==== '+rq.method+' '+rq.url);l('> Headers');l(rq.headers);l('> Body');l(b);rs.end();});}).listen(3001);"
  • イベントが発生すると、シミュレーションからコンソールでメッセージの受信を開始する必要があります。smee URL https://smee.io/<your_token>に任意のペイロードでPOSTリクエストを送信してセットアップをテストできます。これはコンソールに表示されます。