User Level

The User Level regroups the features that have an impact on the user experience.

The Socket barcode scanners provide ways to notify the user when the barcode read is correct or incorrect without the need for the user to check the screen of the host.

The scanner has 3 types of feedback: sound, LED and vibrate.

For example, depending on the environment, you may want to turn off the sound and use only the vibration.

Here are some examples on how to use these feedback mechanisms.

Turning off the Sound, Vibrate and LED Flash

Turning off some of the device’s User Interface (UI) is a simple 2 step process.

Since this setting is persistent on the scanner, it is best to first read this setting when the scanner connects and depending on its state, either change it or just continue on.

Let’s imagine we would like to offer to the user three check boxes to turn on or off the beep, the vibrate and the LED flash when scanning a barcode.

The property of the device for this setting is called LocalDecodeActionDevice.

The SocketMobile.CaptureEventIds.DeviceArrival event handler is used to request the actual state of the scanner local decode action so the check boxes reflect the actual state of the scanner local decode action.

The code might look like this:

const eventNotification = (event, handle) => {
  if(event) {
    console.log('event: ', event);
    if(event.id === SocketMobile.CaptureEventIds.DeviceArrival) {
      console.log('Open the device:', event.value.guid);
      captureDevice = new SocketMobile.Capture();
      captureDevice.guid = event.value.guid;
      captureDevice.openDevice(event.value.guid, capture)
      .then(result => {
        console.log('opening device returns:', result);
        setButtonTitle(BTN_CLOSE);

        // getting the current value of the device local decode action
        const property = new SocketMobile.CaptureProperty(
          SocketMobile.CapturePropertyIds.LocalDecodeActionDevice,
          SocketMobile.CapturePropertyTypes.None,
          {}
        );
        captureDevice.getProperty(property)
        .then(decodeAction => {
          console.log(`local decode action: ${decodeAction.value}`);
          updateDeviceUi(decodeAction.value);
          enableDeviceUi(true);
        })
        .catch(err => {
          console.log('error while getting local decode action: ', err);
        });

      })
      .catch(err => {
        console.log(err);
      });
    }
    else if (event.id === SocketMobile.CaptureEventIds.DeviceRemoval) {
      enableDeviceUi(false);

      ...

Then the handler of the updateDeviceUi and enableDeviceUi functions to enable and update the check boxes could look like this:

function updateDeviceUi(currentValue) {
  let check = document.getElementById('beep');
  check.checked = currentValue & SocketMobile.LocalDecodeAction.Beep;
  check = document.getElementById('rumble');
  check.checked = currentValue & SocketMobile.LocalDecodeAction.Rumble;
  check = document.getElementById('flash');
  check.checked = currentValue & SocketMobile.LocalDecodeAction.Flash;
}

function enableDeviceUi(enable) {
  let check = document.getElementById('beep');
  check.disabled = !enable;
  check = document.getElementById('rumble');
  check.disabled = !enable;
  check = document.getElementById('flash');
  check.disabled = !enable;
  const btn = document.getElementById('setConfig');
  if(enable === false) {
    btn.style = "display:none";
  }
  else {
    btn.style = "display:inline";
  }
}

The web page has a Set button that sends the actual LocalDecodeActionDevice setting to the device in function of the state of the 3 check boxes.

Simple UI with 3 check boxes and a set button

The Set button handler code could then be something like this:

function onSetConfig() {
  const beep = document.getElementById('beep');
  const rumble = document.getElementById('rumble');
  const led = document.getElementById('flash');
  let value = SocketMobile.LocalDecodeAction.None;
  if(beep.checked) {
    value |= SocketMobile.LocalDecodeAction.Beep;
  }
  if(rumble.checked) {
    value |= SocketMobile.LocalDecodeAction.Rumble;
  }
  if(led.checked) {
    value |= SocketMobile.LocalDecodeAction.Flash;
  }
  const property = new SocketMobile.CaptureProperty(
    SocketMobile.CapturePropertyIds.LocalDecodeActionDevice,
    SocketMobile.CapturePropertyTypes.Byte,
    value
  );
  captureDevice.setProperty(property)
  .catch(err => {
    setStatus(`unable to set the device UI: ${err}`);
  });
}

This code assumes the captureDevice is the capture object that was used to open the device.

Locate the Scanner

‘’Locate the Scanner’’ might be a nice feature to help the user identify which scanner is theirs in a situation where more than one scanner is in the area.

This feature could be implemented with a repeated action of sending a Data Confirmation to the scanner to cause the scanner to beep or flash or vibrate.

Here is code example of a command that would need to be in a timer handler:

function onFindDevice() {
  const btn = document.getElementById('btnFindDevice');
  if(btn.innerHTML === BTN_FIND){
    btn.innerHTML = BTN_STOP;
    this.idTimeout = setInterval(() => {
        const action = (SocketMobile.DataConfirmationRumble.Good<<4) +
          (SocketMobile.DataConfirmationBeep.Good<<2) +
          SocketMobile.DataConfirmationLed.Green;
        const property = new SocketMobile.CaptureProperty(
          SocketMobile.CapturePropertyIds.DataConfirmationDevice,
          SocketMobile.CapturePropertyTypes.Ulong,
          action
        );
        captureDevice.setProperty(property)
        .catch(err => {
          clearInterval(this.idTimeout);
        });
      }, 500);
  }
  else {
    clearInterval(this.idTimeout);
    btn.innerHTML = BTN_FIND;
  }
}

This is assuming the device has been opened and the captureDevice is a reference to it.

Wrong Barcode Indication

Wrong barcode indication can be useful when a user scans a barcode but that barcode was not expected at that moment in the application or is not the expected symbology or format. Of course the application UI could display a user friendly error, but maybe the user is scanning a bunch of barcodes without looking at the screen. So sending back to the user an indication that something is wrong after having scanning a barcode might be useful.

Here is an example of code that can be invoked when such a condition occurs in the application:

function SendWrongBarcodeIndication() {
  const action = (SocketMobile.DataConfirmationRumble.Bad<<4) +
    (SocketMobile.DataConfirmationBeep.Bad<<2) +
    SocketMobile.DataConfirmationLed.Red;
  const property = new SocketMobile.CaptureProperty(
    SocketMobile.CapturePropertyIds.DataConfirmationDevice,
    SocketMobile.CapturePropertyTypes.Ulong,
    action
  );
  captureDevice.setProperty(property)
  .catch(err => {
    console.log(`error sending wrong barcode indication: ${err}`);
  });
}

This is assuming the device has been opened and the captureDevice is a reference to it.

Note

The action in this last code cannot be mixed between Good and Bad. So if a Bad beep is choosen as setting, the LED can then only be set to Red or None but cannot be Green, and the Rumble can only be Bad or None but cannot be Good. If a mix of Good/Green and Bad/Red is used then an error SocketMobile.SktErrors.ESKT_NOTSUPPORTED (-15) will be returned.

Disabling the Scanner Trigger Button

Upon detection of a wrong barcode and requiring the user to acknowledge an eventual informational message on the host screen, the Scanner Trigger button can be disabled.

Here is a sample code for disabling the Scanner Trigger button:

const BTN_LOCK = "Lock the trigger";
const BTN_UNLOCK = "Unlock the trigger";

function onLockUnlock() {
  const btn = document.getElementById('btnLockUnlock');
  let action = SocketMobile.Trigger.Disable;
  if(btn.innerHTML === BTN_LOCK){
    btn.innerHTML = BTN_UNLOCK;
  }
  else {
    btn.innerHTML = BTN_LOCK;
    action = SocketMobile.Trigger.Enable;
  }
  const property = new SocketMobile.CaptureProperty(
    SocketMobile.CapturePropertyIds.TriggerDevice,
    SocketMobile.CapturePropertyTypes.Byte,
    action
  );
  captureDevice.setProperty(property)
  .catch(err => {
    btn.innerHTML = BTN_LOCK;
  });
}

This is assuming the device that is actually open is referred by captureDevice.

Note

The Scanner can be configured with a Data Confirmation Mode set to either the application or to Capture. In both cases, the trigger is disabled until the data is confirmed or a timeout has elapsed. Please refer to the Application Level Data Confirmation from the App.