Skip to main content

WebSocket Interface

Enterprise Kitchen uses a WebSocket interface to communicate back to the client. For the client point of sale (POS) system to get information from Enterprise Kitchen, it must establish a WebSocket connection. With a Websocket connection, information is represented by various events that Enterprise Kitchen sends according to actions that have occurred.

WebSocket Server

Enterprise Kitchen uses a custom implementation of the WebSocket server that is based on Chrome (for Cordova) or net native node module (for Electron). It also includes a self-testing interval that controls a web server healthcare interval check to react instantly to system errors and to keep the server functional.

Every client that has been connected to the WebSocket server gets its own socket with a heartbeat tick. The heartbeat tick is represented by an isAlive? message that is sent every one second. It does not use a ping-pong strategy to track client's availability. It is a one-way message that the client can use to implement an idle timeout mechanism.

Note

The Enterprise Kitchen WebSocket server does not require a response to the isAlive? message. The client should consider it as a beacon that shows the server's availability.

Connecting to the Enterprise Kitchen WebSocket Server

Enterprise Kitchen does not have a specific endpoint to handle the WebSocket connection. A WebSocket server starts on the local IP address with a specific WebSocket port, which is the only information that a client needs to establish a connection.

The following is a basic example (Node.js) illustrating how a connection can be established:

var WebSocketClient = require('websocket').client;
const SERVER_URL = '<ip_address>';
const PORT = '<port>';
var client = new WebSocketClient();

client.on('connect', function(connection) {
	console.log('WebSocket Client Connected');

	connection.on('error', function(error) {
		console.log("Connection Error: " + error.toString());
	});
	connection.on('close', function() {
		console.log('Connection Closed');
	});
	connection.on('message', function(message) {
		console.log(message);
	});
});

client.on('connectFailed', function(error) {
	console.log('Connect Error: ' + error.toString());
});

client.connect('ws://${SERVER_URL}:${PORT}/');

Note

Enterprise Kitchen does not handle any messages that might be sent from the client. It should be considered as a one-way flow of messages, from server to client.

Events

The WebSocket server connection has the following purposes:

  • Track the server’s availability by the isAlive? heartbeat

  • Handle Enterprise Kitchen events. All events represent order and item states that have been set after specific actions within Enterprise Kitchen.

Enterprise Kitchen supports the following events:

Order-Level Bump or Recall Event

The Order-Level Bump or Recall event represents a bump or recall operation that occurred for a specific order.

{
	src: "bumpMessenger",
	dst: "bumpService",
	action: "bumpRecord",
	event: {
		trigger: "auto" | "auto-state" | "manual", // shows what triggered 
bump/recall operation
		kvs: <string>, // screen name where order was bumped/recalled
		kvs_id: <string> // screen unique identifier where order was 
bumped/recalled
	},
	type: "bump" | "recall", // represents operation type
	level: "order",
	data: {
		arrivaltime: <string>, // date and time in ISO format when order was 
received.
		businessdate: <string>, // date in ISO format that represents order's 
business date.
		orderid: <string>, // order's unique identifier
		terminalid: <string>, // unique POS terminal identifier related to the 
order
		bumpedtime?: <string>, // date and time in ISO format when order was 
bumped.
		recalltime?: <string> // date and time in ISO format when order was 
recalled.
	}
}

Item-Level Bump or Recall Event

The Item-Level Bump or Recall event represents a bump or recall operation that occurred for a specific item that belongs to an order. This event is generated for every active item on a kitchen screen (kvs) during an order bump or recall operation. For example, if an order with five items is bumped from an Enterprise Kitchen screen, then one order-level and five item-level bump events are sent to every client.

{
	src: "bumpMessenger",
	dst: "bumpService",
	action: "bumpRecord",
	event: {
	trigger: "auto" | "auto-state" | "manual", // shows what triggered 
bump/recall operation
		kvs: <string>, // screen name where item was bumped/recalled
		kvs_id: <string> // screen unique identifier where item was 
bumped/recalled
	},
	type: "bump" | "recall", // represents operation type
	level: "item",
	data: {
		arrivaltime: <string>, // date and time in ISO format when item 
was first displayed on screen
		businessdate: <string>, // date in ISO format that represents 
order's business date
		itemnumber: <string>, // item's human-readable identifier
		orderid: <string>, // order's unique identifier
		serial: <string>, // item's unique identifier
		terminalid: <string>, // unique POS terminal identifier related to the 
order
		type: "bump" | "recall", // represents operation type 
(duplicated field)
		bumpedtime?: <string>, // date and time in ISO format. 
		recalltime?: <string>, // date and time in ISO format. 
Represents the last recall time. 
		fulfillmentstatus?: "ready" | "fulfilled" // date time in ISO 
format. Represents item fulfillment status.
	}
}

