Complete QF100 ops commands and detail UI
This commit is contained in:
@ -215,7 +215,70 @@ Behavior:
|
||||
- If `fw-version` is equal but `fw-build` is greater, the device starts OTA.
|
||||
- Otherwise, the device logs that no update is needed.
|
||||
|
||||
## 5. MQTT Device Heartbeat
|
||||
## 5. MQTT Dynamic QR Display Payload
|
||||
|
||||
The backend can ask the device to display a dynamic QR code by publishing to `mqtt.subscribe-topic`:
|
||||
|
||||
```json
|
||||
{
|
||||
"header": {
|
||||
"category": 4
|
||||
},
|
||||
"data": {
|
||||
"qr-url": "https://pay.example/qr/abc123",
|
||||
"amount": 25000,
|
||||
"expire-seconds": 60
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Required Fields
|
||||
|
||||
| Field | Type | Required | Notes |
|
||||
| --- | --- | --- | --- |
|
||||
| `header.category` | number | yes | Use `4` for dynamic QR display. |
|
||||
| `data.qr-url` | string | yes | Content encoded into the QR code. This can be a URL or any QR payload string. |
|
||||
| `data.amount` | number | yes | Amount shown on the QR page. Must be greater than `0`. |
|
||||
| `data.expire-seconds` | number | no | QR validity duration in seconds. Defaults to `60` if missing or invalid. |
|
||||
|
||||
Behavior:
|
||||
|
||||
- The device displays the QR code immediately after receiving a valid category `4` payload.
|
||||
- The QR page shows `data.qr-url` as QR content and displays `data.amount`.
|
||||
- When `expire-seconds` elapses, the device returns to the default `Bizone System` status screen.
|
||||
- If a category `1` payment notification is received while the QR page is active, the device immediately hides the QR page and returns to the default status screen before playing the payment notification.
|
||||
- This command only controls the display. It does not start the internal POS QR transaction flow.
|
||||
|
||||
## 6. MQTT Reboot Command Payload
|
||||
|
||||
The backend can ask the device to reboot by publishing to `mqtt.subscribe-topic`:
|
||||
|
||||
```json
|
||||
{
|
||||
"header": {
|
||||
"category": 5
|
||||
},
|
||||
"data": {
|
||||
"command": "reboot"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Required Fields
|
||||
|
||||
| Field | Type | Required | Notes |
|
||||
| --- | --- | --- | --- |
|
||||
| `header.category` | number | yes | Use `5` for device reboot command. |
|
||||
| `data.command` | string | yes | Must be exactly `reboot`. |
|
||||
|
||||
Behavior:
|
||||
|
||||
- The device validates `data.command` before rebooting.
|
||||
- If `data.command` is missing or not exactly `reboot`, the payload is ignored.
|
||||
- When valid, the device plays the reboot audio, shows `Rebooting...`, waits about 2 seconds, then restarts.
|
||||
- This command is backend-to-device only.
|
||||
|
||||
## 7. MQTT Device Heartbeat
|
||||
|
||||
The firmware publishes an application-level heartbeat over MQTT after it has connected and subscribed successfully.
|
||||
|
||||
@ -264,6 +327,7 @@ Timing:
|
||||
- The device publishes one heartbeat immediately after MQTT subscribe succeeds.
|
||||
- The device then publishes periodically using `mqtt.keep-alive` seconds from the config response.
|
||||
- If `mqtt.keep-alive` is `0`, firmware falls back to `60` seconds.
|
||||
- Current firmware synchronizes device time with NTP timezone `UTC+7`, so `data.time` represents WIB local time.
|
||||
|
||||
Backend handling:
|
||||
|
||||
@ -280,11 +344,11 @@ Backend handling:
|
||||
| `data.client-id` | string | yes | MQTT client ID from config response. |
|
||||
| `data.fw-version` | string | yes | Firmware version. |
|
||||
| `data.fw-build` | number | yes | Firmware build number. |
|
||||
| `data.time` | string | yes | Device local time in `YYYYMMDDHHMMSS` format. |
|
||||
| `data.time` | string | yes | Device local time in `YYYYMMDDHHMMSS` format, currently WIB/UTC+7. |
|
||||
| `data.battery-level` | number | yes | Battery percentage calculated by firmware, `0` to `100`. |
|
||||
| `data.wifi-ap` | object | optional | Present only when WiFi data is available. |
|
||||
| `data.wifi-ap.ssid` | string | optional | Current configured WiFi SSID. |
|
||||
| `data.wifi-ap.mac` | string | optional | AP MAC/BSSID, included only when the firmware can match it from WiFi scan result. |
|
||||
| `data.wifi-ap.mac` | string | optional | Reserved for AP MAC/BSSID. Current stability-focused firmware does not scan AP list during heartbeat, so this is usually absent. |
|
||||
| `data.wifi-ap.rssi` | number | optional | Connected WiFi RSSI from SDK. |
|
||||
| `data.main-cell-info` | object | optional | Present only when GPRS/cellular data is available. |
|
||||
| `data.main-cell-info.mcc` | number | optional | Parsed from IMSI when available. |
|
||||
@ -294,12 +358,12 @@ Backend handling:
|
||||
Important:
|
||||
|
||||
- `wifi-ap` and `main-cell-info` are optional. Backend should not reject heartbeat if either object is absent.
|
||||
- `wifi-ap.mac` is optional because the current SDK exposes AP MAC through scan results, not a direct "current BSSID" API.
|
||||
- `wifi-ap.mac` is optional because the current SDK exposes AP MAC through scan results, not a direct "current BSSID" API. The firmware avoids WiFi scanning inside routine heartbeat to keep heartbeat stable.
|
||||
- `main-cell-info.lac` and `main-cell-info.cell-id` are not sent by this firmware build because no SDK API for those values is available in this repo.
|
||||
|
||||
## 6. Unsupported Categories
|
||||
## 8. Unsupported Categories
|
||||
|
||||
For any category other than `1` or `2`, the firmware still requires:
|
||||
For unsupported categories, the firmware still requires:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -310,9 +374,9 @@ For any category other than `1` or `2`, the firmware still requires:
|
||||
}
|
||||
```
|
||||
|
||||
The current firmware does not perform any action for unsupported categories.
|
||||
The current firmware handles categories `1`, `2`, `4`, and `5` from backend-to-device messages. Category `3` is used by device-to-backend heartbeat. Other categories do not perform any action.
|
||||
|
||||
## 7. OTA Check API Response
|
||||
## 9. OTA Check API Response
|
||||
|
||||
After an OTA trigger, the device calls the update check API configured by `UPDATE_ADDR`.
|
||||
|
||||
@ -345,7 +409,7 @@ Special error codes:
|
||||
|
||||
The firmware treats both as no-update conditions.
|
||||
|
||||
## 8. OTA Result Upload
|
||||
## 10. OTA Result Upload
|
||||
|
||||
The device uploads OTA result to `RESULT_ADDR`.
|
||||
|
||||
@ -360,7 +424,7 @@ Request body:
|
||||
|
||||
The current firmware sends the request but does not parse the response body.
|
||||
|
||||
## 9. Recommended Topic Design
|
||||
## 11. Recommended Topic Design
|
||||
|
||||
Use one downlink topic per device:
|
||||
|
||||
@ -397,7 +461,7 @@ Backend can listen for heartbeat on:
|
||||
soundbox/{dev-sn}/down/heartbeat
|
||||
```
|
||||
|
||||
## 10. End-to-End Example
|
||||
## 12. End-to-End Example
|
||||
|
||||
### Config Response
|
||||
|
||||
@ -459,6 +523,50 @@ Payload:
|
||||
}
|
||||
```
|
||||
|
||||
### Dynamic QR Publish
|
||||
|
||||
Publish to:
|
||||
|
||||
```text
|
||||
soundbox/QF100123456/down
|
||||
```
|
||||
|
||||
Payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"header": {
|
||||
"category": 4
|
||||
},
|
||||
"data": {
|
||||
"qr-url": "https://pay.example/qr/abc123",
|
||||
"amount": 25000,
|
||||
"expire-seconds": 60
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Reboot Command Publish
|
||||
|
||||
Publish to:
|
||||
|
||||
```text
|
||||
soundbox/QF100123456/down
|
||||
```
|
||||
|
||||
Payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"header": {
|
||||
"category": 5
|
||||
},
|
||||
"data": {
|
||||
"command": "reboot"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Heartbeat From Device
|
||||
|
||||
Subscribe to:
|
||||
@ -485,11 +593,12 @@ Payload received:
|
||||
}
|
||||
```
|
||||
|
||||
## 11. Notes For Backend Implementation
|
||||
## 13. Notes For Backend Implementation
|
||||
|
||||
- Always publish valid JSON.
|
||||
- Always use JSON numbers for numeric fields.
|
||||
- Do not use strings for `category`, `pay-amount`, `fw-build`, `broker-port`, or `keep-alive`.
|
||||
- Do not use strings for `category`, `pay-amount`, `amount`, `expire-seconds`, `fw-build`, `broker-port`, or `keep-alive`.
|
||||
- For reboot, send `data.command` exactly as the string `reboot`.
|
||||
- Keep `client-id` unique per device.
|
||||
- Use the device serial number `dev-sn` as the main device identifier.
|
||||
- The firmware logs MQTT payloads through CATStudio/DIAG, useful for debugging invalid payloads.
|
||||
|
||||
Reference in New Issue
Block a user