QBOID Confidential and Proprietary Information
Perceptor products provide 2 different sets of APIs that would cover different use case scenarios:
In addition, Perceptor products place at the disposal the following features:
Supported applications
This documentation covers the following M2 applications developed and maintained by QBOID:
Item and Parcel Dimensioning App
Throughout this document, it will be referred to as Parcel
This application enables the automatic measurement of the length, width, and height of both cuboidal and irregular-shaped items and parcels. It can optionally integrate with Bluetooth scales for seamless weight acquisition.
When the M2 device is connected to the S1 accessory, the same application is used for operation.
Pallet Dimensioning App
Throughout this document, it will be referred to as Pallet
This application automatically computes the dimensions of a pallet (length, width, and height) by analyzing individual faces. This method allows dimensioning even when the entire pallet is not fully visible from a single perspective.
The QBOID equipment responsible for generating dimensioning records. It can be either a Perceptor M2 or S1.
The system that receives and processes dimensioning records from the QBOID device.
A dimensioning record is a structure containing the information about a single item for either the WiFi or the Intent APIs. It is generally formatted as a JSON
string with a structure like the following:
{ "timestamp": "2021\/02\/14 07:19:38", "l": 195, "w": 165, "h": 72, "weight": 7709, "barcode": "845973030506", "shape": "Cuboidal", "device": "FH0402211100001", "note": "", "attributes": { "hazmat": "true" }, "image": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gIoSUNDX1BST0ZJTEU..." }
Field | Format | Description |
---|---|---|
timestamp |
string yyyy/MM/dd HH:mm:ss |
UTC timestamp using the Device time. Hour format is (0-23). |
l |
int |
Length of the item in mm. Length is defined as the biggest among the 2 measurements parallel to the ground plane. Parcel When the option Mandatory dimensioning is disabled, this field will be set to -1 if any dimensional field (l ,w ,h ) is missing. |
w |
int |
Width of the item in mm. Width is defined as the smallest among the 2 measurements parallel to the ground plane. Parcel When the option Mandatory dimensioning is disabled, this field will be set to -1 if any dimensional field (l ,w ,h ) is missing. |
h |
int |
Height of the item in mm. Height is defined as the measurement orthogonal to the ground plane. Parcel When the option Mandatory dimensioning is disabled, this field will be set to -1 if any dimensional field (l ,w ,h ) is missing. |
weight |
int (Optional) |
Weight of the item in g (grams). |
barcode |
string |
|
shape |
string |
Currently supported values are Irregular and Cuboidal . Additional shapes will be supported in the future. Filled only by the Parcel App. When the option Mandatory dimensioning is disabled, this field will be set to an empty String if dimensional information is missing. |
device |
string |
Device serial number. Same as shown in Settings -> System -> About Phone -> Status -> Serial number . |
note |
string |
User-composed alphanumeric note string. |
attributes |
map(string->string) {} when empty |
Contains the values assigned using the attributes buttons. Attribute buttons are fully customizable; any arbitrary combination of key/value may be present. |
image |
string PNG/JPEG base64 image (Optional) |
Full resolution color image with bounding box drawn on top. Can be enabled/disabled in settings. The default image format is JPEG , while PNG can be selected in the application settings. (See WiFi API Settings for more info) |
imagecolor |
string PNG/JPEG base64 image (Optional) |
Full resolution color image without bounding box drawn on top. Can be enabled/disabled in settings. The default image format is JPEG , while PNG can be selected in the application settings. (See WiFi API Settings for more info) |
imageseg |
string PNG/JPEG base64 image (Optional) |
Color image cropped to show the dimensioned object. Used only by the Parcel App. Can be enabled/disabled in settings. The background can be configured to be transparent. The default image format is JPEG , but PNG may be used depending on the application settings for format and transparency. (See WiFi API Settings for more info) |
String fields are escaped as per JSON standard, more specifically:
Input | Output |
---|---|
New Line |
\n |
\ |
\\ |
/ |
\/ |
Carriage return |
\r |
Tab |
\t |
Images are encoded in the JSON request as a Data URI scheme with a base64 encoding adhering RFC-2045.
Following is an example of an encoded image:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAHklEQVR42mP8z8AARNQDjKMGjho4auCogaMGjlQDAUwCJ+0NBcXlAAAAAElFTkSuQmCC Note: Previous string can be copied and pasted to browser address bar to visualize the image.
Note: RFC-2045 specification requires that: The encoded output stream must be represented in lines of no more than 76 characters each.. For that reason, the encoded images will contain line breaks (i.e.: \n
) that must be ignored by the decoding software.
This is a REST-like API where a JSON message is sent to a local or internet HTTP endpoint, and is designed to be familiar to developers doing client server web development.
Once the scan event is completed, either manually by an operator specific key press, or automatically by QBOID software, the dimensioning record is immediately queued up for offloading to a remote resource, e.g. a WMS system or manifesting software.
The Device will send a POST
request with a JSON
body to the HTTP
endpoint defined in its configuration expecting a 200-299
HTTP response code.
There are two groups of settings that can impact the data transmitted through the WiFi API:
Acquisition
is a collection of parameters that will affect the data acquisition during the dimensioning process. Adjusting these settings will not affect the sequences already collected, unless otherwise specified.WiFi API
is a collection of parameters for configuring the data transmitted over WiFi. Changing these settings will affect the sequences already collected, unless otherwise specified.Acquisition
settings
Added in 2.4.0
Acquisition parameters can be configured in the M2
applications.
Entry | Default | App | Description |
---|---|---|---|
Settings > Developers Settings > Color Resolution |
0.3MP |
Parcel | Defines which camera should be used for acquiring the color image.0.3MP : will collect a 640x480 image with the low-resolution sensor, which is also used for the preview. The camera is located in the middle of the main sensor bar.13MP : will collect a 4160x3120 image with the high-resolution camera situated beneath the main sensor bar and near the flashlight.Note: Sequences captured at a resolution of 13MP will consume approximately 6MB of storage space, whereas 0.3MP sequences will only use around 1MB of storage space. |
Settings > Data Settings > Acquisition > Compute Alpha Channel |
disabled |
Parcel | If enabled, a foreground/background image segmentation will be performed on the result and pixels that belong to the background will have the alpha channel set to 0 on the segmented image (i.e.: imageseg field).The image format for imageseg will be forced to PNG when Compute Alpha Channel is enabled regardless of the value of Use JPEG format |
WiFi API
settings
Optional fields, image format and endpoint can be configured in the M2
applications in the section: Settings -> Data Settings -> WiFi API
.
Entry | Default | App | Description |
---|---|---|---|
API endpoint |
http://192.168.7.100 :5000/newEntry |
Parcel Pallet | Define the URL for the HTTP/HTTPS endpoint. |
Upload timeout |
5 |
Parcel Pallet | Define the connection and data read timeout in seconds. |
Upload result image |
disabled |
Parcel Pallet | Enable/Disable the image field. |
Upload color image |
disabled |
Parcel Pallet | Enable/Disable the imagecolor field. |
Upload segmented image |
disabled |
Parcel Pallet | Enable/Disable the imageseg field. |
Use JPEG format |
enabled |
Parcel Pallet | When enabled , JPEG format will be used for image , imagecolor and imageseg fields when transferred over WiFi.PNG will instead be used if the option is disabled .imageseg will be forced to PNG when Compute Alpha Channel is enabled, regardless of the value of Use JPEG format .Note: To conserve resources and limit bandwidth usage, the resolution of PNG images will be capped at 1MP when transferred over WiFi. Such a limitation will be relevant only if 13MP is selected as Color Resolution . A pop-up will inform the user about the 1MP limitation when 13MP+PNG configuration is selected. |
Custom request header
settingsAdded in 2.4.2
Under the section Settings -> Data Settings -> WiFi API -> Custom request header
, the HTTP/HTTPS
headers can be customized.
Entry | App | Description |
---|---|---|
Authorization header |
Parcel Pallet | Define the value for the Authorization HTTP/HTTPS header key. This parameter can be used to specify a Bearer Token used to authenticate and authorize access to a protected resource. |
User-Agent header |
Parcel Pallet | Define the value for the User-Agent HTTP/HTTPS header key. |
Custom headers JSON |
Parcel Pallet | Define a JSON string where a set of custom key-value HTTP/HTTPS headers can be defined. E.g.:{"p1":"a", "p2":3} |
HTTP request is configured as follows:
Property | Value |
---|---|
Request Method |
POST |
Content-Type |
application/json; utf-8 |
Accept |
application/json |
A response code in the range 200-299
is expected as a response.
POST /newEntry HTTP/1.1 Content-Type: application/json; utf-8 Accept: application/json User-Agent: Dalvik/2.1.0 (Linux; U; Android 8.1.0; Scorpio Build/V008R001) Host: 192.168.7.103:5000 Connection: Keep-Alive Accept-Encoding: gzip Content-Length: 199 {"timestamp":"2021\/02\/25 02:16:25","l":266,"w":203,"h":72,"weight":6807,"barcode":"X001SS387V","shape":"Irregular","device":"FH0402211100001","note":"QWERTY","attributes":{"batt":"false","hazmat":"true"}}
Added in 2.1.0
HTTP over TLS
can be used by simply defining https
as protocol in the URL of the endpoint.
If the server's SSL certificate was issued by a well-known Certificate Authority (CA), no further action is necessary.
A self-signed certificate is one that is signed with the servers own private key instead of being signed by a CA.
If the server is using a self-signed certificate, adding the certificate to the Perceptor M2 (see link) will be necessary. Failure to do so will throw the following error when the M2 is attempting to communicate with the server:
javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
Following is an example on how to create a self-signed certificate using OpenSSL command line tool
openssl req -x509 -newkey rsa:4096 -keyout self_key.pem -out self_cert.pem -sha256 -days 365 -nodes \ -subj "/C=US/ST=California/L=San Jose/O=Qboid/OU=TestingWebService/CN=testing.qboid.ai/emailAddress=info@qboid.ai" \ -addext "subjectAltName=DNS:testing.qboid.ai"
self_cert.pem
) to the M2 using the M2's Web Browser app, or from a PC over the M2's USB-C port.Settings -> Security -> Encryption & Credential -> Install from storage
Certificate Name
VPN and apps
is selected as Credential use
QBOID provides a testing www server that can be used for experimenting with the different API configurations/protocols.
The test server can be reached through a reverse proxy that's exposing the same service with different combinations of protocols and certificates. All endpoints refer to the same service, so data pushed over https
will be visible on the http
page and vice versa.
Disclaimer
Before using the server, please review the following:
Protocol | Web Visualization URL | M2 Endpoint |
---|---|---|
HTTP | http://testing.qboid.ai:5001/ | http://testing.qboid.ai:5001/newEntry |
HTTPS (self signed) | https://testing.qboid.ai:5002/ | https://testing.qboid.ai:5002/newEntry |
HTTPS (public CA) | https://testing.qboid.ai:5003/ | https://testing.qboid.ai:5003/newEntry |
Web Visualization URLs
can be opened with any PC or Phone browser. The page will wait for 120s for incoming data sent by any M2 device that's currently using a Testing Server Endpoint.
QR code link to HTTP Web Visualization URL
Testing server endpoints can be configured on the M2 settings in Data Settings -> API Endpoint
.
Click on Use Testing Server
and select the desired combination of Protocol and certificate.
For using the self-signed certificate:
Disclaimer: The code is for illustration and learning purposes only. It prioritizes simplicity over production-level robustness and should not be used in a production environment.
Code
from flask import Flask from flask import request import json app = Flask(__name__) @app.route("/newEntry", methods=['POST']) def newEntry(): data = json.loads(request.data) print("Barcode: %s Size: %ix%ix%i" % (data["barcode"], data["l"], data["w"], data["h"])) return "" if __name__ == "__main__": app.run(host = '0.0.0.0')
Output (2 dimensioning events of the same object)
Barcode: X001SS387V Size: 266x201x72
192.168.7.108 - - [24/Feb/2021 19:34:15] "POST /newEntry HTTP/1.1" 200 -
Barcode: X001SS387V Size: 267x200x72
192.168.7.108 - - [24/Feb/2021 19:36:00] "POST /newEntry HTTP/1.1" 200 -
For testing the previous code set the device endpoint to:
http://[HOST-IP]:5000/newEntry
where [HOST-IP] is the IP address of the PC running the code. E.g.: `192.168.7.100`
Code
import requests import json import random import string from datetime import datetime # To be changed according to the setup ENDPOINT = 'http://127.0.0.1:5000/newEntry' def rndString(minsize, maxSize): return ''.join(random.choices(string.ascii_uppercase + string.digits, k = random.randint(minsize, maxSize))) def createJsonEntry(): data = {} data['timestamp'] = datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') data['l'] = random.randint(10,500) data['w'] = random.randint(10,500) data['h'] = random.randint(10,500) data['weight'] = random.randint(10,50000) data['barcode'] = rndString(2,20) data['shape'] = 'Irregular' data['device'] = rndString(8,8) data['note'] = rndString(0,20) attributes = {} for i in range(random.randint(0, 4)): attributes[rndString(3,5)] = rndString(3,5) data['attributes'] = attributes strjson = json.dumps(data) # Explicitly escaping "/" since python json library is not doing it by default strjson = strjson.replace('/', '\/') return strjson if __name__ == "__main__": jsonMsg = createJsonEntry() print(jsonMsg) headers = {'content-type': 'application/json; utf-8', 'Accept' : 'application/json'} try: response = requests.post(ENDPOINT, data=jsonMsg, headers=headers) if (response.ok): print('Success') else: print('Error. Endpoint %s returned code: %i' % (ENDPOINT, response.status_code)) except Exception as e: print('Error while sending request to endpoint: %s' % ENDPOINT)
Output (Success)
{"timestamp": "2021\/02\/25 05:02:08", "l": 56, "w": 419, "h": 68, "weight": 46405, "barcode": "KPGVETAS", "shape": "Irregular", "device": "Y3S9JH1D", "note": "3RI9CKE2N", "attributes": {"FJ4": "U1HC6"}}
Success
Output (Endpoint returned an error)
{"timestamp": "2021\/02\/25 05:04:52", "l": 494, "w": 430, "h": 290, "weight": 31464, "barcode": "GE7WJ83B3PNJBN", "shape": "Irregular", "device": "DO1KF5ZI", "note": "A3KYJ", "attributes": {"SVRAJ": "HMXK"}}
Error. Endpoint http://127.0.0.1:5000/newEntry returned code: 405
Output (Endpoint unreachable)
{"timestamp": "2021\/02\/25 05:06:08", "l": 449, "w": 129, "h": 432, "weight": 2339, "barcode": "UUYXJ9Y447M", "shape": "Irregular", "device": "BO2X6TD2", "note": "B71U", "attributes": {"AF7Y": "BX44"}}
Error while sending request to endpoint: http://127.0.0.1:5000/newEntry
Code
from flask import Flask from flask import request import json app = Flask(__name__) @app.route("/newEntry", methods=['POST']) def newEntry(): print("Authorization: %s" % request.headers.get('Authorization', "")) if request.headers.get("Authorization", "") != "qboid": return "Authorization error!", 401 data = json.loads(request.data) print("User-Agent: %s" % request.headers.get('User-Agent')) print("Headers: %s" % str(dict(request.headers))) print("Barcode: %s Size: %ix%ix%i" % (data["barcode"], data["l"], data["w"], data["h"])) return "" if __name__ == "__main__": app.run(host = '0.0.0.0')
Output (Success)
Barcode: X001SS387V Size: 266x201x72
192.168.7.108 - - [13/Mar/2023 14:19:57] "POST /newEntry HTTP/1.1" 200 -
Output (Wrong Authorization)
192.168.7.108 - - [13/Mar/2023 14:19:21] "POST /newEntry HTTP/1.1" 401 -
For testing the previous code set the device end point to:
http://[HOST-IP]:5000/newEntry
where [HOST-IP] is the IP address of the PC running the code. E.g.: `192.168.7.100`
And set the Authorization header to:
qboid
Added in 2.3.0
This is an Android Intent based API where a local application can invoke the QBOID M2 applications and optionally retrieve a dimensioning record.
The API is designed to work with Android Applications following the Android's Intent paradigm, but it also provides equivalent functionalities even to Web Applications running in a common Web Browser.
QBOID M2 applications can be invoked using an explicit intent with the following parameters:
Item and Parcel Dimensioning App | Pallet Dimensioning App | |
---|---|---|
Package | ai.qboid.glapp |
ai.qboid.palletsize |
Class | ai.qboid.glapp.DimActivity |
ai.qboid.palletsize.PalletActivity |
Optionally, an action
and a JSON configuration
for that action
can be specified in the Extra Bundle
Field | Format | Description |
---|---|---|
action |
string (optional) |
Action to be performed by the app. If not specified, the app will simply open the main activity |
config |
JSON string (optional) |
Configuration to be used for the requested action. If not specified, default values would be used as specified in the documentation for each action |
dim
M2 applications will be invoked for acquiring a single Dimensioning Record. The workflow will return to the caller once the user confirms/saves the data for the current item. Application settings, upload queue and history won't be accessible until the action is completed or aborted.
Field | Format | Default | App | Description |
---|---|---|---|---|
target |
string |
queue |
Parcel Pallet | Possible values are queue , callback or none . queue : The record will be added to the standard QBOID application upload queue. The default WiFi API settings will be used. The upload may not happen immediately, depending on settings and network availabilitycallback : The record won't be added to the QBOID application upload queue nor the History but it will instead be sent immediately to the endpoint and the application won't return to the caller until the record is fully transmitted or an error occurrednone : The record won't be added to the QBOID application upload queue nor to the History. |
endpoint |
string |
As defined in Settings > Data Settings > WiFi API > API endpoint |
Parcel Pallet | Used when target=callback . Define the URL for the HTTP/HTTPS endpoint. |
usejpg |
boolean |
true |
Parcel Pallet | Used when target=callback . If true , JPEG format will be used for image , imagecolor and imageseg fields, PNG will be used otherwise. Additional constraints apply depending on the other Acquisition and WiFi API settings. (See WiFi API Settings for more info) |
enableimage |
boolean |
false |
Parcel Pallet | Used when target=callback . Enable/Disable the image field for the callback to the endpoint . |
enableimageseg |
boolean |
false |
Parcel Pallet | Used when target=callback . Enable/Disable the imageseg field for the callback to the endpoint |
enableimagecolor |
boolean |
false |
Parcel Pallet | Used when target=callback . Enable/Disable the imagecolor field for the callback to the endpoint |
headerauthorization |
string |
As defined in Settings > Data Settings > WiFi API > API endpoint > Custom request header |
Parcel Pallet | Used when target=callback . Defines the value for the Authorization HTTP header field. |
headeruseragent |
string |
As defined in Settings > Data Settings > WiFi API > API endpoint > Custom request header |
Parcel Pallet | Used when target=callback . Defines the value for the User-Agent HTTP header field. |
headercustom |
JSON object |
As defined in Settings > Data Settings > WiFi API > API endpoint > Custom request header |
Parcel Pallet | Used when target=callback . Defines a set of key-value pairs of strings for sending custom HTTP header fields.Example: {"Proxy-Authorization":"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==","Cache-Control":"no-cache"} |
prefill |
JSON object |
null |
Parcel | Added in 2.6.6 Pre-fills the specified fields in the M2 interface upon opening. The required format is a JSON object structured according to the Dimensioning Record. Although the full dimensioning record can be provided, only the following fields will be processed:
The accepted data types and units for each field are consistent with those defined in the Dimensioning Record. |
gridimage_enable |
boolean |
true |
Pallet | Used when target=callback . If set to true , image and imagecolor will display all recorded angles in a single image using a grid format. If set to false , only the first viewpoint will be used. |
gridimage_printdim |
boolean |
true |
Pallet | Used when target=callback and gridimage_printdim=true . If set to true , measured dimensions will be displayed on each viewpoint in the grid. They are positioned in the top left corner of each viewpoint. |
gridimage_customunits |
boolean |
false |
Pallet | Used when target=callback , gridimage_printdim=true , and gridimage_printdim=true . If set to true , the dimensions reported inside image will reflect the current unit, precision, and rounding settings. Otherwise, dimensions will be reported as per the standard API format (mm ), with no rounding and a precision of 1. |
When the caller Activity is resumed, an Intent Result will be returned with a resultCode
.
If the user returned to the caller activity without scanning an item (i.e.: Some of the mandatory fields needed for record creation, as indicated by the application configuration, are missing), the returned values would be resultCode = 0
and a null
Intent.
If the user correctly scanned an item, the caller will receive a resultCode = -1
and an Intent with the Extra Bundle containing the result of the task.
Returned Extra Bundle Structure
Field | Format | Description |
---|---|---|
res |
int |
0 : If an object record creation task succeeded <0 : If an error occurred |
sent |
boolean |
Present only when target is set to callback . If true , the dimensioning record has been successfully sent via the API, false otherwise. |
record |
JSON string |
The Dimensioning Record as defined here, with the difference that the image fields (i.e.:image ,imagecolor and imageseg ) will contain the absolute path on the sdcard for the images instead of the base64 encoding of the content. Note: The WiFi API settings and the action configuration will not affect the content of the record. The path to the images will always be returned, if available, in PNG format. |
Example of record
field in the Extra Bundle
{ "timestamp": "2022\/10\/05 23:06:45", "l": 319, "w": 203, "h": 421, "barcode": "TBA065003602504", "shape": "Irregular", "device": "FH0402211700146", "note": "Comment", "attributes": { "ovpk": "true", "batt": "false", "frgl": "true", "hazmat": "true" }, "image": "\/sdcard\/qboid\/data\/2022_10_05\/2022_10_05_23_06_15\/Frames\/result_img_1.png", "imageseg": "\/sdcard\/qboid\/data\/2022_10_05\/2022_10_05_23_06_15\/Frames\/color0_segmented_1.png", "imagecolor": "\/sdcard\/qboid\/data\/2022_10_05\/2022_10_05_23_06_15\/Frames\/color0_1.png" }
Following is a description of the most common use cases for the Android Intent API integration and how they can be implemented using the provided API. All these workflows apply to both the Parcel and the Pallet App.
Scenario
The customer uses several apps and has his own Launcher Application. Once the M2 Dimensioning App is opened, multiple sequences may be collected, settings may be changed, and data offloading can be performed over WiFi using the settings defined in the application.
Implementation
The M2 Dimensioning App will be launched with an Intent with no action
and no other Extra defined in the Bundle.
Scenario
The main workflow is directed by a Third Party app that may require the collection of dimensions, picture and/or other metadata for an item during the workflow. The local Third Party app doesn't require immediate feedback, and there is no hard constraint on when the data needs to be sent over WiFi. Instead, we want to be able to buffer the network requests in case of a slow network or no connection.
Implementation
We want to invoke an intent with action=dim
and a config
with target=queue
(Note: queue
is the default value so the config
field can be omitted).
The M2 API settings needs to be configured with the correct endpoint
.
The endpoint
needs to be able to associate the received record to the correct entry in the workflow.
Scenario
The main workflow is directed by a Third Party app that may require the collection of dimensions, picture and/or other metadata for an item during the workflow. The app would need to use and/or display the information generated by the M2 Dimensioning App as soon as it regains focus. Additionally, the caller App wants to bypass the default Qboid configuration and keep the acquired sequences away from the standard Upload Queue and History defined in the Qboid app.
Implementation
We want to invoke an intent with action=dim
and we need to properly construct the config
attribute.
If the caller is an Android app, the target
would generally be set to none
(or callback
if a remote endpoint
has to be notified) and the Dimensioning Record would be read from the Intent Returned Value.
If the caller is a Web App, the target
has to be set to callback
and the proper endpoint
should be set to the wanted URL. Generally the endpoint
will be defined on the same Web Server that is running the Web Application and would contain the information to identify the current request and/or session. Once the focus is returned to the Web App, it will take care of retrieving the Dimensioning Record for the Web Server.
This section provides sample code on how to invoke the Explicit Intent, and how to receive the Intent Result for the different typical use cases. Examples are in Java
using Activity.onActivityResult. Equivalent code may be written in Kotlin
and/or using ActivityResultContracts. Changing the package and class name is sufficient to make it work with the Parcel App or the Pallet App.
A) Open an M2 Dimensioning App
For Invoking the M2 Dimensioning App with no action we can simply define the Explicit Intent and call it with startActivity
// A) Open the M2 Item and Parcel Dimensioning App Intent intent = new Intent(); ComponentName cName = new ComponentName("ai.qboid.glapp", "ai.qboid.glapp.DimActivity"); // For the Pallet Dimensioning App use: // ComponentName cName = new ComponentName("ai.qboid.palletsize", "ai.qboid.palletsize.PalletActivity"); intent.setComponent(cName); context.startActivity(intent);
B) Trigger a single dimensioning operation
An action=dim
can be set as Extra simply adding intent.putExtra("action", "dim");
to the previous example
// B) Trigger a single dimensioning operation with the M2 Item and Parcel Dimensioning App Intent intent = new Intent(); ComponentName cName = new ComponentName("ai.qboid.glapp", "ai.qboid.glapp.DimActivity"); // For the Pallet Dimensioning App use: // ComponentName cName = new ComponentName("ai.qboid.palletsize", "ai.qboid.palletsize.PalletActivity"); intent.setComponent(cName); intent.putExtra("action", "dim"); // Select dim as action context.startActivity(intent);
C) Request a dimensioning operation and retrieve the result
Setting the target=none
for the config
field can be done using a JSONObject
instance.
Additionally, for receiving the result, the M2 Dimensioning Activity needs to be started with startActivityForResult, that will take a requestCode
argument to help identify the request that triggered the result being returned.
onActivityResult will be invoked when the called Activity is closed and it will contain the data generated by the M2 Dimensioning App.
// C) Request a dimensioning operation and retrieve the result with the M2 Item and Parcel Dimensioning App Intent intent = new Intent(); ComponentName cName = new ComponentName("ai.qboid.glapp", "ai.qboid.glapp.DimActivity"); // For the Pallet Dimensioning App use: // ComponentName cName = new ComponentName("ai.qboid.palletsize", "ai.qboid.palletsize.PalletActivity"); intent.setComponent(cName); intent.putExtra("action", "dim"); // Select dim as action // Add config field with target->none to the Intent Extras JSONObject json = new JSONObject(); try { json.put("target", "none"); intent.putExtra("config", json.toString()); } catch (JSONException e) {} // Start activity and wait for result context.startActivityForResult(intent, REQUEST_CODE); // REQUEST_CODE can be any number and it's used to identify the result. //! Process the result obtained once the called Activity is closed protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE && data != null && resultCode == -1){ String recordJson = data.getStringExtra("record"); // -- PROCESS HERE THE DIMENSIONING RECORD -- } }
A Web Application can launch an Android Application with an Intent as described in: Android Intents with Chrome.
The M2 Applications are configured to receive a BROWSABLE
Intent with scheme intentapi
on their activities.
Below are a few examples on how to invoke the Explicit Intent, and how to receive the Intent Result for the different typical use cases. Examples are provided in Python with Flask + Javascript. Equivalent code may be written in different programming languages and different Web Server. The examples illustrate the usage for the Parcel App, but the same applies to the Pallet App.
A) Open the M2 Item and Parcel Dimensioning App
This use case may be simply implemented adding a link (or a button) pointing to the following URI: intent://#Intent;scheme=intentapi;package=ai.qboid.glapp;end
HTML example:
<a href="intent://#Intent;scheme=intentapi;package=ai.qboid.glapp;end"> A) Open the M2 Item and Parcel Dimensioning App</a>
B) Trigger a single dimensioning operation
The URI from the previous example can be altered using the syntax for defining String extras to configure dim
as action
: S.action=dim
HTML example:
<a href="intent://#Intent;scheme=intentapi;package=ai.qboid.glapp;S.action=dim;end"> B) Trigger a single dimensioning operation</a>
C) Request a dimensioning operation and retrieve the result
Web Applications are unable to receive the Intent Returned value when running in a Web Browser, so a result can be obtained instructing the M2 Dimensioning App on how to send data to the Web Server and then retrieving that information when the Browser Tab is resumed. This workflow can be split in the following steps (diagram):
The goal would be to generate an intent URI with a configuration where target=callback
and the endpoint
is set to a value generated by the current Web Application.
Here is an example of the config
JSON string where the server is running at the address http://192.168.1.164:5000
and /callback
is the endpoint handling the record coming from M2 Dimensioning App:
{"target":"callback","endpoint":"http://192.168.1.164:5000/callback"}
The config
String would then need to be converted to the correct URI encoding using a library like urllib
, obtaining something like:
%7B%22target%22%3A%22callback%22%2C%22endpoint%22%3A%22http%3A//192.168.1.164%3A5000/callback%22%7D
The encoded config
can then be added to the URI in the previous example prepending it with the attribute: S.config=
. The final result would look like:
intent://#Intent;scheme=intentapi;package=ai.qboid.glapp;S.action=dim;S.config=%7B%22target%22%3A%22callback%22%2C%22endpoint%22%3A%22http%3A//192.168.1.164%3A5000/callback%22%7D;end
Following is the sample Python + Flask code for generating the URI:
config = '{"target":"callback","endpoint":"%scallback"}' % request.url_root intent = "intent://#Intent;scheme=intentapi;package=ai.qboid.glapp;S.action=dim;S.config=%s;end" % urllib.parse.quote(config)
Once the user confirms/saves the data for the current item, the dimensioning record will be sent to the endpoint
as defined by the caller. The application would then close and return the focus to the browser running the Web App.
Once the Tab with the Web Application is resumed, the server needs to be queried to retrieve the information sent by the M2 Dimensioning App. This can be done by fetching the data from an endpoint on the server as soon as the Web Document becomes visible again.
Following is a javascript
example that detects when document.visibilityState
is changed to visible
and invokes the update()
function that will be implemented to retrieve the information from the server.
<script> document.addEventListener("visibilitychange", () => { if (document.visibilityState === 'visible') update(); }); function update() { // Query the server for the result } </script>
Web Application use case C) diagram
|
We are presenting here an example in Python with Flask + Javascript, summarizing the 3 uses cases discussed before both for the Parcel App and the Pallet App. It includes code to be used in an HTML template and the endpoints to be defined in Flask. We finally provide a fully self-contained Python app.
Disclaimer: The code is for illustration and learning purposes only. It prioritizes simplicity over production-level robustness and should not be used in a production environment.
HTML Template (main.html)
A)
, B)
, and C)
for the Parcel AppD)
, E)
, and F)
) for the Pallet App/size
when the Tab is resumed and print the result in a <pre>
element.<a href="intent://#Intent;scheme=intentapi;package=ai.qboid.glapp;end">A) (Parcel) Open M2 Dimensioning App</a> <hr> <a href="intent://#Intent;scheme=intentapi;package=ai.qboid.glapp;S.action=dim;end">B) (Parcel) Trigger a single dimensioning operation</a> <hr> <a href="{{intent_c}}">C) (Parcel) Request a dimensioning operation and retrieve the result</a> <hr> <a href="intent://#Intent;scheme=intentapi;package=ai.qboid.palletsize;end">D) (Pallet) Open M2 Dimensioning App</a> <hr> <a href="intent://#Intent;scheme=intentapi;package=ai.qboid.palletsize;S.action=dim;end">E) (Pallet) Trigger a single dimensioning operation</a> <hr> <a href="{{intent_f}}">F) (Pallet) Request a dimensioning operation and retrieve the result</a><br> <pre id="result"></pre> <script> document.addEventListener("visibilitychange", () => { if (document.visibilityState === 'visible') update(); }); function update() { var xhttp = new XMLHttpRequest(); xhttp.open("GET", "size", true); xhttp.onload = function () { let responseTxt = xhttp.responseText; document.getElementById('result').innerHTML = responseTxt; }; xhttp.onerror = function () { document.getElementById('result').innerHTML = "Request Error"; }; xhttp.send(); } </script>
Python Web Server
main.html
at the endpoint /
./callback
and stores it locally./size
.latestResponse = "---" @app.route("/", methods=['GET']) def main(): config = '{"target":"callback","endpoint":"%scallback"}' % request.url_root intent_c = "intent://#Intent;scheme=intentapi;package=ai.qboid.glapp;S.action=dim;S.config=%s;end" % urllib.parse.quote(config) intent_f = "intent://#Intent;scheme=intentapi;package=ai.qboid.palletsize;S.action=dim;S.config=%s;end" % urllib.parse.quote(config) res = render_template("main.html", intent_c = intent_c, intent_f = intent_f) return res @app.route("/callback", methods=['POST']) def callback(): global latestResponse data = json.dumps(json.loads(request.data), indent = 4) latestResponse = data return "" @app.route("/size", methods=['GET']) def size(): global latestResponse retSize = latestResponse latestResponse = "---" return retSize
Note: In this example, for simplicity, the case where multiple sessions can be established with the server is not supported. In an actual production implementation the /callback
and /size
endpoints would require additional variables to properly identify a device and/or session.
Full python code with embedded HTML
from flask import Flask, render_template_string,request,render_template import json import urllib.parse app = Flask(__name__) main_html = """ <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <h3>Perceptor Android API Test</h3> <a href="intent://#Intent;scheme=intentapi;package=ai.qboid.glapp;end">A) (Parcel) Open M2 Dimensioning App</a> <hr> <a href="intent://#Intent;scheme=intentapi;package=ai.qboid.glapp;S.action=dim;end">B) (Parcel) Trigger a single dimensioning operation</a> <hr> <a href="{{intent_c}}">C) (Parcel) Request a dimensioning operation and retrieve the result</a> <hr> <a href="intent://#Intent;scheme=intentapi;package=ai.qboid.palletsize;end">D) (Pallet) Open M2 Dimensioning App</a> <hr> <a href="intent://#Intent;scheme=intentapi;package=ai.qboid.palletsize;S.action=dim;end">E) (Pallet) Trigger a single dimensioning operation</a> <hr> <a href="{{intent_f}}">F) (Pallet) Request a dimensioning operation and retrieve the result</a><br> <pre id="result"></pre> <script> document.addEventListener("visibilitychange", () => { if (document.visibilityState === 'visible') update(); }); function update() { var xhttp = new XMLHttpRequest(); xhttp.open("GET", "size", true); xhttp.onload = function () { let responseTxt = xhttp.responseText; document.getElementById('result').innerHTML = responseTxt; }; xhttp.onerror = function () { document.getElementById('result').innerHTML = "Request Error"; }; xhttp.send(); } </script> </body> </html> """ latestResponse = "---" @app.route("/", methods=['GET']) def main(): config = '{"target":"callback","endpoint":"%scallback"}' % request.url_root intent_c = "intent://#Intent;scheme=intentapi;package=ai.qboid.glapp;S.action=dim;S.config=%s;end" % urllib.parse.quote(config) intent_f = "intent://#Intent;scheme=intentapi;package=ai.qboid.palletsize;S.action=dim;S.config=%s;end" % urllib.parse.quote(config) res = render_template("main.html", intent_c = intent_c, intent_f = intent_f) return res @app.route("/callback", methods=['POST']) def callback(): global latestResponse data = json.dumps(json.loads(request.data), indent = 4) latestResponse = data return "" @app.route("/size", methods=['GET']) def size(): global latestResponse retSize = latestResponse latestResponse = "---" return retSize if __name__ == "__main__": app.run(host = '0.0.0.0')
QBOID provides a testing server with http
and https
endpoints running a live version of the sample Web Application described in this section.
Disclaimer
Before using the server, please review the following:
Testing Server URLs
Protocol | URL | QR code |
---|---|---|
HTTP | http://testing.qboid.ai:5001/api | |
HTTPS | https://testing.qboid.ai:5003/api |
Added in 2.5.0
The purpose of this functionality is to facilitate the export and import of M2 settings, also referred to as preferences, allowing them to be easily applied across multiple devices as well.
To export the configuration of an M2 DImensionig App, the specific button placed under Settings -> Import/Export Settings -> Export settings to local file
can be used. Once clicked, this will save the current device configuration to the file /sdcard/qboid/preferences.json
, for the Parcel App, and to the file /sdcard/qboid/pallet_preferences.json
for the Pallet App.
There are two main workflows to import a previously saved configuration into an M2 device:
Settings -> Import/Export Settings
and click the Import settings from local file
button.Choose File
to select the JSON file that needs to be encoded as a QR code. If the file is a valid configuration, a QR code will be displayed on the webpage. The generated QR code can then be downloaded as a PNG or SVG image. The configuration can be loaded into the M2 device simply scanning the QR code from the main M2 application window or from Settings -> Import/Export Settings
.When exporting to a file or generating a QR code, only the settings that differ from the default values are exported.
The behavior when importing preferences is determined by the restoredefault
entry in the JSON:
true
, all preferences NOT defined in the QR code/file will be reset to their default values.false
, preferences not defined in the QR code/file will remain unchanged.There is one exception to this rule for the configuration of Attributes (i.e., the 4 soft keys defined on the home screen). This exception will be discussed in more detail in the next section.
Since version 2.6.6
, with the introduction of different types for the four attributes on the home screen, more advanced logic has been introduced for exporting and importing attribute configurations to fully support the use case where a QR code is used to reconfigure all attribute entries on the fly.
Here’s how the logic works:
When exporting an attribute, if any value (key
, type
, or values
) has been changed from the default, the entire configuration of that attribute will be exported, regardless of whether some values are still set to default.
When importing an older QR code/file (version <2.6.6
), if any attribute is modified, the other preferences for that attribute that were not explicitly set will be restored to their default values.
Name | Type | Default value | Min version | App | Description |
---|---|---|---|---|---|
allow_empty_trash Settings pathApplication settings → Data Settings → History → Allow Empty Trash |
boolean |
false |
2.5.0 |
Parcel Pallet | Allow to empty the trash from records |
api_content_type Settings pathApplication settings → Data Settings → WiFi API → Custom request header → Content Type |
string |
2.6.7 |
Parcel Pallet | The content type to use when sending an API request | |
api_custom_headers Settings pathApplication settings → Data Settings → WiFi API → Custom request header → Custom headers JSON |
JSON string |
2.5.0 |
Parcel Pallet | The custom headers (specified as JSON key-value entries) to be used when sending an API request | |
api_endpoint Settings pathApplication settings → Data Settings → WiFi API → API endpoint |
string |
http://192.168.7.100:5000/newEntry |
2.5.0 |
Parcel Pallet | The API endpoint to upload the results |
api_header_authorization Settings pathApplication settings → Data Settings → WiFi API → Custom request header → Authorization header |
string |
2.5.0 |
Parcel Pallet | The Authorization header to use when sending an API request | |
api_header_useragent Settings pathApplication settings → Data Settings → WiFi API → Custom request header → User-Agent header |
string |
2.5.0 |
Parcel Pallet | The User-Agent header to use when sending an API request | |
api_upload_format_jpeg Settings pathApplication settings → Data Settings → WiFi API → Use JPEG format |
boolean |
true |
2.5.0 |
Parcel Pallet | Upload all the images in JPEG format when sending a record via API |
api_upload_grid Settings pathApplication settings → Data Settings → Grid layout output → Enable grid layout output |
boolean |
true |
3.2.0 |
Pallet | Upload images containing all the pallet PoV as a grid when sending a record via API |
api_upload_grid_custom_dims Settings pathApplication settings → Data Settings → Grid layout output → Custom units for grid layout |
boolean |
false |
3.2.0 |
Pallet | In the PoV grid images use the local application unit to display measured dimensions |
api_upload_grid_show_dims Settings pathApplication settings → Data Settings → Grid layout output → Add dimensions to grid layout |
boolean |
true |
3.2.0 |
Pallet | In the PoV grid images display the measured dimensions |
api_upload_img_color Settings pathApplication settings → Data Settings → WiFi API → Upload color image |
boolean |
false |
2.5.0 |
Parcel Pallet | Upload the color image when sending a record via API |
api_upload_img_result Settings pathApplication settings → Data Settings → WiFi API → Upload result image |
boolean |
false |
2.5.0 |
Parcel Pallet | Upload the result image when sending a record via API |
api_upload_img_seg Settings pathApplication settings → Data Settings → WiFi API → Upload segmented image |
boolean |
false |
2.5.0 |
Parcel Pallet | Upload the segmented image when sending a record via API |
api_upload_results Settings pathApplication settings → Data Settings → WiFi API → Realtime WMS upload |
boolean |
false |
2.5.0 |
Parcel Pallet | Realtime WMS upload after a completed dimensioning |
api_upload_timeout Settings pathApplication settings → Data Settings → WiFi API → Upload timeout |
numeric |
5 |
2.5.0 |
Parcel Pallet | The timeout in seconds to be used when sending an API request |
api_upload_unmetered Settings pathApplication settings → Data Settings → WiFi API → Upload on unmetered connections only |
boolean |
false |
2.5.7 |
Parcel Pallet | Upload on unmetered connections only |
attribute1_key Settings pathApplication settings → Data Settings → Configure Attributes → Attribute 1 → Key |
string |
2.5.0 |
Parcel Pallet | The key of the first attribute | |
attribute1_show_values Settings pathApplication settings → Data Settings → Configure Attributes → Attribute 1 → Show Values |
boolean |
false |
2.5.0 |
Parcel Pallet | Show the values of the first attribute |
attribute1_type Settings pathApplication settings → Data Settings → Configure Attributes → Attribute 1 → Type |
string |
softkey |
2.6.6 |
Parcel Pallet | The type of the first attribute. Allowed values: softkey , list , number |
attribute1_values Settings pathApplication settings → Data Settings → Configure Attributes → Attribute 1 → Values |
string |
2.5.0 |
Parcel Pallet | The values of the first attribute | |
attribute2_key Settings pathApplication settings → Data Settings → Configure Attributes → Attribute 2 → Key |
string |
2.5.0 |
Parcel Pallet | The key of the second attribute | |
attribute2_show_values Settings pathApplication settings → Data Settings → Configure Attributes → Attribute 2 → Show Values |
boolean |
false |
2.5.0 |
Parcel Pallet | Show the values of the second attribute |
attribute2_type Settings pathApplication settings → Data Settings → Configure Attributes → Attribute 2 → Type |
string |
softkey |
2.6.6 |
Parcel Pallet | The type of the second attribute. Allowed values: softkey , list , number |
attribute2_values Settings pathApplication settings → Data Settings → Configure Attributes → Attribute 2 → Values |
string |
2.5.0 |
Parcel Pallet | The values of the second attribute | |
attribute3_key Settings pathApplication settings → Data Settings → Configure Attributes → Attribute 3 → Key |
string |
2.5.0 |
Parcel Pallet | The key of the third attribute | |
attribute3_show_values Settings pathApplication settings → Data Settings → Configure Attributes → Attribute 3 → Show Values |
boolean |
false |
2.5.0 |
Parcel Pallet | Show the values of the third attribute |
attribute3_type Settings pathApplication settings → Data Settings → Configure Attributes → Attribute 3 → Type |
string |
softkey |
2.6.6 |
Parcel Pallet | The type of the third attribute. Allowed values: softkey , list , number |
attribute3_values Settings pathApplication settings → Data Settings → Configure Attributes → Attribute 3 → Values |
string |
2.5.0 |
Parcel Pallet | The values of the third attribute | |
attribute4_key Settings pathApplication settings → Data Settings → Configure Attributes → Attribute 4 → Key |
string |
2.5.0 |
Parcel Pallet | The key of the fourth attribute | |
attribute4_show_values Settings pathApplication settings → Data Settings → Configure Attributes → Attribute 4 → Show Values |
boolean |
false |
2.5.0 |
Parcel Pallet | Show the values of the fourth attribute |
attribute4_type Settings pathApplication settings → Data Settings → Configure Attributes → Attribute 4 → Type |
string |
softkey |
2.6.6 |
Parcel Pallet | The type of the fourth attribute. Allowed values: softkey , list , number |
attribute4_values Settings pathApplication settings → Data Settings → Configure Attributes → Attribute 4 → Values |
string |
2.5.0 |
Parcel Pallet | The values of the fourth attribute | |
auto_cleanup_days Settings pathApplication settings → Data Settings → Data cleanup → Automatic data cleanup → `` |
numeric |
30 |
2.5.0 |
Parcel Pallet | Duration to retain data in days |
auto_cleanup_enabled Settings pathApplication settings → Data Settings → Data cleanup → Automatic data cleanup → `` |
boolean |
false |
2.5.0 |
Parcel Pallet | Enable automatic cleanup, to automatically delete sequences older than a specified value |
auto_pose_detection Settings pathApplication settings → Workflow Settings → Flow and Interface → Automated pose detection |
boolean |
true |
3.2.0 |
Pallet | Automated pose detection |
barcode_case Settings pathApplication settings → Data Settings → Others → Convert scanned barcodes |
string |
0 |
2.6.9 |
Parcel Pallet | Convert scanned barcodes case mode. Possible values: 0 (Unchanged), 1 (UPPERCASE), 2 (lowercase) |
barcode_mandatory Settings pathApplication settings → Workflow Settings → Scan Constraints → Mandatory Barcode |
boolean |
false |
2.6.0 |
Parcel Pallet | Acquiring barcode is mandatory to save a result |
btscale_enabled Settings pathApplication settings → Workflow Settings → Bluetooth Scale → Settings → Use Bluetooth Scale |
boolean |
false |
2.5.0 |
Parcel | Use bluetooth scale |
btscale_name_prefix Settings pathApplication settings → Workflow Settings → Bluetooth Scale → Settings → `` |
string |
Adam |
2.5.0 |
Parcel | The prefix for the name of the bluetooth scale |
color_resolution Settings pathApplication settings → Developers Settings → Color Resolution |
string |
2 |
2.5.0 |
Parcel | The color resolution to use. Possible values: 2 (0.3MP), 3 (13MP) |
compute_alpha_channel Settings pathApplication settings → Data Settings → Acquisition → Compute Alpha Channel |
boolean |
false |
2.5.0 |
Parcel | Compute the alpha channel on the segmented images |
csv_output_utc Settings pathApplication settings → Data Settings → USB API → CSV Filename UTC |
boolean |
false |
2.5.0 |
Parcel | UTC time zone is used for the CSV file naming |
custom_field_enabled Settings pathApplication settings → Data Settings → Custom Fields → `` |
boolean |
false |
2.5.0 |
Parcel Pallet | Enable the custom field. If disabled, the Sum is computed |
custom_field_formula Settings pathApplication settings → Data Settings → Custom Fields → `` |
string |
L,W,H,+,+ |
2.5.0 |
Parcel Pallet | Formula for computing the custom field. The formula is in Reverse Polish Notation (RPN) using a , delimiter |
custom_field_label Settings pathApplication settings → Data Settings → Custom Fields → `` |
string |
@string/sum |
2.5.0 |
Parcel Pallet | Label for the custom field. Note: Strings exceeding 3 characters in length may affect UI formatting |
dimensioning_mandatory Settings pathApplication settings → Workflow Settings → Scan Constraints → Mandatory dimensioning |
boolean |
true |
2.5.2 |
Parcel Pallet | A successful dimensioning is mandatory to save a result |
note_mandatory Settings pathApplication settings → Workflow Settings → Scan Constraints → Mandatory Note Field |
boolean |
false |
2.6.7 |
Parcel Pallet | Note field is mandatory to save a result |
note_only_numbers Settings pathApplication settings → Data Settings → Others → Use numpad for Note entry |
boolean |
false |
2.5.0 |
Parcel Pallet | Only numbers can be inserted into the Note entry |
preview_timeout Settings pathApplication settings → Workflow Settings → Flow and Interface → Preview display timeout |
string |
8000 |
2.5.0 |
Parcel Pallet | The preview timeout in milliseconds. Possible values: 5000, 8000, 10000, 20000, 30000 |
resume_pose_change Settings pathApplication settings → Workflow Settings → Flow and Interface → Resume on pose change |
boolean |
true |
3.2.0 |
Pallet | Resume the stream on pose change |
rt_feedback_ar_plane Settings pathApplication settings → Workflow Settings → Flow and Interface → Enable Plane Overlay |
boolean |
true |
2.6.5 |
Parcel | Enable the AR plane overlay feedback |
rt_feedback_haptic Settings pathApplication settings → Workflow Settings → Flow and Interface → Haptic feedback |
boolean |
true |
2.6.5 |
Parcel | Enable the haptic feedback to alert the operator of suboptimal scanning conditions |
rt_feedback_profile Settings pathApplication settings → Workflow Settings → Flow and Interface → Real-time feedback |
string |
1 |
2.6.5 |
Parcel | The real-time feedback profile. Possible values: 1 (Standard), 2 (Warning only) and 0 (Unrestricted) |
s1_auto_reset Settings pathS1 Settings → S1 Settings → Auto reset when removed |
boolean |
true |
3.0.0 |
Parcel | [S1] Clear data when the object is removed from the scale |
s1_auto_upload Settings pathS1 Settings → S1 Settings → Auto data upload |
string |
1 |
3.0.0 |
Parcel | [S1] Controls when to automatically upload a result. Possible values: 0 (Disabled), 1 (On scan), 2 (On item removed) |
s1_barcode_ignore_line_ending Settings pathS1 Settings → S1 Settings → Barcode ignore line ending |
boolean |
true |
3.0.1 |
Parcel | [S1] Specifies whether line endings (\\n ) should be ignored when using the external barcode scanner. |
s1_barcode_timeout Settings pathS1 Settings → S1 Settings → Timed sizing after barcode event |
string |
1000 |
3.0.0 |
Parcel | [S1] Sets how long after a barcode scanning event the sequence will automatically trigger. Possible values in ms : -1 (Disabled), 0, 500, 1000, 1500, 2000, 3000, 4000, 5000 |
s1_require_connected_scanner Settings pathS1 Settings → S1 Settings → Require barcode scanner |
boolean |
false |
3.0.0 |
Parcel | [S1] Specifies whether a barcode scanner is required to be connected for operation. |
s1_trigger_sound Settings pathS1 Settings → S1 Settings → Emit sound on sizing event |
boolean |
true |
3.0.0 |
Parcel | [S1] Emit a sound when a sizing event is completed |
s1_voi_margin_back Settings pathS1 Settings → S1 Settings → Volume Of Interest → VOI margin back |
numeric |
50 |
3.0.1 |
Parcel | [S1] Margin in mm, from the pole next to the scale, that delimits the back boundary of the Volume of Interest |
s1_voi_margin_front Settings pathS1 Settings → S1 Settings → Volume Of Interest → VOI margin front |
numeric |
150 |
3.0.1 |
Parcel | [S1] Margin in mm, from the scale plate, that delimits the front boundary of the Volume of Interest |
s1_voi_margin_left Settings pathS1 Settings → S1 Settings → Volume Of Interest → VOI margin left |
numeric |
150 |
3.0.1 |
Parcel | [S1] Margin in mm, from the scale plate, that delimits the left boundary of the Volume of Interest |
s1_voi_margin_right Settings pathS1 Settings → S1 Settings → Volume Of Interest → VOI margin right |
numeric |
150 |
3.0.1 |
Parcel | [S1] Margin in mm, from the scale plate, that delimits the right boundary of the Volume of Interest |
scene_validation_enabled Settings pathApplication settings → Workflow Settings → Flow and Interface → Enable scene validation |
boolean |
true |
3.2.0 |
Pallet | Enable the scene validation |
show_tips Settings pathApplication settings → Workflow Settings → Flow and Interface → Display Tips |
boolean |
true |
2.5.0 |
Parcel | Display the tips to the user |
show_title_bar Settings pathApplication settings → Workflow Settings → Flow and Interface → Show title bar |
boolean |
true |
2.5.0 |
Parcel | Display the title bar of the application |
size_precision Settings pathApplication settings → Data Settings → Displayed dimensions → Dimension precision |
string |
1 |
2.5.0 |
Parcel Pallet | Parcel: Dimension precision. Possible values: 10, 1, 0.5, 0.25, 0.1, 0.01 Pallet: Dimension precision. Possible values: 10, 1, 0.5, 0.25, 0.1 |
size_rounding Settings pathApplication settings → Data Settings → Displayed dimensions → Dimension rounding method |
string |
0 |
2.5.0 |
Parcel Pallet | Default rounding method. Possible values: 0 (nearest), 1 (truncate down), 2 (clamp up) |
size_unit Settings pathApplication settings → Data Settings → Displayed dimensions → Default dimension unit |
string |
mm |
2.5.0 |
Parcel Pallet | Default dimension unit. Possible values: mm, in, cm |
upload_on_barcode Settings pathApplication settings → Workflow Settings → Flow and Interface → Upload on barcode event |
boolean |
false |
2.5.2 |
Parcel Pallet | Upload the current record immediately after a barcode event |
weight_mandatory Settings pathApplication settings → Workflow Settings → Scan Constraints → Mandatory Weight |
boolean |
false |
2.6.0 |
Parcel Pallet | Acquiring weight is mandatory to save a result |
weight_precision Settings pathApplication settings → Data Settings → Displayed weight → Weight precision |
string |
1 |
2.5.0 |
Parcel Pallet | Parcel: Weight precision. Possible values: 10, 1, 0.5, 0.25, 0.1, 0.01 Pallet: Weight precision. Possible values: 10, 1, 0.1 |
weight_rounding Settings pathApplication settings → Data Settings → Displayed weight → Weight rounding method |
string |
0 |
2.5.0 |
Parcel Pallet | Weight rounding method. Possible values: 0 (nearest), 1 (truncate down), 2 (clamp up) |
weight_unit Settings pathApplication settings → Data Settings → Displayed weight → Default weight unit |
string |
Parcel g Pallet Kg |
2.5.0 |
Parcel Pallet | Default weight unit. Possible values: g, Kg, lb, oz |
wifi_manual_upload Settings pathApplication settings → Data Settings → History → Allow Manual Upload |
boolean |
false |
2.5.0 |
Parcel Pallet | Allow to manually upload records from Pending/History |
{ "jsonver": 0, "app": "parcel", "restoredefault": true, "prefs": [] }
{ "jsonver": 0, "app": "pallet", "restoredefault": true, "prefs": [] }
{ "jsonver": 0, "app": "parcel", "restoredefault": false, "prefs": [ { "key": "size_unit", "minver": "2.5.0", "type": "string", "value": "in" }, { "key": "size_precision", "minver": "2.5.0", "type": "string", "value": "0.25" }, { "key": "weight_unit", "minver": "2.5.0", "type": "string", "value": "lb" } ] }
{ "jsonver": 0, "app": "pallet", "restoredefault": false, "prefs": [ { "key": "size_unit", "minver": "2.5.0", "type": "string", "value": "in" }, { "key": "size_precision", "minver": "2.5.0", "type": "string", "value": "0.25" }, { "key": "weight_unit", "minver": "2.5.0", "type": "string", "value": "lb" } ] }
{ "jsonver": 0, "app": "parcel", "restoredefault": false, "prefs": [ { "key": "api_endpoint", "minver": "2.5.0", "type": "string", "value": "https:\/\/testing.qboid.ai:5003\/newEntry" }, { "key": "api_upload_img_result", "minver": "2.5.0", "type": "boolean", "value": true }, { "key": "api_upload_img_seg", "minver": "2.5.0", "type": "boolean", "value": true }, { "key": "api_upload_img_color", "minver": "2.5.0", "type": "boolean", "value": true }, { "key": "api_upload_results", "minver": "2.5.0", "type": "boolean", "value": true } ] }
{ "jsonver": 0, "app": "pallet", "restoredefault": false, "prefs": [ { "key": "api_endpoint", "minver": "2.5.0", "type": "string", "value": "https:\/\/testing.qboid.ai:5003\/newEntry" }, { "key": "api_upload_img_result", "minver": "2.5.0", "type": "boolean", "value": true }, { "key": "api_upload_img_seg", "minver": "2.5.0", "type": "boolean", "value": true }, { "key": "api_upload_img_color", "minver": "2.5.0", "type": "boolean", "value": true }, { "key": "api_upload_results", "minver": "2.5.0", "type": "boolean", "value": true } ] }
{ "jsonver": 0, "app": "parcel", "restoredefault": false, "prefs": [ { "key": "attribute1_key", "minver": "2.5.0", "type": "string", "value": "CASE" }, { "key": "attribute1_show_values", "minver": "2.5.0", "type": "boolean", "value": true }, { "key": "attribute1_values", "minver": "2.5.0", "type": "string", "value": "CASE,0,EACH,0" }, { "key": "attribute2_key", "minver": "2.5.0", "type": "string", "value": "3481" }, { "key": "attribute2_values", "minver": "2.5.0", "type": "string", "value": ",0,true,1,false,2" }, { "key": "attribute3_key", "minver": "2.5.0", "type": "string", "value": "FRAGILITY" }, { "key": "attribute3_show_values", "minver": "2.5.0", "type": "boolean", "value": true }, { "key": "attribute3_values", "minver": "2.5.0", "type": "string", "value": "F-1,0,F-2,0,F-3,0" } ] }
{ "jsonver": 0, "app": "pallet", "restoredefault": false, "prefs": [ { "key": "attribute1_key", "minver": "2.5.0", "type": "string", "value": "CASE" }, { "key": "attribute1_show_values", "minver": "2.5.0", "type": "boolean", "value": true }, { "key": "attribute1_values", "minver": "2.5.0", "type": "string", "value": "CASE,0,EACH,0" }, { "key": "attribute2_key", "minver": "2.5.0", "type": "string", "value": "3481" }, { "key": "attribute2_values", "minver": "2.5.0", "type": "string", "value": ",0,true,1,false,2" }, { "key": "attribute3_key", "minver": "2.5.0", "type": "string", "value": "FRAGILITY" }, { "key": "attribute3_show_values", "minver": "2.5.0", "type": "boolean", "value": true }, { "key": "attribute3_values", "minver": "2.5.0", "type": "string", "value": "F-1,0,F-2,0,F-3,0" } ] }
{ "jsonver": 0, "app": "parcel", "restoredefault": false, "prefs": [ { "key": "auto_cleanup_days", "minver": "2.5.0", "type": "numeric", "value": 90 }, { "key": "auto_cleanup_enabled", "minver": "2.5.0", "type": "boolean", "value": true } ] }
{ "jsonver": 0, "app": "pallet", "restoredefault": false, "prefs": [ { "key": "auto_cleanup_days", "minver": "2.5.0", "type": "numeric", "value": 90 }, { "key": "auto_cleanup_enabled", "minver": "2.5.0", "type": "boolean", "value": true } ] }
{ "jsonver": 0, "app": "parcel", "restoredefault": false, "prefs": [ { "key": "btscale_enabled", "minver": "2.5.0", "type": "boolean", "value": true } ] }
{ "jsonver": 0, "app": "parcel", "restoredefault": false, "prefs": [ { "key": "custom_field_enabled", "minver": "2.5.0", "type": "boolean", "value": true }, { "key": "custom_field_formula", "minver": "2.5.0", "type": "string", "value": "W,H,+,2,*" }, { "key": "custom_field_label", "minver": "2.5.0", "type": "string", "value": "GRH" } ] }
{ "jsonver": 0, "app": "pallet", "restoredefault": false, "prefs": [ { "key": "custom_field_enabled", "minver": "2.5.0", "type": "boolean", "value": true }, { "key": "custom_field_formula", "minver": "2.5.0", "type": "string", "value": "W,H,+,2,*" }, { "key": "custom_field_label", "minver": "2.5.0", "type": "string", "value": "GRH" } ] }
{ "jsonver": 0, "app": "parcel", "restoredefault": false, "prefs": [ { "key": "preferences_import_qr_ask", "minver": "2.5.0", "type": "boolean", "value": false } ] }
{ "jsonver": 0, "app": "pallet", "restoredefault": false, "prefs": [ { "key": "preferences_import_qr_ask", "minver": "2.5.0", "type": "boolean", "value": false } ] }