How to call resource/bridge/switchon and /qr

Hi @mtags,

welcome to the forum! Seem like you already did a lot of work to figure things out. Kudos! :bowing_man:
Did I understand you correctly: you know how the regular access API for NFC cards works and just don’t know how QR access works?

Let’s start with the bad news: We have not yet updated the public bridge API to support the QR feature. We’ve only implemented it for our old, binary bridge API that isn’t documented because it’s much more difficult to use that the public API.

Why haven’t we updated the public API?

Because implementing the QR feature in your bridge firmware is much more involved and technically challenging than supporting the NFC access method and nobody has yet signalled interest in implementing it in their 3rd-party bridges – until you came along. :slight_smile:

So while we haven’t made this public yet, we’re willing to change this if it helps someone make their own awesome bridges.

So how does it work?

The QR feature works a bit differently than you expected. I’ll try to explain all the details below, so you can decide whether you want to go forward with this. Here’s what you need to know:

  1. The QR-Tags are generated on the bridge, not on the server.
  2. As you’ve probably seen, each tag contains a URL of the form https://fabman.io/qr/<access-code>.
  3. The access code is also generated on the bridge and contains base32-encoded binary data. There are a few different alphabets for base32. We’re using Crockford’s variant.
  4. The first 4 bytes of the decoded access code contain the bridge ID (2163 in your case) in big endian format.
  5. The remainder is a 6 byte nonce that’s randomly chosen by the bridge and rotated every 60 seconds. (More on that later.)
  6. In order for the server to be able to contact the bridge when someone presses “Switch on”, the bridge needs to keep a persistent connection to the server. We do this via long-polling on the “/heartbeat” endpoint. (Long-polling isn’t yet part of the public API, but you would append ?wait=true to signal that you’re interested in long-polling.)
  7. When the user presses on “Switch on”, the server queues a new activateWithNonce bridge command for that bridge. The command consists of the nonce and a unique ID.
  8. If there’s an active heartbeat long-poll, the command is sent immediately, otherwise it is sent as part of the next heartbeat response. (The command field is also not yet part of the public heartbeat API.)
  9. When the bridge receives the command, it checks if the nonce is still valid. Our bridge considers the last 3 nonces as valid, you have at most 3 minutes between scanning the code and pressing the button. We do this to ensure that people are really in front of the machine when they turn it on (and haven’t, eg., taken a picture of the code some time ago).
  10. If the nonce is valid, the bridge invalidates all currently active nonces and calls /access with a special key with {type: 'remoteAccess', token: <bridge-command-id>}. This key is only valid once, only for that bridge, and only for a short time.
  11. If the nonce is not valid, the bridge sends a commandError notification as part of its next heartbeat. (These notifications are also not yet part of the public API.) This lets the server inform the user in the browser that the code was expired (or invalid).

As you can see, this is much more work for the bridge than just calling “POST /access” with you NFC key. Getting it right and working reliably requires some programming skills, knowledge of network fundamentals – and effort.

If you’re nonetheless interested in implementing it, I’d be happy to do our part and update the public API so that it supports QR activations.
For your particular use-case you could use a static code instead of the nonce if you don’t mind people being able to re-use the same code over and over again.

Let me know if you have any further questions on this topic. I’d also be interested in learning more about the particular problem you’re trying to solve.