From da884c24dbb68ab751675745c5de86e3086c51dc Mon Sep 17 00:00:00 2001 From: chrin Date: Wed, 31 Jan 2024 11:20:47 +0100 Subject: [PATCH] first draft --- .gitignore | 12 + help/README.md | 6 + help/hush.qrc | 10 + help/hush_resources.py | 197 +++++++++++ help/index.html | 18 + help/make_and_install.sh | 2 + help/makefile | 9 + help/page1.html | 7 + help/page2.html | 7 + help/page3.html | 7 + help/page4.html | 7 + help/page5.html | 7 + hush.json | 78 +++++ hush.py | 229 +++++++++++++ hush.sh | 99 ++++++ pyrcc5/hush_resources.py | 197 +++++++++++ src/gui.py | 695 +++++++++++++++++++++++++++++++++++++++ 17 files changed, 1587 insertions(+) create mode 100644 .gitignore create mode 100644 help/README.md create mode 100644 help/hush.qrc create mode 100644 help/hush_resources.py create mode 100755 help/index.html create mode 100644 help/make_and_install.sh create mode 100644 help/makefile create mode 100755 help/page1.html create mode 100755 help/page2.html create mode 100755 help/page3.html create mode 100755 help/page4.html create mode 100755 help/page5.html create mode 100755 hush.json create mode 100644 hush.py create mode 100755 hush.sh create mode 100644 pyrcc5/hush_resources.py create mode 100644 src/gui.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bb40eab --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +*.*~ +*.*-* +*.*+* +help/*.*~ +help/*.*-* +help/*.*+* +src/*.*~ +src/*.*-* +src/*.*+* +pyrcc5/*.*~ +pyrcc5/*.*-* +pyrcc5/*.*+* diff --git a/help/README.md b/help/README.md new file mode 100644 index 0000000..a7f649a --- /dev/null +++ b/help/README.md @@ -0,0 +1,6 @@ +# to compile hush.qrc: +make +# to install compiled hush_respources.py +make install + +The latter installs hush_respources.py to the ../pyqrcc5 directory \ No newline at end of file diff --git a/help/hush.qrc b/help/hush.qrc new file mode 100644 index 0000000..eefb6cb --- /dev/null +++ b/help/hush.qrc @@ -0,0 +1,10 @@ + + +page5.html +page4.html +page3.html +page2.html +page1.html +index.html + + diff --git a/help/hush_resources.py b/help/hush_resources.py new file mode 100644 index 0000000..e9707eb --- /dev/null +++ b/help/hush_resources.py @@ -0,0 +1,197 @@ +# -*- coding: utf-8 -*- + +# Resource object code +# +# Created by: The Resource Compiler for PyQt5 (Qt v5.15.3) +# +# WARNING! All changes made in this file will be lost! + +from PyQt5 import QtCore + +qt_resource_data = b"\ +\x00\x00\x00\xa7\ +\x3c\ +\x68\x74\x6d\x6c\x3e\x3c\x68\x65\x61\x64\x3e\x3c\x74\x69\x74\x6c\ +\x65\x3e\x57\x65\x62\x20\x48\x65\x6c\x70\x3c\x2f\x74\x69\x74\x6c\ +\x65\x3e\x3c\x2f\x68\x65\x61\x64\x3e\x0a\x3c\x62\x6f\x64\x79\x3e\ +\x0a\x0a\x3c\x70\x3e\x3c\x62\x3e\x50\x61\x67\x65\x20\x31\x20\x6f\ +\x66\x20\x77\x65\x62\x20\x68\x65\x6c\x70\x3c\x2f\x62\x3e\x3c\x2f\ +\x70\x3e\x0a\x3c\x70\x3e\x20\x20\x3c\x61\x20\x68\x72\x65\x66\x3d\ +\x22\x70\x61\x67\x65\x32\x2e\x68\x74\x6d\x6c\x22\x3e\x20\x4e\x65\ +\x78\x74\x3c\x2f\x61\x3e\x3c\x2f\x70\x3e\x0a\x3c\x70\x3e\x3c\x62\ +\x3e\x65\x74\x63\x2e\x2e\x2e\x3c\x2f\x62\x3e\x20\x65\x74\x63\x2e\ +\x2e\x2e\x3c\x2f\x70\x3e\x0a\x3c\x2f\x62\x6f\x64\x79\x3e\x3c\x2f\ +\x68\x74\x6d\x6c\x3e\x0a\ +\x00\x00\x03\x2c\ +\x3c\ +\x68\x74\x6d\x6c\x3e\x3c\x68\x65\x61\x64\x3e\x3c\x74\x69\x74\x6c\ +\x65\x3e\x48\x79\x70\x65\x72\x20\x50\x6f\x77\x65\x72\x20\x55\x73\ +\x61\x67\x65\x20\x61\x6e\x64\x20\x53\x61\x76\x69\x6e\x67\x20\x48\ +\x69\x67\x68\x6c\x69\x67\x68\x74\x73\x20\x61\x74\x20\x50\x72\x6f\ +\x73\x63\x61\x6e\x2c\x20\x48\x55\x53\x48\x21\x3c\x2f\x74\x69\x74\ +\x6c\x65\x3e\x3c\x2f\x68\x65\x61\x64\x3e\x0a\x3c\x62\x6f\x64\x79\ +\x3e\x0a\x0a\x3c\x68\x35\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\ +\x6f\x6c\x6f\x72\x3a\x67\x72\x61\x79\x3b\x22\x3e\x4a\x61\x6e\x75\ +\x61\x72\x79\x20\x32\x30\x32\x34\x2c\x20\x4a\x61\x6e\x20\x43\x68\ +\x72\x69\x6e\x20\x61\x6e\x64\x20\x2e\x2e\x2e\x3c\x2f\x68\x35\x3e\ +\x0a\x3c\x68\x34\x3e\x20\x3c\x73\x70\x61\x6e\x20\x73\x74\x79\x6c\ +\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x20\x72\x65\x64\x3b\x22\x3e\ +\x48\x3c\x2f\x73\x70\x61\x6e\x3e\x79\x70\x65\x72\x20\x3c\x73\x70\ +\x61\x6e\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\ +\x20\x67\x72\x61\x79\x3b\x22\x3e\x50\x6f\x77\x65\x72\x3c\x2f\x73\ +\x70\x61\x6e\x3e\x20\x3c\x73\x70\x61\x6e\x20\x73\x74\x79\x6c\x65\ +\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x20\x72\x65\x64\x3b\x22\x3e\x55\ +\x3c\x2f\x73\x70\x61\x6e\x3e\x73\x61\x67\x65\x20\x61\x6e\x64\x20\ +\x3c\x73\x70\x61\x6e\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\ +\x6f\x72\x3a\x20\x72\x65\x64\x3b\x22\x3e\x53\x3c\x2f\x73\x70\x61\ +\x6e\x3e\x61\x76\x69\x6e\x67\x20\x3c\x73\x70\x61\x6e\x20\x73\x74\ +\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x20\x72\x65\x64\x3b\ +\x22\x3e\x48\x3c\x2f\x73\x70\x61\x6e\x3e\x69\x67\x68\x6c\x69\x67\ +\x68\x74\x73\x20\x61\x74\x20\x50\x72\x6f\x73\x63\x61\x6e\x2c\x20\ +\x3c\x73\x70\x61\x6e\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\ +\x6f\x72\x3a\x20\x72\x65\x64\x3b\x22\x3e\x48\x55\x53\x48\x21\x3c\ +\x2f\x73\x70\x61\x6e\x3e\x3c\x2f\x68\x34\x3e\x0a\x3c\x68\x32\x20\ +\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x62\x6c\x75\ +\x65\x3b\x22\x3e\x41\x62\x6f\x75\x74\x3c\x2f\x68\x32\x3e\x0a\x0a\ +\x3c\x70\x3e\x54\x68\x69\x73\x20\x3c\x62\x3e\x68\x75\x73\x68\x3c\ +\x2f\x62\x3e\x20\x61\x70\x70\x6c\x69\x63\x61\x74\x69\x6f\x6e\x20\ +\x69\x6e\x68\x65\x72\x69\x74\x73\x20\x66\x72\x6f\x6d\x20\x74\x68\ +\x65\x20\x57\x69\x6e\x64\x6f\x77\x20\x62\x61\x73\x65\x20\x63\x6c\ +\x61\x73\x73\x2e\x3c\x62\x72\x3e\x20\x20\x0a\x3c\x70\x3e\x69\x6e\ +\x66\x6f\x72\x6d\x61\x74\x69\x6f\x6e\x20\x63\x6f\x6e\x63\x65\x72\ +\x6e\x69\x6e\x67\x20\x74\x68\x69\x73\x20\x61\x70\x70\x6c\x69\x63\ +\x61\x74\x69\x6f\x6e\x2c\x20\x73\x75\x63\x68\x20\x61\x73\x20\x63\ +\x6f\x6e\x66\x69\x67\x75\x72\x61\x74\x69\x6f\x6e\x20\x70\x61\x72\ +\x61\x6d\x65\x74\x65\x72\x73\x20\x6f\x72\x20\x6f\x74\x68\x65\x72\ +\x2c\x20\x6d\x61\x79\x20\x62\x65\x20\x65\x6e\x74\x65\x72\x65\x64\ +\x2c\x20\x65\x2e\x67\x2e\x2c\x20\x3c\x61\x20\x68\x72\x65\x66\x3d\ +\x22\x70\x61\x67\x65\x31\x2e\x68\x74\x6d\x6c\x22\x3e\x68\x65\x72\ +\x65\x3c\x2f\x61\x3e\x3c\x2f\x70\x3e\x0a\x0a\x3c\x68\x32\x20\x73\ +\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x62\x6c\x75\x65\ +\x3b\x22\x3e\x54\x68\x65\x20\x50\x61\x6e\x65\x6c\x3c\x2f\x68\x32\ +\x3e\x0a\x0a\x3c\x70\x3e\x54\x68\x65\x73\x65\x20\x77\x65\x62\x20\ +\x70\x61\x67\x65\x73\x20\x61\x72\x65\x20\x74\x6f\x20\x62\x65\x20\ +\x63\x6f\x6d\x70\x6c\x65\x74\x65\x64\x20\x62\x79\x20\x74\x68\x65\ +\x20\x61\x70\x70\x6c\x69\x63\x61\x74\x69\x6f\x6e\x20\x6f\x77\x6e\ +\x65\x72\x2e\x3c\x62\x72\x3e\x0a\x0a\x0a\x0a\x0a\x3c\x2f\x62\x6f\ +\x64\x79\x3e\x3c\x2f\x68\x74\x6d\x6c\x3e\x0a\ +\x00\x00\x00\xa7\ +\x3c\ +\x68\x74\x6d\x6c\x3e\x3c\x68\x65\x61\x64\x3e\x3c\x74\x69\x74\x6c\ +\x65\x3e\x57\x65\x62\x20\x48\x65\x6c\x70\x3c\x2f\x74\x69\x74\x6c\ +\x65\x3e\x3c\x2f\x68\x65\x61\x64\x3e\x0a\x3c\x62\x6f\x64\x79\x3e\ +\x0a\x0a\x3c\x70\x3e\x3c\x62\x3e\x50\x61\x67\x65\x20\x34\x20\x6f\ +\x66\x20\x77\x65\x62\x20\x68\x65\x6c\x70\x3c\x2f\x62\x3e\x3c\x2f\ +\x70\x3e\x0a\x3c\x70\x3e\x20\x20\x3c\x61\x20\x68\x72\x65\x66\x3d\ +\x22\x70\x61\x67\x65\x35\x2e\x68\x74\x6d\x6c\x22\x3e\x20\x4e\x65\ +\x78\x74\x3c\x2f\x61\x3e\x3c\x2f\x70\x3e\x0a\x3c\x70\x3e\x3c\x62\ +\x3e\x65\x74\x63\x2e\x2e\x2e\x3c\x2f\x62\x3e\x20\x65\x74\x63\x2e\ +\x2e\x2e\x3c\x2f\x70\x3e\x0a\x3c\x2f\x62\x6f\x64\x79\x3e\x3c\x2f\ +\x68\x74\x6d\x6c\x3e\x0a\ +\x00\x00\x00\x80\ +\x3c\ +\x68\x74\x6d\x6c\x3e\x3c\x68\x65\x61\x64\x3e\x3c\x74\x69\x74\x6c\ +\x65\x3e\x57\x65\x62\x20\x48\x65\x6c\x70\x3c\x2f\x74\x69\x74\x6c\ +\x65\x3e\x3c\x2f\x68\x65\x61\x64\x3e\x0a\x3c\x62\x6f\x64\x79\x3e\ +\x0a\x0a\x3c\x70\x3e\x3c\x62\x3e\x50\x61\x67\x65\x20\x35\x20\x6f\ +\x66\x20\x77\x65\x62\x20\x68\x65\x6c\x70\x3c\x2f\x62\x3e\x3c\x2f\ +\x70\x3e\x0a\x0a\x3c\x70\x3e\x3c\x62\x3e\x65\x74\x63\x2e\x2e\x2e\ +\x3c\x2f\x62\x3e\x20\x65\x74\x63\x2e\x2e\x2e\x3c\x2f\x70\x3e\x0a\ +\x3c\x2f\x62\x6f\x64\x79\x3e\x3c\x2f\x68\x74\x6d\x6c\x3e\x0a\ +\x00\x00\x00\xa7\ +\x3c\ +\x68\x74\x6d\x6c\x3e\x3c\x68\x65\x61\x64\x3e\x3c\x74\x69\x74\x6c\ +\x65\x3e\x57\x65\x62\x20\x48\x65\x6c\x70\x3c\x2f\x74\x69\x74\x6c\ +\x65\x3e\x3c\x2f\x68\x65\x61\x64\x3e\x0a\x3c\x62\x6f\x64\x79\x3e\ +\x0a\x0a\x3c\x70\x3e\x3c\x62\x3e\x50\x61\x67\x65\x20\x33\x20\x6f\ +\x66\x20\x77\x65\x62\x20\x68\x65\x6c\x70\x3c\x2f\x62\x3e\x3c\x2f\ +\x70\x3e\x0a\x3c\x70\x3e\x20\x20\x3c\x61\x20\x68\x72\x65\x66\x3d\ +\x22\x70\x61\x67\x65\x34\x2e\x68\x74\x6d\x6c\x22\x3e\x20\x4e\x65\ +\x78\x74\x3c\x2f\x61\x3e\x3c\x2f\x70\x3e\x0a\x3c\x70\x3e\x3c\x62\ +\x3e\x65\x74\x63\x2e\x2e\x2e\x3c\x2f\x62\x3e\x20\x65\x74\x63\x2e\ +\x2e\x2e\x3c\x2f\x70\x3e\x0a\x3c\x2f\x62\x6f\x64\x79\x3e\x3c\x2f\ +\x68\x74\x6d\x6c\x3e\x0a\ +\x00\x00\x00\xa7\ +\x3c\ +\x68\x74\x6d\x6c\x3e\x3c\x68\x65\x61\x64\x3e\x3c\x74\x69\x74\x6c\ +\x65\x3e\x57\x65\x62\x20\x48\x65\x6c\x70\x3c\x2f\x74\x69\x74\x6c\ +\x65\x3e\x3c\x2f\x68\x65\x61\x64\x3e\x0a\x3c\x62\x6f\x64\x79\x3e\ +\x0a\x0a\x3c\x70\x3e\x3c\x62\x3e\x50\x61\x67\x65\x20\x32\x20\x6f\ +\x66\x20\x77\x65\x62\x20\x68\x65\x6c\x70\x3c\x2f\x62\x3e\x3c\x2f\ +\x70\x3e\x0a\x3c\x70\x3e\x20\x20\x3c\x61\x20\x68\x72\x65\x66\x3d\ +\x22\x70\x61\x67\x65\x33\x2e\x68\x74\x6d\x6c\x22\x3e\x20\x4e\x65\ +\x78\x74\x3c\x2f\x61\x3e\x3c\x2f\x70\x3e\x0a\x3c\x70\x3e\x3c\x62\ +\x3e\x65\x74\x63\x2e\x2e\x2e\x3c\x2f\x62\x3e\x20\x65\x74\x63\x2e\ +\x2e\x2e\x3c\x2f\x70\x3e\x0a\x3c\x2f\x62\x6f\x64\x79\x3e\x3c\x2f\ +\x68\x74\x6d\x6c\x3e\x0a\ +" + +qt_resource_name = b"\ +\x00\x0a\ +\x08\x4a\x34\x9c\ +\x00\x70\ +\x00\x61\x00\x67\x00\x65\x00\x31\x00\x2e\x00\x68\x00\x74\x00\x6d\x00\x6c\ +\x00\x0a\ +\x0c\xba\xf2\x7c\ +\x00\x69\ +\x00\x6e\x00\x64\x00\x65\x00\x78\x00\x2e\x00\x68\x00\x74\x00\x6d\x00\x6c\ +\x00\x0a\ +\x08\x7a\x34\x9c\ +\x00\x70\ +\x00\x61\x00\x67\x00\x65\x00\x34\x00\x2e\x00\x68\x00\x74\x00\x6d\x00\x6c\ +\x00\x0a\ +\x08\x8a\x34\x9c\ +\x00\x70\ +\x00\x61\x00\x67\x00\x65\x00\x35\x00\x2e\x00\x68\x00\x74\x00\x6d\x00\x6c\ +\x00\x0a\ +\x08\x6a\x34\x9c\ +\x00\x70\ +\x00\x61\x00\x67\x00\x65\x00\x33\x00\x2e\x00\x68\x00\x74\x00\x6d\x00\x6c\ +\x00\x0a\ +\x08\x5a\x34\x9c\ +\x00\x70\ +\x00\x61\x00\x67\x00\x65\x00\x32\x00\x2e\x00\x68\x00\x74\x00\x6d\x00\x6c\ +" + +qt_resource_struct_v1 = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x06\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x00\x82\x00\x00\x00\x00\x00\x01\x00\x00\x05\xb5\ +\x00\x00\x00\x68\x00\x00\x00\x00\x00\x01\x00\x00\x05\x0a\ +\x00\x00\x00\x34\x00\x00\x00\x00\x00\x01\x00\x00\x03\xdb\ +\x00\x00\x00\x4e\x00\x00\x00\x00\x00\x01\x00\x00\x04\x86\ +\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x01\x00\x00\x00\xab\ +" + +qt_resource_struct_v2 = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x06\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x01\x8d\x3b\x71\x36\x5d\ +\x00\x00\x00\x82\x00\x00\x00\x00\x00\x01\x00\x00\x05\xb5\ +\x00\x00\x01\x8d\x3b\x71\x36\x75\ +\x00\x00\x00\x68\x00\x00\x00\x00\x00\x01\x00\x00\x05\x0a\ +\x00\x00\x01\x8d\x3b\x71\x36\x78\ +\x00\x00\x00\x34\x00\x00\x00\x00\x00\x01\x00\x00\x03\xdb\ +\x00\x00\x01\x8d\x3b\x71\x36\x90\ +\x00\x00\x00\x4e\x00\x00\x00\x00\x00\x01\x00\x00\x04\x86\ +\x00\x00\x01\x8d\x3b\x71\x36\x94\ +\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x01\x00\x00\x00\xab\ +\x00\x00\x01\x8d\x3b\x78\x4e\xc0\ +" + +qt_version = [int(v) for v in QtCore.qVersion().split('.')] +if qt_version < [5, 8, 0]: + rcc_version = 1 + qt_resource_struct = qt_resource_struct_v1 +else: + rcc_version = 2 + qt_resource_struct = qt_resource_struct_v2 + +def qInitResources(): + QtCore.qRegisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/help/index.html b/help/index.html new file mode 100755 index 0000000..713c5d9 --- /dev/null +++ b/help/index.html @@ -0,0 +1,18 @@ +Hyper Power Usage and Saving Highlights at Proscan, HUSH! + + +
January 2024, Jan Chrin and ...
+

Hyper Power Usage and Saving Highlights at Proscan, HUSH!

+

About

+ +

This hush application inherits from the Window base class.
+

information concerning this application, such as configuration parameters or other, may be entered, e.g., here

+ +

The Panel

+ +

These web pages are to be completed by the application owner.
+ + + + + diff --git a/help/make_and_install.sh b/help/make_and_install.sh new file mode 100644 index 0000000..e7c2b22 --- /dev/null +++ b/help/make_and_install.sh @@ -0,0 +1,2 @@ +make compile +make install diff --git a/help/makefile b/help/makefile new file mode 100644 index 0000000..3ff7d5e --- /dev/null +++ b/help/makefile @@ -0,0 +1,9 @@ +compile: + pyrcc5 hush.qrc > hush_resources.py + +install: + if [ ! -f hush_resources.py ]; then echo "pyrcc5 compilation of resources.qrc failed"; fi + if [ -f hush_resources.py -a -f ../pyrcc5/hush_resources.py-- ]; then cp ../pyrcc5/hush_resources.py-- ../pyrcc5/hush_resources.py---; fi + if [ -f hush_resources.py -a -f ../pyrcc5/hush_resources.py- ]; then cp ../pyrcc5/hush_resources.py- ../pyrcc5/hush_resources.py--; fi + if [ -f hush_resources.py -a -f ../pyrcc5/hush_resources.py ]; then cp ../pyrcc5/hush_resources.py ../pyrcc5/hush_resources.py-; fi + if [ -f hush_resources.py ]; then cp hush_resources.py ../pyrcc5/hush_resources.py; fi diff --git a/help/page1.html b/help/page1.html new file mode 100755 index 0000000..6fa49c5 --- /dev/null +++ b/help/page1.html @@ -0,0 +1,7 @@ +Web Help + + +

Page 1 of web help

+

Next

+

etc... etc...

+ diff --git a/help/page2.html b/help/page2.html new file mode 100755 index 0000000..10f6352 --- /dev/null +++ b/help/page2.html @@ -0,0 +1,7 @@ +Web Help + + +

Page 2 of web help

+

Next

+

etc... etc...

+ diff --git a/help/page3.html b/help/page3.html new file mode 100755 index 0000000..f12e898 --- /dev/null +++ b/help/page3.html @@ -0,0 +1,7 @@ +Web Help + + +

Page 3 of web help

+

Next

+

etc... etc...

+ diff --git a/help/page4.html b/help/page4.html new file mode 100755 index 0000000..64c0eb6 --- /dev/null +++ b/help/page4.html @@ -0,0 +1,7 @@ +Web Help + + +

Page 4 of web help

+

Next

+

etc... etc...

+ diff --git a/help/page5.html b/help/page5.html new file mode 100755 index 0000000..639d750 --- /dev/null +++ b/help/page5.html @@ -0,0 +1,7 @@ +Web Help + + +

Page 5 of web help

+ +

etc... etc...

+ diff --git a/hush.json b/hush.json new file mode 100755 index 0000000..d850efd --- /dev/null +++ b/hush.json @@ -0,0 +1,78 @@ +{ + "menuFlags":{ + "hasFile": 0, + "loadInitFile": 0, + "hasDaq": 0, + "hasH5": 0, + "hasEpics": 0 + }, + "hdf": { + "destination" : "./" + }, + "G1":{ + "standby": [-6.867, 6.867, 9.155, 6.867, 6.867, 9.155, 6.867, -6.867, 6.867, 6.867], + "ref" : [-33.18, 33.18, 118.9, 19.45, 19.45, 118,9, 33.18, -33.18, 43.47826, 45.7666], + "pwrref" : [0.10, 0.10, 0.55, 0.10, 0.10, 0.25, 0.100, -0.10, 0.10, -0.10], + "iocDevice" : ["AME1", "AME2", "QME10"] + }, + "SH":{ + "standby": [-4, 3, 3, -4, 9, 4, -5, -4, + 4, 9], + "ref" : [-34.048, 26.68, 26.68, -34.05, 87.764, 37.424, -47.207, -38.156, + 36.977, 87.642], + "pwrref" : [0.5, 0.3, 0.3, 0.5, 5.5, 0.146, 0.16, 0.343, + 0.43, 0.0], + "iocDevice" : ["QMA7", "AMA2", "QMA12"] + }, + "G2":{ + "standby" : [-4.90, 4.0, -4, 5, -3, -4, 4, -4, + 5, 5, -4, 11, 11, 25], + "ref": [-41.056, 36.548, -30.490, 52.433, -27.636, -37.412, 41.966, -37.296, + 51.200, 53.657, -41.966, 109.543, 109.405, 251.492], + "pwrref" : [0.7, 0.54, 0.39, 1.15, 0.32, 0.375, 0.466, 0.377, + 0.70, 0.771, 0.46, 7.1, 7.1, 21], + "iocDevice" : ["QMB2", "QMB4", "AMF1"] + }, + "O2":{ + "standby": [-4, 3, 3, -4, 6, 3, -3, 3, + -5, 2], + "ref" : [-40.85, 26.974, 26.974, -40.851, 45.988, 30.890, -29.542, 33.742, + -45.960, 20.165], + "pwrref" : [0.68, 0.3, 0.3, 0.67, 1.0, 0.4, 0.36, 0.47, + 0.89, 0.17], + "iocDevice" : ["QMC2", "AMC1", "QMC7"] + }, + "PIF":{ + "standby": [-4, 4, 4, -4, 14, 6, -6, 4, + -6, 3], + "ref" : [-36.159, 34.434, 42.277, -43, 135, 61, -62, 37, + -55, 30], + "pwrref" : [0.16, 0.16, 0.28, 0.31, 3.7, 0.6, 0.73, 0.25, + 0.59, 0.145], + "iocDevice" : ["QMD2", "AMD1", "QMD9"] + }, + "G3":{ + "standby": [-4, 7, -4], + "ref" : [-40.388, 68.393, -34.805], + "pwrref" : [0.64, 1.8, 0.46], + "iocDevice" : ["QMD10", "QMD11", "QMD12"] + }, + "Parameters":{ + + "drawLine" : {"flag" : 0, "data":{ "widget": "QHLine", "text" : "None", "value" : "None"}}, + "delayRamp" : {"flag" : 1, "data":{ "widget": "QDoubleSpinBox", "text" : "Ramp delay (s):", + "value" : 0.1, "min": 0.00, "max": 0.20, "step": 0.01, + "tooltip":"Wait time between sending set point to each magnet in 'Restore'/'Standby' "}}, + "drawLine2" : {"flag" : 0, "data":{ "widget": "QHLine", "text" : "None", "value" : "None"}} + + }, + "Expert":{ + "debug": {"flag" : 0, "data":{ "widget": "None", "text" : "Debug", "value" : 0}}, + "simulation": {"flag" : 1, "data":{ "widget": "None", "text" : "Dry run", "value" : 1}} + }, + "GUI": { + "resultsTabTitle" : "Results", + "subResultsTabTitle" : [], + "resultsSeq" : [] + } +} diff --git a/hush.py b/hush.py new file mode 100644 index 0000000..92d7502 --- /dev/null +++ b/hush.py @@ -0,0 +1,229 @@ +import inspect +import logging +import os +import platform +import random +import sys +import time + + +from qtpy import QtCore, QtGui +from qtpy.QtGui import QColor, QFont, QIcon +from qtpy.QtCore import __version__ as QT_VERSION_STR +from qtpy.QtCore import ( + PYQT_VERSION_STR, QFile, QIODevice, Qt, QThread, Signal, Slot) +from qtpy.QtWidgets import ( + QApplication, QDockWidget, QGridLayout, QGroupBox, QHBoxLayout, QLabel, + QMainWindow, QMessageBox, QProgressBar, QPushButton, QSizePolicy, + QSpacerItem, QTabWidget, QTableWidget, QTableWidgetItem, QVBoxLayout, + QWidget) + +from apps4ops.bdbase.base import BaseWindow +from apps4ops.bdbase.enumkind import MsgSeverity, UserMode, Facility +from apps4ops.bdbase.helpbrowser import HelpBrowser +from apps4ops.proscan.sendelogproscan import QSendToELOG + +from apps4ops.proscan.enumkind import ElogPROSCAN + +from src.gui import AppGui +from pyrcc5 import hush_resources + +_pymodule = os.path.basename(__file__) +_appname, _appext = _pymodule.split(".") +_appversion = "1.0.0" +#_title = """Power Usage & Saving Hierarchy""" #, HUSH!""" +_title = """HUSH!""" + +def _line(): + """Macro to return the current line number. + + The current line number within the file is used when + reporting messages to the message logging window. + + Returns: + int: Current line number. + """ + return inspect.currentframe().f_back.f_lineno + +class StartMain(BaseWindow): + trigger_log_message = Signal(str, str, int, str, dict) + + def __init__(self, parent=None): + super(StartMain, self).__init__( + parent=parent, pymodule=_pymodule, appversion=_appversion, + title=_title, user_mode=UserMode.OPERATION, facility=Facility.PROSCAN, + has_optics=False, has_procedure=False) + + self.appname = _appname + self.gui = AppGui(self) + + + @Slot() + def send_to_elog(self): + + @Slot() + def save_fig_thread_finished(): + + time.sleep(0.2) + + if self.all_data: + QSendToELOG(self, logbook=self.logbook, + eintragIdx=self.eintrag_idx, + systemIdx=self.system_idx, + effektIdx=self.effekt_idx, + title=self.title, + message=self.message, + attachFile=self.attach_files) + + time.sleep(1.0) + return + + #if not self.verify_send_to_elog(): + # return + + + elog = ElogPROSCAN() + + + self.system_idx = elog.system.GENERAL + self.eintrag_idx = elog.eintrag.INFO + self.effekt_idx = elog.effekt.NO + + + self.attach_files = [] + + _simulation = self.input_parameters['simulation'] + + if self.all_data: + if self.all_data['Input data'] is not None: + try: + _simulation = self.all_data['Input data']['simulation'] + except KeyError: + _simulation = self.input_parameters['simulation'] + pass + + + self.logbook = "Sandkasten" if _simulation else "Proscan" + self.title = _title + + sector = ["
G1: ","
SH: ","
G2: ", "
O2: ","
PIF: ", + "
G3: ","
------------------
Tot: "] + pvlist = ['PG1-HUSH:TOTSAVE', 'PSH-HUSH:TOTSAVE', 'PG2-HUSH:TOTSAVE', + 'PO2-HUSH:TOTSAVE', 'PPIF-HUSH:TOTSAVE', 'PG3-HUSH:TOTSAVE', + 'PRO-HUSH:TOTSAVE'] + + + value, stat, stat_list =self.cafe.getScalarList(pvlist, cacheFlag=True) + + message = "Power saved for the current year stands at {:.3f} MWh:".format( + value[-1]) + for label, val in zip(sector, value): + message += label + "{:.3f}".format(val) + " MWh" + + ''' + message += " PG1: " + str(value[0])+ " MWh
" + message += " PSH: " + str(value[1])+ " MWh
" + message += " PG2: " + str(value[2])+ " MWh
" + message += " PO2: " + str(value[3])+ " MWh
" + message += "PPIF: " + str(value[4])+ " MWh
" + message += " PG3: " + str(value[5])+ " MWh
" + message += "Tot: " + str(value[6])+ " MWh" + ''' + self.message = message + print(self.message, flush=True) + + if not self.all_data: + QSendToELOG(self, logbook=self.logbook, + eintragIdx=self.eintrag_idx, + systemIdx=self.system_idx, + effektIdx=self.effekt_idx, + title=self.title, + message=self.message, + attachFile=self.attach_files) + return + + + _folder_name = self.elog_dest + if not os.path.exists(_folder_name): + os.makedirs(_folder_name) + + ''' + time_in_seconds = self.all_data['Ambient data']['Time in seconds'] + if self.all_data['Processed data']['Reanalysis time']: + reanalysis_time = self.all_data['Processed data'][ + 'Reanalysis time in seconds'] + else: + reanalysis_time = None + ''' + + reanalysis_time = None + + self.folder_name = _folder_name + + save_fig_thread = self.SaveFigureThread( + self, self.folder_name, time_in_seconds, reanalysis_time) + save_fig_thread.finished.connect(save_fig_thread_finished) + + save_fig_thread.start() + time.sleep(0.05) + + + @Slot() + def closeEvent(self, event): + + if not self.verify_close_event(): + event.ignore() + return + + BaseWindow.closeEvent(self, event) + + @Slot() + def show_about(self): + """ To overide by application + """ + QApplication.processEvents() + QMessageBox.about( + self, "About", + """{0} v {1} +

Copyright © Paul Scherrer Institut (PSI). + All rights reserved.

+

Author: J. Chrin, Spring 2023

+

(EPICS db adapted from A. Kovach, 2016)

+

IOC Administrator: H. Lutz

+

1st Responsible: J. Chrin + or 3301 (Control Room)

+ +

Initiates energy saving procedures and records power saved

+

Python {2} - Qt {3} - PyQt {4}
+ cafe {5} - epics {6} on {7}""".format( + _pymodule, _appversion, platform.python_version(), + QT_VERSION_STR, PYQT_VERSION_STR, + self.cafe.CAFE_version(), self.cafe.EPICS_version(), + platform.system())) + QApplication.processEvents() + + @Slot() + def show_help(self): + """ Invoke help pages from hush_resources + """ + index_html ="index.html" #self.appname + "/index.html" + help_base = ":" # + self.appname + help_page = HelpBrowser(help_base, index_html, self) + help_page.show() + +######################################################################### +if __name__ == "__main__": + + app = QApplication(sys.argv) + splash = BaseWindow.initialize_application( + app, appname=_appname, delay=20, facility=Facility.PROSCAN) + + myapp = StartMain() + + myapp.show() + + if splash is not None: + splash.finish(myapp) + + app.exec_() + diff --git a/hush.sh b/hush.sh new file mode 100755 index 0000000..a832307 --- /dev/null +++ b/hush.sh @@ -0,0 +1,99 @@ +#!/bin/bash +cd /proscan/bd/applications/hush/hla/1.0.0 + +# For use if script is sourced rather than executed +appNameDefault="hush.sh" + +module unload gcc +module load gcc/7.3.0 + +if [ -z "$PS1" ] # no prompt? +### if [ -v PS1 ] # On Bash 4.2+ ... +then + # non-interactive + echo "Non-interactive script" +else + # interactive + echo "Interactive/sourced script" +fi + +# Select Python Version here. Currently one of 3.5, 3.7 +PYTHON_VERSION=3.7 + +if [ "$1" ]; then + + if [ "$1" == "3.5" -o "$1" == "35" ]; then + echo "Using default version $PYTHON_VERSION" + elif [ "$1" == "3.7" -o "$1" == "37" ]; then + PYTHON_VERSION=3.7 + else + echo "Requested Python version is not supported" + echo "Using default version $PYTHON_VERSION" + fi + +fi + +echo "PYTHON_VERSION $PYTHON_VERSION" + +_EPICS_HOST_ARCH=${RHREL}-x86_64 +#_EPICS_HOST_ARCH=${EPICS_HOST_ARCH} +. /opt/gfa/python $PYTHON_VERSION + +#/sf/bd/applications/OnlineModel/current/PythonModule:/sf/bd/applications/OnlineModel/current +#/sf/bd/applications/OnlineModel/default/scripts/VA: + +#C_EXT version for Py 3.7: +export PYTHONPATH=.:/opt/gfa/cafe/python/pycafe/cafe-1.19.3/lib/${_EPICS_HOST_ARCH}:/proscan/bd/applications/deps/apps4ops/v1.7.0 + + +echo $PYTHONPATH + +STDOUT_DIR="/tmp" +#Set to 0 if you do not wish std::out to write to logger +STDOUT_FLAG=1 + +if [ "$#" -gt "0" ]; then + appName=$0 + if [ "$appName" == "-bash" ]; then + appName=$appNameDefault + fi +else +appName=$appNameDefault +fi + +#echo "$appName $@ $#" +baseName="${appName##*/}" +name=$(echo "$baseName" | cut -f 1 -d '.') +nameLog=${name}-$USER +echo "Application: $name" +echo "nameLog: $nameLog" + +#Configuration files can be overwritten +#python ${name}.py -s="/sf/bd/deps/pyqtacc/common/config/style.json" -f="/sf/bd/deps/pyqtacc/v1.0.0/pyqtacc/qrc_resources/facility/sf/config/base.json" -q="/sf/bd/deps/pyqtacc/common/config/acc.qss" & + +if [ "${STDOUT_FLAG}" -gt "0" ] ; then +#if changing the std::out destination, remember to also change it in your json config file (for reading) + if test -f "$STDOUT_DIR/${nameLog}.log---"; then + rm -f $STDOUT_DIR/${nameLog}.log--- + fi + if test -f "$STDOUT_DIR/${nameLog}.log--"; then + cp $STDOUT_DIR/${nameLog}.log-- $STDOUT_DIR/${nameLog}.log--- + rm -f $STDOUT_DIR/${nameLog}.log-- + fi + if test -f "$STDOUT_DIR/${nameLog}.log-"; then + cp $STDOUT_DIR/${nameLog}.log- $STDOUT_DIR/${nameLog}.log-- + rm -f $STDOUT_DIR/${nameLog}.log- + fi + if test -f "$STDOUT_DIR/${nameLog}.log"; then + cp $STDOUT_DIR/${nameLog}.log $STDOUT_DIR/${nameLog}.log- + rm -f $STDOUT_DIR/${nameLog}.log + fi + + python ${name}.py -u ${name}.json >> $STDOUT_DIR/${nameLog}.log 2>&1 & + chmod 777 $STDOUT_DIR/${nameLog}.log +else +#Run instead without std::out + python ${name}.py -u ${name}.json & +fi + + diff --git a/pyrcc5/hush_resources.py b/pyrcc5/hush_resources.py new file mode 100644 index 0000000..e9707eb --- /dev/null +++ b/pyrcc5/hush_resources.py @@ -0,0 +1,197 @@ +# -*- coding: utf-8 -*- + +# Resource object code +# +# Created by: The Resource Compiler for PyQt5 (Qt v5.15.3) +# +# WARNING! All changes made in this file will be lost! + +from PyQt5 import QtCore + +qt_resource_data = b"\ +\x00\x00\x00\xa7\ +\x3c\ +\x68\x74\x6d\x6c\x3e\x3c\x68\x65\x61\x64\x3e\x3c\x74\x69\x74\x6c\ +\x65\x3e\x57\x65\x62\x20\x48\x65\x6c\x70\x3c\x2f\x74\x69\x74\x6c\ +\x65\x3e\x3c\x2f\x68\x65\x61\x64\x3e\x0a\x3c\x62\x6f\x64\x79\x3e\ +\x0a\x0a\x3c\x70\x3e\x3c\x62\x3e\x50\x61\x67\x65\x20\x31\x20\x6f\ +\x66\x20\x77\x65\x62\x20\x68\x65\x6c\x70\x3c\x2f\x62\x3e\x3c\x2f\ +\x70\x3e\x0a\x3c\x70\x3e\x20\x20\x3c\x61\x20\x68\x72\x65\x66\x3d\ +\x22\x70\x61\x67\x65\x32\x2e\x68\x74\x6d\x6c\x22\x3e\x20\x4e\x65\ +\x78\x74\x3c\x2f\x61\x3e\x3c\x2f\x70\x3e\x0a\x3c\x70\x3e\x3c\x62\ +\x3e\x65\x74\x63\x2e\x2e\x2e\x3c\x2f\x62\x3e\x20\x65\x74\x63\x2e\ +\x2e\x2e\x3c\x2f\x70\x3e\x0a\x3c\x2f\x62\x6f\x64\x79\x3e\x3c\x2f\ +\x68\x74\x6d\x6c\x3e\x0a\ +\x00\x00\x03\x2c\ +\x3c\ +\x68\x74\x6d\x6c\x3e\x3c\x68\x65\x61\x64\x3e\x3c\x74\x69\x74\x6c\ +\x65\x3e\x48\x79\x70\x65\x72\x20\x50\x6f\x77\x65\x72\x20\x55\x73\ +\x61\x67\x65\x20\x61\x6e\x64\x20\x53\x61\x76\x69\x6e\x67\x20\x48\ +\x69\x67\x68\x6c\x69\x67\x68\x74\x73\x20\x61\x74\x20\x50\x72\x6f\ +\x73\x63\x61\x6e\x2c\x20\x48\x55\x53\x48\x21\x3c\x2f\x74\x69\x74\ +\x6c\x65\x3e\x3c\x2f\x68\x65\x61\x64\x3e\x0a\x3c\x62\x6f\x64\x79\ +\x3e\x0a\x0a\x3c\x68\x35\x20\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\ +\x6f\x6c\x6f\x72\x3a\x67\x72\x61\x79\x3b\x22\x3e\x4a\x61\x6e\x75\ +\x61\x72\x79\x20\x32\x30\x32\x34\x2c\x20\x4a\x61\x6e\x20\x43\x68\ +\x72\x69\x6e\x20\x61\x6e\x64\x20\x2e\x2e\x2e\x3c\x2f\x68\x35\x3e\ +\x0a\x3c\x68\x34\x3e\x20\x3c\x73\x70\x61\x6e\x20\x73\x74\x79\x6c\ +\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x20\x72\x65\x64\x3b\x22\x3e\ +\x48\x3c\x2f\x73\x70\x61\x6e\x3e\x79\x70\x65\x72\x20\x3c\x73\x70\ +\x61\x6e\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\ +\x20\x67\x72\x61\x79\x3b\x22\x3e\x50\x6f\x77\x65\x72\x3c\x2f\x73\ +\x70\x61\x6e\x3e\x20\x3c\x73\x70\x61\x6e\x20\x73\x74\x79\x6c\x65\ +\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x20\x72\x65\x64\x3b\x22\x3e\x55\ +\x3c\x2f\x73\x70\x61\x6e\x3e\x73\x61\x67\x65\x20\x61\x6e\x64\x20\ +\x3c\x73\x70\x61\x6e\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\ +\x6f\x72\x3a\x20\x72\x65\x64\x3b\x22\x3e\x53\x3c\x2f\x73\x70\x61\ +\x6e\x3e\x61\x76\x69\x6e\x67\x20\x3c\x73\x70\x61\x6e\x20\x73\x74\ +\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x20\x72\x65\x64\x3b\ +\x22\x3e\x48\x3c\x2f\x73\x70\x61\x6e\x3e\x69\x67\x68\x6c\x69\x67\ +\x68\x74\x73\x20\x61\x74\x20\x50\x72\x6f\x73\x63\x61\x6e\x2c\x20\ +\x3c\x73\x70\x61\x6e\x20\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\ +\x6f\x72\x3a\x20\x72\x65\x64\x3b\x22\x3e\x48\x55\x53\x48\x21\x3c\ +\x2f\x73\x70\x61\x6e\x3e\x3c\x2f\x68\x34\x3e\x0a\x3c\x68\x32\x20\ +\x73\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x62\x6c\x75\ +\x65\x3b\x22\x3e\x41\x62\x6f\x75\x74\x3c\x2f\x68\x32\x3e\x0a\x0a\ +\x3c\x70\x3e\x54\x68\x69\x73\x20\x3c\x62\x3e\x68\x75\x73\x68\x3c\ +\x2f\x62\x3e\x20\x61\x70\x70\x6c\x69\x63\x61\x74\x69\x6f\x6e\x20\ +\x69\x6e\x68\x65\x72\x69\x74\x73\x20\x66\x72\x6f\x6d\x20\x74\x68\ +\x65\x20\x57\x69\x6e\x64\x6f\x77\x20\x62\x61\x73\x65\x20\x63\x6c\ +\x61\x73\x73\x2e\x3c\x62\x72\x3e\x20\x20\x0a\x3c\x70\x3e\x69\x6e\ +\x66\x6f\x72\x6d\x61\x74\x69\x6f\x6e\x20\x63\x6f\x6e\x63\x65\x72\ +\x6e\x69\x6e\x67\x20\x74\x68\x69\x73\x20\x61\x70\x70\x6c\x69\x63\ +\x61\x74\x69\x6f\x6e\x2c\x20\x73\x75\x63\x68\x20\x61\x73\x20\x63\ +\x6f\x6e\x66\x69\x67\x75\x72\x61\x74\x69\x6f\x6e\x20\x70\x61\x72\ +\x61\x6d\x65\x74\x65\x72\x73\x20\x6f\x72\x20\x6f\x74\x68\x65\x72\ +\x2c\x20\x6d\x61\x79\x20\x62\x65\x20\x65\x6e\x74\x65\x72\x65\x64\ +\x2c\x20\x65\x2e\x67\x2e\x2c\x20\x3c\x61\x20\x68\x72\x65\x66\x3d\ +\x22\x70\x61\x67\x65\x31\x2e\x68\x74\x6d\x6c\x22\x3e\x68\x65\x72\ +\x65\x3c\x2f\x61\x3e\x3c\x2f\x70\x3e\x0a\x0a\x3c\x68\x32\x20\x73\ +\x74\x79\x6c\x65\x3d\x22\x63\x6f\x6c\x6f\x72\x3a\x62\x6c\x75\x65\ +\x3b\x22\x3e\x54\x68\x65\x20\x50\x61\x6e\x65\x6c\x3c\x2f\x68\x32\ +\x3e\x0a\x0a\x3c\x70\x3e\x54\x68\x65\x73\x65\x20\x77\x65\x62\x20\ +\x70\x61\x67\x65\x73\x20\x61\x72\x65\x20\x74\x6f\x20\x62\x65\x20\ +\x63\x6f\x6d\x70\x6c\x65\x74\x65\x64\x20\x62\x79\x20\x74\x68\x65\ +\x20\x61\x70\x70\x6c\x69\x63\x61\x74\x69\x6f\x6e\x20\x6f\x77\x6e\ +\x65\x72\x2e\x3c\x62\x72\x3e\x0a\x0a\x0a\x0a\x0a\x3c\x2f\x62\x6f\ +\x64\x79\x3e\x3c\x2f\x68\x74\x6d\x6c\x3e\x0a\ +\x00\x00\x00\xa7\ +\x3c\ +\x68\x74\x6d\x6c\x3e\x3c\x68\x65\x61\x64\x3e\x3c\x74\x69\x74\x6c\ +\x65\x3e\x57\x65\x62\x20\x48\x65\x6c\x70\x3c\x2f\x74\x69\x74\x6c\ +\x65\x3e\x3c\x2f\x68\x65\x61\x64\x3e\x0a\x3c\x62\x6f\x64\x79\x3e\ +\x0a\x0a\x3c\x70\x3e\x3c\x62\x3e\x50\x61\x67\x65\x20\x34\x20\x6f\ +\x66\x20\x77\x65\x62\x20\x68\x65\x6c\x70\x3c\x2f\x62\x3e\x3c\x2f\ +\x70\x3e\x0a\x3c\x70\x3e\x20\x20\x3c\x61\x20\x68\x72\x65\x66\x3d\ +\x22\x70\x61\x67\x65\x35\x2e\x68\x74\x6d\x6c\x22\x3e\x20\x4e\x65\ +\x78\x74\x3c\x2f\x61\x3e\x3c\x2f\x70\x3e\x0a\x3c\x70\x3e\x3c\x62\ +\x3e\x65\x74\x63\x2e\x2e\x2e\x3c\x2f\x62\x3e\x20\x65\x74\x63\x2e\ +\x2e\x2e\x3c\x2f\x70\x3e\x0a\x3c\x2f\x62\x6f\x64\x79\x3e\x3c\x2f\ +\x68\x74\x6d\x6c\x3e\x0a\ +\x00\x00\x00\x80\ +\x3c\ +\x68\x74\x6d\x6c\x3e\x3c\x68\x65\x61\x64\x3e\x3c\x74\x69\x74\x6c\ +\x65\x3e\x57\x65\x62\x20\x48\x65\x6c\x70\x3c\x2f\x74\x69\x74\x6c\ +\x65\x3e\x3c\x2f\x68\x65\x61\x64\x3e\x0a\x3c\x62\x6f\x64\x79\x3e\ +\x0a\x0a\x3c\x70\x3e\x3c\x62\x3e\x50\x61\x67\x65\x20\x35\x20\x6f\ +\x66\x20\x77\x65\x62\x20\x68\x65\x6c\x70\x3c\x2f\x62\x3e\x3c\x2f\ +\x70\x3e\x0a\x0a\x3c\x70\x3e\x3c\x62\x3e\x65\x74\x63\x2e\x2e\x2e\ +\x3c\x2f\x62\x3e\x20\x65\x74\x63\x2e\x2e\x2e\x3c\x2f\x70\x3e\x0a\ +\x3c\x2f\x62\x6f\x64\x79\x3e\x3c\x2f\x68\x74\x6d\x6c\x3e\x0a\ +\x00\x00\x00\xa7\ +\x3c\ +\x68\x74\x6d\x6c\x3e\x3c\x68\x65\x61\x64\x3e\x3c\x74\x69\x74\x6c\ +\x65\x3e\x57\x65\x62\x20\x48\x65\x6c\x70\x3c\x2f\x74\x69\x74\x6c\ +\x65\x3e\x3c\x2f\x68\x65\x61\x64\x3e\x0a\x3c\x62\x6f\x64\x79\x3e\ +\x0a\x0a\x3c\x70\x3e\x3c\x62\x3e\x50\x61\x67\x65\x20\x33\x20\x6f\ +\x66\x20\x77\x65\x62\x20\x68\x65\x6c\x70\x3c\x2f\x62\x3e\x3c\x2f\ +\x70\x3e\x0a\x3c\x70\x3e\x20\x20\x3c\x61\x20\x68\x72\x65\x66\x3d\ +\x22\x70\x61\x67\x65\x34\x2e\x68\x74\x6d\x6c\x22\x3e\x20\x4e\x65\ +\x78\x74\x3c\x2f\x61\x3e\x3c\x2f\x70\x3e\x0a\x3c\x70\x3e\x3c\x62\ +\x3e\x65\x74\x63\x2e\x2e\x2e\x3c\x2f\x62\x3e\x20\x65\x74\x63\x2e\ +\x2e\x2e\x3c\x2f\x70\x3e\x0a\x3c\x2f\x62\x6f\x64\x79\x3e\x3c\x2f\ +\x68\x74\x6d\x6c\x3e\x0a\ +\x00\x00\x00\xa7\ +\x3c\ +\x68\x74\x6d\x6c\x3e\x3c\x68\x65\x61\x64\x3e\x3c\x74\x69\x74\x6c\ +\x65\x3e\x57\x65\x62\x20\x48\x65\x6c\x70\x3c\x2f\x74\x69\x74\x6c\ +\x65\x3e\x3c\x2f\x68\x65\x61\x64\x3e\x0a\x3c\x62\x6f\x64\x79\x3e\ +\x0a\x0a\x3c\x70\x3e\x3c\x62\x3e\x50\x61\x67\x65\x20\x32\x20\x6f\ +\x66\x20\x77\x65\x62\x20\x68\x65\x6c\x70\x3c\x2f\x62\x3e\x3c\x2f\ +\x70\x3e\x0a\x3c\x70\x3e\x20\x20\x3c\x61\x20\x68\x72\x65\x66\x3d\ +\x22\x70\x61\x67\x65\x33\x2e\x68\x74\x6d\x6c\x22\x3e\x20\x4e\x65\ +\x78\x74\x3c\x2f\x61\x3e\x3c\x2f\x70\x3e\x0a\x3c\x70\x3e\x3c\x62\ +\x3e\x65\x74\x63\x2e\x2e\x2e\x3c\x2f\x62\x3e\x20\x65\x74\x63\x2e\ +\x2e\x2e\x3c\x2f\x70\x3e\x0a\x3c\x2f\x62\x6f\x64\x79\x3e\x3c\x2f\ +\x68\x74\x6d\x6c\x3e\x0a\ +" + +qt_resource_name = b"\ +\x00\x0a\ +\x08\x4a\x34\x9c\ +\x00\x70\ +\x00\x61\x00\x67\x00\x65\x00\x31\x00\x2e\x00\x68\x00\x74\x00\x6d\x00\x6c\ +\x00\x0a\ +\x0c\xba\xf2\x7c\ +\x00\x69\ +\x00\x6e\x00\x64\x00\x65\x00\x78\x00\x2e\x00\x68\x00\x74\x00\x6d\x00\x6c\ +\x00\x0a\ +\x08\x7a\x34\x9c\ +\x00\x70\ +\x00\x61\x00\x67\x00\x65\x00\x34\x00\x2e\x00\x68\x00\x74\x00\x6d\x00\x6c\ +\x00\x0a\ +\x08\x8a\x34\x9c\ +\x00\x70\ +\x00\x61\x00\x67\x00\x65\x00\x35\x00\x2e\x00\x68\x00\x74\x00\x6d\x00\x6c\ +\x00\x0a\ +\x08\x6a\x34\x9c\ +\x00\x70\ +\x00\x61\x00\x67\x00\x65\x00\x33\x00\x2e\x00\x68\x00\x74\x00\x6d\x00\x6c\ +\x00\x0a\ +\x08\x5a\x34\x9c\ +\x00\x70\ +\x00\x61\x00\x67\x00\x65\x00\x32\x00\x2e\x00\x68\x00\x74\x00\x6d\x00\x6c\ +" + +qt_resource_struct_v1 = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x06\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x00\x82\x00\x00\x00\x00\x00\x01\x00\x00\x05\xb5\ +\x00\x00\x00\x68\x00\x00\x00\x00\x00\x01\x00\x00\x05\x0a\ +\x00\x00\x00\x34\x00\x00\x00\x00\x00\x01\x00\x00\x03\xdb\ +\x00\x00\x00\x4e\x00\x00\x00\x00\x00\x01\x00\x00\x04\x86\ +\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x01\x00\x00\x00\xab\ +" + +qt_resource_struct_v2 = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x06\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x01\x8d\x3b\x71\x36\x5d\ +\x00\x00\x00\x82\x00\x00\x00\x00\x00\x01\x00\x00\x05\xb5\ +\x00\x00\x01\x8d\x3b\x71\x36\x75\ +\x00\x00\x00\x68\x00\x00\x00\x00\x00\x01\x00\x00\x05\x0a\ +\x00\x00\x01\x8d\x3b\x71\x36\x78\ +\x00\x00\x00\x34\x00\x00\x00\x00\x00\x01\x00\x00\x03\xdb\ +\x00\x00\x01\x8d\x3b\x71\x36\x90\ +\x00\x00\x00\x4e\x00\x00\x00\x00\x00\x01\x00\x00\x04\x86\ +\x00\x00\x01\x8d\x3b\x71\x36\x94\ +\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x01\x00\x00\x00\xab\ +\x00\x00\x01\x8d\x3b\x78\x4e\xc0\ +" + +qt_version = [int(v) for v in QtCore.qVersion().split('.')] +if qt_version < [5, 8, 0]: + rcc_version = 1 + qt_resource_struct = qt_resource_struct_v1 +else: + rcc_version = 2 + qt_resource_struct = qt_resource_struct_v2 + +def qInitResources(): + QtCore.qRegisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/src/gui.py b/src/gui.py new file mode 100644 index 0000000..e0d7ec9 --- /dev/null +++ b/src/gui.py @@ -0,0 +1,695 @@ +import inspect +import os +import platform +import random +import sys +import time +from datetime import timedelta + + +from qtpy import QtCore, QtGui +from qtpy.QtGui import QColor, QFont, QIcon +from qtpy.QtCore import __version__ as QT_VERSION_STR +from qtpy.QtCore import ( + PYQT_VERSION_STR, QDate, QDateTime, QEventLoop, Qt, Signal, Slot) +from qtpy.QtWidgets import ( + QApplication, QDockWidget, QFrame, QGridLayout, QGroupBox, QHBoxLayout, + QLabel, QMainWindow, QMessageBox, QProgressBar, QPushButton, QSizePolicy, + QSpacerItem, QStackedWidget, QTabBar, QTabWidget, QTableWidget, + QTableWidgetItem, QVBoxLayout, QWidget) + + +from apps4ops.bdbase.base import BaseWindow +from apps4ops.bdbase.enumkind import MsgSeverity, UserMode, Facility +from caqtwidgets.pvwidgets import CAQLabel, CAQLineEdit, CAQTableWidget, QHLine + +_pymodule = os.path.basename(__file__) + +def _line(): + """Macro to return the current line number.688 + + The current line number within the file is used when + reporting messages to the message logging window. + + Returns: + int: Current line number. + """ + return inspect.currentframe().f_back.f_lineno + +class AppGui(QWidget): + + def __init__(self, parent): + super(AppGui, self).__init__() + self.parent = parent + self.cafe = self.parent.cafe + self.cyca = self.parent.cyca + + self.send_to_log_window = self.parent.send_to_log_window + self.gui_frame = self.parent.gui_frame + self.gui_header = self.parent.gui_header + self.font_gui = self.parent.gui_frame.font_gui + self.input_parameters = self.parent.input_parameters + self.input_labels = self.parent.input_labels + self.expert_parameters = self.parent.expert_parameters + self.gui_frame.expert_parameters_group.setFixedWidth(260) + self.gui_frame.operator_parameters_group.setFixedWidth(260) + #self.gui_frame.operator_parameters_group.setFixedHeight(260) + self.gui_frame.measurement_tab_wgt.setMinimumWidth(440) + self.gui_frame.measurement_tab_wgt.setFixedHeight(280) + #self.gui_frame.operator_wgt.setFixedHeight(240) + #self.gui_frame.expert_wgt.setFixedHeight(240) + + self.gui_frame.central_tab_widget.tabBar().setTabText(0, "Control") + self.gui_frame.central_tab_widget.tabBar().setTabText(1, "IOC") + + self.expert_labels = self.parent.expert_labels + self.settings = self.parent.settings + + self.obj_to_upper = True if random.randint(1, 10) > 3 else False + + self.table_sol_dict = {} + self.table_pwr_dict = {} + self.offtime_dict = {} + + self.I_min = 1.0 + + + sec_state_list = ['PG1-HUSH:STATE', 'PSH-HUSH:STATE', + 'PG2-HUSH:STATE', 'PO2-HUSH:STATE', + 'PPIF-HUSH:STATE', 'PG3-HUSH:STATE'] + + self.cafe.openPrepare() + self.cafe.open(['PRO-HUSH:LASTPWR','PRO-HUSH:TOTPWR', + 'PRO:LASTSAVE', 'PPO-HUSH:TOTSAVE']) + self.cafe.open(sec_state_list) + self.cafe.openNowAndWait(0.1) + + + wgt = self.group_sector_qtabwidget() + self.gui_frame.measurement_layout.addWidget( + wgt, 0, 1, 6, 3, alignment=Qt.AlignTop) + + status_wgt = self.group_sector_status() + + self.gui_frame.measurement_layout.addWidget( + status_wgt, 2, 0, 2, 1, alignment=Qt.AlignTop) # | Qt.AlignHCenter) + + qf = QFrame() + qf.setFixedHeight(6) + self.gui_frame.measurement_layout.addWidget( + qf, 4, 0, 1, 1, alignment=Qt.AlignTop) + + self.sectorI_dict = {} + self.sectorI_dict['G1'] = "Geschlossen" + self.sectorI_dict['SH'] = "Geschlossen" + self.sectorI_dict['G2'] = "Geschlossen" + self.sectorI_dict['O2'] = "Geschlossen" + self.sectorI_dict['PIF'] = "Geschlossen" + self.sectorI_dict['G3'] = "Geschlossen" + + g3_line = ["SH", "PIF", "G3"] + pif_line = ["SH", "PIF"] + o2_line = ["SH", "O2"] + g2_line = ["SH", "G2"] + + def enable_disable_beamline(sect, sector_line, value): + self.sectorI_dict[sect] = value + #print("sect/value", sect, value) + for sector in sector_line: + if "Geschlossen" not in self.sectorI_dict[sector]: + #print("sector/value", sector, value) + if self.table_sol_dict[ + sector].standby_value_button.isEnabled(): + self.table_sol_dict[ + sector].standby_value_button.setEnabled(False) + print("DISABLE", sector) + else: + #print("Geschlossen? sector/value", sector, value) + if not self.table_sol_dict[ + sector].standby_value_button.isEnabled(): + self.table_sol_dict[ + sector].standby_value_button.setEnabled(True) + + + def receive_g3_update(value, status, alarm_severity): + print("receive_g3_update", flush=True) + enable_disable_beamline('G3', g3_line, value) + def receive_o2_update(value, status, alarm_severity): + enable_disable_beamline('O2', o2_line, value) + def receive_g2_update(value, status, alarm_severity): + enable_disable_beamline('G2', g2_line, value) + def receive_pif_update(value, status, alarm_severity): + enable_disable_beamline('PIF', pif_line, value) + + self.gui_header.beam_current_wgt_dict[ + "G3"].trigger_monitor_str.connect(receive_g3_update) + self.gui_header.beam_current_wgt_dict[ + "O2"].trigger_monitor_str.connect(receive_o2_update) + self.gui_header.beam_current_wgt_dict[ + "G2"].trigger_monitor_str.connect(receive_g2_update) + self.gui_header.beam_current_wgt_dict[ + "PIF"].trigger_monitor_str.connect(receive_pif_update) + + pvd=self.cafe.getPVCache(self.settings.data["G3"]["status"], dt='str') + receive_g3_update(pvd.value[0], pvd.alarmStatus, pvd.alarmSeverity) + pvd=self.cafe.getPVCache(self.settings.data["PIF"]["status"], dt='str') + receive_pif_update(pvd.value[0], pvd.alarmStatus, pvd.alarmSeverity) + pvd=self.cafe.getPVCache(self.settings.data["G2"]["status"], dt='str') + receive_g2_update(pvd.value[0], pvd.alarmStatus, pvd.alarmSeverity) + pvd=self.cafe.getPVCache(self.settings.data["O2"]["status"], dt='str') + receive_o2_update(pvd.value[0], pvd.alarmStatus, pvd.alarmSeverity) + + def receive_sec_state(handle, pv, pvdata): + pvsplit = pv.split("-") + secsplit = pvsplit[0].split("P") + sec = secsplit[1] + if pvdata.value[0] == 'ON': + #print("sec-ON", secsplit[1], flush=True) + self.table_sol_dict[sec].init_value_button.setEnabled(True) + self.table_pwr_dict[sec].init_value_button.setEnabled(True) + else: + #print("sec-OFF", secsplit[1], flush=True) + self.table_sol_dict[sec].init_value_button.setEnabled(False) + self.table_pwr_dict[sec].init_value_button.setEnabled(False) + + #print("sec", secsplit[1], flush=True) + + for state in sec_state_list: + self.cafe.monitor(state, receive_sec_state) + + + + def group_sector_status(self): + qgrid = QGridLayout() + #Connect all channels + #Heading + idx = self.settings.data["header"].index("G1") + idx_last = self.settings.data["header"].index("MASTER") + #Sector + + qlp = QLabel("Power \n(kW)") + f = qlp.font() + f.setPixelSize(13) + qlp.setFont(f) + qlp.setAlignment(Qt.AlignCenter) + + qli = QLabel("Initial \n(kW)") + f = qli.font() + f.setPixelSize(13) + qli.setFont(f) + qli.setAlignment(Qt.AlignCenter) + qgrid.addWidget(qli, 0, 1, 1, 1) + + qsa = QLabel("Saving \n(MWh)") + f = qsa.font() + f.setPixelSize(13) + qsa.setFont(f) + qsa.setAlignment(Qt.AlignCenter) + + qti = QLabel("Time in \nSaving Mode") + f = qti.font() + f.setPixelSize(13) + qti.setFont(f) + qti.setAlignment(Qt.AlignCenter) + + qtotsav = QLabel("Tot Saved \n(MWh)") + f = qtotsav.font() + f.setPixelSize(13) + qtotsav.setFont(f) + qtotsav.setAlignment(Qt.AlignCenter) + + qgrid.addWidget(qlp, 0, 2, 1, 1) + qgrid.addWidget(qsa, 0, 3, 1, 1) + qgrid.addWidget(qti, 0, 5, 1, 1) + qgrid.addWidget(qtotsav, 0, 6, 1, 1) + + + for i, sector in enumerate(self.settings.data["header"][idx:idx_last]): + a, b, c, d, e, f = self.sector_status(sector) + a.setContentsMargins(2, 0, 0, 0) + qgrid.addWidget(a, i+1, 0, 1, 1) + qgrid.addWidget(b, i+1, 1, 1, 1) + qgrid.addWidget(c, i+1, 2, 1, 1) + qgrid.addWidget(d, i+1, 3, 1, 1) + qgrid.addWidget(e, i+1, 5, 1, 1) + qgrid.addWidget(f, i+1, 6, 1, 1) + _line = QHLine() + _line.setFixedHeight(10) + _row = qgrid.rowCount() + qgrid.addWidget(_line, _row, 1, 1, 6) + #qgrid.setRowMinimumHeight(_row, 60) + + + qtot = QLabel("Total:") + fnt = qtot.font() + fnt.setPixelSize(13) + qtot.setFont(fnt) + qgrid.addWidget(qtot, _row+1, 0, 1, 1) + qgrid.addWidget( + CAQLineEdit(self, pv_name="PRO-HUSH:LASTPWR", show_units=True), + _row+1, 1, 1, 1) + qgrid.addWidget( + CAQLineEdit(self, pv_name="PRO-HUSH:TOTPWR", show_units=True), + _row+1, 2, 1, 1) + qgrid.addWidget( + CAQLineEdit(self, pv_name="PRO-HUSH:LASTSAVE", show_units=True), + _row+1, 3, 1, 2) + qgrid.addWidget( + CAQLineEdit(self, pv_name="PRO-HUSH:TOTSAVE", show_units=True), + _row+1, 6, 1, 2) + + qgrid.setContentsMargins(9, 20, 9, 9) + + qw = QGroupBox("Savings Overview") + qw.setContentsMargins(9, 9, 9, 9) + qw.setObjectName("OUTER") + qw.setLayout(qgrid) + qw.setFixedWidth(596) #480 + + #for column_no in range(0, 5): + # qgrid.itemAtPosition(1, column_no).widget().setStyleSheet("QWidget { background: lightblue; }") #addStyleName( + #item = qgrid.itemAt(2) #.widget().setStyleSheet("QLabel { background-color: green }") + #item.widget().setStyleSheet("background-color: green") #widgets on grid from left to right starting at top rtow + return qw + + + + + def sector_status(self, sector): + '''Create each sector line for inclusion into group + ''' + #device = "SEC-" + sector + device = "P" + sector + "-HUSH" + #Qlabel + qsector = QLabel(sector+":") + f = qsector.font() + f.setPixelSize(13) + qsector.setFont(f) + _color = "black" + try: + _color = self.settings.data[sector]["color"] + except KeyError as ex: + print(ex, self.settings.data[sector]) + + _color_str = "color : {0};".format(_color) + _incolor = "QLabel {" + _color_str + "}" + + qsector.setStyleSheet(_incolor) + #Savings + pv_pwr_tot = device + ":TOTPWR" + pv_pwr_last = device + ":LASTPWR" + pv_pwr_saved = device + ":LASTSAVE" + pv_pwr_timeout = device + ":OFFTIME" + pv_pwr_totsave = device + ":TOTSAVE" + + self.cafe.openPrepare() + self.cafe.open([pv_pwr_tot, pv_pwr_last, pv_pwr_saved, pv_pwr_timeout]) + self.cafe.openNowAndWait(2.0) + time.sleep(0.1) + + #print("device", device, flush=True) + def cb_outtime(handle, pv, pvdata): + try: + _delta = "{}".format(str(timedelta(seconds=(pvdata.value[0])))) + if ", " in _delta: + _split = _delta.split(", ") + if len(_split[1]) == len("0:00:00"): + _delta = _split[0] + ", " + _split[1] + if 'days,' in _delta: + _delta = _delta.replace("days,", "d") + elif 'day,' in _delta: + _delta = _delta.replace("day,", "d") + self.offtime_dict[pv].setText(_delta) + except KeyError: + pass + + now = QDateTime.currentDateTime() + xdate = QDate(now.date().year(), 1, 15) + xstart = QDateTime(xdate) + + qpinit = CAQLineEdit(self, pv_name=pv_pwr_last, show_units=False) + qpnow = CAQLineEdit(self, pv_name=pv_pwr_tot, show_units=False) + qpsave = CAQLineEdit(self, pv_name=pv_pwr_saved, show_units=False) + qptotsave = CAQLineEdit(self, pv_name=pv_pwr_totsave, show_units=False) + + qptime = CAQLineEdit(self, pv_name=pv_pwr_timeout, + monitor_callback=cb_outtime, show_units=True) + self.offtime_dict[pv_pwr_timeout] = qptime + + #Time to allow cb_outtime to fire + time.sleep(0.5) + + + qptime.setFixedWidth(104) + + #qtdis = QBasicTimer() + #qpnow.setAlignment(Qt.AlignRight) + #qpnow.style().polish(qpnow) + return qsector, qpinit, qpnow, qpsave, qptime, qptotsave + + def group_sector_qtabwidget(self): + + idx_last = self.settings.data["header"].index("MASTER") + idx = self.settings.data["header"].index("G1") + + #open all PVS + pv = [] + for sector in self.settings.data["header"][idx:idx_last]: + + device_list = self.settings.data[sector]["device"] + attribute_list = self.settings.data[sector]["attribute"] + for att in attribute_list: + for dev in device_list: + pv.append(dev + ":" + att) + + self.cafe.openPrepare() + self.cafe.open(pv) + self.cafe.openNowAndWait(1.0) + #self.cafe.supplementHandles() + + sector_wgt_dict = {} + + for sector in self.settings.data["header"][idx:idx_last]: + sector_wgt_dict[sector] = self.ca_table_sector_widget(sector=sector) + + sector_tab_widget = QTabWidget() + sector_tab_widget.setFont(self.font_gui) + sector_tab_widget.setStyleSheet("QTabBar {font-size: 12pt;}") + sector_tab_widget.tabBar().setShape(QTabBar.TriangularNorth) + + for i, sector in enumerate(self.settings.data["header"][idx:idx_last]): + sector_tab_widget.addTab(sector_wgt_dict[sector], sector) + color = self.settings.data[sector]["color"] + sector_tab_widget.tabBar().setTabTextColor(i, QColor(color)) + + #sector_tab_widget.addTab(sector_wgt_dict["INJ2"], "RF") + #color = self.settings.data["INJ2"]["color"] + #sector_tab_widget.tabBar().setTabTextColor( + # len(self.settings.data["header"][idx:]), QColor(color)) + + return sector_tab_widget + + + def check_status_list(self, pv_list, status_list, line): + _brk = ("------------------------------------------------------" + + "------------------------------------------------------") + self.parent.trigger_log_message.emit( + MsgSeverity.INFO.name, _pymodule, line, _brk, {}) + + _options = {} + + for pv, stat in zip(pv_list, status_list): + if stat != self.cyca.ICAFE_NORMAL: + _mess = ("Error in 'set' for " + pv + " ") + _options['statusCode'] = ( + str(stat) + " " + + self.cafe.getStatusCodeAsString(stat)) + _options['statusInfo'] = self.cafe.getStatusInfo(stat) + + self.parent.trigger_log_message.emit( + MsgSeverity.WARN.name, _pymodule, line, _mess, _options) + + + self.parent.trigger_log_message.emit( + MsgSeverity.INFO.name, _pymodule, line, _brk, {}) + + _mess = ("The following devices reported an error " + + "in 'set' operation:") + self.parent.trigger_log_message.emit( + MsgSeverity.INFO.name, _pymodule, line, _mess, {}) + + def check_status(self, pv, stat, line): + if stat != self.cyca.ICAFE_NORMAL: + _mess = ("Error in 'set' for " + pv + ".") + _options = {} + _options['statusCode'] = ( + str(stat) + " " + + self.cafe.getStatusCodeAsString(stat)) + _options['statusInfo'] = self.cafe.getStatusInfo( + stat) + self.parent.trigger_log_message.emit( + MsgSeverity.WARN.name, _pymodule, line, + _mess, _options) + + def on_sector_standby(self): + target = self.sender() + sector = target.sector + _table = self.table_sol_dict[sector] + + def is_update_enabled(): + '''Check if update buttons are enabled + if NOT, then do not allow inital values values to be updated" + ''' + + if self.table_pwr_dict[sector].init_value_button.isEnabled() \ + and _table.init_value_button.isEnabled(): + return True + else: + return False + + + QApplication.processEvents(QEventLoop.AllEvents, 1.0) + + #Do NOT do updates if in standby mode! + #Update button is disabled when in standby + + + #disenable widgets to avoid circular behaviour since + #updates of SOL also update PWR, and vice-versa + #Do not click if already on standby!! + + + if is_update_enabled(): + self.table_pwr_dict[sector].init_value_button.setEnabled(False) + _table.init_value_button.click() + time.sleep(0.05) + self.table_pwr_dict[sector].init_value_button.setEnabled(True) + + _table.init_value_button.setEnabled(False) + self.table_pwr_dict[sector].init_value_button.click() + time.sleep(0.05) + self.table_sol_dict[sector].init_value_button.setEnabled(True) + + QApplication.processEvents(QEventLoop.AllEvents, 1.0) + + + + if not self.input_parameters['simulation']: + status, status_list, pv_list = _table.set_standby_values() + + if status != self.cyca.ICAFE_NORMAL: + self.check_status_list(pv_list, status_list, _line()) + + pv = 'P' + target.sector + "-HUSH:STATE" + stat = self.cafe.set(pv, 0) + self.check_status(pv, stat, _line()) + + + def on_sector_restore(self): + target = self.sender() + sector = target.sector + _table = self.table_sol_dict[sector] + + if not self.input_parameters['simulation']: + status, status_list, pv_list = _table.restore_init_values() + + if status != self.cyca.ICAFE_NORMAL: + self.check_status_list(pv_list, status_list, _line()) + + pv = 'P' + target.sector + "-HUSH:STATE" + stat = self.cafe.set(pv, 1) + self.check_status(pv, stat, _line()) + + _table_pwr = self.table_pwr_dict[sector] + row_pwr_dict = _table_pwr.get_init_values() + sum_pwr = sum(list(row_pwr_dict.values())) + pv_last_pwr = 'P' + target.sector + "-HUSH:LASTPWR" + + stat = self.cafe.set(pv_last_pwr, sum_pwr) + self.check_status(pv_last_pwr, stat, _line()) + + + def ca_table_sector_widget(self, sector: str="", color: str="MACHINE"): + device_list = self.settings.data[sector]["device"] + attribute_list = self.settings.data[sector]["attribute"] + try: + _standby_values = self.settings.data[sector]["standby"] + print("Standby Values", sector, _standby_values, flush=True) + except KeyError as ex: + print("On Standby values not given for sector {0}".format(sector)) + + pv_dict = {} + for att in attribute_list: + pv_dict[att] = [] #[None] * len(device_list) + for dev in device_list: + pv_dict[att].append(dev + ":" + att) + + _table_height = 700 + + try: + _delay = self.input_parameters["delayRamp"] + except KeyError: + _delay = 0.09 + pass + + print(pv_dict['SOL:2'], flush=True) + print(_standby_values, flush=True) + table_sol = CAQTableWidget( + self, pv_list=pv_dict['SOL:2'], show_units=True, notify_freq_hz=0, + notify_unison=False, scale_factor=1, show_timestamp=False, + init_column=True, pv_list_show=device_list, standby_column=True, + standby_values=_standby_values, set_delay = _delay) + + table_sol.restore_value_button.setToolTip( + ("Restore devices to their pre-standby values")) + table_sol.init_value_button.setToolTip( + ("Shows initial, pre-standby values. Update is also " + + "executed automatically before the standby procedure.")) + + table_sol.standby_value_button.sector = sector + table_sol.standby_value_button.clicked.disconnect() + table_sol.standby_value_button.clicked.connect(self.on_sector_standby) + table_sol.restore_value_button.sector = sector + table_sol.restore_value_button.clicked.disconnect() + table_sol.restore_value_button.clicked.connect(self.on_sector_restore) + + + self.table_sol_dict[sector] = table_sol + + table_ist = CAQTableWidget( + self, pv_list=pv_dict['IST:2'], show_units=True, notify_freq_hz=2, + notify_unison=True, scale_factor=1, show_timestamp=False, + init_column=False, pv_list_show=[False]) + + table_pwr = CAQTableWidget( + self, pv_list=pv_dict['PWR'], show_units=False, notify_freq_hz=0, + suffix = "kW", + notify_unison=False, scale_factor=0.001, show_timestamp=False, + init_column=True, init_list=pv_dict['PWR'], pv_list_show=[False]) + + table_pwr.init_value_button.setToolTip( + ("Shows initial, pre-standby values. Update is also " + + "executed automatically before the standby procedure.")) + + self.table_pwr_dict[sector] = table_pwr + + header_item = QTableWidgetItem() + header_init = QTableWidgetItem() + header_standby = QTableWidgetItem() + header_value = QTableWidgetItem() + f = header_value.font() + f.setPixelSize(13) + header_item.setFont(f) + header_item.setText('Device') + header_init.setFont(f) + header_init.setText('Init. Value') + header_standby.setFont(f) + header_standby.setText('Standby') + header_value.setFont(f) + header_value.setText('SOL:2') + table_sol.setContentsMargins(15, 0, 15, 10) + table_sol.setHorizontalHeaderItem(0, header_item) + table_sol.setHorizontalHeaderItem(1, header_init) + table_sol.setHorizontalHeaderItem(2, header_standby) + table_sol.setHorizontalHeaderItem(3, header_value) + table_sol.setColumnWidth(0, 80) + table_sol.setColumnWidth(1, 88) + table_sol.setColumnWidth(2, 80) + table_sol.setColumnWidth(3, 88) + table_sol.setFixedWidth(386) + + ioc_magnets = [] + for i, device in enumerate(device_list): + if device in self.settings.data[sector]["iocDevice"]: + ioc_magnets.append(i) + + + header_value = QTableWidgetItem() + f = header_value.font() + f.setPixelSize(13) + header_value.setFont(f) + header_value.setText('IST:2') + table_ist.setContentsMargins(15, 0, 15, 10) + table_ist.setHorizontalHeaderItem(0, header_value) + table_ist.setColumnWidth(0, 90) + table_ist.setFixedWidth(140) + + header_init = QTableWidgetItem() + f = header_init.font() + header_init.setFont(f) + header_init.setText('Init. Value') + header_value = QTableWidgetItem() + f = header_value.font() + f.setPixelSize(13) + header_value.setFont(f) + header_value.setText('PWR') + table_pwr.setContentsMargins(15, 0, 15, 10) + table_pwr.setHorizontalHeaderItem(0, header_init) + table_pwr.setHorizontalHeaderItem(1, header_value) + table_pwr.setColumnWidth(0, 88) + table_pwr.setColumnWidth(1, 88) + table_pwr.setFixedWidth(226) + + for i in ioc_magnets: + table_sol.paint_rows(row_range=[i, i+1], reset=False, + columns=[0, 1]) + table_ist.paint_rows(row_range=[i, i+1], reset=False) + table_pwr.paint_rows(row_range=[i, i+1], reset=False) + + + pvStatus = self.settings.data[sector]['status'] + beamline_status = self.cafe.getCache(pvStatus) + if beamline_status is not None: + #if I < self.I_min: + if "Geschlossen" in beamline_status: + try: + values = self.settings.data[sector]['ref'] + table_sol.set_init_values(values) + except KeyError: + pass + try: + pwr_values = self.settings.data[sector]['pwrref'] + table_pwr.set_init_values(pwr_values) + except KeyError: + pass + + def on_sol_update(): + table_sol.init_value_button.setEnabled(False) + table_pwr.init_value_button.click() + time.sleep(0.1) + table_sol.init_value_button.setEnabled(True) + pv = "P" + table_pwr.init_value_button.sector + "-HUSH:LASTPWR" + _sum = sum(table_pwr.get_init_values().values()) + print("SUM up all the values", pv, _sum, flush=True) + stat = self.cafe.set(pv, _sum) + self.check_status(pv, stat, _line()) + + def on_init_update(): + table_pwr.init_value_button.setEnabled(False) + table_sol.init_value_button.click() + time.sleep(0.1) + table_pwr.init_value_button.setEnabled(True) + + table_sol.init_value_button.sector = sector + table_sol.init_value_button.clicked.connect(on_sol_update) + table_pwr.init_value_button.sector = sector + table_pwr.init_value_button.clicked.connect(on_init_update) + + hbox = QHBoxLayout() + hbox.addWidget(table_sol) + hbox.addWidget(table_ist) + hbox.addWidget(table_pwr) + + hbox.setSpacing(10) + hbox.setAlignment(Qt.AlignTop) + qw = QWidget() + qw.setLayout(hbox) + + + obj_name = self.settings.data[sector]["colorObj"] + if self.obj_to_upper: + obj_name = obj_name.upper() + + qw.setObjectName(obj_name) + + return qw