8. Scan-to-Configure
This chapter is for whoever owns the cloud account and holds the keys. Field operators don't need it and can skip ahead.
Scan-to-Configure packs several device settings — capture metadata, cloud upload (OSS / COS / S3 / GCS / Azure), auto-upload, bitrate, resolution, Wi-Fi, and an optional recording encryption key — into one QR code that the app writes to a device in a single scan. It is built for bulk deployment: the same code is reused, scanned once per device (settings are applied device by device, not to many devices at once).
The flow has two halves: a technician generates the QR code with the official tool (printed, or shown on a screen); an operator scans it in the app and applies it to the connected device.
Generate the settings QR
Generator: visio-settings-qr, included in the public visio-schema package (Python 3.10+).
Install the supplied source archive, or install online:
pip install "visio_schema-0.9.1.tar.gz[display,qr]"
# Or install online:
pip install "visio-schema[qr]"
From a JSON config
Start from the template settings_qr.example.json (shown below),
edit it to your configuration (see the field table), save it as e.g. my.json, then:
# Render the QR code as a PNG
visio-settings-qr --config my.json --out qr.png
# Validate the config only, render nothing
visio-settings-qr --config my.json --check-only
# Print the exact JSON the app will parse (no image)
visio-settings-qr --config my.json --dry-run
Interactively
Run without --config. Choose the prompt language (or pass --lang zh), then enter metadata, cloud provider,
auto-upload, bitrate, resolution, Wi-Fi, and optionally a recording key. Keys and Wi-Fi passwords use hidden input:
visio-settings-qr --out factory7_qr.png
Example config
{
"t": "visio-settings",
"v": 1,
"meta": { "task": "pick-and-place", "location": "Suzhou line 2", "message": "", "capturer": "operator-7" },
"storage": {
"endpoint_url": "https://oss-cn-hangzhou.aliyuncs.com",
"region": "cn-hangzhou",
"bucket": "gilabs-captures",
"access_key_id": "LTAI5EXAMPLEKEYID",
"secret_access_key": "EXAMPLEsecret",
"prefix": "factory-7/"
},
"auto_upload": true,
"bitrate_kbps": 8000,
"resolution": { "width": 1920, "height": 1080 },
"wifi": { "ssid": "FactoryNet", "passphrase": "hunter22" }
}
Every section is optional, but at least one is required; field names are snake_case.
| Section / field | Meaning | Rule |
|---|---|---|
meta.task / location / message / capturer | Default capture metadata | Firmware 1.1.6+: task / capturer 255 English characters (~85 Chinese); location 511 (~170 Chinese); message 1023 (~341 Chinese). Earlier limits are about one quarter; upgrade first. Overlong fields are not applied. All four are replaced together; empty fields are cleared |
storage.endpoint_url | OSS / COS / S3 / GCS / Azure endpoint | Required when storage is present; must start with http(s):// |
storage.region | Region | Inferred for standard OSS / COS / S3 hostnames; required for GCS (auto is valid); not needed for Azure |
storage.bucket / access_key_id | Bucket / access key ID | Required |
storage.secret_access_key | Secret key | May be empty to keep the existing secret, only if both endpoint and access key ID match the current device configuration |
storage.prefix | Path prefix | The generator defaults to recordings/; omitted in handwritten JSON means the bucket root. A trailing / is added |
auto_upload | Auto-upload on / off | true / false |
bitrate_kbps | Video bitrate | Integer 500–50000; takes effect after a reboot |
resolution.width / height | Camera resolution | Each 240–4096 and must be supported by the device; takes effect after a reboot |
wifi.ssid | Wi-Fi the device should join | Required when wifi is present; ≤ 32 bytes |
wifi.passphrase | Wi-Fi password | 8–63 characters if given; empty = open network |
By default, storage secrets and recording keys are encrypted inside the QR, readable by device firmware;
the confirmation screen says they are wrapped in the QR. Wi-Fi passwords remain plaintext. With --plaintext,
legacy codes also expose keys in plaintext. Protect codes containing Wi-Fi passwords and destroy them when finished.
Scan and apply in the app
Make sure the device you want to configure is connected / online in the app first. Scanning itself works offline, but applying needs a live connection to the device.
- Open the device page and tap the scan icon at the top right (labeled Scan settings, next to the gear icon; shown only while a device is connected).
- Scan: point the camera at the QR code (the prompt reads "Point the camera at a Visio settings QR"). Allow the camera permission on first use; HarmonyOS opens the system scanner. Android and iOS can also choose a saved QR image from the photo library.
- Confirm: the app lists every setting it is about to write (secrets and passwords masked), with the note "The device will be set to the values below. Nothing is sent until you tap Apply." Check them and tap Apply to device.
- Apply: settings go out in order — recording encryption (if included) → capture metadata → cloud upload → auto-upload → bitrate → resolution → Wi-Fi (last) — each showing a spinner, then a green tick or a red cross.
- Done: review the summary and tap Done.
Wi-Fi goes last and may disconnect you. If the code carries Wi-Fi, the device switches network and the app may briefly lose it; the app then tries to follow the device onto the new network. If it doesn't reconnect by itself, join the device's new Wi-Fi with your phone and rediscover the device. Bitrate and resolution take effect after a device reboot (the summary page says so). If recording encryption fails, no further settings are sent. Other individual failures do not stop later items.
Messages and troubleshooting
| Message | Meaning / what to do |
|---|---|
| This is not a Visio settings QR | Not a code produced for this feature; regenerate with visio-settings-qr. |
| This settings QR needs a newer app | The code's version is newer than the app; update the app and scan again. |
| The settings QR contains invalid fields | A value is out of range (e.g. bitrate outside 500–50000); fix the config and regenerate. |
| Device could not join that Wi-Fi, back on its hotspot | Wrong network name or password; check the wifi section in the code. |
| I need to configure many devices | Use the same code and scan it once on each device. |
Use visio-settings-qr for the default encrypted format. If plaintext secrets are acceptable, any QR tool can
encode the version-1 JSON above (error-correction level M is sufficient).
Under the hood
Sections a code can carry
| Section | What it sets |
|---|---|
| Capture metadata | Task, location, message, capturer |
| Cloud upload | Endpoint, region, bucket, access key ID, secret key, prefix |
| Auto-upload | On or off |
| Video bitrate | 500–50000 kbps; takes effect after a reboot |
| Camera resolution | Width and height; takes effect after a reboot |
| Device Wi-Fi | Network name and password |
Two behaviors worth knowing: the secret key may be omitted, in which case the device keeps the secret it already has only when the endpoint and access key ID are unchanged — useful for re-provisioning a fleet's Wi-Fi without reprinting credentials. And Wi-Fi is applied last, because the device switches networks at that point and your phone may lose contact.
Encrypted settings QR
Since app 1.1.3 the app also reads a newer, encrypted settings QR format; the plain format above keeps
working. Recording keys are only ever carried in the encrypted format, wrapped for device firmware. To restrict provisioning to specific devices, explicitly pass --device;
encryption alone does not bind the QR to one device. See
12. Recording encryption. Since app 1.1.3 the app can also import a QR image from the
photo library instead of scanning live, and the confirmation page lists the capturer and location IDs when the
code carries them.
Version-control your site config
Keep each site's JSON in a repository and generate codes from it, so a deployment is reproducible.
--check-only validates a config in CI without rendering anything; --dry-run prints the exact payload the app
will parse, which is what to diff when two sites behave differently. Bitrates outside the app's four presets are
only reachable this way — see 4. Phone app & web preview.