{ "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" } }