diff --git a/SCADA_PERSPECTIVE_PARENT_PROJECT/com.inductiveautomation.perspective/views/Alarm-Views/RealTime/view.json b/SCADA_PERSPECTIVE_PARENT_PROJECT/com.inductiveautomation.perspective/views/Alarm-Views/RealTime/view.json index 5fcb913..871a42f 100644 --- a/SCADA_PERSPECTIVE_PARENT_PROJECT/com.inductiveautomation.perspective/views/Alarm-Views/RealTime/view.json +++ b/SCADA_PERSPECTIVE_PARENT_PROJECT/com.inductiveautomation.perspective/views/Alarm-Views/RealTime/view.json @@ -412,14 +412,13 @@ }, { "custom": { - "Severity": "Diagnostic", "background_on": "false" }, "events": { "component": { "onActionPerformed": { "config": { - "script": "\tpriority \u003d \u0027diagnostic\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\"" + "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" @@ -492,6 +491,25 @@ "type": "ia.input.button" } ], + "custom": { + "priorities": { + "diagnostic": true, + "high": true, + "low": true, + "medium": true + } + }, + "events": { + "system": { + "onStartup": { + "config": { + "script": "\tself.custom.priorities \u003d {\n\t \"diagnostic\": True,\n\t \"low\": True,\n\t \"medium\": True,\n\t \"high\": True,\n\t}" + }, + "scope": "G", + "type": "script" + } + } + }, "meta": { "name": "FlexContainer" }, @@ -499,17 +517,6 @@ "basis": "700px", "shrink": 0 }, - "propConfig": { - "custom.priorities": { - "binding": { - "config": { - "bidirectional": true, - "path": ".../FlexContainer_0/AlarmStatusTable.props.filters.active.priorities" - }, - "type": "property" - } - } - }, "props": { "style": { "padding": 0 @@ -537,7 +544,7 @@ "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 \"critical\": False,\n\t \"high\": False,\n\t \"medium\": False,\n\t \"low\": False,\n\t \"diagnostic\": False\n\t}\n\tself.parent.parent.getChild(\"FlexContainer\").custom.priorities \u003d default_priorities" + "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.getChild(\"FlexContainer\").custom.priorities \u003d default_priorities" }, "scope": "G", "type": "script" @@ -879,6 +886,16 @@ "position": { "basis": "973px" }, + "propConfig": { + "props.filters.active.priorities": { + "binding": { + "config": { + "path": ".../FlexContainer/FlexContainer.custom.priorities" + }, + "type": "property" + } + } + }, "props": { "columns": { "active": { @@ -909,139 +926,11 @@ "enableUnshelve": false, "filters": { "active": { - "priorities": { - "critical": false, - "high": false, - "low": false, - "medium": false - }, "results": { - "data": [ - { - "ackNotes": "", - "ackPipeline": "", - "ackTime": "", - "ackUser": "", - "activePipeline": "", - "activeTime": "2025-06-10 10:46:16.547+0400", - "clearPipeline": "", - "clearTime": "2025-06-10 10:48:20.462+0400", - "deadband": "0.0", - "displayPath": "System/close_socket/papapapa", - "eventId": "bb8d48cb-a61e-4e31-a44f-340466686cc7", - "eventTime": "2025-06-10 10:48:20.462+0400", - "eventValue": "false", - "isAcked": "false", - "isActive": "false", - "isClear": "true", - "label": "papapapa", - "name": "papapapa", - "notes": "", - "priority": "Low", - "source": "prov:MTN6_SCADA_TAG_PROVIDER:/tag:System/close_socket:/alm:papapapa", - "state": "Cleared, Unacknowledged" - }, - { - "ackNotes": "", - "ackPipeline": "", - "ackTime": "", - "ackUser": "", - "activePipeline": "", - "activeTime": "2025-06-10 10:48:22.466+0400", - "clearPipeline": "", - "clearTime": "2025-06-10 10:50:24.652+0400", - "deadband": "0.0", - "displayPath": "System/close_socket/papapapa", - "eventId": "479900cc-da53-43f8-8fcc-2f2278b01ccd", - "eventTime": "2025-06-10 10:50:24.652+0400", - "eventValue": "false", - "isAcked": "false", - "isActive": "false", - "isClear": "true", - "label": "papapapa", - "name": "papapapa", - "notes": "", - "priority": "Low", - "source": "prov:MTN6_SCADA_TAG_PROVIDER:/tag:System/close_socket:/alm:papapapa", - "state": "Cleared, Unacknowledged" - }, - { - "ackNotes": "", - "ackPipeline": "", - "ackTime": "", - "ackUser": "", - "activePipeline": "", - "activeTime": "2025-06-10 10:44:18.146+0400", - "clearPipeline": "", - "clearTime": "2025-06-10 10:44:24.496+0400", - "deadband": "0.0", - "displayPath": "System/close_socket/papapapa", - "eventId": "4ff749a9-0a6b-4818-95e0-96ceb3c7d50a", - "eventTime": "2025-06-10 10:44:24.496+0400", - "eventValue": "false", - "isAcked": "false", - "isActive": "false", - "isClear": "true", - "label": "papapapa", - "name": "papapapa", - "notes": "", - "priority": "Low", - "source": "prov:MTN6_SCADA_TAG_PROVIDER:/tag:System/close_socket:/alm:papapapa", - "state": "Cleared, Unacknowledged" - }, - { - "ackNotes": "", - "ackPipeline": "", - "ackTime": "", - "ackUser": "", - "activePipeline": "", - "activeTime": "2025-06-10 10:42:13.975+0400", - "clearPipeline": "", - "clearTime": "2025-06-10 10:44:16.145+0400", - "deadband": "0.0", - "displayPath": "System/close_socket/papapapa", - "eventId": "2f522dec-f2fc-4c05-8acf-a3208aa048c9", - "eventTime": "2025-06-10 10:44:16.145+0400", - "eventValue": "false", - "isAcked": "false", - "isActive": "false", - "isClear": "true", - "label": "papapapa", - "name": "papapapa", - "notes": "", - "priority": "Low", - "source": "prov:MTN6_SCADA_TAG_PROVIDER:/tag:System/close_socket:/alm:papapapa", - "state": "Cleared, Unacknowledged" - }, - { - "ackNotes": "", - "ackPipeline": "", - "ackTime": "", - "ackUser": "", - "activePipeline": "", - "activeTime": "2025-06-10 10:50:26.655+0400", - "clearPipeline": "", - "clearTime": "", - "deadband": "0.0", - "displayPath": "System/close_socket/papapapa", - "eventId": "887b4132-0bfd-4902-9db3-a10b581ca073", - "eventTime": "2025-06-10 10:50:26.655+0400", - "eventValue": "true", - "isAcked": "false", - "isActive": "true", - "isClear": "false", - "label": "papapapa", - "name": "papapapa", - "notes": "", - "priority": "Low", - "source": "prov:MTN6_SCADA_TAG_PROVIDER:/tag:System/close_socket:/alm:papapapa", - "state": "Active, Unacknowledged" - } - ], "enabled": true }, "states": { - "clearAcked": true + "clearUnacked": false } }, "shelved": { @@ -1050,26 +939,45 @@ } } }, + "refreshRate": 1000, "responsive": { "enabled": true }, "rowStyles": { + "activeUnacked": { + "priorities": { + "critical": { + "backgroundColor": "#c86462" + }, + "diagnostic": { + "backgroundColor": "#5da0f9" + }, + "high": { + "backgroundColor": "#fd6059" + }, + "low": { + "backgroundColor": "#fafa6c", + "color": "black" + }, + "medium": { + "backgroundColor": "#fca25f" + } + } + }, "clearAcked": { "base": { - "display": "none" + "display": "block" } }, "clearUnacked": { "base": { - "display": "none" + "display": "block", + "fontWeight": "normal" } } }, "toolbar": { "enableActiveTab": false, - "enableConfiguration": false, - "enableFilter": false, - "enablePreFilters": false, "enableShelvedTab": false, "enabled": false } @@ -1110,7 +1018,7 @@ "component": { "onActionPerformed": { "config": { - "script": "\tshelved_alarm_table \u003d self.parent.parent.parent.getChild(\"FlexContainer_0\").getChild(\"AlarmsTable\")\n\t\n\tselected_alarms \u003d shelved_alarm_table.props.selection.data\n\tif(len(selected_alarms)\u003d\u003d0):\n\t\treturn\n\t\n\tfor alarm in selected_alarms:\n\t\tsystem.alarm.unshelve(alarm.path)\n\t\t\n\tshelved_alarm_table.props.data \u003d []" + "script": "\n\tselected_alarms \u003d self.parent.parent.parent.getChild(\"FlexContainer_0\").getChild(\"AlarmsTable\").props.selection.data\n\tif len(selected_alarms) \u003d\u003d 0:\n\t\treturn\n\t\n\t# Unshelve selected alarms\n\tfor alarm in selected_alarms:\n\t\tsystem.alarm.unshelve(alarm[\u0027path\u0027])\n\t\t\n\tpaths_to_remove \u003d {alarm[\u0027path\u0027] for alarm in selected_alarms}\n\t\n\tshelved_alarms \u003d self.parent.parent.parent.parent.parent.getChild(\"TabContainer\").custom.shelvedAlarms\n\t\t\n\tif shelved_alarms is not None:\n\t\tremaining_data \u003d [a for a in shelved_alarms if a[\u0027path\u0027] not in paths_to_remove]\n\t\t\n\tself.parent.parent.parent.parent.parent.getChild(\"TabContainer\").custom.shelvedAlarms \u003d remaining_data" }, "scope": "G", "type": "script" @@ -1185,9 +1093,6 @@ { "children": [ { - "custom": { - "shelvedAlarmsData": null - }, "meta": { "name": "AlarmsTable" }, @@ -1201,6 +1106,12 @@ "config": { "path": "...../TabContainer.custom.shelvedAlarms" }, + "transforms": [ + { + "code": " data \u003d []\n for row in value: \n keys \u003d row.keys() \n if row[\"priority\"] \u003d\u003d \"High\": \n style \u003d {\"backgroundColor\": \"#fd6059\"} \n elif row[\"priority\"] \u003d\u003d \"Low\": \n style \u003d {\"backgroundColor\": \"#fafa6c\"} \n elif row[\"priority\"] \u003d\u003d \"Diagnostic\": \n style \u003d {\"backgroundColor\": \"#5da0f9\"} \n elif row[\"priority\"] \u003d\u003d \"Medium\": \n style \u003d {\"backgroundColor\": \"#fca25f\"} \n elif row[\"priority\"] \u003d\u003d \"Critical\": \n style \u003d {\"backgroundColor\": \"#c86462\"} \n else:\n style \u003d {\"backgroundColor\": \"\"}\n \n formatted_rows \u003d [{\"value\": v, \"style\": style} for v in row.values()]\n \n row_dict \u003d dict(zip(keys, formatted_rows))\n data.append(row_dict)\n return data ", + "type": "script" + } + ], "type": "property" } }, @@ -1253,6 +1164,7 @@ "align": "center", "justify": "left", "style": { + "backgroundColor": "#FFFEFE", "classes": "" }, "title": "" @@ -1682,7 +1594,6 @@ "text": "No Shelved Alarms" } }, - "enableFooter": true, "selection": { "mode": "multiple interval" } @@ -1720,7 +1631,7 @@ "children": [ { "custom": { - "SetFilter": true + "SetFilter": false }, "events": { "component": { @@ -1818,22 +1729,22 @@ }, { "custom": { - "customTime": true, + "customTime": false, "endDate": { "$": [ "ts", 192, - 1749540890888 + 1749561376741 ], - "$ts": 1749540890888 + "$ts": 1749561376741 }, "startDate": { "$": [ "ts", 192, - 1749540890888 + 1749561376741 ], - "$ts": 1749499200000 + "$ts": 1749559576741 } }, "meta": { @@ -2006,7 +1917,7 @@ } }, "props": { - "formattedValue": "Jun 4, 2025 12:00 AM", + "formattedValue": "Jun 10, 2025 4:46 PM", "style": { "margin": 15 } @@ -2064,6 +1975,7 @@ "config": { "expression": "now()" }, + "enabled": false, "type": "expr" } }, @@ -2090,17 +2002,25 @@ } }, "props": { - "formattedValue": "Jun 5, 2025 11:34 AM", + "formattedValue": "Jun 10, 2025 5:16 PM", + "maxDate": { + "$": [ + "ts", + 192, + 1749542669794 + ], + "$ts": 1749715452000 + }, "style": { "margin": 15 }, "value": { "$": [ "ts", - 0, - 1749541102438 + 201, + 1749561376741 ], - "$ts": 1749108890000 + "$ts": 1749561376741 } }, "scripts": { @@ -2224,13 +2144,14 @@ } ], "custom": { - "ShowFilters": true + "ShowFilters": false }, "meta": { "name": "Filters" }, "position": { "basis": "180px", + "display": false, "grow": 1, "shrink": 0 }, @@ -2285,9 +2206,23 @@ ], "$ts": 1747562336635 }, - "priority_filters": "", - "time_from_filter": 1748980800000, - "time_to_filter": 1749108890000 + "priority_filters": "low", + "time_from_filter": { + "$": [ + "ts", + 192, + 1749634338103 + ], + "$ts": 1749559576741 + }, + "time_to_filter": { + "$": [ + "ts", + 192, + 1749634338103 + ], + "$ts": 1749561376741 + } }, "meta": { "name": "Table" @@ -2302,17 +2237,6 @@ "config": { "path": "this.custom.time_from_filter" }, - "enabled": false, - "transforms": [ - { - "formatType": "datetime", - "formatValue": { - "date": "medium", - "time": "medium" - }, - "type": "format" - } - ], "type": "property" } }, @@ -2321,12 +2245,15 @@ "config": { "path": "this.custom.time_to_filter" }, - "transforms": [ - { - "code": "\tfrom java.util import Date\n\tfrom java.text import SimpleDateFormat\n\n\tif value is not None:\n\t formatter \u003d SimpleDateFormat(\"yyyy-M-d H:mm:ss\")\n\t return formatter.format(Date(value))\n\telse:\n\t return \"\"\n", - "type": "script" - } - ], + "type": "property" + } + }, + "props.columns[2].filter.number.value": { + "binding": { + "config": { + "path": "this.custom.time_to_filter" + }, + "enabled": false, "type": "property" } }, @@ -2458,8 +2385,7 @@ "condition": "" }, "date": { - "condition": "", - "value": "" + "condition": "later than date time" }, "enabled": true, "number": { @@ -3093,26 +3019,30 @@ ], "enabled": true, "filter": { - "enabled": true + "enabled": true, + "results": { + "enabled": true + } }, "pager": { + "activePage": 2, "bottom": false }, "selection": { "data": [ { "Description": "alm:papapapa - papapapa", - "Duration": "00:02:02", - "EndTimestamp": 1749541007000, - "ID": 86, + "Duration": "00:00:09", + "EndTimestamp": 1749565341000, + "ID": 668, "MCM": "System", - "Priority": "Low", - "StartTimestamp": 1749540885000, + "Priority": "Diagnostic", + "StartTimestamp": 1749565332000, "Tag": "alm:papapapa" } ], - "selectedColumn": "EndTimestamp", - "selectedRow": 1 + "selectedColumn": "Duration", + "selectedRow": 29 }, "style": { "margin": 20 @@ -3232,16 +3162,30 @@ "custom": { "download_in_progress": true, "enable_timeout": false, - "priority_filters": "", - "time_from_filter": 1748980800000, - "time_to_filter": 1749108890000, + "priority_filters": "low", + "time_from_filter": { + "$": [ + "ts", + 192, + 1749634338103 + ], + "$ts": 1749559576741 + }, + "time_to_filter": { + "$": [ + "ts", + 192, + 1749634338103 + ], + "$ts": 1749561376741 + }, "type_filters": null }, "events": { "component": { "onActionPerformed": { "config": { - "script": "\twhid \u003d self.session.custom.fc\n\tsession_id \u003d self.session.props.id\n\t\n\tfilters \u003d AWS.build_url_http.get_filters_2(sources \u003d self.custom.source_id_filters, \n\t\t\t\t\t\t\t\t\t\t\t\tdevices \u003d self.custom.device_filters,\n\t\t\t\t\t\t\t\t\t\t\t\tpriorities \u003d self.custom.priority_filters, \n\t\t\t\t\t\t\t\t\t\t\t\ttypes \u003d self.custom.type_filters,\n\t\t\t\t\t\t\t\t\t\t\t\tstart \u003d self.custom.time_from_filter,\n\t\t\t\t\t\t\t\t\t\t\t\tend \u003d self.custom.time_to_filter, \n\t\t\t\t\t\t\t\t\t\t\t\tduration \u003d self.custom.duration_filter)\n\t\n\tCommands.button_commands.send_download_request(whid, filters, session_id)\n\tself.custom.enable_timeout \u003d True\n\tself.custom.download_in_progress \u003d True" + "script": " try:\n # Get filtered data from table (array of dicts)\n filtered_results \u003d self.parent.parent.getChild(\"Table\").getChild(\"Table\").props.filter.results\n filtered_data \u003d filtered_results.data\n \n # Ensure data is valid\n if not filtered_data:\n return\n \n # Get columns from first record\n columns \u003d filtered_data[0].keys()\n \n # Create a list of rows\n rows \u003d []\n for i in range(len(filtered_data)):\n row_dict \u003d filtered_data[i]\n row \u003d [row_dict.get(col) for col in columns]\n rows.append(row)\n \n # Convert to dataset and export\n dataset \u003d system.dataset.toDataSet(columns, rows)\n html_data \u003d system.dataset.dataSetToHTML(1, dataset, \"Filtered Results\")\n system.perspective.download(\"filtered_alarms_history.html\", html_data)\n \n print \"Export completed successfully! Exported\", len(rows), \"records.\"\n \n except Exception as e:\n print \"Export failed:\", str(e)\n\n\t" }, "scope": "G", "type": "script" @@ -3249,7 +3193,11 @@ } }, "meta": { - "name": "Export" + "name": "Export", + "tooltip": { + "enabled": true, + "text": "Exports the data displayed in the table." + } }, "position": { "basis": "120px", @@ -3465,22 +3413,7 @@ } ], "custom": { - "shelvedAlarms": [ - { - "activeTime": "2025-06-10 11:03:10", - "expirationTime": "Tue Jun 24 10:46:41 GET 2025", - "name": "NEEEWWWW", - "path": "prov:MTN6_SCADA_TAG_PROVIDER:/tag:System/DBConnected:/alm:NEEEWWWW", - "priority": "Low" - }, - { - "activeTime": "2025-06-10 11:03:16", - "expirationTime": "Tue Jun 24 10:46:41 GET 2025", - "name": "Alarm", - "path": "prov:MTN6_SCADA_TAG_PROVIDER:/tag:System/wbsckt_logging:/alm:Alarm", - "priority": "Critical" - } - ] + "shelvedAlarms": [] }, "meta": { "name": "TabContainer" @@ -3501,7 +3434,7 @@ "contentStyle": { "classes": "Background-Styles/Grey-Background" }, - "currentTabIndex": 2, + "currentTabIndex": 1, "menuType": "modern", "style": { "classes": "Background-Styles/Grey-Background" diff --git a/SCADA_PERSPECTIVE_PARENT_PROJECT/ignition/named-query/GetAlarms/resource.json b/SCADA_PERSPECTIVE_PARENT_PROJECT/ignition/named-query/GetAlarms/resource.json new file mode 100644 index 0000000..af7a650 --- /dev/null +++ b/SCADA_PERSPECTIVE_PARENT_PROJECT/ignition/named-query/GetAlarms/resource.json @@ -0,0 +1,33 @@ +{ + "scope": "DG", + "version": 2, + "restricted": false, + "overridable": true, + "files": [ + "query.sql" + ], + "attributes": { + "useMaxReturnSize": false, + "autoBatchEnabled": false, + "fallbackValue": "", + "maxReturnSize": 100, + "cacheUnit": "SEC", + "type": "Query", + "enabled": true, + "cacheAmount": 1, + "cacheEnabled": false, + "database": "MariaDB", + "fallbackEnabled": false, + "lastModificationSignature": "6748eaa152183180c6431e52bd5d1c58f2e9026fefc3fe2663abf90dc4b6a2c7", + "permissions": [ + { + "zone": "default", + "role": "" + } + ], + "lastModification": { + "actor": "ilia-gu-autstand", + "timestamp": "2025-06-09T10:14:52Z" + } + } +} \ No newline at end of file diff --git a/SCADA_PERSPECTIVE_PARENT_PROJECT/ignition/script-python/messaging/message_handler/code.py b/SCADA_PERSPECTIVE_PARENT_PROJECT/ignition/script-python/messaging/message_handler/code.py index b0112aa..6427538 100644 --- a/SCADA_PERSPECTIVE_PARENT_PROJECT/ignition/script-python/messaging/message_handler/code.py +++ b/SCADA_PERSPECTIVE_PARENT_PROJECT/ignition/script-python/messaging/message_handler/code.py @@ -101,22 +101,16 @@ def set_message_filters(self): def set_time_from_filters(self): "This filter sets the time from for history" time = self.props.value - utc_offset = -self.session.props.device.timezone.utcOffset - #time = system.date.addHours(time, utc_offset) - epoch = system.date.toMillis(time) payload = {} - payload["data"] = epoch + payload["data"] = time system.perspective.sendMessage("set-from-filters", payload = payload, scope = "page") def set_time_to_filters(self): "This filter sets the time to for history" time = self.props.value - utc_offset = -self.session.props.device.timezone.utcOffset - #time = system.date.addHours(time, utc_offset) - epoch = system.date.toMillis(time) payload = {} - payload["data"] = epoch + payload["data"] = time system.perspective.sendMessage("set-to-filters", payload = payload, scope = "page")