How the Shop Floor Insight server action web service works
The server action web service, TCMServerBarcode, does most of the work in Shop Floor Insight. Each badge scan, routing barcode scan or menu action on the shop floor is sent to it. Shop Floor Insight decides what to do in Business Central, does it, and returns a list of instructions for the client.
This article explains how a request is processed, what the service can do, and how to read its response.
This article is for developers and partners who integrate with or customize Shop Floor Insight. It is not intended for shop floor operators or other end users.
Before you build a custom interface, check whether one of the existing Shop Floor Insight interfaces already fits:
- Web browser: the Shop Floor Insight barcode-optimized interface.
- Windows and Android devices: Shop Floor Insight in Warehouse Insight. See Warehouse Insight Shop Floor Integration.
- Business Central phone and tablet app: the Shop Floor Insight Phone Optimized profile, which uses the phone role center (page 23044186). See Shop Floor Native Phone Client.
Available functionality differs between interfaces, so compare them with the activities your operators need.
Note: This article describes the web services, methods and responses as they were when it was written. They can change as Shop Floor Insight is updated, so responses in your environment may differ slightly. When they differ, go by what your system returns. The OData metadata document (
$metadata) lists current names and parameters.
Before you start
- Run the Shop Floor Insight Setup Wizard so the
TCMServerBarcodeweb service is published. It is page 23044138,SFI WS - Action Handler. - Have a working Shop Floor client configuration, employee badges and production order barcodes in the Business Central company your application connects to.
- Connect your application with OAuth service-to-service authentication. As a security best practice, use your own tenant-specific Microsoft Entra app registration, as outlined in Configure OAuth service-to-service connections in Shop Floor Insight.
- Give the app registration only the Business Central permission sets it needs, as described in that article. The app registration connects your application to Business Central; the employee badge identifies the Shop Floor employee.
- Business Central licensing: a custom interface doesn’t change Microsoft’s Business Central licensing requirements, including access through web services. Business Central device licenses can cover qualifying shared shop floor devices. Confirm the right user or device licensing with your Microsoft partner. See Business Central device licensing information and Business Central licensing guidance.
- Shop Floor Insight licensing is also required when using the Shop Floor Insight web services, even if you are not using the Shop Floor Insight scanning station apps. See licensing requirements for Insight Works apps.
How a server action works
The service is a page web service, but a read of it runs an action. The inputs are sent as filters on the page fields, and the records that come back are the instructions.
- The client sends a GET request to
TCMServerBarcodewith the inputs as$filterconditions (Field eq 'value', joined withand). The Shop Floor Insight web client sends the same request through the Shop Floor Insight Windows service, which passes it on to Business Central. - When Business Central reads the page, the page runs the server action handler, codeunit 23044138,
SFI Action Handler. - The
OnBeforeHandleServerActionevent runs. An extension can handle the action here and skip the standard logic. - A
RESP.NOOPinstruction is always added first, so the response is never empty. - The handler reads
Input_Action_Type_Codeand runs the matching logic. That logic changes Business Central data, such as time cards, and adds instructions to the response. - The
OnAfterHandleServerActionevent runs. - Business Central returns the instruction rows, ordered by
Sort_No.
Note: A read of
TCMServerBarcodecan change time cards. Never cache, prefetch, page through or automatically retry these requests. If a request times out, read the time card to see what happened before you send another action. Repeating a routing scan can stop time the first scan started.
Request fields
Send only the fields the action needs. Field names in OData use underscores; the page shows them with spaces.
| OData field | Page field | What it does |
|---|---|---|
| Input_Action_Type_Code | Input Action Type Code | What kind of action this is, for example BARCODE.SCAN or MENUITEM. Required. |
| Input_Action_Data | Input Action Data | The action payload: the scanned barcode, the menu item name, or JSON data for a workflow. Up to 200 characters. |
| Input_Config_No | Input Config No. | The Shop Floor client configuration. If blank, Shop Floor Insight finds the configuration from the employee and address rules. |
| Input_Employee_No | Input Employee No. | The signed-in employee. Leave blank for the first badge scan. |
| Input_Time_Card_No | Input Time Card No. | The current time card, if known. |
| Input_Screen_Code | Input Screen Code | The screen the request comes from. The same action can do different things on different screens. |
| Input_Address | Input Address | The terminal address, such as its IP address. Used to find the client configuration. It is not a credential. |
| Selected_Row_Key_1 to Selected_Row_Key_3 | Selected Row Key 1 to 3 | The keys of the row selected on the current screen. Their meaning depends on the screen. |
Screen codes
Input_Screen_Code tells the service what the operator was looking at. It changes how actions behave and what the selected row keys mean.
| Screen code | Screen | Selected row keys |
|---|---|---|
LOGIN |
Sign-in screen. A badge scan here always signs the employee in. | Not used. |
TIME_CARD |
The employee’s time card. | Key 1: time card number. Key 2: time card line number. |
PROD_ORDER |
Production dispatch list. | Key 1: production order number. Key 2: production order line number. Key 3: operation number. |
PROD_ORDER_SCHEDULER |
This functionality has been replaced with Graphical Scheduler. | Same as PROD_ORDER. |
JOB_TASK |
Job dispatch list. | Key 1: job number. Key 3: job task number. Leave key 2 blank. |
What the server action can do
Action types
| Input_Action_Type_Code | Input_Action_Data | What it does |
|---|---|---|
BARCODE.SCAN |
Barcode data | Decodes the barcode and acts on it: signs in, clocks on or off, or runs a custom scan. See “Barcode scans.” |
BARCODE.LPSCAN |
License plate number | Gets or creates a License Plating license plate for the selected production order line, saves it on the time card, and reloads the time card. |
MENUITEM |
Menu item name | Runs a menu action, such as ClockOn or EndShift. See “Menu actions.” |
ADDREGISTEREDABSENCE |
Absence details | Registers an absence from the production scheduler. |
WORKFLOW.CONTINUE |
JSON with the workflow instance, step and the user’s answer | Continues a Business Central workflow that paused to ask the operator a question. |
Barcode scans
For BARCODE.SCAN, Shop Floor Insight first decodes the barcode and adds a RESP.DECODE instruction. It then loads the employee, time card, client configuration and selected line, and acts based on the barcode type.
| Barcode type | Identifies | What the scan does |
|---|---|---|
| R | Employee badge (including break badges) | Signs the employee in, switches to a different employee, or logs out and locks the screen. See below. |
| O | Production routing operation, run time | Clocks on or off run time for the operation. |
| N | Production routing operation, setup time | Clocks on or off setup time for the operation. |
| J | Job task: job number, job task number and an optional job planning line number | Records time against the job task. |
| A | Asset | Records time against the asset. |
| W | Work center | Records time against the work center. |
| T | Work type | Records time with the work type. |
| S | Service | Records time against the service item. |
| C | Custom | Runs the custom scan through Shop Floor Insight workflow integration. |
| (none) | A barcode that is not a Shop Floor Insight barcode | On the TIME_CARD screen only, looks up the item with the enabled barcode rules and clocks on or off the matching production routing lines. |
An employee badge scan works like this:
- On the
LOGINscreen, or when a different employee scans, the employee is signed in and placed on site, and a time card is found or created. The response includesRESP.SIGNIN. - When the signed-in employee scans their own badge again, they are logged out and the response includes
RESP.LOCK. - On a group time card, scanning the group badge locks the screen. Scanning a member’s badge reloads the time card.
For a routing barcode in the Auto or Auto – Same Entry Only time entry modes, the first scan starts time and a second scan of the same barcode stops it. In Manual mode, a scan that matches an open line selects it without stopping it.
Menu actions
For MENUITEM, Input_Action_Data is the menu item name. Before running it, Shop Floor Insight updates the time card’s logout time. Some items work on any screen; others depend on Input_Screen_Code. An unknown item returns the error “Unknown menu action”.
| Menu item | Screens | What it does |
|---|---|---|
Output |
Any | Opens output entry for the selected or matching production line. Depending on Output ClockOn Behavior on the client configuration, it can clock on or off first, or start a workflow. |
Consume |
Any | Opens consumption entry for the selected line. |
ClockOn |
Dispatch screens | Starts time on the selected dispatch row. |
ClockOff |
Time card and dispatch screens | Stops time on the selected time card line, or on the open line that matches the selected dispatch row. |
ClockOffSingle |
Time card and dispatch screens | Stops only the selected line. On a work center that splits time across lines, the other lines keep running. |
Delete |
TIME_CARD |
Deletes the selected time card line. |
SelectActivity,... |
TIME_CARD |
Records time against an activity chosen from the activity menu. |
ShowRegisterAbsence |
Dispatch screens | Shows the register absence dialog. |
EndShift |
Time card, dispatch and sign-in screens | Ends the shift: clocks off open lines, marks the employee off site and closes the time card. |
LoginEmployee |
LOGIN |
Signs in the employee given in Input_Employee_No after checking their authorization. |
CUSTOM:... |
Any | Runs a custom menu item set up through Shop Floor Insight workflow integration. |
Response
The response is a list of rows. Each row has Sort_No, Response_Code and Response_Data. Process the rows in Sort_No order, one instruction at a time. Some instructions, such as RESP.MESSAGE and RESP.CONFIRM, wait for the operator before the next one runs.
Chunked data
Response_Data holds up to 200 characters. Longer data continues in the following rows with the response code CHUNK. Append each CHUNK row to the previous instruction’s data with no separator, and parse JSON only after the data is complete.
// Rebuild instructions from the TCMServerBarcode response
var actions = [];
var previous = null;
rows.sort(function (a, b) { return a.Sort_No - b.Sort_No; });
rows.forEach(function (row) {
if (row.Response_Code === 'CHUNK') {
previous.Response_Data += row.Response_Data; // no separator
} else {
previous = { code: row.Response_Code, data: row.Response_Data };
actions.push(previous);
}
});
// Then handle each action in order, skipping RESP.NOOP.
Response codes
| Response code | What the client should do |
|---|---|
RESP.NOOP |
Always the first row. Holds diagnostic JSON (server time, company, session and user). Ignore it for processing. |
RESP.DECODE |
Barcode decode details as JSON, such as return_value, type and mapid. It does not mean an action completed. |
RESP.SIGNIN |
Sign-in succeeded. JSON with Time_Card_Header_No, Employee_No, Employee_Name, Login_Time, Client_Config_No and the client and menu configuration. |
RESP.LOCK |
Clear the signed-in employee and lock the screen. |
RESP.RELOADTC |
Reload the time card named in the JSON. |
RESP.SELECTLINE |
Select the time card line named in the JSON (Line_No). |
RESP.RELOAD |
Refresh the current screen. |
RESP.VIEWON |
Switch to the screen named in the data, for example TIME_CARD. |
RESP.SETFILTER |
Put the data into the screen’s search box. |
RESP.OUTPUT |
Open output entry. |
RESP.CONSUME |
Open consumption entry. |
RESP.QUALITY |
Open quality inspection. |
RESP.ERROR |
Show the plain-text error. The HTTP request still succeeds. |
RESP.MESSAGE |
Show a message. JSON with title and message. |
RESP.CONFIRM |
Ask the operator to confirm. Continue with the next instruction only if they confirm. |
RESP.PROMPT |
Ask the operator to type a value. |
RESP.SETWORKFLOW |
Remember the workflow instance, step and code, so the answer to the next confirm or prompt can be sent back with WORKFLOW.CONTINUE. |
RESP.SERVERACTION |
Send another server action. The data is the action type to send. |
RESP.SHOWLIGHTBOX |
Show a dialog on the production scheduler, defined by the JSON. |
RESP.JS |
Script for the Shop Floor Insight web client. Custom applications can ignore it or report it as unsupported. |
CHUNK |
Continuation of the previous row’s data. See “Chunked data.” |
An HTTP success does not mean time started or stopped. Check for RESP.ERROR, and read the time card lines to confirm the result.
Examples
These examples use OData. BASE_URL stands for your Business Central OData base URL, for example:
https://api.businesscentral.dynamics.com/v2.0/{tenant}/{environment}/ODataV4
Filters are shown on separate lines for readability; send them as one URL-encoded query.
Sign in with an employee badge
GET BASE_URL/Company('CRONUS Canada, Inc.')/TCMServerBarcode?$filter=
Input_Action_Type_Code eq 'BARCODE.SCAN' and
Input_Action_Data eq '/R00000001%' and
Input_Config_No eq 'CFG000001' and
Input_Screen_Code eq 'LOGIN' and
Input_Address eq '192.168.123.45'
Authorization: Bearer {access_token}
Accept: application/json
A successful sign-in returns rows like these:
{
"value": [
{ "Sort_No": 1, "Response_Code": "RESP.NOOP", "Response_Data": "{\"CURRENDDATETIME\":\"...\",\"COMPANYNAME\":\"CRONUS Canada, Inc.\", ..." },
{ "Sort_No": 2, "Response_Code": "CHUNK", "Response_Data": "...rest of the diagnostic JSON...}" },
{ "Sort_No": 3, "Response_Code": "RESP.DECODE", "Response_Data": "{\"return_value\":\"...\",\"type\":\"Employee\", ..." },
{ "Sort_No": 4, "Response_Code": "RESP.SIGNIN", "Response_Data": "{\"Time_Card_Header_No\":\"TC000123\",\"Employee_No\":\"EMP001\", ..." },
{ "Sort_No": 5, "Response_Code": "CHUNK", "Response_Data": "...rest of the sign-in JSON...}" }
]
}
Keep Employee_No, Time_Card_Header_No and Client_Config_No from RESP.SIGNIN and send them with later actions.
Start time on a selected dispatch row
GET BASE_URL/Company('CRONUS Canada, Inc.')/TCMServerBarcode?$filter=
Input_Action_Type_Code eq 'MENUITEM' and
Input_Action_Data eq 'ClockOn' and
Input_Config_No eq 'CFG000001' and
Input_Employee_No eq 'EMP001' and
Input_Time_Card_No eq 'TC000123' and
Input_Screen_Code eq 'PROD_ORDER' and
Input_Address eq '192.168.123.45' and
Selected_Row_Key_1 eq 'RPO00123' and
Selected_Row_Key_2 eq '10000' and
Selected_Row_Key_3 eq '20'
Extend the server action
To change what the server action does, subscribe to the events in codeunit 23044144, SFI AL Hooks. Each event receives the SFI Action Response Buffer record, which carries the inputs as filters and collects the instructions.
| Event | When it runs |
|---|---|
OnBeforeHandleServerAction |
Before any action is handled. Set pbHandled to replace the standard handling. |
OnAfterHandleServerAction |
After the action is handled. Add or change instructions. |
OnBeforeHandleBarcodeScan |
Before a barcode is decoded. Can change the barcode or replace the handling. |
OnHandleBarcodeScan |
After decoding, with the employee, time card and configuration loaded. Set pbEventHandled to replace the standard handling. |
OnAfterHandleBarcodeScan |
After a barcode scan is handled. |
OnBeforeHandleMenu |
Before a menu action is handled. Set pbHandled to replace the standard handling. |
OnAfterHandleMenu |
After a menu action is handled. |
To add instructions, use codeunit 23044141, SFI Action Response Builder, for example AddMessageResponse, AddErrorResponse or AddReloadTimeCardResponse. It handles the response codes and chunking for you.
Troubleshooting tips
- To test the round trip without changing data, send a
BARCODE.SCANwhose data containsTESTfollowed by a keyword, such asTESTMSG(a message),TESTERR(an error),TESTCONF(a confirmation),TESTLOCK(lock the screen) orTESTVTIME(switch to the time card). - If a service is not found, check its name, object type, object ID and Published setting on the Business Central Web Services page.