Skip to content

Duress DV (duress.json)

This is the Device View shown when a staff member opens the Duress app on the CC2 badge.
It displays incoming duress alerts with the subject’s name and location, lets the user configure alert feedback (LED, vibration, sound), and shows a detailed view of a single alert for acknowledgement.

File: /dvs/duress.json


Click to expand
{
"displayIcon": "ic_bug_report_black_24dp",
"displayName": "duress",
"infopages": [
{
"displayName": "Alert Home",
"id": "1",
"infowidgets": [
{
"interaction": "static",
"region": { "h": 100, "w": 100, "x": 35, "y": 20 },
"value": "alert_bell",
"format": "graphic",
"formatter": {
"name": "basic",
"outline": "solid_rounded",
"outline_sz": 2,
"halign": "c",
"valign": "c"
}
},
{
"name": "alerts",
"region": { "h": 40, "w": 156, "x": 10, "y": 130 },
"format": "text",
"interaction": "editable",
"onEntry": "updateRemote",
"value": [
{ "id": "1", "subj": "Brian", "location": "Room 101", "resp": 0 },
{ "id": "2", "subj": "Toto", "location": "Room 102", "resp": 0 },
{ "id": "3", "subj": "Tata", "location": "Room 103", "resp": 0 }
],
"formatter": {
"name": "text",
"autobreak": true,
"font": { "sz": 34, "weight": "normal" },
"outline": "solid_rounded",
"outline_sz": 1,
"halign": "c",
"valign": "c"
},
"ded": {
"type": "alerts",
"dv": "duress",
"ip": "ded_alert_skel"
}
}
]
},
{
"id": "2",
"infowidgets": [
{
"interaction": "static",
"region": { "x": 5, "y": 0, "w": 165, "h": 30 },
"value": "Config Duress",
"format": "text",
"formatter": {
"name": "basic",
"valign": "center",
"halign": "center",
"autobreak": true,
"font": { "sz": 22 }
}
},
{
"interaction": "button",
"name": "devcfg.alert.showFlash",
"region": { "x": 5, "y": 40, "w": 50, "h": 50 },
"value": true,
"onEntry": "updateLocal",
"format": "text",
"formatter": {
"name": "bool",
"valign": "center",
"halign": "center",
"autobreak": true,
"text_true": "Flash LEDs",
"text_false": "No LEDs",
"outline": "solid_rounded",
"outline_sz": 1,
"font": { "sz": 22 }
},
"ded": { "type": "bool_inplace" }
},
{
"interaction": "button",
"name": "devcfg.alert.showVibr",
"region": { "x": 60, "y": 40, "w": 50, "h": 50 },
"value": true,
"onEntry": "updateLocal",
"format": "text",
"formatter": {
"name": "bool",
"valign": "center",
"halign": "center",
"autobreak": true,
"text_true": "Vibr ON",
"text_false": "Vibr OFF",
"outline": "solid_rounded",
"outline_sz": 1,
"font": { "sz": 22 }
},
"ded": { "type": "bool_inplace" }
},
{
"interaction": "editable",
"name": "devcfg.alert.showSound",
"region": { "x": 115, "y": 40, "w": 50, "h": 50 },
"value": true,
"onEntry": "updateLocal",
"format": "text",
"formatter": {
"name": "bool",
"valign": "center",
"halign": "center",
"autobreak": true,
"text_true": "Audio ON",
"text_false": "Audio OFF",
"outline": "solid_rounded",
"outline_sz": 1,
"font": { "sz": 22 }
},
"ded": { "type": "bool_inplace" }
},
{
"interaction": "button",
"name": "play_vibr",
"region": { "x": 5, "y": 100, "w": 50, "h": 50 },
"displayValue": "Vibr test",
"value": "V10S10V10S10V10",
"onEntry": "updateOutput",
"target": "devcfg.vibr.song",
"format": "text",
"formatter": {
"name": "basic",
"valign": "center",
"halign": "center",
"autobreak": true,
"outline": "solid_rounded",
"outline_sz": 1,
"font": { "sz": 22 }
}
},
{
"interaction": "editable",
"name": "led_colour",
"region": { "x": 60, "y": 100, "w": 50, "h": 50 },
"onEntry": "updateOutput",
"target": "devcfg.led.led0",
"value": "S1:LED0 ON:0,S0:LED0 OFF:0,F0:LED0 SLOW:0,F1:LED0 FAST:1,B0:LED0 BLINKS:0,B1:LED0 BLINKF:0",
"format": "text",
"formatter": {
"name": "list",
"halign": "center",
"valign": "center",
"autobreak": true,
"outline": "solid_rounded",
"outline_sz": 1,
"font": { "sz": 22 }
},
"ded": { "type": "1ofN_inplace" }
},
{
"interaction": "button",
"name": "play_alert",
"region": { "x": 115, "y": 100, "w": 50, "h": 50 },
"displayValue": "Audio test",
"value": "ABF",
"onEntry": "updateOutput",
"target": "devcfg.audioout.alert",
"format": "text",
"formatter": {
"name": "basic",
"valign": "center",
"halign": "center",
"autobreak": true,
"outline": "solid_rounded",
"outline_sz": 1,
"font": { "sz": 22 }
}
},
{
"interaction": "editable",
"name": "devcfg.nfc.emul",
"region": { "x": 5, "y": 160, "w": 50, "h": 50 },
"value": false,
"format": "text",
"formatter": {
"name": "bool",
"valign": "center",
"halign": "center",
"autobreak": true,
"text_true": "NFC ON",
"text_false": "NFC OFF",
"outline": "solid_rounded",
"outline_sz": 1,
"font": { "sz": 22 }
},
"ded": { "type": "bool_inplace" }
}
]
},
{
"displayName": "Alert",
"id": "ded_alert_skel",
"infowidgets": [
{
"name": "isRead",
"region": { "h": 40, "w": 156, "x": 10, "y": 5 },
"format": "bool",
"formatter": {
"text_true": "Alert",
"text_false": "**Alert**",
"autobreak": true,
"font": { "sz": 34, "weight": "normal" },
"halign": "c",
"outline": "solid_rounded",
"outline_sz": 2,
"valign": "c"
},
"interaction": "static",
"value": "Alert"
},
{
"name": "msgIdx",
"region": { "h": 20, "w": 30, "x": 55, "y": 50 },
"format": "number",
"formatter": {
"autobreak": false,
"dp": 0,
"font": { "sz": 14, "weight": "bold" },
"halign": "r",
"outline": "none",
"valign": "c"
},
"interaction": "dynamic",
"value": "-"
},
{
"region": { "h": 20, "w": 20, "x": 85, "y": 50 },
"format": "text",
"formatter": {
"autobreak": false,
"font": { "sz": 14, "weight": "bold" },
"halign": "c",
"outline": "none",
"valign": "c"
},
"interaction": "static",
"value": "/"
},
{
"name": "nMsgs",
"region": { "h": 20, "w": 30, "x": 105, "y": 50 },
"format": "number",
"formatter": {
"autobreak": false,
"dp": 0,
"font": { "sz": 14, "weight": "bold" },
"halign": "l",
"outline": "none",
"valign": "c"
},
"interaction": "dynamic",
"value": "-"
},
{
"name": "subj",
"region": { "h": 30, "w": 156, "x": 10, "y": 75 },
"format": "text",
"formatter": {
"autobreak": true,
"font": { "sz": 26, "weight": "normal" },
"halign": "c",
"outline": "none",
"outline_sz": 2,
"valign": "c"
},
"interaction": "dynamic",
"value": ""
},
{
"region": { "h": 20, "w": 156, "x": 10, "y": 110 },
"format": "text",
"formatter": {
"autobreak": true,
"font": { "sz": 14, "weight": "bold" },
"halign": "c",
"outline": "none",
"outline_sz": 2,
"valign": "c"
},
"interaction": "static",
"value": "location"
},
{
"name": "location",
"region": { "h": 40, "w": 156, "x": 10, "y": 130 },
"format": "text",
"formatter": {
"autobreak": true,
"font": { "sz": 26, "weight": "normal" },
"halign": "c",
"outline": "none",
"underline": true,
"valign": "c"
},
"interaction": "dynamic",
"value": ""
},
{
"name": "ackyes",
"region": { "h": 60, "w": 60, "x": 10, "y": 180 },
"format": "graphic",
"formatter": {
"halign": "center",
"name": "basic",
"outline": "solid_rounded",
"outline_sz": 2,
"valign": "center"
},
"interaction": "button",
"value": "ic_done_black_24dp",
"actions": [{ "a": "updateRemote", "p": "yes" }]
},
{
"name": "resp",
"region": { "h": 30, "w": 40, "x": 80, "y": 180 },
"format": "number",
"formatter": {
"autobreak": true,
"dp": 0,
"font": { "sz": 26, "weight": "normal" },
"halign": "c",
"outline": "none",
"valign": "c"
},
"interaction": "dynamic",
"value": ""
},
{
"name": "iresp",
"region": { "h": 30, "w": 40, "x": 80, "y": 210 },
"format": "bool",
"formatter": {
"text_true": "YES",
"text_false": "NO",
"autobreak": true,
"font": { "sz": 14, "weight": "bold" },
"halign": "c",
"outline": "none",
"valign": "c"
},
"interaction": "dynamic",
"value": false
},
{
"name": "del",
"region": { "h": 60, "w": 40, "x": 130, "y": 180 },
"format": "graphic",
"formatter": {
"halign": "center",
"name": "basic",
"outline": "solid_rounded",
"outline_sz": 2,
"valign": "center"
},
"interaction": "button",
"value": "bin_closed",
"actions": [{ "a": "delmsg" }]
}
]
}
]
}

