2026-02-28 17:04:25 +04:00

865 lines
35 KiB
JSON

{
"custom": {
"MCM": "",
"currentTable": "ACTIVE",
"dockedOpen": "value",
"page": "",
"view": ""
},
"params": {},
"propConfig": {
"custom.MCM": {
"binding": {
"config": {
"expression": "if({view.custom.view} !\u003d \"\", {view.custom.view}, {view.custom.page})"
},
"type": "expr"
},
"persistent": true
},
"custom.currentTable": {
"persistent": true
},
"custom.dockedOpen": {
"persistent": true
},
"custom.page": {
"binding": {
"config": {
"path": "page.props.path"
},
"transforms": [
{
"code": "\ttry:\n\t\tif \"MCM\" in value:\n\t\t\tindex \u003d value.find(\"MCM\")\n\t\t\treturn value[index:index+5] # MCM + 2 digits\n\texcept:\n\t\t\tpass\n\treturn \"\"",
"type": "script"
}
],
"type": "property"
},
"persistent": true
},
"custom.view": {
"binding": {
"config": {
"path": "page.props.primaryView"
},
"transforms": [
{
"code": "\ttry:\n\t\tif \"MCM\" in value:\n\t\t\tindex \u003d value.find(\"MCM\")\n\t\t\treturn value[index:index+5] # MCM + 2 digits\n\texcept:\n\t\t\tpass\n\treturn \"\"",
"type": "script"
}
],
"type": "property"
},
"persistent": true
}
},
"props": {
"defaultSize": {
"height": 250,
"width": 1920
}
},
"root": {
"children": [
{
"children": [
{
"meta": {
"name": "Label"
},
"position": {
"basis": "32px",
"grow": 1
},
"type": "ia.display.label"
}
],
"meta": {
"name": "FlexContainer"
},
"position": {
"basis": "70px",
"shrink": 0
},
"props": {
"direction": "column",
"style": {
"backgroundColor": "#3B3B3B"
}
},
"type": "ia.container.flex"
},
{
"children": [
{
"children": [
{
"custom": {
"priorities": 2
},
"events": {
"component": {
"onRowDoubleClick": {
"config": {
"script": "\tdata \u003d self.props.selection.data\n\talarms.alarm_click.handleClick(data)"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "active-table"
},
"position": {
"basis": "1080px",
"grow": 1
},
"propConfig": {
"props.data": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "direct",
"tagPath": "[MTN6_SCADA_TAG_PROVIDER]System/Queries/Alarms/ActiveAlarmsTable"
},
"transforms": [
{
"code": "\tfrom system.dataset import toPyDataSet\n\t\n\tif value is None:\n\t return []\n\t\n\tds \u003d toPyDataSet(value)\n\tcols \u003d list(ds.columnNames)\n\tdata \u003d []\n\t\n\tfor row in ds:\n\t className \u003d row[\"Style\"] # style class from the dataset\n\t\n\t row_dict \u003d {}\n\t for col in cols:\n\t row_dict[col] \u003d {\n\t \"value\": row[col],\n\t \"style\": {\"classes\": className}\n\t }\n\t data.append(row_dict)\n\t\n\treturn data",
"type": "script"
}
],
"type": "tag"
}
},
"props.query": {
"binding": {
"config": {
"expression": "now(10000)"
},
"enabled": false,
"type": "expr"
},
"onChange": {
"enabled": null,
"script": "\tfrom system import date\n\timport system\n\t\n\t# Build one row for the table\n\tdef testRow(number, eventTimeStamp, duration, priorityText, location, description, tag, styleClass):\n\t\treturn {\n\t\t\t\"value\": {\n\t\t\t\t\"NumberID\": number,\n\t\t\t\t\"EventTimestamp\": eventTimeStamp,\n\t\t\t\t\"Duration\": duration,\n\t\t\t\t\"Priority\": priorityText, # shown as \"Priority\" in your column\n\t\t\t\t\"Location\": location, # shown as \"Location\"\n\t\t\t\t\"Description\": description,\n\t\t\t\t\"Tag\": tag\n\t\t\t},\n\t\t\t\"style\": {\n\t\t\t\t\"classes\": styleClass # use Perspective style class\n\t\t\t}\n\t\t}\n\t\n\t# Map int priority -\u003e text\n\tdef priorityTextFromInt(p):\n\t\ttry:\n\t\t\tp \u003d int(p)\n\t\texcept:\n\t\t\treturn \"Unknown\"\n\t\tif p \u003d\u003d 0: return \"Diagnostic\"\n\t\tif p \u003d\u003d 1: return \"Low\"\n\t\tif p \u003d\u003d 2: return \"Medium\"\n\t\tif p \u003d\u003d 3: return \"High\"\n\t\tif p \u003d\u003d 4: return \"Critical\"\n\t\treturn \"Unknown\"\n\t\n\t# Map text priority -\u003e style class\n\tdef styleClassFromPriority(priority_str):\n\t\tif priority_str in (\"High\", \"Critical\"):\n\t\t\treturn \"Alarms-Styles/High\"\n\t\telif priority_str \u003d\u003d \"Medium\":\n\t\t\treturn \"Alarms-Styles/Medium\"\n\t\telif priority_str \u003d\u003d \"Low\":\n\t\t\treturn \"Alarms-Styles/Low\"\n\t\telif priority_str \u003d\u003d \"Diagnostic\":\n\t\t\treturn \"Alarms-Styles/Diagnostic\"\n\t\telse:\n\t\t\treturn \"Alarms-Styles/NoAlarm\"\n\t\n\t\n\t# -------------------- 0) Priority filter from FilterStatus --------------------\n\ttry:\n\t\tfilterVal \u003d self.custom.priorities\n\texcept:\n\t\tfilterVal \u003d None\n\t\n\tallPriorities \u003d [0, 1, 2, 3, 4]\n\t\n\tif filterVal is None:\n\t\tallowedPriorities \u003d allPriorities\n\telse:\n\t\ttry:\n\t\t\tf \u003d int(filterVal)\n\t\texcept:\n\t\t\tf \u003d -1\n\t\n\t\tif f \u003d\u003d 3:\n\t\t\t# High + Critical\n\t\t\tallowedPriorities \u003d [3, 4]\n\t\telif f \u003d\u003d 2:\n\t\t\t# Medium and above\n\t\t\tallowedPriorities \u003d [2, 3, 4]\n\t\telif f \u003d\u003d 1:\n\t\t\t# Low and above\n\t\t\tallowedPriorities \u003d [1, 2, 3, 4]\n\t\telif f \u003d\u003d 0:\n\t\t\t# Diagnostic and above (all)\n\t\t\tallowedPriorities \u003d [0, 1, 2, 3, 4]\n\t\telse:\n\t\t\tallowedPriorities \u003d allPriorities\n\t\n\t\n\t# -------------------- 1) queryStatus (runtime truth) -------------------------\n\tresults \u003d system.alarm.queryStatus(\n\t\tstate\u003d[\u0027ActiveUnacked\u0027, \u0027ActiveAcked\u0027],\n\t\tpriority\u003dallowedPriorities\n\t)\n\t\n\tif not results:\n\t\tself.props.data \u003d []\n\t\treturn\n\t\n\t# Unique eventIds from active alarms\n\teventIds \u003d []\n\tseen \u003d set()\n\tfor alarm in results:\n\t\tif alarm is None:\n\t\t\tcontinue\n\t\teid \u003d str(alarm.id)\n\t\tif not eid or eid in seen:\n\t\t\tcontinue\n\t\tseen.add(eid)\n\t\teventIds.append(eid)\n\t\n\tif not eventIds:\n\t\tself.props.data \u003d []\n\t\treturn\n\t\n\t\n\t# -------------------- 2) Single batched SQL to alarm_events ------------------\n\tplaceholders \u003d \",\".join([\"?\"] * len(eventIds))\n\t\n\tsql \u003d \"\"\"\n\tSELECT\n\t\tae.id AS dbId,\n\t\tae.eventid AS eventid,\n\t\tae.eventtime AS eventtime,\n\t\tae.displaypath AS displaypath,\n\t\tae.source AS source,\n\t\tae.priority AS priority,\n\t\tloc.strValue AS myLocation,\n\t\ttag.strValue AS myTag\n\tFROM alarm_events ae\n\tJOIN (\n\t\t-- FIRST activation row per eventid (start time)\n\t\tSELECT eventid, MIN(id) AS first_id\n\t\tFROM alarm_events\n\t\tWHERE eventid IN (%s)\n\t\t AND eventtype \u003d 0\n\t\tGROUP BY eventid\n\t) first ON ae.id \u003d first.first_id\n\tLEFT JOIN alarm_event_data loc\n\t\tON loc.id \u003d ae.id AND loc.propname \u003d \u0027myLocation\u0027\n\tLEFT JOIN alarm_event_data tag\n\t\tON tag.id \u003d ae.id AND tag.propname \u003d \u0027myTag\u0027\n\tORDER BY ae.eventtime DESC\n\t\"\"\" % placeholders\n\t\n\tds \u003d system.db.runPrepQuery(sql, eventIds, \"MariaDB\")\n\t\n\tdata \u003d []\n\tnow \u003d date.now()\n\tmidnightToday \u003d date.midnight(now)\n\t\n\tfor row in ds:\n\t\ttry:\n\t\t\tdbId \u003d row[\"dbId\"]\n\t\t\teventTime \u003d row[\"eventtime\"]\n\t\t\tdisplay \u003d row[\"displaypath\"] or \"\"\n\t\t\tsource \u003d row[\"source\"] or \"\"\n\t\t\tpriority \u003d row[\"priority\"]\n\t\t\tmyLocation \u003d row[\"myLocation\"] or \"\"\n\t\t\tmyTag \u003d row[\"myTag\"] or \"\"\n\t\n\t\t\t# Priority text + style class\n\t\t\tpriorityText \u003d priorityTextFromInt(priority)\n\t\t\tstyleClass \u003d styleClassFromPriority(priorityText)\n\t\n\t\t\t# Duration \u003d now - first activation\n\t\t\tseconds \u003d date.secondsBetween(eventTime, now)\n\t\t\tdurTime \u003d date.addSeconds(midnightToday, seconds)\n\t\t\tduration_str \u003d date.format(durTime, \"HH:mm:ss\")\n\t\n\t\t\t# Event timestamp\n\t\t\tevent_ts_str \u003d date.format(eventTime, \"yyyy-MM-dd HH:mm:ss\")\n\t\n\t\t\t# Description: displaypath (fixed) + alm name from source\n\t\t\tif \":/alm:\" in source:\n\t\t\t\tdesc_suffix \u003d source.split(\":/alm:\", 1)[1]\n\t\t\telse:\n\t\t\t\tdesc_suffix \u003d source\n\t\t\tdescription \u003d (display.replace(\"_\", \"-\") + \" \" + desc_suffix).strip()\n\t\n\t\t\tdata.append(\n\t\t\t\ttestRow(\n\t\t\t\t\tdbId + 30000,\n\t\t\t\t\tevent_ts_str,\n\t\t\t\t\tduration_str,\n\t\t\t\t\tpriorityText,\n\t\t\t\t\tmyLocation,\n\t\t\t\t\tdescription,\n\t\t\t\t\tmyTag,\n\t\t\t\t\tstyleClass\n\t\t\t\t)\n\t\t\t)\n\t\n\t\texcept Exception, e:\n\t\t\tsystem.perspective.print(\"Alarm row error: %s\" % e)\n\t\n\tself.props.data \u003d data"
}
}
},
"props": {
"columns": [
{
"align": "center",
"boolean": "checkbox",
"dateFormat": "MM/DD/YYYY",
"editable": false,
"field": "NumberID",
"filter": {
"boolean": {
"condition": ""
},
"date": {
"condition": "",
"value": ""
},
"enabled": false,
"number": {
"condition": "",
"value": ""
},
"string": {
"condition": "",
"value": ""
},
"visible": "on-hover"
},
"footer": {
"align": "center",
"justify": "left",
"style": {
"classes": ""
},
"title": ""
},
"header": {
"align": "center",
"justify": "center",
"style": {
"classes": ""
},
"title": ""
},
"justify": "center",
"nullFormat": {
"includeNullStrings": false,
"nullFormatValue": "",
"strict": false
},
"number": "value",
"numberFormat": "0,0.##",
"progressBar": {
"bar": {
"color": "",
"style": {
"classes": ""
}
},
"max": 100,
"min": 0,
"track": {
"color": "",
"style": {
"classes": ""
}
},
"value": {
"enabled": true,
"format": "0,0.##",
"justify": "center",
"style": {
"classes": ""
}
}
},
"render": "auto",
"resizable": true,
"sort": "none",
"sortable": true,
"strictWidth": false,
"style": {
"classes": ""
},
"toggleSwitch": {
"color": {
"selected": "",
"unselected": ""
}
},
"viewParams": {},
"viewPath": "",
"visible": true,
"width": 30
},
{
"align": "center",
"boolean": "checkbox",
"dateFormat": "MM/DD/YYYY HH:mm:ss",
"editable": false,
"field": "EventTimestamp",
"filter": {
"boolean": {
"condition": ""
},
"date": {
"condition": "",
"value": ""
},
"enabled": false,
"number": {
"condition": "",
"value": ""
},
"string": {
"condition": "",
"value": ""
},
"visible": "on-hover"
},
"footer": {
"align": "center",
"justify": "left",
"style": {
"classes": ""
},
"title": ""
},
"header": {
"align": "center",
"justify": "center",
"style": {
"classes": ""
},
"title": "Event Timestamp"
},
"justify": "center",
"nullFormat": {
"includeNullStrings": false,
"nullFormatValue": "",
"strict": false
},
"number": "value",
"numberFormat": "0,0.##",
"progressBar": {
"bar": {
"color": "",
"style": {
"classes": ""
}
},
"max": 100,
"min": 0,
"track": {
"color": "",
"style": {
"classes": ""
}
},
"value": {
"enabled": true,
"format": "0,0.##",
"justify": "center",
"style": {
"classes": ""
}
}
},
"render": "auto",
"resizable": true,
"sort": "none",
"sortable": true,
"strictWidth": false,
"style": {
"classes": ""
},
"toggleSwitch": {
"color": {
"selected": "",
"unselected": ""
}
},
"viewParams": {},
"viewPath": "",
"visible": true,
"width": 60
},
{
"align": "center",
"boolean": "checkbox",
"dateFormat": "MM/DD/YYYY",
"editable": false,
"field": "Duration",
"filter": {
"boolean": {
"condition": ""
},
"date": {
"condition": "",
"value": ""
},
"enabled": true,
"number": {
"condition": "",
"value": ""
},
"string": {
"condition": "equals",
"value": ""
},
"visible": "never"
},
"footer": {
"align": "center",
"justify": "left",
"style": {
"classes": ""
},
"title": ""
},
"header": {
"align": "center",
"justify": "center",
"style": {
"classes": ""
},
"title": "Duration"
},
"justify": "center",
"nullFormat": {
"includeNullStrings": false,
"nullFormatValue": "",
"strict": false
},
"number": "value",
"numberFormat": "0,0.##",
"progressBar": {
"bar": {
"color": "",
"style": {
"classes": ""
}
},
"max": 100,
"min": 0,
"track": {
"color": "",
"style": {
"classes": ""
}
},
"value": {
"enabled": true,
"format": "0,0.##",
"justify": "center",
"style": {
"classes": ""
}
}
},
"render": "string",
"resizable": true,
"sort": "none",
"sortable": true,
"strictWidth": false,
"style": {
"classes": ""
},
"toggleSwitch": {
"color": {
"selected": "",
"unselected": ""
}
},
"viewParams": {},
"viewPath": "",
"visible": true,
"width": 30
},
{
"align": "center",
"boolean": "checkbox",
"dateFormat": "MM/DD/YYYY",
"editable": false,
"field": "Priority",
"filter": {
"boolean": {
"condition": ""
},
"date": {
"condition": "",
"value": ""
},
"enabled": false,
"number": {
"condition": "",
"value": ""
},
"string": {
"condition": "",
"value": ""
},
"visible": "on-hover"
},
"footer": {
"align": "center",
"justify": "left",
"style": {
"classes": ""
},
"title": ""
},
"header": {
"align": "center",
"justify": "center",
"style": {
"classes": ""
},
"title": ""
},
"justify": "center",
"nullFormat": {
"includeNullStrings": false,
"nullFormatValue": "",
"strict": false
},
"number": "value",
"numberFormat": "0,0.##",
"progressBar": {
"bar": {
"color": "",
"style": {
"classes": ""
}
},
"max": 100,
"min": 0,
"track": {
"color": "",
"style": {
"classes": ""
}
},
"value": {
"enabled": true,
"format": "0,0.##",
"justify": "center",
"style": {
"classes": ""
}
}
},
"render": "auto",
"resizable": true,
"sort": "none",
"sortable": true,
"strictWidth": false,
"style": {
"classes": ""
},
"toggleSwitch": {
"color": {
"selected": "",
"unselected": ""
}
},
"viewParams": {},
"viewPath": "",
"visible": true,
"width": 30
},
{
"align": "center",
"boolean": "checkbox",
"dateFormat": "MM/DD/YYYY",
"editable": false,
"field": "Location",
"filter": {
"boolean": {
"condition": ""
},
"date": {
"condition": "",
"value": ""
},
"enabled": false,
"number": {
"condition": "",
"value": ""
},
"string": {
"condition": "equals",
"value": ""
},
"visible": "never"
},
"footer": {
"align": "center",
"justify": "left",
"style": {
"classes": ""
},
"title": ""
},
"header": {
"align": "center",
"justify": "center",
"style": {
"classes": ""
},
"title": ""
},
"justify": "center",
"nullFormat": {
"includeNullStrings": false,
"nullFormatValue": "",
"strict": false
},
"number": "value",
"numberFormat": "0,0.##",
"progressBar": {
"bar": {
"color": "",
"style": {
"classes": ""
}
},
"max": 100,
"min": 0,
"track": {
"color": "",
"style": {
"classes": ""
}
},
"value": {
"enabled": true,
"format": "0,0.##",
"justify": "center",
"style": {
"classes": ""
}
}
},
"render": "auto",
"resizable": true,
"sort": "none",
"sortable": true,
"strictWidth": false,
"style": {
"classes": ""
},
"toggleSwitch": {
"color": {
"selected": "",
"unselected": ""
}
},
"viewParams": {},
"viewPath": "",
"visible": true,
"width": 30
},
{
"align": "center",
"boolean": "checkbox",
"dateFormat": "MM/DD/YYYY",
"editable": false,
"field": "Description",
"filter": {
"boolean": {
"condition": ""
},
"date": {
"condition": "",
"value": ""
},
"enabled": false,
"number": {
"condition": "",
"value": ""
},
"string": {
"condition": "",
"value": ""
},
"visible": "on-hover"
},
"footer": {
"align": "center",
"justify": "left",
"style": {
"classes": ""
},
"title": ""
},
"header": {
"align": "center",
"justify": "center",
"style": {
"classes": ""
},
"title": ""
},
"justify": "center",
"nullFormat": {
"includeNullStrings": false,
"nullFormatValue": "",
"strict": false
},
"number": "value",
"numberFormat": "0,0.##",
"progressBar": {
"bar": {
"color": "",
"style": {
"classes": ""
}
},
"max": 100,
"min": 0,
"track": {
"color": "",
"style": {
"classes": ""
}
},
"value": {
"enabled": true,
"format": "0,0.##",
"justify": "center",
"style": {
"classes": ""
}
}
},
"render": "auto",
"resizable": true,
"sort": "none",
"sortable": true,
"strictWidth": false,
"style": {
"classes": ""
},
"toggleSwitch": {
"color": {
"selected": "",
"unselected": ""
}
},
"viewParams": {},
"viewPath": "",
"visible": true,
"width": 100
},
{
"align": "center",
"boolean": "checkbox",
"dateFormat": "MM/DD/YYYY",
"editable": false,
"field": "Tag",
"filter": {
"boolean": {
"condition": ""
},
"date": {
"condition": "",
"value": ""
},
"enabled": false,
"number": {
"condition": "",
"value": ""
},
"string": {
"condition": "",
"value": ""
},
"visible": "on-hover"
},
"footer": {
"align": "center",
"justify": "left",
"style": {
"classes": ""
},
"title": ""
},
"header": {
"align": "center",
"justify": "center",
"style": {
"classes": "",
"textAlign": "center"
},
"title": "Tag"
},
"justify": "center",
"nullFormat": {
"includeNullStrings": false,
"nullFormatValue": "",
"strict": false
},
"number": "value",
"numberFormat": "0,0.##",
"progressBar": {
"bar": {
"color": "",
"style": {
"classes": ""
}
},
"max": 100,
"min": 0,
"track": {
"color": "",
"style": {
"classes": ""
}
},
"value": {
"enabled": true,
"format": "0,0.##",
"justify": "center",
"style": {
"classes": ""
}
}
},
"render": "auto",
"resizable": true,
"sort": "none",
"sortable": true,
"strictWidth": false,
"style": {
"classes": ""
},
"toggleSwitch": {
"color": {
"selected": "",
"unselected": ""
}
},
"viewParams": {},
"viewPath": "",
"visible": true,
"width": 150
}
],
"emptyMessage": {
"noData": {
"text": "No Active Alarms"
},
"noFilterResults": {
"text": "No Active Alarms"
}
},
"filter": {
"results": {
"enabled": true
}
},
"pager": {
"bottom": false
},
"query": {
"$": [
"ts",
192,
1764608478535
],
"$ts": 1764608478535
}
},
"type": "ia.display.table"
}
],
"meta": {
"name": "FlexContainer_0"
},
"position": {
"basis": "1920px",
"grow": 1
},
"type": "ia.container.flex"
}
],
"meta": {
"name": "FlexContainer_0"
},
"position": {
"basis": "200px",
"grow": 1
},
"props": {
"direction": "column"
},
"type": "ia.container.flex"
}
],
"events": {
"system": {
"onStartup": {
"config": {
"script": "\tif self.view.custom.currentTable \u003d\u003d \"\":\n\t\tself.view.custom.currentTable \u003d \"ACTIVE\""
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "root"
},
"type": "ia.container.flex"
}
}