WebSocket Client#
The MeiliWebsocketClient class manages WebSocket connections, message sending, and receiving. It uses callback functions to handle events and messages from the FMS. It is the recommended way to integrate your robots with the FMS, independent of the robot’s way of communication.
The idea is to create a script that acts as a bridge between the FMS and your robot’s control system. This script should communicate with the robot using its native protocol and with the FMS using the MeiliWebsocketClient, so as status updates and commands can be exchanged.
Importing#
from meili_sdk import MeiliWebsocketClientAuthentication#
In order to be able to connect to the FMS, you need to provide the fleet token when creating the MeiliWebsocketClient instance. You can find the fleet token in the FMS, searching for your fleet and looking for the ‘password’ field.
Callback Functions#
When creating a MeiliWebsocketClient, you can provide any combination of the following callback functions. Each is called when a specific event or message is received from the FMS:
open_handler: Called when the WebSocket connection is established.close_handler: Called when the WebSocket connection is closed.error_handler: Called when an error occurs.task_v2_handler: Called when a new task is assigned.task_cancellation_handler: Called when a task cancellation message is received.slow_down_handler: Called when a slow down message is received.path_rerouting_handler: Called when a path rerouting message is received.collision_clearance_handler: Called when a collision clearance message is received.message_error_handler: Called when a message error occurs.update_map_handler: Called when an update map message is received.vehicle_initial_position_handler: Called when a vehicle initial position message isreceived.update_vehicle_settings: Called when vehicle settings are updated.pause_task_handler: Called when a pause task message is received.resume_task_handler: Called when a resume task message is received.remove_vehicle_from_fleet_handler: Called when a vehicle is removed from the fleet.set_initial_position_handler: Called when a set initial position message is received.update_map_id_handler: Called when an update map ID message is received.topic_list_handler: Called when a topic list message is received.topic_list_initializer_handler: Called when a topic list initializer message is received.docking_routine_request_handler: Called when a docking routine request message is received.docking_routine_finalize_handler: Called when a docking routine is finalized.
You only need to implement the callbacks relevant to your application.
Example of Basic MeiliWebsocketClient implementation
from meili_sdk.websockets import MeiliWebsocketClient
from meili_sdk.websockets.models.task_v2 import TaskV2
def open_handler():
print("Connection opened")
def close_handler():
print("Connection closed")
def error_handler(_, error):
print(f"Error: {error}")
def task_v2_handler(self, task: TaskV2, vehicle_uuid: str):
print(f"Received task: {task} for vehicle: {vehicle_uuid}")
send_task_to_robot(task, vehicle_uuid) # Your task handling logic here
client = MeiliWebsocketClient(
"fdd27e8e1a2b4c3d8e9f0a1b2c3d4e5f",
open_handler=open_handler,
close_handler=close_handler,
error_handler=error_handler,
task_v2_handler=task_v2_handler,
)
client.add_vehicle("afe4b5c6d7e8f9a0b1c2d3e4f5g6h7i8j") # FMS vehicle UUID
client.run_in_thread() Message Sending#
The MeiliWebsocketClient lets you send various message types to the FMS to report robot status and events. Below are the main message types you can use:
Location#
Report the robot’s current position. Supported formats:
- Meters:
xm,ym - Latitude/Longitude:
lat,lon - ROS Coordinates:
x,y
message_loc = Message(
event=constants.EVENT_LOCATION,
value={"xm": 1, "ym": 2, "rotation": 90, "map_id": "first_floor"},
vehicle=uuid
)
message_loc.validate()
client.send(message_loc)Speed#
Report the robot’s speed in meters per second.
message_speed = Message(
event=constants.EVENT_SPEED,
value={"speed": 0.5},
vehicle=uuid
)
message_speed.validate()
client.send(message_speed)Battery#
Report battery percentage and charging status.
class PowerSupplyStatuses:
DISCHARGING = 2
NOT_CHARGING = 3
message_battery = Message(
event=constants.EVENT_BATTERY,
value={"value": 81, "power_supply_status": PowerSupplyStatuses.NOT_CHARGING},
vehicle=uuid
)
message_battery.validate()
client.send(message_battery)Goal Status#
Update the status of a mission or task.
class GoalStatuses:
ACTIVE = 1
SUCCEEDED = 3
ABORTED = 4
message_goal = Message(
event=constants.EVENT_GOAL_STATUS,
value={"goal_id": "fms_task_uuid", "status_id": GoalStatuses.ACTIVE},
vehicle=uuid
)
message_goal.validate()
client.send(message_goal)Notification#
Send notifications to the FMS interface. Levels: info, warning, error.
message_notification = Message(
event=constants.EVENT_NOTIFICATION,
value={"level": "error", "message": "Lost communication"},
vehicle=uuid
)
message_notification.validate()
client.send(message_notification)State#
Send a combined update of location, speed, and battery.
location = {"xm": 1, "ym": 2, "rotation": 90, "map_id": "first_floor"}
speed = {"speed": 1.5}
battery = {"value": 82, "power_supply_status": PowerSupplyStatuses.NOT_CHARGING}
message_state = Message(
event=constants.EVENT_STATE,
value={"location": location, "speed": speed, "battery": battery},
vehicle=uuid
)
message_state.validate()
client.send(message_state)Map Update#
Send updates to the map, such as new stations.
message_map = Message(
event=constants.EVENT_MAP_UPDATE,
value={
"stations": [
{
"uuid": "ff2a1b1c1e5d4f0c9f3d1234567890ab",
"title": "Station 1",
"station_type": "default",
"points_in_meters": [1, 0],
"rotation": 0.0
},
{
"uuid": "aa3b2c3d4e5f67890abcdef123456789",
"title": "Station 2",
"station_type": "default",
"points_in_meters": [1, -1],
"rotation": 0.0
}
],
},
vehicle=uuid
)
message_map.validate()
client.send(message_map)As a result, the FMS will update its map with the new stations provided in the message and send back a confirmation message, indicating the UUIDs assigned to the stations. This will be handled by the update_map_handler callback if implemented.
Synchronization#
When the user sends a synchronization request via the FMS, update_map_handler is triggered, the message contains the current map configuration, available actions, stations, paths, and presets. Key fields include:
action_definitions: List of actions the robot can performstations: Map stations with coordinatespaths: Connections between stationspresets: Predefined action sequencesdisplayable_image,height,width: Map image and dimensionsyaml_file: Map configuration detailsuuid: Map identifier
This message provides all necessary information for the robot agent to operate and interact with the FMS.