Device Binding in sim-dashboard¶
Device binding is the process of associating a simulated e-ink device with your Inklet user account. Once bound, you can send commands to the device and see its display output in the dashboard.
Binding Methods¶
There are two ways to bind a device:
Method 1: Claim Code¶
The claim code method uses a 6-character alphanumeric code displayed on the device's e-ink screen.
How it works:
- When an unbound device starts up, it requests a claim code from the backend
- The backend generates a code (e.g.,
A3X9K2) and sends it to the device - The device renders the code on its e-ink display
- You enter the code in the sim-dashboard to bind the device to your account
Method 2: NFC Payload¶
The NFC payload method uses the HMAC-signed hardware identifier that sim-hw generates.
How it works:
- sim-hw writes an NFC payload to
{data-dir}/nfc-payloadon startup - The payload has the format
inklet:1:{hwId}:{signature} - You paste this string in the sim-dashboard binding dialog
- The backend verifies the HMAC signature and binds the device
Which method should I use?
For day-to-day simulator use, the claim code method is simpler since the code is displayed right on the simulated screen. The NFC payload method is useful for testing the NFC binding flow specifically or for automated testing scripts.
Step-by-Step Binding Guide¶
Step 1: Start sim-hw¶
Launch a simulated device in its own terminal:
On startup, sim-hw will:
- Register with AWS IoT Core (provisioning on first run)
- Send a heartbeat to the backend, which creates the device record
- Request a claim code from the backend
- Render the claim code on its simulated e-ink display
- Push the framebuffer to sim-dashboard
You should see log output like:
INFO Connected as inklet-a1b2c3d4
INFO Sending heartbeat...
INFO Received claim_code command: A3X9K2
INFO Rendering claim code to display...
INFO Framebuffer pushed to sim-dashboard
Step 2: View the Claim Code¶
The claim code is visible in two places:
- sim-dashboard display --- If you are already viewing the device at its public URL (
/device/{hwid}), the claim code renders on the simulated e-ink screen - sim-hw logs --- The claim code is printed in the terminal output
Step 3: Bind the Device¶
In the sim-dashboard (logged in at http://localhost:5173):
- Click the "Bind Device" button in the top-right area of the dashboard
- A dialog appears with two tabs: Claim Code and NFC Payload
Step 4: Device Appears in Dashboard¶
After successful binding:
- The backend sends a
boundcommand to the device via MQTT - sim-hw renders "Device bound successfully" on the display
- The device appears in your dashboard with a live e-ink preview
- The device is now ready to receive
textcommands
Step 5: Send a Command¶
With the device bound, you can send text to its display:
Click on the device card to open the detail view. Use the text input to send content to the device.
The text renders on the simulated e-ink display with a realistic refresh animation.
Unbinding a Device¶
To unbind a device and return it to the pairing state:
What happens after unbinding:
- The backend sends an
unboundcommand to the device via MQTT - sim-hw receives the command and clears the display
- sim-hw automatically publishes a
request_claimmessage - The backend generates a new claim code and sends it to the device
- The device displays the new claim code, ready for re-pairing
- The device disappears from your dashboard's bound device list
Device Continues Running
Unbinding does not stop the simulated device. sim-hw continues running, sending heartbeats, and displaying its claim code. You can re-bind it at any time.
Binding Lifecycle Diagram¶
sim-hw starts
│
├── Heartbeat → Backend creates device record
│
├── request_claim → Backend generates code
│
├── claim_code received → Display shows "A3X9K2"
│
│ User enters code in sim-dashboard
│ │
│ POST /api/devices/bind/code
│ │
│ Backend binds device to user
│ │
├── bound received → Display shows "Bound successfully"
│
│ Device appears in dashboard
│ User sends text commands
│ │
├── text received → Display renders content
│
│ User clicks "Unbind"
│ │
│ POST /api/devices/{thing}/unbind
│ │
├── unbound received → Display clears
│
└── request_claim → Cycle repeats
Troubleshooting¶
Claim code not appearing¶
- Verify sim-hw is running and connected (check logs for
Connected as inklet-...) - Ensure the backend is running on
http://localhost:4000 - Check that sim-dashboard's Fastify server is running on
http://localhost:3001 - Verify sim-hw is configured with
--sim-url http://localhost:3001
"Device not found" error when binding¶
- The device must have sent at least one heartbeat before binding. Wait a few seconds after starting sim-hw and try again.
- Ensure the claim code has not expired. If it has, the device will automatically request a new one.
"Device already bound" error¶
- The device is already bound to another user account. Unbind it first, or log in with the account that owns the device.
Display not updating after binding¶
- Check the WebSocket connection in browser dev tools
- Verify the Fastify server is receiving framebuffer POSTs from sim-hw
- Try refreshing the page