Files
Stream_PHX_A7/Gateways/FE/projects/.resources/0ec7361528b93f2e4a762524ff5649bf362b413089b705521bcb13a6e80176b7

850 lines
34 KiB
Plaintext

{
"custom": {
"refreshTimerInterval": null
},
"params": {
"deviceType": "Battery",
"tagPath": "[PHXA2_IG_COMN]System/Device Lists/Battery"
},
"propConfig": {
"custom.automaticUpdateEnabled": {
"binding": {
"config": {
"bidirectional": true,
"coalesce": true,
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/Config/Enable Automatic Refresh"
},
"type": "tag"
},
"persistent": false
},
"custom.deviceData": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/Device Data"
},
"type": "tag"
},
"persistent": false
},
"custom.isLoaded": {
"binding": {
"config": {
"struct": {
"deviceData": "{view.custom.deviceData}"
},
"waitOnAll": true
},
"transforms": [
{
"expression": "True",
"type": "expression"
}
],
"type": "expr-struct"
},
"persistent": false
},
"custom.lastUpdate": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/Last Update"
},
"transforms": [
{
"expression": "//dateFormat({value}, \"MM/dd, hh:mm:ss aa\")\r\ndateFormat(dateArithmetic({value}, -7, \"hour\"), \"MM/dd, hh:mm:ss aa\")",
"type": "expression"
}
],
"type": "tag"
},
"persistent": false
},
"custom.refreshTimerInterval": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/Parameters.Refresh Timer Interval"
},
"type": "tag"
},
"persistent": true
},
"custom.tableColumns": {
"binding": {
"config": {
"path": "view.custom.tagsToRead"
},
"transforms": [
{
"code": "\timport copy, time\n\t\n\t# Convert a string to camelCase. We do this because Ignition doesn\u0027t like\n\t# keys being spaced strings. (i.e \u0027Discharge Air Temperature\u0027)\n\tdef to_camel_case(text):\n\t words \u003d text.split()\n\t return words[0].lower() + \u0027\u0027.join(word.capitalize() for word in words[1:])\n\t \n\t# Define the default configuration for a column.\n\tbase_config \u003d {\n\t \"field\": \"\",\n\t \"visible\": True,\n\t \"editable\": False,\n\t \"render\": \"auto\",\n\t \"justify\": \"auto\",\n\t \"align\": \"center\",\n\t \"resizable\": True,\n\t \"sortable\": True,\n\t \"sort\": \"none\",\n\t \"filter\": {\n\t \"enabled\": False,\n\t \"visible\": \"on-hover\",\n\t \"string\": {\"condition\": \"\", \"value\": \"\"},\n\t \"number\": {\"condition\": \"\", \"value\": \"\"},\n\t \"boolean\": {\"condition\": \"\"},\n\t \"date\": {\"condition\": \"\", \"value\": \"\"}\n\t },\n\t \"viewPath\": \"\",\n\t \"viewParams\": {},\n\t \"boolean\": \"checkbox\",\n\t \"number\": \"value\",\n\t \"progressBar\": {\n\t \"max\": 100,\n\t \"min\": 0,\n\t \"bar\": {\"color\": \"\", \"style\": {\"classes\": \"\"}},\n\t \"track\": {\"color\": \"\", \"style\": {\"classes\": \"\"}},\n\t \"value\": {\n\t \"enabled\": True,\n\t \"format\": \"0,0.##\",\n\t \"justify\": \"center\",\n\t \"style\": {\"classes\": \"\"}\n\t }\n\t },\n\t \"toggleSwitch\": {\n\t \"color\": {\"selected\": \"\", \"unselected\": \"\"}\n\t },\n\t \"nullFormat\": {\n\t \"includeNullStrings\": False,\n\t \"strict\": False,\n\t \"nullFormatValue\": \"\"\n\t },\n\t \"numberFormat\": \"0,0.##\",\n\t \"dateFormat\": \"MM/DD/YYYY\",\n\t \"width\": \"\",\n\t \"strictWidth\": False,\n\t \"header\": {\n\t \"title\": \"nothingBurger\",\n\t \"justify\": \"left\",\n\t \"align\": \"center\",\n\t \"style\": {\"classes\": \"\"}\n\t },\n\t \"footer\": {\n\t \"title\": \"\",\n\t \"justify\": \"left\",\n\t \"align\": \"center\",\n\t \"style\": {\"classes\": \"\"}\n\t },\n\t \"style\": {\"classes\": \"\"}\n\t}\n\t\n\tres \u003d []\n\tfor idx, column in enumerate(value): # Expects \u0027CHW Valve Command\u0027\n\t\tconfig \u003d copy.deepcopy(base_config)\n\t\t\n\t\t# Convert \"Meta/Building\" -\u003e \"Building\"\n\t\tif \u0027/\u0027 in column:\n\t\t\tcolumn \u003d column.split(\u0027/\u0027)[-1] \n\t\t\t\n\t\tif \u0027Parameters\u0027 in column:\n\t\t\tcolumn \u003d column[10:]\n\t\t\t\n\t\tif idx \u003d\u003d 0: # Set extra width to the device name column.\n\t\t\tconfig[\u0027width\u0027] \u003d 120\n\t\t\t\n\t\t# Update the column data and header to the tagToRead.\n\t\tconfig[\u0027field\u0027] \u003d to_camel_case(column) # \"CHW Valve Command\" -\u003e \"chwValveCommand\"\n\t\tconfig[\u0027header\u0027][\u0027title\u0027] \u003d column\n\t\tres.append(config)\n\n\treturn res\n\t",
"type": "script"
}
],
"type": "property"
},
"persistent": false
},
"custom.tagsToRead": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/Config/Tags To Read"
},
"type": "tag"
},
"persistent": false
},
"custom.updateTableTimer": {
"binding": {
"config": {
"expression": "now(15000) // This updates the binding every fifteen seconds, which triggers the on-change script."
},
"enabled": false,
"transforms": [
{
"expression": "dateFormat({value}, \"h:mm:ss a\")",
"type": "expression"
}
],
"type": "expr"
},
"onChange": {
"enabled": null,
"script": "\tif self.custom.automaticUpdateEnabled:\n\t\tsystem.perspective.sendMessage(\u0027updateTableData\u0027, {})"
},
"persistent": false
},
"params.deviceType": {
"paramDirection": "input",
"persistent": true
},
"params.selectedDeviceTagpath": {
"binding": {
"config": {
"path": "/root/Location/Table.props.selection.selectedRow"
},
"transforms": [
{
"expression": "{view.custom.deviceData}[{value}][\u0027value\u0027][\u0027tagPath\u0027]",
"type": "expression"
}
],
"type": "property"
},
"paramDirection": "output",
"persistent": false
},
"params.tagPath": {
"paramDirection": "input",
"persistent": true
}
},
"props": {
"defaultSize": {
"height": 1584,
"width": 1303
},
"loading": {
"mode": "blocking"
}
},
"root": {
"children": [
{
"children": [
{
"children": [
{
"children": [
{
"meta": {
"name": "Markdown_1"
},
"position": {
"shrink": 0
},
"props": {
"source": "Batteries",
"style": {
"alignSelf": "center",
"classes": "labels/text-xl"
}
},
"type": "ia.display.markdown"
},
{
"children": [
{
"children": [
{
"events": {
"dom": {
"onClick": {
"config": {
"script": "\tself.view.custom.automaticUpdateEnabled \u003d not self.view.custom.automaticUpdateEnabled"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "Icon",
"tooltip": {
"enabled": true,
"location": "top",
"style": {
"classes": "labels/text-md"
}
}
},
"position": {
"grow": 1
},
"propConfig": {
"meta.tooltip.text": {
"binding": {
"config": {
"struct": {
"automaticUpdateInterval": "numberFormat(toInt({view.custom.refreshTimerInterval}) / 1000, \u00270.#\u0027)",
"automaticUpdatesEnabled": "{view.custom.automaticUpdateEnabled}"
},
"waitOnAll": true
},
"transforms": [
{
"expression": "if({value}[\u0027automaticUpdatesEnabled\u0027],\r\n\tstringFormat(\"Automatic updates are currently enabled. \\nThe table will update every %s seconds.\", {value}[\u0027automaticUpdateInterval\u0027]),\r\n\t\"Automatic updates are currently disabled. Click to enable them.\"\r\n)",
"type": "expression"
}
],
"type": "expr-struct"
}
},
"props.color": {
"binding": {
"config": {
"path": "view.custom.automaticUpdateEnabled"
},
"transforms": [
{
"fallback": "#AAAAAA",
"inputType": "scalar",
"mappings": [
{
"input": true,
"output": "#00D9D9"
}
],
"outputType": "color",
"type": "map"
}
],
"type": "property"
}
},
"props.style.classes": {
"binding": {
"config": {
"path": "view.custom.automaticUpdateEnabled"
},
"transforms": [
{
"expression": "if({value}, \u0027rotate\u0027, \u0027\u0027)",
"type": "expression"
}
],
"type": "property"
}
}
},
"props": {
"path": "material/autorenew",
"style": {
"cursor": "pointer"
}
},
"type": "ia.display.icon"
}
],
"meta": {
"name": "IconContainer"
},
"position": {
"basis": "1.5rem",
"shrink": 0
},
"props": {
"style": {
"classes": "Animation/pulse containers/HoverOver",
"marginLeft": "0.5rem",
"overflow": "hidden"
}
},
"type": "ia.container.flex"
},
{
"events": {
"dom": {
"onClick": {
"config": {
"script": "\tself.view.custom.automaticUpdateEnabled \u003d not self.view.custom.automaticUpdateEnabled"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "updateLabel"
},
"position": {
"grow": 1,
"shrink": 0
},
"propConfig": {
"props.source": {
"binding": {
"config": {
"path": "view.custom.lastUpdate"
},
"transforms": [
{
"expression": "concat(\"Last Update: \", {value})",
"type": "expression"
}
],
"type": "property"
},
"onChange": {
"enabled": null,
"script": "\tsystem.perspective.sendMessage(\u0027flashTimerText\u0027, {})"
},
"persistent": true
}
},
"props": {
"markdown": {
"escapeHtml": false
},
"source": "Last Update: 05/14, 02:25:30 PM",
"style": {
"alignContent": "center",
"classes": "labels/text-sm, Animation/fadeToBlack_A",
"cursor": "pointer",
"fontWeight": "400",
"opacity": 0.5,
"paddingRight": "0.25rem",
"textAlign": "right"
}
},
"type": "ia.display.markdown"
},
{
"events": {
"dom": {
"onClick": {
"config": {
"script": "\tsystem.perspective.sendMessage(\u0027updateTableData\u0027, {})"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "Button"
},
"position": {
"basis": "6rem",
"shrink": 0
},
"props": {
"image": {
"height": 0,
"width": 0
},
"style": {
"backgroundColor": "--tagvalue-color",
"color": "white"
},
"text": "Refresh Data",
"textStyle": {
"color": "white"
}
},
"type": "ia.input.button"
}
],
"meta": {
"name": "FlexContainer"
},
"position": {
"grow": 1
},
"props": {
"alignItems": "center",
"style": {
"gap": "0.5rem",
"overflow": "hidden",
"padding": "1rem 0"
},
"wrap": "wrap"
},
"type": "ia.container.flex"
}
],
"meta": {
"name": "LargeHeader"
},
"position": {
"size": "large"
},
"props": {
"alignItems": "center",
"style": {
"overflow": "hidden",
"paddingRight": "0.5rem",
"width": "100%"
}
},
"type": "ia.container.flex"
},
{
"children": [
{
"meta": {
"name": "Markdown_1"
},
"position": {
"shrink": 0
},
"props": {
"source": "Device List",
"style": {
"alignSelf": "center",
"classes": "labels/text-xl"
}
},
"type": "ia.display.markdown"
},
{
"children": [
{
"children": [
{
"events": {
"dom": {
"onClick": {
"config": {
"script": "\tself.view.custom.automaticUpdateEnabled \u003d not self.view.custom.automaticUpdateEnabled"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "Icon",
"tooltip": {
"enabled": true,
"location": "top",
"style": {
"classes": "labels/text-md"
}
}
},
"position": {
"grow": 1
},
"propConfig": {
"meta.tooltip.text": {
"binding": {
"config": {
"struct": {
"automaticUpdateInterval": "numberFormat(toInt({view.custom.refreshTimerInterval}) / 1000, \u00270.#\u0027)",
"automaticUpdatesEnabled": "{view.custom.automaticUpdateEnabled}"
},
"waitOnAll": true
},
"transforms": [
{
"expression": "if({value}[\u0027automaticUpdatesEnabled\u0027],\r\n\tstringFormat(\"Automatic updates are currently enabled. \\nThe table will update every %s seconds.\", {value}[\u0027automaticUpdateInterval\u0027]),\r\n\t\"Automatic updates are currently disabled. Click to enable them.\"\r\n)",
"type": "expression"
}
],
"type": "expr-struct"
}
},
"props.color": {
"binding": {
"config": {
"path": "view.custom.automaticUpdateEnabled"
},
"transforms": [
{
"fallback": "#AAAAAA",
"inputType": "scalar",
"mappings": [
{
"input": true,
"output": "#00D9D9"
}
],
"outputType": "color",
"type": "map"
}
],
"type": "property"
}
},
"props.style.classes": {
"binding": {
"config": {
"path": "view.custom.automaticUpdateEnabled"
},
"transforms": [
{
"expression": "if({value}, \u0027rotate\u0027, \u0027\u0027)",
"type": "expression"
}
],
"type": "property"
}
}
},
"props": {
"path": "material/autorenew",
"style": {
"cursor": "pointer"
}
},
"type": "ia.display.icon"
}
],
"meta": {
"name": "IconContainer"
},
"position": {
"basis": "1.5rem",
"shrink": 0
},
"props": {
"style": {
"classes": "Animation/pulse containers/HoverOver",
"marginLeft": "0.5rem",
"overflow": "hidden"
}
},
"type": "ia.container.flex"
},
{
"events": {
"dom": {
"onClick": {
"config": {
"script": "\tsystem.perspective.sendMessage(\u0027updateTableData\u0027, {})"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "Button"
},
"position": {
"basis": "6rem",
"shrink": 0
},
"props": {
"image": {
"height": 0,
"width": 0
},
"style": {
"backgroundColor": "--tagvalue-color",
"color": "white"
},
"text": "Refresh Data",
"textStyle": {
"color": "white"
}
},
"type": "ia.input.button"
}
],
"meta": {
"name": "FlexContainer"
},
"position": {
"grow": 1
},
"props": {
"alignItems": "center",
"justify": "space-between",
"style": {
"gap": "0.5rem",
"overflow": "hidden",
"padding": "1rem 0"
},
"wrap": "wrap"
},
"type": "ia.container.flex"
}
],
"meta": {
"name": "SmallHeader"
},
"props": {
"alignItems": "center",
"style": {
"overflow": "hidden",
"paddingRight": "0.5rem",
"width": "100%"
}
},
"type": "ia.container.flex"
}
],
"meta": {
"name": "BreakpointContainer"
},
"position": {
"basis": "2.5rem",
"shrink": 0
},
"props": {
"breakpoint": 480,
"currentBreakpoint": "large"
},
"type": "ia.container.breakpt"
},
{
"children": [
{
"meta": {
"name": "Markdown"
},
"props": {
"source": "Loading...",
"style": {
"classes": "Animation/loading labels/text-xl",
"textAlign": "center"
}
},
"type": "ia.display.markdown"
},
{
"meta": {
"name": "Progress"
},
"props": {
"bar": {
"color": "#D5D5D5"
},
"mode": "indeterminate",
"style": {
"height": "0.5rem",
"width": "12rem"
},
"track": {
"color": "#AAAAAA"
}
},
"type": "ia.display.progress"
}
],
"meta": {
"name": "Loading"
},
"position": {
"basis": "100%",
"grow": 1,
"shrink": 0
},
"propConfig": {
"position.display": {
"binding": {
"config": {
"expression": "!{view.custom.isLoaded}"
},
"type": "expr"
}
}
},
"props": {
"alignItems": "center",
"direction": "column",
"justify": "center",
"style": {
"backgroundColor": "#d9d8d4",
"gap": "1rem"
}
},
"type": "ia.container.flex"
},
{
"events": {
"component": {
"onRowClick": {
"config": {
"script": "\ttagPath \u003d str(self.view.params.selectedDeviceTagpath)\n\t\n\t# Retrieve device name from tagpath, accounting for /1 and nested UDTs.\n\tnoTagProvider \u003d tagPath.partition(\u0027]\u0027)[2]\n\tstart, _, after \u003d noTagProvider.partition(\u0027PHXA2\u0027)\n\tmiddle, _, _ \u003d after.rpartition(\u0027/\u0027)\n\t\n\tif middle:\n\t\tsystem.perspective.sendMessage(\u0027updateFloorplanDeviceRoom\u0027, \u0027PHXA2%s\u0027 % middle)\n\telse:\n\t\tsystem.perspective.sendMessage(\u0027updateFloorplanDeviceRoom\u0027, \u0027PHXA2%s\u0027 % after)"
},
"enabled": false,
"scope": "G",
"type": "script"
},
"onRowDoubleClick": {
"config": {
"script": "\tutils.nav.openEQPopup(self.view.params.deviceType, self.view.params.selectedDeviceTagpath)"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "Table"
},
"position": {
"grow": 1,
"shrink": 0
},
"propConfig": {
"meta.visible": {
"binding": {
"config": {
"path": "view.custom.isLoaded"
},
"type": "property"
}
},
"position.display": {
"binding": {
"config": {
"path": "view.custom.isLoaded"
},
"type": "property"
},
"persistent": false
},
"props.columns": {
"binding": {
"config": {
"path": "view.custom.tableColumns"
},
"type": "property"
}
},
"props.data": {
"binding": {
"config": {
"path": "view.custom.deviceData"
},
"type": "property"
}
}
},
"props": {
"cells": {
"style": {
"cursor": "pointer"
}
},
"emptyMessage": {
"noData": {
"text": "N/A"
}
},
"filter": {
"results": {
"enabled": true
}
},
"pager": {
"bottom": false
},
"rows": {
"striped": {
"color": {
"even": "#D5D5D5"
}
}
}
},
"type": "ia.display.table"
}
],
"meta": {
"name": "Location"
},
"position": {
"basis": "33%",
"grow": 1
},
"props": {
"alignContent": "space-between",
"direction": "column",
"justify": "space-around",
"style": {
"gap": "0.25rem",
"height": "100%",
"overflow": "hidden"
}
},
"type": "ia.container.flex"
}
],
"meta": {
"name": "root"
},
"props": {
"direction": "column"
},
"scripts": {
"customMethods": [],
"extensionFunctions": null,
"messageHandlers": [
{
"messageType": "updateTableData",
"pageScope": true,
"script": "\t# If the data hasn\u0027t loaded, don\u0027t refresh.\n\tif not self.view.custom.isLoaded:\n\t\treturn\n\t\n\t# Write to the manual refresh command and refresh the time.\n\tsystem.tag.writeBlocking(self.view.params.tagPath + \u0027/Config/Manual Refresh Command\u0027, True)\n#\tcurrentTime \u003d \u0027Last Update: *{}*\u0027.format(system.date.format(system.date.now(), \"hh:mm:ss aa\"))\n#\tself.getChild(\"Location\").getChild(\"FlexContainer\").getChild(\"FlexContainer\").getChild(\"updateLabel\").props.source \u003d currentTime\n\t\n#\t\t\n#\ttry:\n#\t\tself.view.refreshBinding(\u0027custom.deviceData\u0027)\n#\texcept:\n#\t\tsystem.perspective.print(\u0027Device data binding disabled.\u0027)",
"sessionScope": false,
"viewScope": true
},
{
"messageType": "flashTimerText",
"pageScope": true,
"script": "\t\"\"\"\n\t\tHelper function called by the \u0027Last Update:\u0027 text to flash when it updates.\n\t\"\"\"\n\tclasses \u003d self.getChild(\"Location\").getChild(\"BreakpointContainer\").getChild(\"LargeHeader\").getChild(\"FlexContainer\").getChild(\"updateLabel\").props.style.classes\n\t\n\t# Refresh the animation by toggling between two identical classes.\n\tif \u0027fadeToBlack_A\u0027 in classes:\n\t\tself.getChild(\"Location\").getChild(\"BreakpointContainer\").getChild(\"LargeHeader\").getChild(\"FlexContainer\").getChild(\"updateLabel\").props.style.classes \u003d \"labels/text-sm, Animation/fadeToBlack_B\"\n\telse:\n\t\tself.getChild(\"Location\").getChild(\"BreakpointContainer\").getChild(\"LargeHeader\").getChild(\"FlexContainer\").getChild(\"updateLabel\").props.style.classes \u003d \"labels/text-sm, Animation/fadeToBlack_A\"",
"sessionScope": false,
"viewScope": true
}
]
},
"type": "ia.container.flex"
}
}