01 / Surface
Fourteen groups.
One object.
Every group below is running on devices today; a line marked with a version needs that ArdaPlayer release or later. Use the ones your device needs and ignore the rest. The same object is there in developer mode on your laptop, in the kiosk on the device, and with no screen at all under -headless.
Device & settings Working
Arda.device() · Arda.config
Who am I, what am I on, what can a person do here — and the settings the operator set in the portal, as a frozen object on your first line.
- deviceId · phase · hostname · model · ips · wifi
- can: screen · keyboard · mouse · touch · audioOut · audioIn
- Arda.config.currency ?? 'GBP' — absent, never null
- a 'rows' setting arrives as an array of objects
- per-device overrides applied; a portal change lands in ~3 s
- Arda.config.set(key, value) — this device's own value, for a setting the manifest marks
writable.device (v1.1.17) - a choice from the device's own printers or screens (v1.2.1)
- Arda.battery.status() · Arda.on('battery') — level, charging, time left, where the machine has a battery (v1.3.0)
Datasets & outbox Working
Arda.db
Your data, kept on the device so the app works offline — only this device's share of it, encrypted. And a queue for what the app saves, which survives a power cut and sends itself when the line is back.
- dataset(name) — asking is subscribing
- push(dataset, data, key?) — at-least-once, 128 KB cap
- status() — which datasets have landed; connected, and what is still queued (v1.2.0)
- on('ack') — your records reached ArdaForm · sync() — a "Sync now" (v1.2.0)
- declared in app/manifest.json
Files Working
/storage/…
Pictures and documents the project holds, copied to the device and checked, then used like any other path in your page.
- <img src="/storage/catalogue/13388.webp">
- read-only on the device, re-checked every sweep
- folders the app needs at boot fetched first
- 'files' event with done / total / bytes
Events Working
Arda.on(kind, fn)
The player telling the app what moved. Register as many listeners as you like.
- 'sync' · 'files' · 'device' · 'config'
- 'ack' — ArdaForm stored your pushes (v1.2.0)
- 'barcode' · 'nfc'
- 'update' · 'updateStart'
- 'screens' — a monitor unplugged or plugged in
- 'power' — the button was pressed; save what you must
- console.* captured to the portal on demand
Keyboard Working
Arda.keyboard(opts)
The on-screen keyboard for a machine with none. The app opens it; a promise resolves the value, an object of fields, or null on cancel.
- layouts: full · numeric · pin · date · time · datetime
- fields with mask, prefix, suffix, secret
- till-style money entry with decimals and pos
- themeable, on a named screen if you like
- sized to the screen, not the page's font size; theme {unit: '20px'} scales the whole keyboard (v1.1.12)
Screens & audio Working
Arda.screens · Arda.screen[name] · Arda.audio
The connected displays, their brightness, contrast and scale, the speakers — and a second screen as a real Document you append nodes into. On a device with two monitors, which one the app is on.
- screens.list() · screens.ready() · screen['customer']
- screens.controls() · screens.set(name, {brightness, contrast, volume, scale}, onboot)
- scale 50–150 %, per screen · HDMI monitors over DDC/CI
- audio.get() · audio.set({volume, muted}, onboot)
- second screens as Documents: developer mode today
- list() entries carry kind: 'app' — or 'video', a device monitor a camera can be shown on (v1.1.12, PC-type devices installed from its images)
- on('screens') — list() is already current inside it, so a monitor that comes after the app can take a camera (v1.1.13)
- screens.set(name, {primary: true}) — move the app to that monitor; the page starts over there (v1.1.12, the same devices)
Cameras Working
Arda.camera
An RTSP or IP camera — the CCTV over a bay, the door camera — on the screen. The player picks the best way this device has and keeps the picture live.
- set(name, {url, user, password, fps, width, quality, hw}) · forget(name) — the login beside the link, never inside it (v1.1.14)
- play(name, el, {maxLag, fit}) — the camera's own H.264/H.265 in a <video>, motion JPEG where it must
- hardware decoding where the board has it — six at once on a Pi 4
- always the newest frame; a camera that reboots comes back
- url(name) · video(name) · status()
- onvif({address, user, password}) — a camera's details and its streams · discover() — ONVIF cameras on the network (v1.1.14)
- show(name, {screen, delay}) · shows() — full-screen on a device's second monitor while the app runs on the first; rtsp cameras (v1.1.12, a PC-type device installed from its images; not the Raspberry Pi image yet); delay 0–5000 ms or left to the player; rtmp:// sources; Reolink rtsp:// links played over RTMP (v1.1.14)
Printers Working
Arda.printers
The player finds printers and moves bytes; what to print is yours. USB, network (port 9100) and Bluetooth all the same way.
- list() → id · make · model · proto · dots · usable
- print(id, bytes) — ESC/POS, ZPL, Star, TSPL, ESC/P (dot-matrix, v1.2.2), raw
- print(id, bytes, {copies, signal}, onStatus) — many copies in one job, a status per copy: printing · queued · stalled · done · error · cancelled (v1.1.11)
- a busy or stuck label printer no longer holds up the receipt printer beside it (v1.1.11)
- discover() · add() · remove() — receipt printers on the device's own network, found and kept (v1.3.0)
- width guessed and correctable from the portal
- control bytes stripped from text
Serial Working
Arda.serial
USB-serial adapters and UARTs, opened raw. The player owns the port; the protocol is yours — scales, customer displays, PLCs, inverters.
- list() → stable by-id names, vendor, driver
- open(id, {baud, dataBits, parity, stopBits})
- write(id, bytes) · read(id, {max, timeoutMs})
- close(id)
Readers Working
Arda.on('barcode' | 'nfc')
Barcode and QR scanners and most RFID readers are keyboard wedges. The player reads them from the input layer, so a scan says which device produced it.
- {kind, text, device, node}
- two scanners on one machine never mix
- nfc for readers recognised as card readers
- the reader still types into a focused field
System & Wi-Fi Working
Arda.system · Arda.wifi
For an app that owns the machine: power it off at closing time, or offer a Wi-Fi screen that cannot strand the device.
- system.shutdown() · system.reboot()
- wifi.list() — strongest first, active and known flagged
- wifi.connect(ssid, key) — tested before anything is kept
- simulated on a developer's own machine
- on Android shutdown() closes the player, reboot() needs device owner, Arda.on('back') hears the back key (v1.3.0)
Updates Working
Arda.update
A new version arrives staged and the player is about to apply it. Say nothing and it goes in five seconds; mid-transaction, buy a minute.
- on('updateStart') — version, mode, kind, decideInMs
- update.pause() — up to five times
- update.apply() — reloads onto the new version
- update.pending() — the round, at any time
Webhooks Working
Arda.webhook.call(slug, data)
Tell one of your own servers that something happened. ArdaForm makes the call from its servers and signs it — the key never sits on the device.
- → {id, ok, status, ms, body, error}
- a 4xx or 5xx is an answer; it rejects only when nobody was asked
- defined per project: the Webhooks tab or /v1/webhooks
- up to 64 KiB of JSON · 10 s · the first 4 KiB back
- no URL: the calls are only recorded, read in the portal or through the API
- on your desk, arda.dev.json lists them and the player calls them itself
Headless Working
Arda.headless
The same app with nothing to draw on — an end-of-day job, a sensor box, a back-office printer. Same object, no DOM.
- ardaplayer -headless myapp/
- Arda.headless === true before your first line
- fetch and WebSocket to your own servers, like a page
- document throws with the fix named
- console.* is how it is heard
- From v1.1.17: the app deployed to a device with no screen runs here too (in progress, not yet proved on a device)
GPIO, camera capture, face matching Planned
Digital I/O on boards that have it, capture and QR scanning through a camera attached to the device, and on-device face matching are designed around and not started. Showing a network camera on a screen works today (the cameras group); a QR flow uses a USB scanner through the readers group.
The HTTP API Working
The other side of the datasets: api.ardaform.net/v1, API keys per project, records in and out, and a keyless GET /v1/openapi.json for your client tooling. What a device pushes, your systems read; what your systems write, the devices sync.