Bumped-From-All Event

The Bumped-From-All event indicates that the order has now been bumped from all online screens.

{
	src: "bumpMessenger",
	dst: "bumpService",
	action: "bumpRecord",
	type: "bumpedFromAll",
	level: "order",
	bumped: <boolean>, // Indicates if order is bumped from all online screens
	timestamp: <string>, // Date and time in ISO format. Represents the moment, 
when current event appeared
	data: {
		orderid: <string>, // order's unique identifier
		terminalid: <string>, // unique POS terminal identifier related to the 
order
		businessdate: <string> // date in ISO format that represents 
order's business date
	}
}

Item Lifecycle Event

If the advanced lifecycle is setup, items in every order may have an additional state. That state can be set for every item during a claim or complete user action. As a result, every change of item state generates an additional item-level event.

{
	src: "claimMessenger",
	dst: "claimService",
	action: "claimRecord",
	event: {
		trigger: "manual",
		kvs: <string>, // screen name where item was claimed/completed
		kvs_id: <string>, // screen unique identifier where item was 
claimed/completed
	},
	type: "claim",
	level: "item",
	data: {
		orderId: <string>, // order's unique identifier
		serialNumber: <string>, // item's unique identifier
		station: <string>, // unique station's identifier where item was 
claimed/completed
		type: "claimed" | "claimComplete" | "unclaimed",
		claimTime: <string>, // date and time in ISO format. 
Represents the moment when item was claimed/completed/unclaimed
		claimColor: <string>, // represents the claim color
		claimCheckColor: <string>, // represents the complete color
		claimBackgroundColor: <string>, // represents unclaimed color
		businessdate: <string> // date in ISO format, that represents 
order's business date
	}
}

Item Fulfillment Event

The Item Fulfillment special event indicates that “no work” for the specified items will be performed within Enterprise Kitchen to advance their fulfillment status. The reason can be one of the following:

  • Items do not route to any display in the current kitchen scheme

  • Items should route to a screen with a fulfillment event configured, but that screen is not available currently

{
	src: "itemFulfillmentMessenger",
	dst: "itemFulfillmentService",
	action: "itemFulfillmentRecord",
	type: "itemFulfillment",
	level: "order",
	data: {
		orderid: <string>, // order's unique identifier
		businessdate: <string>, // date in ISO format that represents 
order's business date
		items: <array>[
			reason: "item_not_routed" | "offline_screen",
			serialnumber: <string>, // unique item's identifier
			status: 'no_work'
		]	
	}
}

Park Event

A Park event is generated every time an order is parked or unparked.

{
	src: "parkMessenger",
	dst: "parkService",
	action: "parkRecord",
	event: {
		trigger: "manual",
		kvs: <string>, // screen name where item was parked/unparked
		kvs_id: <string> // screen unique identifier where item was 
parked/unparked
	},
	type: "park",
	level: "order",
	data: {
		orderId: <string>, // order's unique identifier
		parkStatus: "parked" | "unparked",
		parkTime: <string>, // date and time in ISO format. 
Represents the moment when order was parked/unparked
		businessdate: <string> // date in ISO format that represents 
order's business date
	}
}

Purge Event

A Purge event is generated when an order is purged from the Enterprise Kitchen system.

{
	src: "purgeMessenger",
	dst: "purgeService",
	action: "purgeRecord",
	type: "purge",
	level: "order",
	data: {
		orderid: <string>, // order's unique identifier
		orderitemids: array<string>, // unique identifiers of order 
items that have been purged
		purgetime: <string>, // date and time in ISO format. 
Represents the moment when order has been purged
		businessdate: <string> // date in ISO format that represents 
order's business date
	}
}