Code readingHow-to

Scan barcodes in a web HMI: camera access and navigation

Scan with a web HMI: open the device camera in its mobile app, catch the decoded text in the Barcode Scanned session event, and navigate to the URL it holds.

LumaSpec Vision9 min read Share on LinkedIn

On this page 9 sections
  1. 01Why won't the web HMI open my browser's camera?
  2. 02Which component starts the scan and where does the text land?
  3. 03Where does the decoded string come out of the session event?
  4. 04Why does navigate throw "view not found"?
  5. 05Why does self.getSibling fail in the Barcode Scanned session event?
  6. 06Wiring scan to URL, step by step
  7. 07When does a phone camera stop being enough?
  8. 08What to check before the first production scan
  9. 09Questions

A phone in an operator's hand is the scanner the floor already owns, and a web-deployed HMI can use it — but only through the HMI vendor's mobile app, and only when the pieces are wired in the right order. Get the order wrong and you collect a view not found error, a script that dies on a missing self, or a navigation call that never fires. This guide wires the Scan Barcode action, captures the decoded payload in the Barcode Scanned session event, and opens a URL carried inside a code, with a guard that refuses strings which are not addresses. It ends at the point every phone-based scheme reaches: where a handheld or fixed code reader does the job better.

Why won't the web HMI open my browser's camera?

It will not: the platform exposes no camera to a desktop browser at all, and on a phone or tablet the camera path exists only inside the vendor's native mobile app, where the Scan Barcode action is permitted to open the device camera.

Browser sandboxes keep page scripts away from hardware, and the vendor opens exactly one hole: scan use cases, through the app. Plan around that. Install the app on the phone or tablet and sign in to the same project the browser session uses. Grant camera permission when the operating system asks — a denied permission looks identical to a missing feature. A desktop session never gets the camera, so a bench or office station scans with hardware, and a wired USB handheld that types the code into the focused field is the simplest:

Handheld code readersHikrobot MV-IDH2000P/13NR/05RN/U Industial Wired Handheld Code ReaderMV-IDH2000P/13NR/05RN/U
Interface
USB
Connection
Wired
$179.00View part

If the app-versus-browser split is the decision still open, the HMI barcode scan: app vs browser camera access guide takes it apart on its own.

Which component starts the scan and where does the text land?

Any component with a click event can start it: attach the Scan Barcode action to a button, and the decoded string arrives separately, in the Barcode Scanned session event, where the vendor's examples read it as data.text.

The split matters. The action only opens the camera and decodes; nothing it returns lands on the component that fired it. The result travels through the session event as a payload, and data.text on that payload is the decoded string, one value per scan. The firing component and the receiving handler never share a scope, so anything the scan produces must be stored somewhere both can reach — which is the next step. Successive scans deliver successive payloads, so decide early what happens when a second scan lands before the first is acted on; the launch checklist at the end carries that guard.

Where does the decoded string come out of the session event?

Write it to a memory tag: session events run without a view, so a tag is the one store the event, every view and the gateway can all reach.

Keep the handler to one job: read data.text and write the string to a tag, for example the memory tag [default]Barcode Data. On the scan view, bind a Label's text property to that tag, and the last code sits on screen where the operator works. Resist doing more in the event: parsing, checks and navigation belong on the view, where a fault shows in the browser console instead of vanishing into a session log.

If a component elsewhere should react to each new value, the barcode scanner property change script pattern handles the payload side.

Why does navigate throw "view not found"?

Because the address was quoted: navigate(url = 'self.getSibling("Label").props.text') asks the HMI to open a view literally named self.getSibling("Label").props.text, no such view exists, and the platform answers view not found.

The two lines differ by one pair of quotes:

navigate(url = 'self.getSibling("Label").props.text')   # wrong: the quoted text IS the address
navigate(url = self.getSibling("Label").props.text)     # right: the property value is the address

Quoted text is a string literal; unquoted text is an expression the platform evaluates. The decoded URL must arrive as a value. Whenever view not found appears right after a scan, read the call once for stray quotes before touching anything else — that one character causes most of these failures.

Why does self.getSibling fail in the Barcode Scanned session event?

Because session events carry no component scope: self does not exist there, and self.getSibling("Label") resolves only in a script running on the same view as the Label — a component event, not a session event.

Two symptoms, one cause. Paste the view-level navigation script into the session event and it dies on the missing self. Repair the scope and navigation can still refuse to run: integrators report again and again that the navigation call does not execute from the session-event context even when its arguments are correct. The dependable shape is therefore two steps in two places. The session event stores; a component on the view acts. That split also gives the scheme check, the logging and the operator's button somewhere visible to live.

Wiring scan to URL, step by step

Three pieces and two buttons: a scan button carrying the Scan Barcode action, a Barcode Scanned session event that stores data.text into a memory tag, and an Open link button on the same view whose script navigates to that tag's value, unquoted and scheme-checked.

  1. Install the vendor's mobile app, sign in to the same project, and accept the camera-permission prompt on first launch.
  2. Drop a button on the view and attach the Scan Barcode action to its click event.
  3. Add the Barcode Scanned session event script, and make it store only:
# Barcode Scanned session event — store only
# data.text: string, the decoded payload supplied by the platform
code_text = str(data.text)
# then write code_text to the memory tag, e.g. [default]Barcode Data,
# using the vendor's asynchronous tag-write function
  1. Bind a Label's text property on the view to that tag, so the last code is always on screen.
  2. Add the Open link button with this click script:
# Click event of "Open link", on the same view as the Label
url_value = self.getSibling("Label").props.text        # string, bound to the tag
if url_value.startswith(("http://", "https://")):
    navigate(url = url_value)   # the vendor's session navigation function
# else: log url_value as a rejected code; do not navigate

navigate here stands for the vendor's session navigation function; check its exact name and arguments in the session event scripting section of the platform's own documentation before you deploy.

  1. Prove both paths before the floor sees the station. Scan a test code carrying https://example.com/MAT-1042 and confirm the app leaves the view and loads that page — that run proves the variable reaches the navigation call. Then scan MAT-1042, scheme-less, and confirm the view stays put and the rejection is logged — that run proves the check lives in the script the platform actually executes.

When the code selects rather than points — a recipe, a work order, a bin — the same store-then-act shape runs a recipe change instead of a browser jump; scan a barcode to select a recipe on your HMI shows that variant end to end.

When does a phone camera stop being enough?

When the read must be hands-free, repeatable or fast: a compact fixed reader such as the LS-CRD-0047 covers a 60-120 mm reading distance on the bench, and an LS-CRD-0028 decodes up to 60 codes/s at 30 fps, rates a hand-held phone session cannot hold.

Split the replacement by job. For aisle and yard work — asset tags, rack labels, tote IDs — the scan happens where the part sits, so the reader goes to the part:

Handheld code readersHikrobot MV-IDH9000B/13DP/04RP/LS Ultra-rugged Wireless Handheld Code Reader PackageMV-IDH9000B/13DP/04RP/LS
Connection
Wireless
$2,979.00 · quotedView and quote
Handheld code readersHandheld industrial barcode reader, 1.0 MP (LS-HCR-0002)LS-HCR-0002
Resolution
Up to 3 MP
Shutter
Global
$539.00View part

How the code then reaches the HMI is the same for any scanner: USB barcode scanner on a PLC HMI: HID keyboard mode or serial port compares the two paths into a PLC HMI, and the keyboard wedge over RDP guide explains why typed scans vanish on remote desktops. A keyboard-mode reader lands text in whatever field has focus, and focus is the usual failure point — the auto-advance focus setup for scanned fields addresses exactly that.

On the line the phone comes off entirely. A reader fixed over the tape reads every label that passes, with no operator in the loop:

Fixed code readersHikrobot MV-ID3013PM-12M-WBN 12mm focal length 1.3 MP Compact Industrial Code ReaderMV-ID3013PM-12M-WBN
Interface
Fast Ethernet
Resolution
Up to 3 MP
Shutter
Global
Lens mount
M12
$1,979.00View part

Its 12 mm focal length and 1.3 MP resolution fit a code on a belt read from a short stand, and the same sizing logic — lens to code size, stand-off to focus depth — scales across the fixed code readers and handheld code readers categories. Whichever reader wins, the framing rules carry over: the CR LF suffix guide covers why Enter-after-scan decides whether a typed code commits.

What to check before the first production scan

Six checks, in order: the app session on the right project, camera permission granted, the tag store updating on each scan, the scheme check inside the executed script, a repeat guard on identical codes, and a logged rejection path for codes that are not addresses.

  • Session source: open the view in the app, never in a desktop browser — the camera will simply not appear there.
  • Permission: if a tap does nothing, check the operating system's camera permission for the app before debugging a single script.
  • Store: watch the tag while scanning; a value that never changes means the session event never fired.
  • Scheme check: scan a plain part number once. Navigation must not run — that one test proves the check lives in the script the platform executes, not in a copy of it.
  • Repeats: ignore an identical code inside a one-second window, so a double tap or a nervous thumb cannot open the page twice.
  • Rejections: log every refused string with a timestamp to the second; the pattern over a shift tells you whether labels or logic are at fault.

More decode-side patterns, from framing to archiving, sit on the code-reading topic page.

Decisions by case: phone plus app for lookup at the point of work; a wired USB handheld wherever a desktop HMI owns a focused text field; a wireless handheld for aisle and yard; a fixed reader over the tape once labels move on their own; and store-then-act scripting for every code that must open something. When a case lands in the hardware rows, size the reader to the real code at the code-reader finder, or ask the applications team through the contact page with the code type, module size and line speed.

Questions

Why does nothing happen when I press scan inside the mobile app?

Check three things in order: that the session is open in the app and not in a desktop browser, that the operating system has granted the app camera permission, and that the app is signed into the same project that carries the Scan Barcode action. A denied permission looks exactly like a missing feature, and a wrong project shows a view with no scan action at all.

Can the page open automatically after each scan, without the Open link button?

You can attempt the navigation call inside the session event, but integrators report it frequently does not execute from that context. The dependable options are the button pattern, or a property-change script on a view component that fires when the stored tag updates and navigates then. Keep the scheme guard in whichever script actually runs.

Will scan-to-URL work on a tablet with no network connection?

No. A web HMI session lives on its connection to the server; with no session there is no scan action, no session event and nowhere to navigate. An offline station needs a reader wired to the machine controller over serial, USB or Ethernet, so the decode never depends on a live page.

What changes if the code selects a recipe instead of carrying a URL?

Nothing upstream and one thing downstream. The payload still arrives as data.text in the session event and still lands in the same memory tag; only the acting script changes, from a navigation call to a recipe write. Keep the same store-then-act split so the scheme check and the logging stay in one place.