{ "custom": { "activityLogger": { "alt_pageid": "alarms", "pageid": "alarms/ActiveAlarms", "start_time": { "$": [ "ts", 192, 1748425447154 ], "$ts": 1748425447154 } } }, "events": { "system": { "onStartup": { "config": { "script": "\tself.getChild(\"root\").getChild(\"TabContainer\").getChild(\"Hit_List\").getChild(\"FlexContainer\").getChild(\"Time\").getChild(\"Dropdown\").props.value \u003d 30\n\tself.getChild(\"root\").getChild(\"TabContainer\").getChild(\"Historical_tab\").getChild(\"root\").getChild(\"Filters\").getChild(\"Time\").getChild(\"Dropdown\").props.value \u003d 30" }, "scope": "G", "type": "script" } } }, "params": {}, "propConfig": { "custom.activityLogger": { "persistent": true } }, "props": { "defaultSize": { "height": 1080, "width": 1920 } }, "root": { "children": [ { "children": [ { "children": [ { "children": [ { "children": [ { "meta": { "name": "Label_0" }, "position": { "basis": "10px" }, "type": "ia.display.label" }, { "custom": { "Severity": "High", "background_on": "true" }, "events": { "component": { "onActionPerformed": { "config": { "script": "\tpriority \u003d \u0027high\u0027\n\t# Copy and toggle the filter\n\tpriorities \u003d dict(self.parent.custom.priorities)\n\tpriorities[priority] \u003d not priorities.get(priority, False)\n\tself.parent.custom.priorities \u003d priorities\n\t\n\tself.custom.background_on \u003d \"true\" if priorities[priority] else \"false\"" }, "scope": "G", "type": "script" } } }, "meta": { "name": "Button_0" }, "position": { "basis": "120px" }, "propConfig": { "props.style.classes": { "binding": { "config": { "expression": "if({this.custom.background_on}\u003d\"false\",0,\r\nif({session.custom.colours.colour_impaired},2,1))" }, "transforms": [ { "fallback": "", "inputType": "scalar", "mappings": [ { "input": 0, "output": "" }, { "input": 1, "output": "Alarms-Styles/High" }, { "input": 2, "output": "Alarms-Styles/Alt-Colours/High" } ], "outputType": "style-list", "type": "map" } ], "type": "expr" } } }, "props": { "image": { "icon": { "path": "material/priority_high" } }, "primary": false, "style": { "margin": 15 }, "text": "High" }, "scripts": { "customMethods": [], "extensionFunctions": null, "messageHandlers": [ { "messageType": "reset-filters", "pageScope": true, "script": "\tbackground \u003d \"false\"\n\tseverity \u003d payload[\"reset\"]\n\tif severity \u003d\u003d \"false\":\n\t\tbackground \u003d \"false\"\n\telse:\n\t\tbackground \u003d \"true\"\n\tself.custom.background_on \u003d background", "sessionScope": false, "viewScope": false } ] }, "type": "ia.input.button" }, { "meta": { "name": "Label_1" }, "position": { "basis": "10px" }, "type": "ia.display.label" }, { "meta": { "name": "Label_4" }, "position": { "basis": "10px" }, "type": "ia.display.label" }, { "custom": { "Severity": "Medium", "background_on": "true" }, "events": { "component": { "onActionPerformed": { "config": { "script": "\tpriority \u003d \u0027medium\u0027\n\t# Copy and toggle the filter\n\tpriorities \u003d dict(self.parent.custom.priorities)\n\tpriorities[priority] \u003d not priorities.get(priority, False)\n\tself.parent.custom.priorities \u003d priorities\n\t\n\tself.custom.background_on \u003d \"true\" if priorities[priority] else \"false\"" }, "scope": "G", "type": "script" } } }, "meta": { "name": "Button_1" }, "position": { "basis": "120px" }, "propConfig": { "props.style.classes": { "binding": { "config": { "expression": "if({this.custom.background_on}\u003d\"false\",0,\r\nif({session.custom.colours.colour_impaired},2,1))" }, "transforms": [ { "fallback": "Buttons/PB_1", "inputType": "scalar", "mappings": [ { "input": 0, "output": "" }, { "input": 1, "output": "Alarms-Styles/Medium" }, { "input": 2, "output": "Alarms-Styles/Alt-Colours/Medium" } ], "outputType": "style-list", "type": "map" } ], "type": "expr" } } }, "props": { "image": { "icon": { "path": "material/priority_high" } }, "primary": false, "style": { "margin": 15 }, "text": "Medium" }, "scripts": { "customMethods": [], "extensionFunctions": null, "messageHandlers": [ { "messageType": "reset-filters", "pageScope": true, "script": "\tbackground \u003d \"false\"\n\tseverity \u003d payload[\"reset\"]\n\tif severity \u003d\u003d \"false\":\n\t\tbackground \u003d \"false\"\n\telse:\n\t\tbackground \u003d \"true\"\n\tself.custom.background_on \u003d background", "sessionScope": false, "viewScope": false } ] }, "type": "ia.input.button" }, { "meta": { "name": "Label_2" }, "position": { "basis": "10px" }, "type": "ia.display.label" }, { "custom": { "Severity": "Low", "background_on": "false" }, "events": { "component": { "onActionPerformed": { "config": { "script": "\tpriority \u003d \u0027low\u0027\n\t# Copy and toggle the filter\n\tpriorities \u003d dict(self.parent.custom.priorities)\n\tpriorities[priority] \u003d not priorities.get(priority, False)\n\tself.parent.custom.priorities \u003d priorities\n\t\n\tself.custom.background_on \u003d \"true\" if priorities[priority] else \"false\"" }, "scope": "G", "type": "script" } } }, "meta": { "name": "Button_2" }, "position": { "basis": "120px" }, "propConfig": { "props.style.classes": { "binding": { "config": { "expression": "if({this.custom.background_on}\u003d\"false\",0,\r\nif({session.custom.colours.colour_impaired},2,1))" }, "transforms": [ { "fallback": "Buttons/PB_1", "inputType": "scalar", "mappings": [ { "input": 0, "output": "" }, { "input": 1, "output": "Alarms-Styles/Low" }, { "input": 2, "output": "Alarms-Styles/Alt-Colours/Low" } ], "outputType": "style-list", "type": "map" } ], "type": "expr" } } }, "props": { "image": { "icon": { "path": "material/low_priority" } }, "primary": false, "style": { "margin": 15 }, "text": "Low" }, "scripts": { "customMethods": [], "extensionFunctions": null, "messageHandlers": [ { "messageType": "reset-filters", "pageScope": true, "script": "\tbackground \u003d \"false\"\n\tseverity \u003d payload[\"reset\"]\n\tif severity \u003d\u003d \"false\":\n\t\tbackground \u003d \"false\"\n\telse:\n\t\tbackground \u003d \"true\"\n\tself.custom.background_on \u003d background", "sessionScope": false, "viewScope": false } ] }, "type": "ia.input.button" }, { "meta": { "name": "Label_3" }, "position": { "basis": "10px" }, "type": "ia.display.label" }, { "custom": { "background_on": "false" }, "events": { "component": { "onActionPerformed": { "config": { "script": "\tpriority \u003d \u0027diagnostic\u0027\n\n\tpriorities \u003d dict(self.parent.custom.priorities)\n\tpriorities[priority] \u003d not priorities.get(priority, False)\n\tself.parent.custom.priorities \u003d priorities\n\t\n\tself.custom.background_on \u003d \"true\" if priorities[priority] else \"false\"" }, "scope": "G", "type": "script" } } }, "meta": { "name": "Button_3" }, "position": { "basis": "120px" }, "propConfig": { "props.style.classes": { "binding": { "config": { "expression": "if({this.custom.background_on}\u003d\"false\",0,\r\nif({session.custom.colours.colour_impaired},2,1))" }, "transforms": [ { "fallback": "Buttons/PB_1", "inputType": "scalar", "mappings": [ { "input": 0, "output": "" }, { "input": 1, "output": "Alarms-Styles/Diagnostic" }, { "input": 2, "output": "Alarms-Styles/Alt-Colours/Diagnostic" } ], "outputType": "style-list", "type": "map" } ], "type": "expr" } } }, "props": { "image": { "icon": { "path": "material/warning" } }, "primary": false, "style": { "margin": 15 }, "text": "Diagnostic" }, "scripts": { "customMethods": [], "extensionFunctions": null, "messageHandlers": [ { "messageType": "reset-filters", "pageScope": true, "script": "\t# implement your handler here\n\tbackground \u003d \"false\"\n\tseverity \u003d payload[\"reset\"]\n\tif severity \u003d\u003d \"false\":\n\t\tbackground \u003d \"false\"\n\telse:\n\t\tbackground \u003d \"true\"\n\tself.custom.background_on \u003d background", "sessionScope": false, "viewScope": false } ] }, "type": "ia.input.button" }, { "meta": { "name": "Dropdown" }, "position": { "basis": "200px" }, "propConfig": { "props.value": { "persistent": false } }, "props": { "options": [ { "label": "MCM01", "value": "MCM01" }, { "label": "MCM02", "value": "MCM02" }, { "label": "MCM03", "value": "MCM03" }, { "label": "MCM04", "value": "MCM04" }, { "label": "MCM05", "value": "MCM05" }, { "label": "SMC", "value": "SMC" } ], "placeholder": { "text": "Filter MCMs..." }, "style": { "margin": 15 } }, "scripts": { "customMethods": [], "extensionFunctions": null, "messageHandlers": [ { "messageType": "hjsgdfn", "pageScope": false, "script": "\tpass", "sessionScope": false, "viewScope": false } ] }, "type": "ia.input.dropdown" } ], "custom": { "priorities": { "diagnostic": false, "high": true, "low": false, "medium": true } }, "events": { "system": { "onStartup": { "config": { "script": "\tself.custom.priorities \u003d {\n\t \"diagnostic\": False,\n\t \"low\": False,\n\t \"medium\": True,\n\t \"high\": True,\n\t}" }, "scope": "G", "type": "script" } } }, "meta": { "name": "FlexContainer" }, "position": { "basis": "881px", "shrink": 0 }, "props": { "style": { "padding": 0 } }, "type": "ia.container.flex" }, { "children": [ { "meta": { "name": "Label" }, "position": { "basis": "20px" }, "type": "ia.display.label" }, { "custom": { "Severity": "Critical", "background_on": "false" }, "events": { "component": { "onActionPerformed": { "config": { "script": "\tpayload \u003d {}\n\tfilter_on \u003d \"false\"\n\tpayload[\"reset\"] \u003d filter_on\n\tsystem.perspective.sendMessage(\"reset-filters\", payload \u003dpayload, scope \u003d \"page\")\n\tdefault_priorities \u003d {\n\t \"diagnostic\": False,\n\t \"low\": False,\n\t \"medium\": False,\n\t \"high\": False,\n\t \"critical\": False\n\t}\n\tself.parent.parent.parent.getChild(\"FlexContainer_0\").getChild(\"Table\").props.filter.text \u003d \"\"\n\tself.parent.parent.getChild(\"FlexContainer\").custom.priorities \u003d default_priorities\n\tself.parent.parent.getChild(\"FlexContainer\").getChild(\"Dropdown\").props.value \u003d \"\"" }, "scope": "G", "type": "script" } } }, "meta": { "name": "Button" }, "position": { "basis": "120px" }, "props": { "image": { "icon": { "color": "#000000", "path": "material/clear" } }, "primary": false, "style": { "margin": 15 }, "text": "Reset" }, "scripts": { "customMethods": [], "extensionFunctions": null, "messageHandlers": [ { "messageType": "button-severity-indicator", "pageScope": true, "script": "\tbackground \u003d \"false\"\n\tseverity \u003d payload[\"severity\"]\n\tbutton_severity \u003d self.custom.Severity\n\tif severity \u003d\u003d button_severity:\n\t\tbackground \u003d \"true\"\n\telse:\n\t\tbackground \u003d \"false\"\n\t\n\tself.custom.background_on \u003d background\n\t", "sessionScope": false, "viewScope": false } ] }, "type": "ia.input.button" }, { "meta": { "name": "Label_2" }, "position": { "basis": "10px" }, "type": "ia.display.label" }, { "custom": { "Severity": "High", "background_on": "true", "update_on": false }, "events": { "component": { "onActionPerformed": { "config": { "script": "\tfrom datetime import datetime\n\ttry:\n\t # Get table data\n\t data \u003d self.parent.parent.parent.getChild(\"FlexContainer_0\").getChild(\"Table\").props.data\n\t \n\t column_order \u003d [\n\t \"ID\",\n\t \"StartTimestamp\", \n\t \"Duration\",\n\t \"Priority\",\n\t \"Location\",\n\t \"Description\",\n\t \"Tag\"\n\t ]\n\t\n\t # CSV header\n\t csv_content \u003d \",\".join(column_order) + \"\\n\"\n\t \n\t def unwrap(v):\n\t\t\tif hasattr(v, \u0027value\u0027):\n\t\t\t\treturn str(v.value)\n\t \t\n\t\t\treturn v\n\t \n\t if data and len(data) \u003e 0:\n\t for item in data:\n\t row_data \u003d []\n\t \n\t for col in column_order:\n\t # Look for the column in the current item\n\t if col in item:\n\t cell \u003d item[col]\n\t # Extract the value from the nested structure\n\t if isinstance(cell, dict) and \"value\" in cell:\n\t raw_value \u003d cell[\"value\"]\n\t else:\n\t raw_value \u003d cell\n\t else:\n\t raw_value \u003d \"\"\n\t \n\t # Process and clean the value\n\t processed_value \u003d unwrap(raw_value).replace(\",\", \";\")\n\t row_data.append(processed_value)\n\t \n\t csv_content +\u003d \",\".join(row_data) + \"\\n\"\n\t else:\n\t csv_content +\u003d \"No alarms in current view\\n\"\n\t\n\texcept Exception as e:\n\t system.perspective.print(\"Export Error: \" + str(e))\n\t csv_content \u003d \"Export failed\\n\"\n\t\n\tcsv_bytes \u003d csv_content.encode(\"utf-8\")\n\tsystem.perspective.download(\"active_alarms.csv\", csv_bytes) \n\t \n\t \n\t \n\t\n#\t if data and len(data) \u003e 0:\n#\t for row in data:\n#\t val \u003d row.get(\"value\", {})\n#\t row_data \u003d [\n#\t str(val.get(\"NumberID\", \"\")),\n#\t str(val.get(\"EventTimestamp\", \"\")),\n#\t str(val.get(\"Duration\", \"\")),\n#\t str(val.get(\"Priority\", \"\")),\n#\t str(val.get(\"Description\", \"\")),\n#\t str(val.get(\"Tag\", \"\"))\n#\t ]\n#\t\n#\t # Escape commas for CSV safety\n#\t row_data \u003d [field.replace(\",\", \";\") for field in row_data]\n#\t csv_content +\u003d \",\".join(row_data) + \"\\n\"\n#\t else:\n#\t csv_content +\u003d \"No alarms in current view\\n\"\n#\t\n#\texcept Exception as e:\n#\t system.perspective.print(\"Error during CSV export: \" + str(e))\n#\t csv_content \u003d \"Error exporting alarm data\\n\"\n#\t\n#\t# Convert to bytes and trigger download\n#\tcsv_bytes \u003d csv_content.encode(\u0027utf-8\u0027)\n#\tsystem.perspective.download(\"active_alarms.csv\", csv_bytes)\n " }, "scope": "G", "type": "script" } } }, "meta": { "name": "Button_1" }, "position": { "basis": "120px" }, "props": { "image": { "icon": { "path": "material/import_export" } }, "primary": false, "style": { "margin": 15 }, "text": "Export" }, "scripts": { "customMethods": [], "extensionFunctions": null, "messageHandlers": [ { "messageType": "button-severity-indicator", "pageScope": true, "script": "\tbackground \u003d \"false\"\n\tseverity \u003d payload[\"severity\"]\n\tbutton_severity \u003d self.custom.Severity\n\tif severity \u003d\u003d button_severity:\n\t\tbackground \u003d \"true\"\n\telse:\n\t\tbackground \u003d \"false\"\n\t\n\tself.custom.background_on \u003d background", "sessionScope": false, "viewScope": false } ] }, "type": "ia.input.button" }, { "meta": { "name": "Label_0" }, "position": { "basis": "10px" }, "type": "ia.display.label" }, { "meta": { "name": "Label_1" }, "position": { "basis": "10px" }, "type": "ia.display.label" } ], "meta": { "name": "FlexContainer_0" }, "position": { "basis": "513px", "shrink": 0 }, "props": { "style": { "padding": 0 } }, "type": "ia.container.flex" } ], "meta": { "name": "FlexContainer" }, "position": { "basis": "70px", "shrink": 0 }, "props": { "alignContent": "flex-start", "style": { "overflow": "visible" } }, "type": "ia.container.flex" }, { "children": [ { "custom": { "query": { "$": [ "ts", 192, 1759905591388 ], "$ts": 1759905591388 } }, "events": { "component": { "onRowDoubleClick": { "config": { "script": "\n\tmyData \u003d self.props.selection.data\n\n\talarms.alarm_click.handleClick(myData)\n\t\n\t" }, "scope": "G", "type": "script" } } }, "meta": { "name": "Table" }, "position": { "basis": "972.9px" }, "propConfig": { "custom.priorities": { "binding": { "config": { "path": ".../FlexContainer/FlexContainer.custom.priorities" }, "transforms": [ { "code": "\t# value looks like: {\"diagnostic\": True, \"high\": True, \"low\": False, ...}\n\tfrom system.util import jsonEncode, jsonDecode\n\t\n\tprio_map \u003d {\u0027diagnostic\u0027:0,\u0027low\u0027:1,\u0027medium\u0027:2,\u0027high\u0027:3,\u0027critical\u0027:4}\n\t\n\t# Coerce Perspective objects (PyDictionary/Java Map) to a plain Python dict\n\ttry:\n\t d \u003d value if isinstance(value, dict) else jsonDecode(jsonEncode(value))\n\texcept:\n\t d \u003d {}\n\t\n\t# Normalize keys and build CSV (\u0027\u0027 means \"all\")\n\tenabled \u003d [str(prio_map[k]) for k in prio_map if bool(d.get(k, False))]\n\treturn \",\".join(enabled) if enabled else \"\"", "type": "script" } ], "type": "property" } }, "custom.query": { "onChange": { "enabled": false, "script": "\tfrom system import date\n\t\n\tdef class_color(cls):\n\t\tm \u003d {\"Error\":\"#FFE5E5\",\"Warning\":\"#FFF7E0\",\"Message\":\"#EAF4FF\"}\n\t\treturn m.get(cls, \"#FFFFFF\")\n\t\n\tdef mk_row(number_id, start_ts, end_ts, duration_hms, cls, area, desc_, tag_):\n\t\treturn {\n\t\t\t\"value\": {\n\t\t\t\t\"NumberID\": number_id,\n\t\t\t\t\"Start Timestamp\": start_ts,\n\t\t\t\t\"End Timestamp\": end_ts,\n\t\t\t\t\"Duration\": duration_hms,\n\t\t\t\t\"Class\": cls,\n\t\t\t\t\"Area\": area,\n\t\t\t\t\"Description\": desc_,\n\t\t\t\t\"Tag\": tag_\n\t\t\t},\n\t\t\t\"style\": {\"backgroundColor\": class_color(cls), \"classes\": \"some-class\"}\n\t\t}\n\t\n\tds_name \u003d \"MariaDB80\"\n\t\n\t# Time window (java.util.Date)\n\tend_dt \u003d getattr(self.custom, \"endTime\", None) or date.now()\n\tstart_dt \u003d getattr(self.custom, \"startTime\", None) or date.addHours(end_dt, -24)\n\t\n\t# Class filter from DropdownMinClass\n\ttry:\n\t\tmin_choice \u003d self.parent.parent.parent.getChild(\"DropdownMinClass\").props.value\n\texcept:\n\t\tmin_choice \u003d \"Message\"\n\t\n\tif min_choice \u003d\u003d \"Error\":\n\t\tclass_list \u003d [\"Error\"]\n\telif min_choice \u003d\u003d \"Warning\":\n\t\tclass_list \u003d [\"Error\",\"Warning\"]\n\telse:\n\t\tclass_list \u003d [\"Error\",\"Warning\",\"Message\"]\n\t\n\tcls1 \u003d class_list[0] if len(class_list)\u003e0 else None\n\tcls2 \u003d class_list[1] if len(class_list)\u003e1 else None\n\tcls3 \u003d class_list[2] if len(class_list)\u003e2 else None\n\t\n\t# Optional priorities CSV from self.custom.priorities\n\tpriorities_csv \u003d getattr(self.custom, \"priorities\", \"\") or \"\"\n\t\n\tsql \u003d u\"\"\"\n\tSELECT\n\t ae.id AS NumberID,\n\t ae.eventtime AS `Start Timestamp`,\n\t clr.eventtime AS `End Timestamp`,\n\t IFNULL(\n\t SEC_TO_TIME(TIMESTAMPDIFF(SECOND, ae.eventtime, clr.eventtime)),\n\t SEC_TO_TIME(TIMESTAMPDIFF(SECOND, ae.eventtime, NOW()))\n\t ) AS Duration,\n\t cls.strvalue AS Class,\n\t loc.strvalue AS Area,\n\t des.strvalue AS Description,\n\t tag.strvalue AS Tag\n\tFROM alarm_events ae\n\tLEFT JOIN alarm_events clr\n\t ON clr.eventid \u003d ae.eventid AND clr.eventtype \u003d 1\n\tLEFT JOIN alarm_event_data cls\n\t ON cls.id \u003d ae.id AND cls.propname \u003d \u0027Class\u0027\n\tLEFT JOIN alarm_event_data loc\n\t ON loc.id \u003d ae.id AND loc.propname \u003d \u0027Area\u0027\n\tLEFT JOIN alarm_event_data des\n\t ON des.id \u003d ae.id AND des.propname \u003d \u0027Description\u0027\n\tLEFT JOIN alarm_event_data tag\n\t ON tag.id \u003d ae.id AND tag.propname \u003d \u0027Tag\u0027\n\tWHERE\n\t ae.eventtype \u003d 0\n\t AND ae.eventtime BETWEEN ? AND ?\n\t AND (\n\t ( ? IS NOT NULL AND cls.strvalue \u003d ? )\n\t OR ( ? IS NOT NULL AND cls.strvalue \u003d ? )\n\t OR ( ? IS NOT NULL AND cls.strvalue \u003d ? )\n\t )\n\t AND ( ? \u003d \u0027\u0027 OR FIND_IN_SET(CAST(ae.priority AS CHAR), ?) \u003e 0 )\n\tORDER BY ae.eventtime DESC\n\t\"\"\"\n\t\n\t# ORDER MATTERS: must match the ? placeholders above\n\tparams \u003d [\n\t\tstart_dt, end_dt,\n\t\tcls1, cls1,\n\t\tcls2, cls2,\n\t\tcls3, cls3,\n\t\tpriorities_csv, priorities_csv\n\t]\n\t\n\trows \u003d system.db.runPrepQuery(sql, params, ds_name)\n\t\n\tdata \u003d []\n\tfor r in rows:\n\t\ttry:\n\t\t\tstart_s \u003d system.date.format(r[\"Start Timestamp\"], \"yyyy-MM-dd HH:mm:ss\") if r[\"Start Timestamp\"] else \"\"\n\t\t\tend_s \u003d system.date.format(r[\"End Timestamp\"], \"yyyy-MM-dd HH:mm:ss\") if r[\"End Timestamp\"] else \"\"\n\t\t\tdur_s \u003d str(r[\"Duration\"]) if r[\"Duration\"] is not None else \"\"\n\t\t\tdata.append(\n\t\t\t\tmk_row(\n\t\t\t\t\tnumber_id \u003d int(r[\"NumberID\"]) + 30000,\n\t\t\t\t\tstart_ts \u003d start_s,\n\t\t\t\t\tend_ts \u003d end_s,\n\t\t\t\t\tduration_hms\u003d dur_s,\n\t\t\t\t\tcls \u003d r[\"Class\"] or \"\",\n\t\t\t\t\tarea \u003d r[\"Area\"] or \"\",\n\t\t\t\t\tdesc_ \u003d r[\"Description\"] or \"\",\n\t\t\t\t\ttag_ \u003d r[\"Tag\"] or \"\"\n\t\t\t\t)\n\t\t\t)\n\t\texcept Exception as ex:\n\t\t\tsystem.perspective.print(\"Row shape error: %s\" % ex)\n\t\n\tself.props.data \u003d data" } }, "props.columns[3].filter.string.value": { "binding": { "config": { "path": ".../FlexContainer/FlexContainer/Dropdown.props.value" }, "type": "property" } }, "props.data": { "binding": { "config": { "parameters": { "priorityList": "{this.custom.priorities}" }, "polling": { "enabled": true, "rate": "3" }, "queryPath": "GetActiveAlarms" }, "transforms": [ { "code": "\n\tfrom system.dataset import toPyDataSet\n\n\tds \u003d toPyDataSet(value)\n\tdata \u003d []\n\n\tcolumn_names \u003d list(ds.columnNames)\n\n\tfor row in ds:\n\t\tpriority \u003d row[\"Priority\"]\n\n\t\t# Use style class names from Perspective\n\t\tif priority \u003d\u003d \"High\":\n\t\t\tclassName \u003d \"Alarms-Styles/High\"\n\t\telif priority \u003d\u003d \"Medium\":\n\t\t\tclassName \u003d \"Alarms-Styles/Medium\"\n\t\telif priority \u003d\u003d \"Low\":\n\t\t\tclassName \u003d \"Alarms-Styles/Low\"\n\t\telif priority \u003d\u003d \"Diagnostic\":\n\t\t\tclassName \u003d \"Alarms-Styles/Diagnostic\"\n\t\telse:\n\t\t\tclassName \u003d \"Alarms-Styles/NoAlarm\"\n\n\t\t# Apply the style class to all cells in the row\n\t\trow_dict \u003d {\n\t\t\tcol: {\n\t\t\t\t\"value\": \"SMC\" if col \u003d\u003d \"Location\" and row[col] \u003d\u003d \"Chute\" else row[col],\n\t\t\t\t\"style\": { \"classes\": className }\n\t\t\t\t\n\t\t\t} for col in column_names\n\t\t}\n\t\tdata.append(row_dict)\n\n\n\treturn data", "type": "script" } ], "type": "query" } } }, "props": { "columns": [ { "align": "center", "boolean": "checkbox", "dateFormat": "MM/DD/YYYY", "editable": false, "field": "ID", "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": "" }, { "align": "center", "boolean": "checkbox", "dateFormat": "MM/DD/YYYY HH:mm:ss", "editable": false, "field": "StartTimestamp", "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": 70 }, { "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": 70 }, { "align": "center", "boolean": "checkbox", "dateFormat": "MM/DD/YYYY", "editable": false, "field": "Location", "filter": { "boolean": { "condition": "" }, "date": { "condition": "", "value": "" }, "enabled": true, "number": { "condition": "", "value": "" }, "string": { "condition": "equals" }, "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": 70 }, { "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": 70 }, { "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": 150 }, { "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": "ascending", "sortable": true, "strictWidth": false, "style": { "classes": "" }, "toggleSwitch": { "color": { "selected": "", "unselected": "" } }, "viewParams": {}, "viewPath": "", "visible": true, "width": "" }, { "align": "center", "boolean": "checkbox", "dateFormat": "MM/DD/YYYY", "editable": false, "field": "FullTag", "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": "FullTag" }, "justify": "auto", "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": "", "display": "none" }, "toggleSwitch": { "color": { "selected": "", "unselected": "" } }, "viewParams": {}, "viewPath": "", "visible": true, "width": "" }, { "align": "center", "boolean": "checkbox", "dateFormat": "MM/DD/YYYY", "editable": false, "field": "Device", "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": "Device" }, "justify": "auto", "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": "", "display": "none" }, "toggleSwitch": { "color": { "selected": "", "unselected": "" } }, "viewParams": {}, "viewPath": "", "visible": true, "width": "" } ], "emptyMessage": { "noData": { "text": "No Active Alarms" }, "noFilterResults": { "text": "No Active Alarms" } }, "filter": { "enabled": true, "results": { "enabled": true } }, "pager": { "activeOption": 100 }, "style": { "margin": 25 } }, "type": "ia.display.table" } ], "meta": { "name": "FlexContainer_0" }, "position": { "basis": "980px", "grow": 1 }, "props": { "direction": "column" }, "type": "ia.container.flex" } ], "meta": { "name": "Active_tab" }, "props": { "direction": "column", "justify": "space-evenly" }, "type": "ia.container.flex" }, { "children": [ { "children": [ { "custom": { "SetFilter": true }, "events": { "component": { "onActionPerformed": { "config": { "script": "\tpayload \u003d {}\n\tif self.custom.SetFilter \u003d\u003d True:\n\t\tpayload[\"data\"] \u003d False\n\t\tself.custom.SetFilter \u003d False\n\t\n\telif self.custom.SetFilter \u003d\u003d False:\n\t\tpayload[\"data\"] \u003d True\n\t\tself.custom.SetFilter \u003d True\n\t\n\tsystem.perspective.sendMessage(\"show-historical-filters\", payload \u003d payload, scope \u003d \"page\")\n\t" }, "scope": "G", "type": "script" } } }, "meta": { "name": "Button", "tooltip": { "enabled": true, "style": { "background-color": "white", "borderColor": "#000000", "borderStyle": "solid", "borderWidth": "1px", "box-shadow": "5px 5px 5px grey", "color": "#000000", "fontFamily": "Arial", "fontWeight": "normal" }, "text": "Show Filters" } }, "position": { "basis": "120px" }, "props": { "image": { "icon": { "path": "material/filter_alt" }, "position": "center" }, "primary": false, "style": { "margin": 15, "marginLeft": 20 }, "text": "" }, "type": "ia.input.button" }, { "meta": { "name": "Label" }, "position": { "basis": "281px" }, "props": { "style": { "color": "#FF0000", "margin-left": "20px" }, "text": "ALL TIMESTAMPS ARE IN UTC" }, "type": "ia.display.label" } ], "meta": { "name": "Show filters" }, "position": { "basis": "70px", "shrink": 0 }, "type": "ia.container.flex" }, { "children": [ { "children": [ { "meta": { "name": "Label_1" }, "position": { "basis": "100px" }, "props": { "style": { "fontFamily": "Arial", "fontWeight": "bold", "textAlign": "center" }, "text": "Period:" }, "type": "ia.display.label" }, { "custom": { "customTime": false, "endDate": { "$": [ "ts", 192, 1760665941637 ], "$ts": 1760665941636 }, "startDate": { "$": [ "ts", 192, 1760665941637 ], "$ts": 1760664141636 } }, "meta": { "name": "Dropdown" }, "position": { "basis": "200px" }, "propConfig": { "props.value": { "onChange": { "enabled": null, "script": "\t# e.g. Dropdown onChange / propertyChange\n\tnow \u003d system.date.now()\n\ttoday0 \u003d system.date.setTime(now, 0, 0, 0) # today 00:00:00\n\tyday0 \u003d system.date.addDays(today0, -1) # yesterday 00:00:00\n\t\n\tval \u003d str(currentValue.value or \u0027\u0027).strip()\n\t\n\t# Custom range: let user pick dates, don\u0027t touch start/end.\n\tif val \u003d\u003d \"custom\":\n\t self.custom.customTime \u003d True\n\t return\n\t\n\tself.custom.customTime \u003d False\n\t\n\tdef t(day, h, m, s):\n\t \"\"\"time of day on a given day anchor\"\"\"\n\t return system.date.setTime(day, h, m, s)\n\t\n\tif val \u003d\u003d \"currentDay\":\n\t start, end \u003d today0, now\n\t\n\telif val \u003d\u003d \"morning\": # 02:30–07:30 today\n\t start, end \u003d t(today0, 2, 30, 0), t(today0, 7, 30, 0)\n\t\n\telif val \u003d\u003d \"daylight\": # 07:30–13:00 today\n\t start, end \u003d t(today0, 7, 30, 0), t(today0, 13, 0, 0)\n\t\n\telif val \u003d\u003d \"twilight\": # 13:00–now (if before 13:00, use 13:00 yesterday–now)\n\t if now \u003e\u003d t(today0, 13, 0, 0):\n\t start, end \u003d t(today0, 13, 0, 0), now\n\t else:\n\t start, end \u003d t(yday0, 13, 0, 0), now\n\t\n\telif val \u003d\u003d \"night\": # 18:30–23:30 yesterday (your original intent)\n\t start, end \u003d t(yday0, 18, 30, 0), t(yday0, 23, 30, 0)\n\t\n\telif val \u003d\u003d \"wrapDown\": # 23:30 yesterday – 02:30 today\n\t start, end \u003d t(yday0, 23, 30, 0), t(today0, 2, 30, 0)\n\t\n\telif val \u003d\u003d \"currentShot\": # alias of twilight per your use\n\t if now \u003e\u003d t(today0, 13, 0, 0):\n\t start, end \u003d t(today0, 13, 0, 0), now\n\t else:\n\t start, end \u003d t(yday0, 13, 0, 0), now\n\t\n\telse:\n\t # Treat any other value as \"last N minutes\"\n\t try:\n\t mins \u003d int(val)\n\t except:\n\t mins \u003d 60\n\t end \u003d now\n\t start \u003d system.date.addMinutes(end, -mins)\n\t\n\t# Final assign\n\tself.custom.startDate \u003d start\n\tself.custom.endDate \u003d end" }, "persistent": false } }, "props": { "options": [ { "label": "Past 30 Min", "value": 30 }, { "label": "Past Hour", "value": 60 }, { "label": "Past 2 Hour", "value": 120 }, { "label": "Past 4 Hour", "value": 240 }, { "label": "Past 8 Hour", "value": 480 }, { "label": "Current Day", "value": "currentDay" }, { "label": "Morning", "value": "morning" }, { "label": "Daylight", "value": "daylight" }, { "label": "Twilight", "value": "twilight" }, { "label": "Night", "value": "night" }, { "label": "Wrap Down", "value": "wrapDown" }, { "label": "Current Shot", "value": "currentShot" }, { "label": "Custom", "value": "custom" } ], "style": { "margin": 15 } }, "scripts": { "customMethods": [], "extensionFunctions": null, "messageHandlers": [ { "messageType": "reset-historical-filters", "pageScope": true, "script": "#\treset \u003d payload[\"data\"]\n#\tself.props.value \u003d None\n\tpass", "sessionScope": false, "viewScope": false } ] }, "type": "ia.input.dropdown" }, { "meta": { "name": "Label" }, "position": { "basis": "100px" }, "props": { "style": { "fontFamily": "Arial", "fontWeight": "bold", "textAlign": "center" }, "text": "Start Date" }, "type": "ia.display.label" }, { "custom": { "max_duration_days": 365 }, "events": { "component": { "onActionPerformed": { "config": { "script": "\tmessaging.message_handler.set_time_from_filters(self)\n\t" }, "scope": "G", "type": "script" } } }, "meta": { "name": "DateTimeInput", "tooltip": { "enabled": true } }, "position": { "basis": "200px" }, "propConfig": { "props.enabled": { "binding": { "config": { "path": "../Dropdown.custom.customTime" }, "type": "property" } }, "props.maxDate": { "binding": { "config": { "expression": "now()" }, "type": "expr" } }, "props.minDate": { "access": "PUBLIC" }, "props.value": { "binding": { "config": { "path": "../Dropdown.custom.startDate" }, "type": "property" }, "onChange": { "enabled": null, "script": "\tmessaging.message_handler.set_time_from_filters(self)\n\t\t\n\tif system.date.secondsBetween(self.props.value,self.getSibling(\"DateTimeInput_0\").props.value) \u003e 604800:\n\t\tself.getSibling(\"DateTimeInput_0\").props.value \u003d system.date.addSeconds(self.props.value,604800)" } } }, "props": { "formattedValue": "Oct 17, 2025 5:22 AM", "minDate": { "$": [ "ts", 192, 1759755629641 ], "$ts": 1728219629641 }, "style": { "margin": 15 } }, "scripts": { "customMethods": [], "extensionFunctions": null, "messageHandlers": [ { "messageType": "reset-historical-filters", "pageScope": true, "script": "#\treset \u003d payload[\"data\"]\n#\tself.props.value \u003d None\n\tpass", "sessionScope": false, "viewScope": false } ] }, "type": "ia.input.date-time-input" }, { "meta": { "name": "Label_0" }, "position": { "basis": "89px" }, "props": { "style": { "fontFamily": "Arial", "fontWeight": "bold", "textAlign": "center" }, "text": "End Date" }, "type": "ia.display.label" }, { "meta": { "name": "DateTimeInput_0" }, "position": { "basis": "200px" }, "propConfig": { "props.enabled": { "binding": { "config": { "path": "../Dropdown.custom.customTime" }, "type": "property" } }, "props.maxDate": { "binding": { "config": { "expression": "if(dateDiff({../DateTimeInput.props.value},now(),\"day\") \u003c 7, now(),dateArithmetic({../DateTimeInput.props.value}, 7, \"days\"))" }, "type": "expr" } }, "props.minDate": { "binding": { "config": { "expression": "{../DateTimeInput.props.value}" }, "type": "expr" } }, "props.value": { "binding": { "config": { "path": "../Dropdown.custom.endDate" }, "type": "property" }, "onChange": { "enabled": null, "script": "\tmessaging.message_handler.set_time_to_filters(self)" }, "persistent": true } }, "props": { "formattedValue": "Oct 17, 2025 5:52 AM", "style": { "margin": 15 }, "value": { "$": [ "ts", 201, 1760665941637 ], "$ts": 1760665941636 } }, "scripts": { "customMethods": [], "extensionFunctions": null, "messageHandlers": [ { "messageType": "reset-historical-filters", "pageScope": true, "script": "#\tsystem.perspective.print(payload)\n#\treset \u003d payload[\"data\"]\n#\tself.props.value \u003d None\n\tpass", "sessionScope": false, "viewScope": false } ] }, "type": "ia.input.date-time-input" } ], "meta": { "name": "Time" }, "position": { "basis": "70px", "shrink": 0 }, "type": "ia.container.flex" }, { "children": [ { "meta": { "name": "Label" }, "position": { "basis": "100px" }, "props": { "style": { "fontFamily": "Arial", "fontWeight": "bold", "textAlign": "center" }, "text": "Priority" }, "type": "ia.display.label" }, { "events": { "component": { "onActionPerformed": { "config": { "script": "\tmessaging.message_handler.set_priority_filters(self)" }, "scope": "G", "type": "script" } } }, "meta": { "name": "Dropdown" }, "position": { "basis": "490px" }, "propConfig": { "props.value": { "persistent": false } }, "props": { "options": [ { "label": "All", "value": "" }, { "label": "Diagnostic", "value": "diagnostic" }, { "label": "Low", "value": "low" }, { "label": "Medium", "value": "medium" }, { "label": "High", "value": "high" } ], "style": { "margin": 15 } }, "scripts": { "customMethods": [], "extensionFunctions": null, "messageHandlers": [ { "messageType": "reset-historical-filters", "pageScope": true, "script": "#\treset \u003d payload[\"data\"]\n#\tself.props.value \u003d None\n\tpass", "sessionScope": false, "viewScope": false } ] }, "type": "ia.input.dropdown" }, { "meta": { "name": "Label_0" }, "position": { "basis": "100px" }, "props": { "style": { "fontFamily": "Arial", "fontWeight": "bold", "textAlign": "center" }, "text": "MCM" }, "type": "ia.display.label" }, { "meta": { "name": "Dropdown_0" }, "position": { "basis": "200px" }, "propConfig": { "props.value": { "persistent": false } }, "props": { "options": [ { "label": "All", "value": "" }, { "label": "MCM01", "value": "MCM01" }, { "label": "MCM02", "value": "MCM02" }, { "label": "MCM03", "value": "MCM03" }, { "label": "MCM04", "value": "MCM04" }, { "label": "MCM05", "value": "MCM05" }, { "label": "SMC", "value": "SMC" } ], "placeholder": { "text": "Filter MCMs..." }, "style": { "margin": 15 } }, "scripts": { "customMethods": [], "extensionFunctions": null, "messageHandlers": [ { "messageType": "hjsgdfn", "pageScope": false, "script": "\tpass", "sessionScope": false, "viewScope": false } ] }, "type": "ia.input.dropdown" } ], "meta": { "name": "Priority" }, "position": { "basis": "70px", "shrink": 0 }, "type": "ia.container.flex" } ], "custom": { "ShowFilters": true }, "meta": { "name": "Filters" }, "position": { "basis": "180px", "shrink": 0 }, "propConfig": { "position.display": { "binding": { "config": { "path": "this.custom.ShowFilters" }, "type": "property" }, "persistent": true } }, "props": { "direction": "column", "style": { "borderStyle": "solid", "borderWidth": "1px", "box-shadow": "0 4px 20px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19)", "marginBottom": 10, "marginLeft": 20, "marginRight": 20, "marginTop": 10 } }, "scripts": { "customMethods": [], "extensionFunctions": null, "messageHandlers": [ { "messageType": "show-historical-filters", "pageScope": true, "script": "\tshow \u003d payload[\"data\"]\n\tself.custom.ShowFilters \u003d show", "sessionScope": false, "viewScope": false } ] }, "type": "ia.container.flex" }, { "children": [ { "events": { "component": { "onRowDoubleClick": { "config": { "script": "\t\n\tmyData \u003d self.props.selection.data\n\n\talarms.alarm_click.handleClick(myData)" }, "scope": "G", "type": "script" } } }, "meta": { "name": "AlarmsTable" }, "position": { "basis": "1920px", "grow": 1 }, "propConfig": { "props.columns[4].filter.string.value": { "binding": { "config": { "path": ".../Filters/Priority/Dropdown_0.props.value" }, "type": "property" } }, "props.columns[5].filter.string.value": { "binding": { "config": { "path": ".../Filters/Priority/Dropdown.props.value" }, "type": "property" } }, "props.data": { "binding": { "config": { "parameters": { "endTime": "{.../Filters/Time/DateTimeInput_0.props.value}", "startTime": "{.../Filters/Time/DateTimeInput.props.value}" }, "polling": { "enabled": true, "rate": "10" }, "queryPath": "GetAlarmsWithCount" }, "transforms": [ { "code": "\n\tfrom system.dataset import toPyDataSet\n\n\tds \u003d toPyDataSet(value)\n\tdata \u003d []\n\n\tcolumn_names \u003d list(ds.columnNames)\n\n\tfor row in ds:\n\t\tpriority \u003d row[\"Priority\"]\n\n\t\t# Use style class names from Perspective\n\t\tif priority \u003d\u003d \"High\":\n\t\t\tclassName \u003d \"Alarms-Styles/High\"\n\t\telif priority \u003d\u003d \"Medium\":\n\t\t\tclassName \u003d \"Alarms-Styles/Medium\"\n\t\telif priority \u003d\u003d \"Low\":\n\t\t\tclassName \u003d \"Alarms-Styles/Low\"\n\t\telif priority \u003d\u003d \"Diagnostic\":\n\t\t\tclassName \u003d \"Alarms-Styles/Diagnostic\"\n\t\telse:\n\t\t\tclassName \u003d \"Alarms-Styles/NoAlarm\"\n\t\n\t\trow_dict \u003d {\n\t\t\tcol: {\n\t\t\t\t\"value\": \"SMC\" if col \u003d\u003d \"Location\" and row[col] \u003d\u003d \"Chute\" else row[col],\n\t\t\t\t\"style\": { \"classes\": className }\n\t\t\t\t\n\t\t\t} for col in column_names\n\t\t}\n\t\tdata.append(row_dict)\n\n\treturn data\n", "type": "script" } ], "type": "query" } }, "props.editingCell": { "onChange": { "enabled": null, "script": "\tall_alarms \u003d system.alarm.queryStatus(includeShelved\u003dTrue)\n\tshelved_alarms \u003d [alarm for alarm in all_alarms if alarm.isShelved()]\n\t\n\t# Build dataset for table\n\theaders \u003d [\u0027ID\u0027, \u0027StartTimestamp\u0027, \u0027EndTimestamp\u0027, \u0027Duration\u0027, \u0027Description\u0027, \u0027Priority\u0027, \u0027Tag\u0027, \u0027MCM\u0027]\n\tdata \u003d []\n\t\n\tfor alarm in shelved_alarms:\n\t # Calculate duration (time since shelved)\n\t if alarm.activeTime:\n\t duration_ms \u003d system.date.now().getTime() - alarm.activeTime.getTime()\n\t duration_seconds \u003d duration_ms / 1000\n\t hours \u003d int(duration_seconds / 3600)\n\t minutes \u003d int((duration_seconds % 3600) / 60)\n\t seconds \u003d int(duration_seconds % 60)\n\t duration \u003d \"%02d:%02d:%02d\" % (hours, minutes, seconds)\n\t else:\n\t duration \u003d \"00:00:00\"\n\t \n\t # Extract tag name from source\n\t tag_name \u003d alarm.source.split(\u0027/\u0027)[-1] if \u0027/\u0027 in alarm.source else alarm.source\n\t \n\t row \u003d [\n\t str(alarm.id) if hasattr(alarm, \u0027id\u0027) else \u0027\u0027,\n\t alarm.activeTime if alarm.activeTime else system.date.now(),\n\t None, # End timestamp (shelved alarms don\u0027t have end time yet)\n\t duration,\n\t alarm.displayPath if alarm.displayPath else alarm.source,\n\t alarm.priority.name if alarm.priority else \u0027Unknown\u0027,\n\t tag_name,\n\t \u0027System\u0027 # Adjust based on your source format\n\t ]\n\t data.append(row)\n\t\n\t# Create dataset and update the custom property\n\tdataset \u003d system.dataset.toDataSet(headers, data)\n\tself.custom.shelvedAlarmsData \u003d dataset" } }, "props.selection": { "persistent": true } }, "props": { "columns": [ { "align": "center", "boolean": "checkbox", "dateFormat": "MM/DD/YYYY HH:mm:ss", "editable": false, "field": "FirstTimestamp", "filter": { "boolean": { "condition": "" }, "date": { "condition": "", "value": "" }, "enabled": true, "number": { "condition": "", "value": "" }, "string": { "condition": "", "value": "" }, "visible": "never" }, "footer": { "align": "center", "justify": "center", "style": { "classes": "" }, "title": "" }, "header": { "align": "center", "justify": "center", "style": { "classes": "" }, "title": "First 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": "" }, { "align": "center", "boolean": "value", "dateFormat": "MM/DD/YYYY HH:mm:ss", "editable": false, "field": "LastTimestamp", "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": "Last Timestamp" }, "justify": "center", "nullFormat": { "includeNullStrings": false, "nullFormatValue": "", "strict": false }, "number": "value", "numberFormat": "none", "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": "" }, { "align": "center", "boolean": "checkbox", "dateFormat": "MM-DD-YYYY HH:mm:ss", "editable": false, "field": "Count", "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": "Count" }, "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": "" }, { "align": "center", "boolean": "checkbox", "dateFormat": "none", "editable": false, "field": "Duration", "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": "Duration" }, "justify": "center", "nullFormat": { "includeNullStrings": false, "nullFormatValue": "", "strict": false }, "number": "value", "numberFormat": "none", "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": "" }, { "align": "center", "boolean": "checkbox", "dateFormat": "MM/DD/YYYY", "editable": false, "field": "Location", "filter": { "boolean": { "condition": "" }, "date": { "condition": "", "value": "" }, "enabled": true, "number": { "condition": "", "value": "" }, "string": { "condition": "equals" }, "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": "" }, { "align": "center", "boolean": "checkbox", "dateFormat": "MM/DD/YYYY", "editable": false, "field": "Priority", "filter": { "boolean": { "condition": "" }, "date": { "condition": "", "value": "" }, "enabled": true, "number": { "condition": "", "value": "" }, "string": { "condition": "equals" }, "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": "ascending", "sortable": true, "strictWidth": false, "style": { "classes": "" }, "toggleSwitch": { "color": { "selected": "", "unselected": "" } }, "viewParams": {}, "viewPath": "", "visible": true, "width": "" }, { "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": 150 }, { "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": "" }, "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": "" }, { "align": "center", "boolean": "checkbox", "dateFormat": "MM/DD/YYYY", "editable": false, "field": "FullTag", "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": "left", "style": { "classes": "" }, "title": "" }, "justify": "auto", "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": "", "display": "none" }, "toggleSwitch": { "color": { "selected": "", "unselected": "" } }, "viewParams": {}, "viewPath": "", "visible": true, "width": "" }, { "align": "center", "boolean": "checkbox", "dateFormat": "MM/DD/YYYY", "editable": false, "field": "Device", "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": "left", "style": { "classes": "" }, "title": "" }, "justify": "auto", "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": "", "display": "none" }, "toggleSwitch": { "color": { "selected": "", "unselected": "" } }, "viewParams": {}, "viewPath": "", "visible": true, "width": "" } ], "emptyMessage": { "noData": { "text": "No Alarms" }, "noFilterResults": { "text": "No Alarms" } }, "filter": { "enabled": true, "results": { "enabled": true } }, "pager": { "activeOption": 100 }, "style": { "margin": 20 } }, "type": "ia.display.table" } ], "meta": { "name": "FlexContainer_0" }, "position": { "basis": "980px", "grow": 1 }, "props": { "direction": "column" }, "type": "ia.container.flex" }, { "children": [ { "events": { "component": { "onActionPerformed": { "config": { "script": "\n\tfrom datetime import datetime\n\t\n\ttry:\n\t data \u003d self.parent.parent.getChild(\"FlexContainer_0\").getChild(\"AlarmsTable\").props.data\n\t\n\t column_order \u003d [\n\t \"FirstTimestamp\",\n\t \"LastTimestamp\", \n\t \"Count\",\n\t \"Duration\",\n\t \"Priority\",\n\t \"Location\",\n\t \"Description\",\n\t \"Tag\"\n\t ]\n\t\n\t csv_content \u003d \",\".join(column_order) + \"\\n\"\n\t \n\t def unwrap(v):\n\t if hasattr(v, \u0027value\u0027):\n\t return str(v.value)\n\t return str(v)\n\t\n\t if data and len(data) \u003e 0:\n\t for item in data:\n\t row_data \u003d []\n\t for col in column_order:\n\t if col in item:\n\t cell \u003d item[col]\n\t if isinstance(cell, dict) and \"value\" in cell:\n\t raw_value \u003d cell[\"value\"]\n\t else:\n\t raw_value \u003d cell\n\t else:\n\t raw_value \u003d \"\"\n\t\n\t processed_value \u003d unwrap(raw_value).replace(\",\", \";\")\n\t row_data.append(processed_value)\n\t\n\t csv_content +\u003d \",\".join(row_data) + \"\\n\"\n\t else:\n\t csv_content +\u003d \"No alarms in current view\\n\"\n\t\n\texcept Exception as e:\n\t system.perspective.print(\"Export Error: \" + str(e))\n\t csv_content \u003d \"Export failed\\n\"\n\t\n\tcsv_bytes \u003d csv_content.encode(\"utf-8\")\n\tsystem.perspective.download(\"hitList_alarms.csv\", csv_bytes)" }, "scope": "G", "type": "script" } } }, "meta": { "name": "Export" }, "position": { "basis": "120px" }, "props": { "image": { "icon": { "path": "material/import_export" } }, "primary": false, "style": { "margin": 15, "marginLeft": 20 }, "text": "Export" }, "scripts": { "customMethods": [], "extensionFunctions": null, "messageHandlers": [ { "messageType": "button-severity-indicator", "pageScope": true, "script": "\tbackground \u003d \"false\"\n\tseverity \u003d payload[\"severity\"]\n\tbutton_severity \u003d self.custom.Severity\n\tif severity \u003d\u003d button_severity:\n\t\tbackground \u003d \"true\"\n\telse:\n\t\tbackground \u003d \"false\"\n\t\n\tself.custom.background_on \u003d background", "sessionScope": false, "viewScope": false } ] }, "type": "ia.input.button" } ], "meta": { "name": "FlexContainer" }, "position": { "basis": 100, "grow": 1 }, "type": "ia.container.flex" } ], "meta": { "name": "Hit_List" }, "position": { "tabIndex": 1 }, "props": { "direction": "column" }, "type": "ia.container.flex" }, { "children": [ { "children": [ { "children": [ { "custom": { "SetFilter": true }, "events": { "component": { "onActionPerformed": { "config": { "script": "\tpayload \u003d {}\n\tif self.custom.SetFilter \u003d\u003d True:\n\t\tpayload[\"data\"] \u003d False\n\t\tself.custom.SetFilter \u003d False\n\t\n\telif self.custom.SetFilter \u003d\u003d False:\n\t\tpayload[\"data\"] \u003d True\n\t\tself.custom.SetFilter \u003d True\n\t\n\tsystem.perspective.sendMessage(\"show-historical-filters\", payload \u003d payload, scope \u003d \"page\")\n\t" }, "scope": "G", "type": "script" } } }, "meta": { "name": "Button", "tooltip": { "enabled": true, "style": { "background-color": "white", "borderColor": "#000000", "borderStyle": "solid", "borderWidth": "1px", "box-shadow": "5px 5px 5px grey", "color": "#000000", "fontFamily": "Arial", "fontWeight": "normal" }, "text": "Show Filters" } }, "position": { "basis": "120px" }, "props": { "image": { "icon": { "path": "material/filter_alt" }, "position": "center" }, "primary": false, "style": { "margin": 15, "marginLeft": 20 }, "text": "" }, "type": "ia.input.button" }, { "meta": { "name": "Label" }, "position": { "basis": "281px" }, "props": { "style": { "color": "#FF0000", "margin-left": "20px" }, "text": "ALL TIMESTAMPS ARE IN UTC" }, "type": "ia.display.label" } ], "meta": { "name": "Show filters" }, "position": { "basis": "70px", "shrink": 0 }, "type": "ia.container.flex" }, { "children": [ { "children": [ { "meta": { "name": "Label_1" }, "position": { "basis": "100px" }, "props": { "style": { "fontFamily": "Arial", "fontWeight": "bold", "textAlign": "center" }, "text": "Period:" }, "type": "ia.display.label" }, { "custom": { "customTime": false, "endDate": { "$": [ "ts", 192, 1760668996778 ], "$ts": 1760668996778 }, "startDate": { "$": [ "ts", 192, 1760668996778 ], "$ts": 1760667196778 } }, "meta": { "name": "Dropdown" }, "position": { "basis": "200px" }, "propConfig": { "props.value": { "onChange": { "enabled": null, "script": "\t# e.g. Dropdown onChange / propertyChange\n\tnow \u003d system.date.now()\n\ttoday0 \u003d system.date.setTime(now, 0, 0, 0) # today 00:00:00\n\tyday0 \u003d system.date.addDays(today0, -1) # yesterday 00:00:00\n\t\n\tval \u003d str(currentValue.value or \u0027\u0027).strip()\n\t\n\t# Custom range: let user pick dates, don\u0027t touch start/end.\n\tif val \u003d\u003d \"custom\":\n\t self.custom.customTime \u003d True\n\t return\n\t\n\tself.custom.customTime \u003d False\n\t\n\tdef t(day, h, m, s):\n\t \"\"\"time of day on a given day anchor\"\"\"\n\t return system.date.setTime(day, h, m, s)\n\t\n\tif val \u003d\u003d \"currentDay\":\n\t start, end \u003d today0, now\n\t\n\telif val \u003d\u003d \"morning\": # 02:30–07:30 today\n\t start, end \u003d t(today0, 2, 30, 0), t(today0, 7, 30, 0)\n\t\n\telif val \u003d\u003d \"daylight\": # 07:30–13:00 today\n\t start, end \u003d t(today0, 7, 30, 0), t(today0, 13, 0, 0)\n\t\n\telif val \u003d\u003d \"twilight\": # 13:00–now (if before 13:00, use 13:00 yesterday–now)\n\t if now \u003e\u003d t(today0, 13, 0, 0):\n\t start, end \u003d t(today0, 13, 0, 0), now\n\t else:\n\t start, end \u003d t(yday0, 13, 0, 0), now\n\t\n\telif val \u003d\u003d \"night\": # 18:30–23:30 yesterday (your original intent)\n\t start, end \u003d t(yday0, 18, 30, 0), t(yday0, 23, 30, 0)\n\t\n\telif val \u003d\u003d \"wrapDown\": # 23:30 yesterday – 02:30 today\n\t start, end \u003d t(yday0, 23, 30, 0), t(today0, 2, 30, 0)\n\t\n\telif val \u003d\u003d \"currentShot\": # alias of twilight per your use\n\t if now \u003e\u003d t(today0, 13, 0, 0):\n\t start, end \u003d t(today0, 13, 0, 0), now\n\t else:\n\t start, end \u003d t(yday0, 13, 0, 0), now\n\t\n\telse:\n\t # Treat any other value as \"last N minutes\"\n\t try:\n\t mins \u003d int(val)\n\t except:\n\t mins \u003d 60\n\t end \u003d now\n\t start \u003d system.date.addMinutes(end, -mins)\n\t\n\t# Final assign\n\tself.custom.startDate \u003d start\n\tself.custom.endDate \u003d end" }, "persistent": false } }, "props": { "options": [ { "label": "Past 30 Min", "value": 30 }, { "label": "Past Hour", "value": 60 }, { "label": "Past 2 Hour", "value": 120 }, { "label": "Past 4 Hour", "value": 240 }, { "label": "Past 8 Hour", "value": 480 }, { "label": "Current Day", "value": "currentDay" }, { "label": "Morning", "value": "morning" }, { "label": "Daylight", "value": "daylight" }, { "label": "Twilight", "value": "twilight" }, { "label": "Night", "value": "night" }, { "label": "Wrap Down", "value": "wrapDown" }, { "label": "Current Shot", "value": "currentShot" }, { "label": "Custom", "value": "custom" } ], "style": { "margin": 15 } }, "scripts": { "customMethods": [], "extensionFunctions": null, "messageHandlers": [ { "messageType": "reset-historical-filters", "pageScope": true, "script": "#\treset \u003d payload[\"data\"]\n#\tself.props.value \u003d None\n\tpass", "sessionScope": false, "viewScope": false } ] }, "type": "ia.input.dropdown" }, { "meta": { "name": "Label" }, "position": { "basis": "100px" }, "props": { "style": { "fontFamily": "Arial", "fontWeight": "bold", "textAlign": "center" }, "text": "Start Date" }, "type": "ia.display.label" }, { "custom": { "max_duration_days": 365 }, "events": { "component": { "onActionPerformed": { "config": { "script": "\tmessaging.message_handler.set_time_from_filters(self)\n\t" }, "scope": "G", "type": "script" } } }, "meta": { "name": "DateTimeInput", "tooltip": { "enabled": true } }, "position": { "basis": "200px" }, "propConfig": { "props.enabled": { "binding": { "config": { "path": "../Dropdown.custom.customTime" }, "type": "property" } }, "props.maxDate": { "binding": { "config": { "expression": "now()" }, "type": "expr" } }, "props.minDate": { "access": "PUBLIC" }, "props.value": { "binding": { "config": { "path": "../Dropdown.custom.startDate" }, "type": "property" }, "onChange": { "enabled": null, "script": "\tmessaging.message_handler.set_time_from_filters(self)\n\t\t\n\tif system.date.secondsBetween(self.props.value,self.getSibling(\"DateTimeInput_0\").props.value) \u003e 604800:\n\t\tself.getSibling(\"DateTimeInput_0\").props.value \u003d system.date.addSeconds(self.props.value,604800)" } } }, "props": { "formattedValue": "Oct 17, 2025 6:13 AM", "minDate": { "$": [ "ts", 192, 1759755629641 ], "$ts": 1728219629641 }, "style": { "margin": 15 } }, "scripts": { "customMethods": [], "extensionFunctions": null, "messageHandlers": [ { "messageType": "reset-historical-filters", "pageScope": true, "script": "#\treset \u003d payload[\"data\"]\n#\tself.props.value \u003d None\n\tpass", "sessionScope": false, "viewScope": false } ] }, "type": "ia.input.date-time-input" }, { "meta": { "name": "Label_0" }, "position": { "basis": "89px" }, "props": { "style": { "fontFamily": "Arial", "fontWeight": "bold", "textAlign": "center" }, "text": "End Date" }, "type": "ia.display.label" }, { "meta": { "name": "DateTimeInput_0" }, "position": { "basis": "200px" }, "propConfig": { "props.enabled": { "binding": { "config": { "path": "../Dropdown.custom.customTime" }, "type": "property" } }, "props.maxDate": { "binding": { "config": { "expression": "if(dateDiff({../DateTimeInput.props.value},now(),\"day\") \u003c 7, now(),dateArithmetic({../DateTimeInput.props.value}, 7, \"days\"))" }, "type": "expr" } }, "props.minDate": { "binding": { "config": { "expression": "{../DateTimeInput.props.value}" }, "type": "expr" } }, "props.value": { "binding": { "config": { "path": "../Dropdown.custom.endDate" }, "type": "property" }, "onChange": { "enabled": null, "script": "\tmessaging.message_handler.set_time_to_filters(self)" }, "persistent": true } }, "props": { "formattedValue": "Oct 17, 2025 6:43 AM", "style": { "margin": 15 }, "value": { "$": [ "ts", 201, 1760668996778 ], "$ts": 1760668996778 } }, "scripts": { "customMethods": [], "extensionFunctions": null, "messageHandlers": [ { "messageType": "reset-historical-filters", "pageScope": true, "script": "#\tsystem.perspective.print(payload)\n#\treset \u003d payload[\"data\"]\n#\tself.props.value \u003d None\n\tpass", "sessionScope": false, "viewScope": false } ] }, "type": "ia.input.date-time-input" } ], "meta": { "name": "Time" }, "position": { "basis": "70px", "shrink": 0 }, "type": "ia.container.flex" }, { "children": [ { "meta": { "name": "Label" }, "position": { "basis": "100px" }, "props": { "style": { "fontFamily": "Arial", "fontWeight": "bold", "textAlign": "center" }, "text": "Priority" }, "type": "ia.display.label" }, { "events": { "component": { "onActionPerformed": { "config": { "script": "\tmessaging.message_handler.set_priority_filters(self)" }, "scope": "G", "type": "script" } } }, "meta": { "name": "Dropdown" }, "position": { "basis": "490px" }, "propConfig": { "props.value": { "persistent": false } }, "props": { "options": [ { "label": "All", "value": "" }, { "label": "Diagnostic", "value": "diagnostic" }, { "label": "Low", "value": "low" }, { "label": "Medium", "value": "medium" }, { "label": "High", "value": "high" } ], "style": { "margin": 15 } }, "scripts": { "customMethods": [], "extensionFunctions": null, "messageHandlers": [ { "messageType": "reset-historical-filters", "pageScope": true, "script": "#\treset \u003d payload[\"data\"]\n#\tself.props.value \u003d None\n\tpass", "sessionScope": false, "viewScope": false } ] }, "type": "ia.input.dropdown" }, { "meta": { "name": "Label_0" }, "position": { "basis": "100px" }, "props": { "style": { "fontFamily": "Arial", "fontWeight": "bold", "textAlign": "center" }, "text": "MCM" }, "type": "ia.display.label" }, { "meta": { "name": "Dropdown_0" }, "position": { "basis": "200px" }, "propConfig": { "props.value": { "persistent": false } }, "props": { "options": [ { "label": "All", "value": "" }, { "label": "MCM01", "value": "MCM01" }, { "label": "MCM02", "value": "MCM02" }, { "label": "MCM03", "value": "MCM03" }, { "label": "MCM04", "value": "MCM04" }, { "label": "MCM05", "value": "MCM05" }, { "label": "SMC", "value": "SMC" } ], "placeholder": { "text": "Filter MCMs..." }, "style": { "margin": 15 } }, "scripts": { "customMethods": [], "extensionFunctions": null, "messageHandlers": [ { "messageType": "hjsgdfn", "pageScope": false, "script": "\tpass", "sessionScope": false, "viewScope": false } ] }, "type": "ia.input.dropdown" } ], "meta": { "name": "Priority" }, "position": { "basis": "70px", "shrink": 0 }, "type": "ia.container.flex" } ], "custom": { "ShowFilters": true }, "meta": { "name": "Filters" }, "position": { "basis": "180px", "grow": 1, "shrink": 0 }, "propConfig": { "position.display": { "binding": { "config": { "path": "this.custom.ShowFilters" }, "type": "property" }, "persistent": true } }, "props": { "direction": "column", "style": { "borderStyle": "solid", "borderWidth": "1px", "box-shadow": "0 4px 20px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19)", "marginBottom": 10, "marginLeft": 20, "marginRight": 20, "marginTop": 10 } }, "scripts": { "customMethods": [], "extensionFunctions": null, "messageHandlers": [ { "messageType": "show-historical-filters", "pageScope": true, "script": "\tshow \u003d payload[\"data\"]\n\tself.custom.ShowFilters \u003d show", "sessionScope": false, "viewScope": false } ] }, "type": "ia.container.flex" }, { "children": [ { "custom": { "amount": 0, "device_filters": null, "duration_filter": null, "hasNext": true, "hit_limit": false, "loading": false, "max_duration": { "$": [ "ts", 192, 1748426336635 ], "$ts": 1747562336635 }, "page_size": 100, "record_count": 0, "source_id_filters": null, "type_filters": null }, "events": { "component": { "onRowDoubleClick": { "config": { "script": "\t\n\tmyData \u003d self.props.selection.data\n\n\talarms.alarm_click.handleClick(myData)" }, "scope": "G", "type": "script" } } }, "meta": { "name": "Table" }, "position": { "basis": "1920px", "grow": 1 }, "propConfig": { "custom.priority_filters": { "binding": { "config": { "path": ".../Filters/Priority/Dropdown.props.value" }, "transforms": [ { "expression": "coalesce({value},\u0027\u0027)", "type": "expression" } ], "type": "property" } }, "custom.time_from_filter": { "binding": { "config": { "path": ".../Filters/Time/DateTimeInput.props.value" }, "type": "property" } }, "custom.time_to_filter": { "binding": { "config": { "path": ".../Filters/Time/DateTimeInput_0.props.value" }, "type": "property" } }, "props.columns[1].filter.date.value": { "binding": { "config": { "path": "this.custom.time_from_filter" }, "transforms": [ { "expression": "coalesce({value}, dateArithmetic(now(), -30, \"minute\"))", "type": "expression" } ], "type": "property" } }, "props.columns[2].filter.date.value": { "binding": { "config": { "path": "this.custom.time_to_filter" }, "transforms": [ { "expression": "coalesce({value},NOW())", "type": "expression" } ], "type": "property" } }, "props.columns[5].filter.string.value": { "binding": { "config": { "path": "this.custom.priority_filters" }, "transforms": [ { "expression": "coalesce({value},\"\")", "type": "expression" } ], "type": "property" } }, "props.columns[6].filter.string.value": { "binding": { "config": { "path": ".../Filters/Priority/Dropdown_0.props.value" }, "type": "property" } }, "props.data": { "binding": { "config": { "parameters": { "TabIndex": "{....../TabContainer.props.currentTabIndex}", "endtime": "{this.custom.time_to_filter}", "starttime": "{this.custom.time_from_filter}" }, "polling": { "enabled": true, "rate": "10" }, "queryPath": "GetAlarms" }, "transforms": [ { "code": "\t# Transform (script)\n\tfrom system.dataset import toPyDataSet\n\t\n\t# Handle null/empty input\n\tds \u003d toPyDataSet(value) if value is not None else None\n#\tif not ds:\n#\t self.custom.loading \u003d False\n#\t self.custom.record_count \u003d 0\n#\t self.custom.hit_limit \u003d False\n#\t return []\n\t\n\t# Priority to style class mapping\n\tPRIORITY_STYLES \u003d {\n\t \"High\": \"Alarms-Styles/High\",\n\t \"Medium\": \"Alarms-Styles/Medium\",\n\t \"Low\": \"Alarms-Styles/Low\",\n\t \"Diagnostic\": \"Alarms-Styles/Diagnostic\",\n\t \"Critical\": \"Alarms-Styles/Critical\"\n\t}\n\tDEFAULT_STYLE \u003d \"Alarms-Styles/NoAlarm\"\n\t\n\t\n\tcols \u003d list(ds.columnNames)\n\tdata \u003d []\n\t\n\tfor row in ds:\n\t # Get priority and map to style class\n\t priority \u003d row.get(\"Priority\", None) if hasattr(row, \"get\") else row[\"Priority\"]\n\t className \u003d PRIORITY_STYLES.get(priority, DEFAULT_STYLE)\n\t \n\t # Build row with transformations\n\t row_dict \u003d {}\n\t for col in cols:\n\t cell_value \u003d row[col]\n\t \n\t # Transform Location: Chute -\u003e SMC\n\t if col \u003d\u003d \"Location\" and cell_value \u003d\u003d \"Chute\":\n\t cell_value \u003d \"SMC\"\n\t \n\t row_dict[col] \u003d {\n\t \"value\": cell_value,\n\t \"style\": {\"classes\": className}\n\t }\n\t \n\t data.append(row_dict)\n\t\n\t# Update component state\n\tself.custom.loading \u003d False\n\tself.custom.record_count \u003d len(data)\n\tself.custom.hit_limit \u003d False\n\t\n\treturn data", "type": "script" } ], "type": "query" } } }, "props": { "bekaxui": 50, "box-shadow": "0 4px 20px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19)", "columns": [ { "align": "center", "boolean": "checkbox", "dateFormat": "none", "editable": false, "field": "ID", "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": "", "paddingLeft": 12 }, "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": 50 }, { "align": "center", "boolean": "checkbox", "dateFormat": "MM/DD/YYYY HH:mm:ss", "editable": false, "field": "StartTimestamp", "filter": { "boolean": { "condition": "" }, "date": { "condition": "later than date time" }, "enabled": true, "number": { "condition": "", "value": "" }, "string": { "condition": "", "value": "" }, "visible": "never" }, "footer": { "align": "center", "justify": "left", "style": { "classes": "" }, "title": "" }, "header": { "align": "center", "justify": "center", "style": { "classes": "" }, "title": "Start Timestamp" }, "justify": "center", "nullFormat": { "includeNullStrings": false, "nullFormatValue": "", "strict": false }, "number": "value", "numberFormat": "none", "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": 50 }, { "align": "center", "boolean": "checkbox", "dateFormat": "MM/DD/YYYY HH:mm:ss", "editable": false, "field": "EndTimestamp", "filter": { "boolean": { "condition": "" }, "date": { "condition": "earlier than date time" }, "enabled": true, "number": { "condition": "", "value": "" }, "string": { "condition": "", "value": "" }, "visible": "never" }, "footer": { "align": "center", "justify": "left", "style": { "classes": "" }, "title": "" }, "header": { "align": "center", "justify": "center", "style": { "classes": "" }, "title": "End Timestamp" }, "justify": "center", "nullFormat": { "includeNullStrings": false, "nullFormatValue": "", "strict": false }, "number": "value", "numberFormat": "none", "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": 50 }, { "align": "center", "boolean": "checkbox", "dateFormat": "none", "editable": false, "field": "Duration", "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": "", "paddingLeft": 12 }, "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": 50 }, { "align": "center", "boolean": "checkbox", "dateFormat": "none", "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": 50 }, { "align": "center", "boolean": "checkbox", "dateFormat": "MM/DD/YYYY", "editable": false, "field": "Priority", "filter": { "boolean": { "condition": "" }, "date": { "condition": "", "value": "" }, "enabled": true, "number": { "condition": "", "value": "" }, "string": { "condition": "contains" }, "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": 50 }, { "align": "center", "boolean": "checkbox", "dateFormat": "MM/DD/YYYY", "editable": false, "field": "Location", "filter": { "boolean": { "condition": "" }, "date": { "condition": "", "value": "" }, "enabled": true, "number": { "condition": "", "value": "" }, "string": { "condition": "equals" }, "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": 50 }, { "align": "center", "boolean": "checkbox", "dateFormat": "MM/DD/YYYY", "editable": false, "field": "Tag", "filter": { "boolean": { "condition": "" }, "date": { "condition": "", "value": "" }, "enabled": true, "number": { "condition": "", "value": "" }, "string": { "condition": "contains", "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": 50 }, { "align": "center", "boolean": "checkbox", "dateFormat": "MM/DD/YYYY", "editable": false, "field": "FullTag", "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": "left", "style": { "classes": "" }, "title": "" }, "justify": "auto", "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": "", "display": "none" }, "toggleSwitch": { "color": { "selected": "", "unselected": "" } }, "viewParams": {}, "viewPath": "", "visible": true, "width": "" }, { "align": "center", "boolean": "checkbox", "dateFormat": "MM/DD/YYYY", "editable": false, "field": "Device", "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": "left", "style": { "classes": "" }, "title": "" }, "justify": "auto", "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": "", "display": "none" }, "toggleSwitch": { "color": { "selected": "", "unselected": "" } }, "viewParams": {}, "viewPath": "", "visible": true, "width": 300 } ], "emptyMessage": { "noData": { "text": "No Alarms" }, "noFilterResults": { "text": "No Alarms" } }, "enabled": true, "filter": { "enabled": true, "results": { "enabled": true } }, "pager": { "activeOption": 100 }, "style": { "margin": 20 }, "total": "value" }, "scripts": { "customMethods": [], "extensionFunctions": null, "messageHandlers": [ { "messageType": "update-first-request", "pageScope": true, "script": "\tdata \u003d payload[\"data\"]\n\tinitial_data \u003d payload[\"initial_data\"]\n\tself.props.data \u003d data\n\tself.custom.initial_data \u003d initial_data", "sessionScope": false, "viewScope": false }, { "messageType": "update-historical-data", "pageScope": true, "script": "\thistorical_data \u003d payload[\"data\"]\n\tself.props.data \u003d historical_data", "sessionScope": false, "viewScope": false }, { "messageType": "load_initial_data", "pageScope": true, "script": "\trequest \u003d payload[\"data\"]\n\tsystem.perspective.print(\"initial message received\")\n\tif request \u003d\u003d True:\n\t\tself.props.data \u003d self.custom.initial_data", "sessionScope": false, "viewScope": false }, { "messageType": "reset-historical-filters", "pageScope": true, "script": "\tval \u003d payload[\"data\"] if isinstance(payload, dict) and \"data\" in payload else payload\n\tif val \u003d\u003d \"reset\":\n\t self.props.data \u003d []\n\t self.custom.device_filters \u003d None\n\t self.custom.priority_filters \u003d None\n\t self.custom.source_id_filters \u003d None\n\t self.custom.time_from_filter \u003d None\n\t self.custom.time_to_filter \u003d None\n\t self.custom.type_filters \u003d None\n\t self.custom.duration_filter \u003d None\n\t self.props.enabled \u003d True", "sessionScope": false, "viewScope": false }, { "messageType": "set-source-filters", "pageScope": true, "script": "\tfilters \u003d payload[\"data\"]\n\tself.custom.source_id_filters \u003d filters", "sessionScope": false, "viewScope": false }, { "messageType": "set-device-filters", "pageScope": true, "script": "\tfilters \u003d payload[\"data\"]\n\tself.custom.device_filters \u003d filters", "sessionScope": false, "viewScope": false }, { "messageType": "set-priority-filters", "pageScope": true, "script": "\tfilters \u003d payload[\"data\"]\n\tself.custom.priority_filters \u003d filters", "sessionScope": false, "viewScope": false }, { "messageType": "set-from-filters", "pageScope": true, "script": "\ttime \u003d payload[\"data\"]\n\tself.custom.time_from_filter \u003d time", "sessionScope": false, "viewScope": false }, { "messageType": "set-to-filters", "pageScope": true, "script": "\ttime \u003d payload[\"data\"]\n\tself.custom.time_to_filter \u003d time", "sessionScope": false, "viewScope": false }, { "messageType": "set-type-filters", "pageScope": true, "script": "\tfilters \u003d payload[\"data\"]\n\tself.custom.type_filters \u003d filters", "sessionScope": false, "viewScope": false }, { "messageType": "set-duration-filters", "pageScope": true, "script": "\tduration \u003d payload[\"data\"]\n\tself.custom.duration_filter \u003d duration", "sessionScope": false, "viewScope": false }, { "messageType": "refreshHistoricalTable", "pageScope": true, "script": "\tself.refreshBinding(\"props.data\")", "sessionScope": false, "viewScope": true } ] }, "type": "ia.display.table" } ], "meta": { "name": "Table" }, "position": { "basis": "980px", "grow": 1 }, "props": { "direction": "column" }, "scripts": { "customMethods": [], "extensionFunctions": null, "messageHandlers": [ { "messageType": "update-historical-data", "pageScope": true, "script": "#\tdata \u003d payload[\"data\"]\n#\tself.getChild(\"Table\").props.data \u003d data\n\tpass", "sessionScope": false, "viewScope": false } ] }, "type": "ia.container.flex" }, { "children": [ { "children": [ { "custom": { "download_in_progress": true, "enable_timeout": false, "priority_filters": "medium", "time_from_filter": { "$": [ "ts", 192, 1759316536954 ], "$ts": 1756755000000 }, "time_to_filter": { "$": [ "ts", 192, 1759316533389 ], "$ts": 1759271400000 }, "type_filters": null }, "events": { "component": { "onActionPerformed": { "config": { "script": "\t# Historical_tab → Paginate → FlexContainer → Export → onActionPerformed\n\t\n\tfrom datetime import datetime\n\t\n\ttry:\n\t # Get the table data - try filtered first, then fall back to all data\n\t root \u003d self.parent.parent.parent\n\t table \u003d root.getChild(\"Table\").getChild(\"Table\")\n\t \n\t # Try to get filtered data first, otherwise use all data\n\t data \u003d None\n\t try:\n\t # Check if filtered data exists and has content\n\t filtered_data \u003d table.props.filter.results.data\n\t if filtered_data and len(filtered_data) \u003e 0:\n\t data \u003d filtered_data\n\t system.perspective.print(\"Using filtered data: %d records\" % len(data))\n\t except:\n\t pass\n\t \n\t # Fall back to all data if no filtered data\n\t if not data:\n\t data \u003d table.props.data\n\t system.perspective.print(\"Using all data: %d records\" % len(data))\n\t \n\t # Apply sorting if sortOrder exists\n\t try:\n\t sort_order \u003d table.props.sortOrder\n\t if sort_order and len(sort_order) \u003e 0:\n\t system.perspective.print(\"Applying sort: \" + str(sort_order))\n\t \n\t # Ignition table sortOrder is typically a list of objects with \u0027field\u0027 and \u0027direction\u0027\n\t for sort_item in reversed(sort_order): # Apply in reverse for multiple sorts\n\t field \u003d None\n\t direction \u003d \u0027asc\u0027\n\t \n\t # Try different ways to access the sort configuration\n\t if hasattr(sort_item, \u0027field\u0027):\n\t field \u003d sort_item.field\n\t direction \u003d getattr(sort_item, \u0027direction\u0027, \u0027asc\u0027)\n\t elif hasattr(sort_item, \u0027column\u0027):\n\t field \u003d sort_item.column \n\t direction \u003d getattr(sort_item, \u0027direction\u0027, \u0027asc\u0027)\n\t elif isinstance(sort_item, dict):\n\t field \u003d sort_item.get(\u0027field\u0027) or sort_item.get(\u0027column\u0027)\n\t direction \u003d sort_item.get(\u0027direction\u0027, \u0027asc\u0027)\n\t \n\t if field:\n\t def get_sort_value(item):\n\t if field in item:\n\t cell \u003d item[field]\n\t if isinstance(cell, dict) and \"value\" in cell:\n\t val \u003d cell[\"value\"]\n\t else:\n\t val \u003d cell\n\t \n\t # Handle None values\n\t if val is None:\n\t return \"\"\n\t elif hasattr(val, \u0027value\u0027):\n\t return val.value\n\t else:\n\t return val\n\t return \"\"\n\t \n\t reverse_sort \u003d (str(direction).lower() \u003d\u003d \u0027desc\u0027)\n\t data \u003d sorted(data, key\u003dget_sort_value, reverse\u003dreverse_sort)\n\t system.perspective.print(\"Sorted by %s (%s)\" % (field, direction))\n\t except Exception as e:\n\t system.perspective.print(\"Sort error: \" + str(e))\n\t\n\t column_order \u003d [\n\t \"ID\",\n\t \"StartTimestamp\",\n\t \"EndTimestamp\", \n\t \"Duration\",\n\t \"Description\",\n\t \"Priority\",\n\t \"Location\",\n\t \"Tag\",\n\t \"FullTag\",\n\t \"Device\"\n\t ]\n\t\n\t csv_content \u003d \",\".join(column_order) + \"\\n\"\n\t \t\n\t def unwrap(v):\n\t if hasattr(v, \u0027value\u0027):\n\t return str(v.value)\n\t return str(v) if v is not None else \"\"\n\t \t\n\t if data and len(data) \u003e 0:\n\t for item in data:\n\t row_data \u003d []\n\t \n\t for col in column_order:\n\t # Look for the column in the current item\n\t if col in item:\n\t cell \u003d item[col]\n\t # Extract the value from the nested structure\n\t if isinstance(cell, dict) and \"value\" in cell:\n\t raw_value \u003d cell[\"value\"]\n\t else:\n\t raw_value \u003d cell\n\t else:\n\t raw_value \u003d \"\"\n\t \n\t # Process and clean the value\n\t processed_value \u003d unwrap(raw_value).replace(\",\", \";\").replace(\"\\r\", \" \").replace(\"\\n\", \" \")\n\t row_data.append(processed_value)\n\t \n\t csv_content +\u003d \",\".join(row_data) + \"\\n\"\n\t else:\n\t csv_content +\u003d \"No alarms in current view\\n\"\n\t\n\t csv_bytes \u003d csv_content.encode(\"utf-8\")\n\t system.perspective.download(\"historical_alarms.csv\", csv_bytes)\n\t system.perspective.print(\"Historical export: CSV download started\")\n\t\n\texcept Exception as e:\n\t system.perspective.print(\"Historical export failed: \" + str(e))" }, "scope": "G", "type": "script" } } }, "meta": { "name": "Export", "tooltip": { "enabled": true, "text": "Exports the data displayed in the table." } }, "position": { "basis": "120px", "shrink": 0 }, "propConfig": { "custom.disable": { "binding": { "config": { "expression": "if(isNull({this.custom.start_time}), False, secondsBetween({this.custom.start_time}, {this.custom.time_now}))" }, "transforms": [ { "code": "\tif value \u003e 60:\n\t\tself.custom.enable_timeout \u003d False\n\t\treturn False\n\telse:\n\t\treturn True", "type": "script" } ], "type": "expr" } }, "custom.download_complete": { "binding": { "config": { "path": "session.custom.downloads" }, "transforms": [ { "code": "\tif value \u003d\u003d True:\n\t\tself.custom.download_in_progress \u003d False", "type": "script" } ], "type": "property" } }, "custom.priority_filters": { "persistent": true }, "custom.start_time": { "binding": { "config": { "expression": "{this.custom.enable_timeout}" }, "transforms": [ { "code": "\tif value \u003d\u003d True:\n\t\treturn self.custom.time_now", "type": "script" } ], "type": "expr" } }, "custom.time_from_filter": { "persistent": true }, "custom.time_now": { "binding": { "config": { "expression": "now()" }, "type": "expr" } }, "custom.time_to_filter": { "persistent": true }, "props.enabled": { "binding": { "config": { "expression": "!{this.custom.enable_timeout} || !{this.custom.download_in_progress} " }, "type": "expr" } }, "props.text": { "binding": { "config": { "expression": "if(!{this.custom.enable_timeout}, \"Export\",\r\nif({this.custom.download_in_progress}, \"Exporting...\",\r\n\"Export\"))" }, "type": "expr" } } }, "props": { "image": { "icon": { "path": "material/import_export" } }, "primary": false, "style": { "margin": 15, "marginLeft": 20 } }, "scripts": { "customMethods": [], "extensionFunctions": null, "messageHandlers": [ { "messageType": "set-source-filters", "pageScope": true, "script": "#\tfilters \u003d payload[\"data\"]\n#\tself.custom.source_id_filters \u003d filters\n\tpass", "sessionScope": false, "viewScope": false }, { "messageType": "set-device-filters", "pageScope": true, "script": "#\tfilters \u003d payload[\"data\"]\n#\tself.custom.device_filters \u003d filters\n\tpass", "sessionScope": false, "viewScope": false }, { "messageType": "set-message-filters", "pageScope": true, "script": "#\tfilters \u003d payload[\"data\"]\n#\tself.custom.message_filters \u003d filters\n\tpass", "sessionScope": false, "viewScope": false }, { "messageType": "set-priority-filters", "pageScope": true, "script": "#\tfilters \u003d payload[\"data\"]\n#\tself.custom.priority_filters \u003d filters\n\tpass", "sessionScope": false, "viewScope": false }, { "messageType": "set-from-filters", "pageScope": true, "script": "#\ttime \u003d payload[\"data\"]\n#\tself.custom.time_from_filter \u003d time\n\tpass", "sessionScope": false, "viewScope": false }, { "messageType": "set-to-filters", "pageScope": true, "script": "#\ttime \u003d payload[\"data\"]\n#\tself.custom.time_to_filter \u003d time\n\tpass", "sessionScope": false, "viewScope": false }, { "messageType": "reset-historical-filters", "pageScope": true, "script": "#\taction \u003d payload[\"data\"]\n#\tif action \u003d\u003d \"reset\":\n#\t\tself.custom.device_filters \u003d None\n#\t\tself.custom.priority_filters \u003d None\n#\t\tself.custom.source_id_filters \u003d None\n#\t\tself.custom.time_from_filter \u003d None\n#\t\tself.custom.time_to_filter \u003d None\n#\t\tself.custom.type_filters \u003d None\n#\t\tself.custom.duration_filter \u003d None\n#\t\tself.props.enabled \u003dTrue\n#\t\t\n\tpass", "sessionScope": false, "viewScope": false }, { "messageType": "set-type-filters", "pageScope": true, "script": "#\tfilters \u003d payload[\"data\"]\n#\tself.custom.type_filters \u003d filters\n\tpass", "sessionScope": false, "viewScope": false }, { "messageType": "set-duration-filters", "pageScope": true, "script": "#\tduration \u003d payload[\"data\"]\n#\tself.custom.duration_filter \u003d duration\n#\tpass", "sessionScope": false, "viewScope": false } ] }, "type": "ia.input.button" }, { "meta": { "name": "Label" }, "position": { "basis": "580px", "grow": 1 }, "type": "ia.display.label" } ], "meta": { "name": "FlexContainer" }, "position": { "basis": "960px" }, "type": "ia.container.flex" }, { "children": [ { "events": { "component": { "onActionPerformed": { "config": { "script": "\troot \u003d self.parent.parent.parent\n\ttable \u003d root.getChild(\"Table\").getChild(\"Table\")\n\t\n\tcur \u003d self.getSibling(\"NumericEntryField\").props.value\n\tif cur \u003e 1 and not getattr(table.custom, \"loading\", False):\n\t table.custom.loading \u003d True\n\t self.getSibling(\"NumericEntryField\").props.value \u003d cur - 1" }, "scope": "G", "type": "script" } } }, "meta": { "name": "Button", "tooltip": { "enabled": true } }, "position": { "basis": 150 }, "propConfig": { "meta.tooltip.text": { "binding": { "config": { "expression": "if(coalesce({../../../Table/Table.custom.loading}, true),\r\n \"Loading previous page…\",\r\n if({../NumericEntryField.props.value} \u003c\u003d 1,\r\n \"You\u0027re on the first page.\",\r\n \"Go to previous page\"))\r\n" }, "type": "expr" } }, "props.enabled": { "binding": { "config": { "expression": "({../NumericEntryField.props.value} \u003e 1)\r\n\u0026\u0026 !coalesce({../../../Table/Table.custom.loading}, true)\r\n" }, "type": "expr" } } }, "props": { "image": { "height": 50, "width": 50 }, "primary": false, "text": "Back" }, "type": "ia.input.button" }, { "meta": { "name": "NumericEntryField", "tooltip": { "enabled": true } }, "position": { "basis": "196px" }, "propConfig": { "meta.tooltip.text": { "binding": { "config": { "expression": "if(coalesce({../../../Table/Table.custom.loading}, true),\r\n \"Page change disabled while loading…\",\r\n \"Enter page number\")\r\n" }, "type": "expr" } }, "props.enabled": { "binding": { "config": { "expression": "!coalesce({../../../Table/Table.custom.loading}, true)\r\n" }, "type": "expr" } } }, "props": { "format": "0,0", "spinner": { "enabled": false }, "value": 1 }, "type": "ia.input.numeric-entry-field" }, { "events": { "component": { "onActionPerformed": { "config": { "script": "\troot \u003d self.parent.parent.parent\n\ttable \u003d root.getChild(\"Table\").getChild(\"Table\")\n\t\n\tif getattr(table.custom, \"hasNext\", False) and not getattr(table.custom, \"loading\", False):\n\t table.custom.loading \u003d True\n\t cur \u003d self.getSibling(\"NumericEntryField\").props.value\n\t self.getSibling(\"NumericEntryField\").props.value \u003d cur + 1" }, "scope": "G", "type": "script" } } }, "meta": { "name": "Button_0", "tooltip": { "enabled": true } }, "position": { "basis": 150 }, "propConfig": { "custom.hasNext": { "binding": { "config": { "expression": "{../../../Table/Table.custom.hasNext} \u0026\u0026 !{../../../Table/Table.custom.loading}\r\n" }, "type": "expr" } }, "meta.tooltip.text": { "binding": { "config": { "expression": "if(coalesce({../../../Table/Table.custom.loading}, true),\r\n \"Loading next page…\",\r\n if(!coalesce({../../../Table/Table.custom.hasNext}, false),\r\n \"You\u0027re on the last page. No more rows to load.\",\r\n \"Go to next page\"))\r\n" }, "type": "expr" } }, "props.enabled": { "binding": { "config": { "expression": "coalesce({../../../Table/Table.custom.hasNext}, false)\r\n\u0026\u0026 !coalesce({../../../Table/Table.custom.loading}, true)\r\n" }, "type": "expr" } } }, "props": { "image": { "height": 50, "width": 50 }, "primary": false, "text": "Next" }, "type": "ia.input.button" } ], "meta": { "name": "FlexContainer_0" }, "position": { "basis": 960 }, "props": { "justify": "space-evenly" }, "type": "ia.container.flex" }, { "meta": { "name": "FlexContainer_1" }, "position": { "basis": 960 }, "type": "ia.container.flex" } ], "meta": { "name": "Paginate" }, "position": { "basis": "70px", "shrink": 0 }, "props": { "justify": "space-evenly", "style": { "display": "none" } }, "type": "ia.container.flex" }, { "children": [ { "custom": { "download_in_progress": true, "enable_timeout": false, "priority_filters": "medium", "time_from_filter": { "$": [ "ts", 192, 1759316536954 ], "$ts": 1756755000000 }, "time_to_filter": { "$": [ "ts", 192, 1759316533389 ], "$ts": 1759271400000 }, "type_filters": null }, "events": { "component": { "onActionPerformed": { "config": { "script": "\t# Historical_tab → Paginate → FlexContainer → Export → onActionPerformed\n\t\n\tfrom datetime import datetime\n\t\n\ttry:\n\t # Get the table data - try filtered first, then fall back to all data\n\t # Navigate up the component hierarchy to find the table\n\t current \u003d self\n\t table \u003d None\n\t \n\t # Try different navigation paths to find the table\n\t try:\n\t # Method 1: Try the original path\n\t root \u003d self.parent.parent.parent\n\t table \u003d root.getChild(\"Table\").getChild(\"Table\")\n\t except:\n\t try:\n\t # Method 2: Try going up more levels\n\t root \u003d self.parent.parent.parent.parent\n\t table \u003d root.getChild(\"Table\").getChild(\"Table\")\n\t except:\n\t try:\n\t # Method 3: Try finding by component name search\n\t current \u003d self.parent\n\t while current and not hasattr(current, \u0027meta\u0027) or current.meta.name !\u003d \u0027Historical_tab\u0027:\n\t current \u003d current.parent\n\t if current:\n\t table \u003d current.getChild(\"root\").getChild(\"Table\").getChild(\"Table\")\n\t except:\n\t pass\n\t \n\t if not table:\n\t raise Exception(\"Could not find table component\")\n\t \n\t # Try to get filtered data first, otherwise use all data\n\t data \u003d None\n\t try:\n\t # Check if filtered data exists and has content\n\t filtered_data \u003d table.props.filter.results.data\n\t if filtered_data and len(filtered_data) \u003e 0:\n\t data \u003d filtered_data\n\t system.perspective.print(\"Using filtered data: %d records\" % len(data))\n\t except:\n\t pass\n\t \n\t # Fall back to all data if no filtered data\n\t if not data:\n\t data \u003d table.props.data\n\t system.perspective.print(\"Using all data: %d records\" % len(data))\n\t \n\t # Apply sorting if sortOrder exists\n\t try:\n\t sort_order \u003d table.props.sortOrder\n\t if sort_order and len(sort_order) \u003e 0:\n\t system.perspective.print(\"Applying sort: \" + str(sort_order))\n\t \n\t # Sort the data based on the sort order\n\t for sort_config in reversed(sort_order): # Apply in reverse for multiple sorts\n\t field \u003d None\n\t direction \u003d \u0027asc\u0027\n\t \n\t # Try different ways to get field and direction\n\t if isinstance(sort_config, dict):\n\t field \u003d sort_config.get(\u0027field\u0027) or sort_config.get(\u0027column\u0027)\n\t direction \u003d sort_config.get(\u0027direction\u0027, \u0027asc\u0027)\n\t elif hasattr(sort_config, \u0027field\u0027):\n\t field \u003d sort_config.field\n\t direction \u003d getattr(sort_config, \u0027direction\u0027, \u0027asc\u0027)\n\t elif hasattr(sort_config, \u0027column\u0027):\n\t field \u003d sort_config.column\n\t direction \u003d getattr(sort_config, \u0027direction\u0027, \u0027asc\u0027)\n\t \n\t if field:\n\t def get_sort_value(item):\n\t if field in item:\n\t cell \u003d item[field]\n\t if isinstance(cell, dict) and \"value\" in cell:\n\t val \u003d cell[\"value\"]\n\t else:\n\t val \u003d cell\n\t \n\t # Handle None values\n\t if val is None:\n\t return \"\"\n\t elif hasattr(val, \u0027value\u0027):\n\t return val.value\n\t else:\n\t return val\n\t return \"\"\n\t \n\t reverse_sort \u003d (str(direction).lower() \u003d\u003d \u0027desc\u0027)\n\t data \u003d sorted(data, key\u003dget_sort_value, reverse\u003dreverse_sort)\n\t system.perspective.print(\"Sorted by %s (%s)\" % (field, direction))\n\t except Exception as e:\n\t system.perspective.print(\"Sort error: \" + str(e))\n\t\n\t column_order \u003d [\n\t \"ID\",\n\t \"StartTimestamp\",\n\t \"EndTimestamp\", \n\t \"Duration\",\n\t \"Description\",\n\t \"Priority\",\n\t \"Location\",\n\t \"Tag\",\n\t \"FullTag\",\n\t \"Device\"\n\t ]\n\t\n\t csv_content \u003d \",\".join(column_order) + \"\\n\"\n\t \t\n\t def unwrap(v):\n\t if hasattr(v, \u0027value\u0027):\n\t return str(v.value)\n\t return str(v) if v is not None else \"\"\n\t \t\n\t if data and len(data) \u003e 0:\n\t for item in data:\n\t row_data \u003d []\n\t \n\t for col in column_order:\n\t # Look for the column in the current item\n\t if col in item:\n\t cell \u003d item[col]\n\t # Extract the value from the nested structure\n\t if isinstance(cell, dict) and \"value\" in cell:\n\t raw_value \u003d cell[\"value\"]\n\t else:\n\t raw_value \u003d cell\n\t else:\n\t raw_value \u003d \"\"\n\t \n\t # Process and clean the value\n\t processed_value \u003d unwrap(raw_value).replace(\",\", \";\").replace(\"\\r\", \" \").replace(\"\\n\", \" \")\n\t row_data.append(processed_value)\n\t \n\t csv_content +\u003d \",\".join(row_data) + \"\\n\"\n\t else:\n\t csv_content +\u003d \"No alarms in current view\\n\"\n\t\n\t csv_bytes \u003d csv_content.encode(\"utf-8\")\n\t system.perspective.download(\"historical_alarms.csv\", csv_bytes)\n\t system.perspective.print(\"Historical export: CSV download started\")\n\t\n\texcept Exception as e:\n\t system.perspective.print(\"Historical export failed: \" + str(e))" }, "scope": "G", "type": "script" } } }, "meta": { "name": "Export", "tooltip": { "enabled": true, "text": "Exports the data displayed in the table." } }, "position": { "basis": "120px", "shrink": 0 }, "propConfig": { "custom.disable": { "binding": { "config": { "expression": "if(isNull({this.custom.start_time}), False, secondsBetween({this.custom.start_time}, {this.custom.time_now}))" }, "transforms": [ { "code": "\tif value \u003e 60:\n\t\tself.custom.enable_timeout \u003d False\n\t\treturn False\n\telse:\n\t\treturn True", "type": "script" } ], "type": "expr" } }, "custom.download_complete": { "binding": { "config": { "path": "session.custom.downloads" }, "transforms": [ { "code": "\tif value \u003d\u003d True:\n\t\tself.custom.download_in_progress \u003d False", "type": "script" } ], "type": "property" } }, "custom.priority_filters": { "persistent": true }, "custom.start_time": { "binding": { "config": { "expression": "{this.custom.enable_timeout}" }, "transforms": [ { "code": "\tif value \u003d\u003d True:\n\t\treturn self.custom.time_now", "type": "script" } ], "type": "expr" } }, "custom.time_from_filter": { "persistent": true }, "custom.time_now": { "binding": { "config": { "expression": "now()" }, "type": "expr" } }, "custom.time_to_filter": { "persistent": true }, "props.enabled": { "binding": { "config": { "expression": "!{this.custom.enable_timeout} || !{this.custom.download_in_progress} " }, "type": "expr" } }, "props.text": { "binding": { "config": { "expression": "if(!{this.custom.enable_timeout}, \"Export\",\r\nif({this.custom.download_in_progress}, \"Exporting...\",\r\n\"Export\"))" }, "type": "expr" } } }, "props": { "image": { "icon": { "path": "material/import_export" } }, "primary": false, "style": { "margin": 15, "marginLeft": 20 } }, "scripts": { "customMethods": [], "extensionFunctions": null, "messageHandlers": [ { "messageType": "set-source-filters", "pageScope": true, "script": "#\tfilters \u003d payload[\"data\"]\n#\tself.custom.source_id_filters \u003d filters\n\tpass", "sessionScope": false, "viewScope": false }, { "messageType": "set-device-filters", "pageScope": true, "script": "#\tfilters \u003d payload[\"data\"]\n#\tself.custom.device_filters \u003d filters\n\tpass", "sessionScope": false, "viewScope": false }, { "messageType": "set-message-filters", "pageScope": true, "script": "#\tfilters \u003d payload[\"data\"]\n#\tself.custom.message_filters \u003d filters\n\tpass", "sessionScope": false, "viewScope": false }, { "messageType": "set-priority-filters", "pageScope": true, "script": "#\tfilters \u003d payload[\"data\"]\n#\tself.custom.priority_filters \u003d filters\n\tpass", "sessionScope": false, "viewScope": false }, { "messageType": "set-from-filters", "pageScope": true, "script": "#\ttime \u003d payload[\"data\"]\n#\tself.custom.time_from_filter \u003d time\n\tpass", "sessionScope": false, "viewScope": false }, { "messageType": "set-to-filters", "pageScope": true, "script": "#\ttime \u003d payload[\"data\"]\n#\tself.custom.time_to_filter \u003d time\n\tpass", "sessionScope": false, "viewScope": false }, { "messageType": "reset-historical-filters", "pageScope": true, "script": "#\taction \u003d payload[\"data\"]\n#\tif action \u003d\u003d \"reset\":\n#\t\tself.custom.device_filters \u003d None\n#\t\tself.custom.priority_filters \u003d None\n#\t\tself.custom.source_id_filters \u003d None\n#\t\tself.custom.time_from_filter \u003d None\n#\t\tself.custom.time_to_filter \u003d None\n#\t\tself.custom.type_filters \u003d None\n#\t\tself.custom.duration_filter \u003d None\n#\t\tself.props.enabled \u003dTrue\n#\t\t\n\tpass", "sessionScope": false, "viewScope": false }, { "messageType": "set-type-filters", "pageScope": true, "script": "#\tfilters \u003d payload[\"data\"]\n#\tself.custom.type_filters \u003d filters\n\tpass", "sessionScope": false, "viewScope": false }, { "messageType": "set-duration-filters", "pageScope": true, "script": "#\tduration \u003d payload[\"data\"]\n#\tself.custom.duration_filter \u003d duration\n#\tpass", "sessionScope": false, "viewScope": false } ] }, "type": "ia.input.button" } ], "meta": { "name": "FlexContainer" }, "position": { "basis": 100 }, "type": "ia.container.flex" } ], "meta": { "name": "root" }, "props": { "direction": "column", "style": { "classes": "Background-Styles/Grey-Background" } }, "type": "ia.container.flex" } ], "meta": { "name": "Historical_tab" }, "position": { "tabIndex": 2 }, "props": { "direction": "column", "justify": "space-evenly" }, "type": "ia.container.flex" } ], "custom": { "shelvedAlarms": [] }, "meta": { "name": "TabContainer" }, "position": { "basis": "300px", "grow": 1 }, "propConfig": { "props.currentTabIndex": { "onChange": { "enabled": null, "script": "\tlogger \u003d system.util.getLogger(\"DropdownTimeChange\")\n\n\ttry:\n\t\tif currentValue is None or currentValue.value is None:\n\t\t\tlogger.info(\"No currentValue, exiting.\")\n\t\t\treturn\n\n\t\tval_num \u003d int(currentValue.value)\n\t\tlogger.info(\"Tab index changed to: %d\" % val_num)\n\n\t\t# Get dropdown for each tab\n\t\tif val_num \u003d\u003d 1:\n\t\t\tdd \u003d self.getChild(\"Hit_List\").getChild(\"FlexContainer\").getChild(\"Time\").getChild(\"Dropdown\")\n\t\t\tlogger.info(\"Selected Hit_List Dropdown.\")\n\t\telif val_num \u003d\u003d 2:\n\t\t\tdd \u003d self.getChild(\"Historical_tab\").getChild(\"root\").getChild(\"Filters\").getChild(\"Time\").getChild(\"Dropdown\")\n\t\t\tlogger.info(\"Selected Historical_tab Dropdown.\")\n\t\telse:\n\t\t\tlogger.info(\"Unhandled tab value: %s\" % str(val_num))\n\t\t\treturn\n\n\t\tnow \u003d system.date.now()\n\t\ttoday0 \u003d system.date.setTime(now, 0, 0, 0)\n\t\tyday0 \u003d system.date.addDays(today0, -1)\n\n\t\tval \u003d str(dd.props.value or \u0027\u0027).strip()\n\t\tlogger.info(\"Dropdown value: %s\" % val)\n\n\t\tif val \u003d\u003d \"custom\":\n\t\t\tdd.custom.customTime \u003d True\n\t\t\tlogger.info(\"Custom mode selected — skipping time overwrite.\")\n\t\t\treturn\n\t\tdd.custom.customTime \u003d False\n\n\t\tdef t(day, h, m, s):\n\t\t\treturn system.date.setTime(day, h, m, s)\n\n\t\tif val \u003d\u003d \"currentDay\":\n\t\t\tstart, end \u003d today0, now\n\t\telif val \u003d\u003d \"morning\":\n\t\t\tstart, end \u003d t(today0, 2, 30, 0), t(today0, 7, 30, 0)\n\t\telif val \u003d\u003d \"daylight\":\n\t\t\tstart, end \u003d t(today0, 7, 30, 0), t(today0, 13, 0, 0)\n\t\telif val \u003d\u003d \"twilight\":\n\t\t\tif now \u003e\u003d t(today0, 13, 0, 0):\n\t\t\t\tstart, end \u003d t(today0, 13, 0, 0), now\n\t\t\telse:\n\t\t\t\tstart, end \u003d t(yday0, 13, 0, 0), now\n\t\telif val \u003d\u003d \"night\":\n\t\t\tstart, end \u003d t(yday0, 18, 30, 0), t(yday0, 23, 30, 0)\n\t\telif val \u003d\u003d \"wrapDown\":\n\t\t\tstart, end \u003d t(yday0, 23, 30, 0), t(today0, 2, 30, 0)\n\t\telif val \u003d\u003d \"currentShot\":\n\t\t\tif now \u003e\u003d t(today0, 13, 0, 0):\n\t\t\t\tstart, end \u003d t(today0, 13, 0, 0), now\n\t\t\telse:\n\t\t\t\tstart, end \u003d t(yday0, 13, 0, 0), now\n\t\telse:\n\t\t\ttry:\n\t\t\t\tmins \u003d int(val)\n\t\t\texcept:\n\t\t\t\tmins \u003d 60\n\t\t\t\tlogger.warn(\"Invalid numeric value \u0027%s\u0027, defaulting to 60 min.\" % val)\n\t\t\tend \u003d now\n\t\t\tstart \u003d system.date.addMinutes(end, -mins)\n\n\t\t# Apply to dropdown\n\t\tdd.custom.startDate \u003d start\n\t\tdd.custom.endDate \u003d end\n\n\t\tlogger.info(\"Time range applied successfully: start\u003d%s | end\u003d%s\" %\n\t\t (system.date.format(start, \"yyyy-MM-dd HH:mm:ss\"),\n\t\t system.date.format(end, \"yyyy-MM-dd HH:mm:ss\")))\n\n\texcept Exception as e:\n\t\tlogger.error(\"Error in valueChanged: %s\" % str(e))" } } }, "props": { "contentStyle": { "classes": "Background-Styles/Grey-Background" }, "menuType": "modern", "style": { "classes": "Background-Styles/Grey-Background" }, "tabSize": { "width": 140 }, "tabStyle": { "active": { "backgroundColor": "#EEEEEE", "borderLeftColor": "#7FFF00", "borderLeftStyle": "solid", "borderLeftWidth": 5, "borderTopLeftRadius": 5, "borderTopRightRadius": 5, "color": "#000000", "fontFamily": "Arial", "fontWeight": "bold", "outlineStyle": "none", "textDecoration": "underline" }, "inactive": { "backgroundColor": "#D7D7D7", "borderLeftColor": "#FFFFFF", "borderTopLeftRadius": 5, "borderTopRightRadius": 5, "color": "#969696", "fontFamily": "Arial" } }, "tabs": [ "Active Alarms", "Alarm Hit List", "Historical" ] }, "type": "ia.container.tab" } ], "meta": { "name": "root" }, "props": { "style": { "classes": "Background-Styles/Main-Background" } }, "type": "ia.container.flex" } }