WidgetTypeInteractionPurpose
alert_bell (static)graphicstaticAlert bell icon decoration
alertsmsglisteditableShows active duress alerts – each with subj, location, resp. Tap opens detail DED.

Value set by: duress_appMQTT app.duress command.
The initial static array [ { "id":"1", "subj":"Brian", ... } ] is only a placeholder; real alerts come from the portal.

WidgetTypeInteractionPurpose
(label) “Config Duress”textstaticPage title
devcfg.alert.showFlashbool_inplacebutton (toggle)Enable/disable LED flash on alert
devcfg.alert.showVibrbool_inplacebutton (toggle)Enable/disable vibration on alert
devcfg.alert.showSoundbool_inplacebutton (toggle)Enable/disable audio on alert
play_vibrbuttonbuttonTest vibration pattern (sends updateOutput to devcfg.vibr.song)
led_colour1ofN_inplaceeditableChange LED0 behaviour (list of P/S/B/F commands)
play_alertbuttonbuttonTest audio alert tone (sends updateOutput to devcfg.audioout.alert)
devcfg.nfc.emulbool_inplacebutton (toggle)Toggle NFC emulation

Page 3: Alert Detail Skeleton (id: "ded_alert_skel")

Section titled “Page 3: Alert Detail Skeleton (id: "ded_alert_skel")”
WidgetTypeInteractionPurpose
isReadboolstaticShows read/unread status (bold if unread)
msgIdxnumberdynamicCurrent message index (e.g., 1 of 3)
(separator)textstaticA / separator between index and total
nMsgsnumberdynamicTotal number of messages
subjtextdynamicThe person who triggered the alert – populated by duress_app
(label) “location”textstaticStatic label “location”
locationtextdynamicThe location string – populated by duress_app
ackyesgraphic (button)buttonAcknowledge alert – sends updateRemote to yes
respnumberdynamicResponder count
irespbooldynamicWhether the alert was acknowledged (YES/NO)
delgraphic (button)buttonDelete alert – sends delmsg

Value set by: the portal’s app.duress MQTT command populates subj, location, resp, and other alert fields.
The device’s own user data (vname, etc.) is not used for these widgets.


The alerts widget and the detail skeleton are populated exclusively by the portal when a duress is triggered. The duress_appsends:

{
"app": {
"duress": {
"data": {
"alerts": [
{
"id": "deviceId",
"subj": "duress_appAssociated User",
"location": "duress_applocation string",
"resp": 0
}
]
},
"actions": [{ "a": "gotoWidget", "p": "duress.alerts" }]
}
}
}

The subj and location fields become the notification text visible to the receiving staff member.
The device’s own vname or duresshome user data never appears here.