From 9b8eb7f8eb8301abd728cc02046e1c7dce530f40 Mon Sep 17 00:00:00 2001
From: David Hammer <dhammer@mailbox.org>
Date: Thu, 28 Oct 2021 18:43:24 +0200
Subject: [PATCH] Rudimentary overview scene starting for manager

---
 src/calng/CalibrationManager.py | 28 +++++++++++++++++++++++-
 src/calng/scenes.py             | 38 ++++++++++++++++++++++++++++++++-
 2 files changed, 64 insertions(+), 2 deletions(-)

diff --git a/src/calng/CalibrationManager.py b/src/calng/CalibrationManager.py
index c4a80d50..69570eae 100644
--- a/src/calng/CalibrationManager.py
+++ b/src/calng/CalibrationManager.py
@@ -23,7 +23,7 @@ from karabo.middlelayer import (
     KaraboError, Device, DeviceClientBase, Descriptor, Hash, Configurable,
     Slot, Node, Type,
     AccessMode, AccessLevel, Assignment, DaqPolicy, State, Unit,
-    UInt16, UInt32, Bool, Double, String, VectorString, VectorHash,
+    UInt16, UInt32, Bool, Double, Schema, String, VectorString, VectorHash,
     background, call, callNoWait, setNoWait, sleep, instantiate, slot, coslot,
     getDevice, getTopology, getConfiguration, getConfigurationFromPast,
     get_property)
@@ -31,6 +31,7 @@ from karabo.middlelayer_api.proxy import ProxyFactory
 
 from karabo import version as karaboVersion
 from ._version import version as deviceVersion
+from . import scenes
 
 
 '''
@@ -302,6 +303,28 @@ class CalibrationManager(DeviceClientBase, Device):
             else []),
         accessMode=AccessMode.READONLY)
 
+    availableScenes = VectorString(
+        displayedName='Available scenes',
+        displayType='Scenes',
+        requiredAccessLevel=AccessLevel.OBSERVER,
+        accessMode=AccessMode.READONLY,
+        defaultValue=['overview'],
+        daqPolicy=DaqPolicy.OMIT)
+
+    @slot
+    def requestScene(self, params):
+        name = params.get('name', default='overview')
+        if name == 'overview':
+            # Assumes there are correction devices known to manager
+            scene_data = scenes.manager_device_overview_scene(
+                self.deviceId,
+                self._correction_device_schema,
+                self._correction_device_ids)
+            payload = Hash('success', True, 'name', name, 'data', scene_data)
+            return Hash('type', 'deviceScene',
+                        'origin', self.deviceId,
+                        'payload', payload)
+
     detectorType = String(
         displayedName='Detector type',
         description='Type of the detector to manage.',
@@ -591,6 +614,9 @@ class CalibrationManager(DeviceClientBase, Device):
         # Obtain the device schema from a correction device server.
         managed_schema, _, _ = await call(corr_server, 'slotGetClassSchema',
                                           self._correction_class_id)
+        # saving this for later
+        self._correction_device_schema = Schema()
+        self._correction_device_schema.copy(managed_schema)
 
         if managed_schema.name != self._correction_class_id:
             self._set_fatal(
diff --git a/src/calng/scenes.py b/src/calng/scenes.py
index a2f3fcf4..73cd358e 100644
--- a/src/calng/scenes.py
+++ b/src/calng/scenes.py
@@ -355,6 +355,9 @@ class CorrectionDeviceStatus:
 
 class CompactCorrectionDeviceOverview:
     def __init__(self, device_id, schema_hash):
+        self.name = LabelModel(
+            text=device_id.split("/")[-1], width=5 * BASE_INC, height=BASE_INC
+        )
         self.status = DisplayStateColorModel(
             show_string=True,
             keys=[f"{device_id}.state"],
@@ -375,6 +378,9 @@ class CompactCorrectionDeviceOverview:
         self.ampeln = ConstantLoadedAmpeln(device_id, schema_hash)
 
     def render(self, x, y):
+        self.name.x = x
+        self.name.y = y
+        x += self.name.width
         self.status.x = x
         self.status.y = y
         x += self.status.width
@@ -384,7 +390,13 @@ class CompactCorrectionDeviceOverview:
         self.tid.x = x
         self.tid.y = y
         x += self.tid.width
-        return [self.status, self.rate, self.tid] + self.ampeln.render(x, y)
+        return [self.name, self.status, self.rate, self.tid] + self.ampeln.render(x, y)
+
+    def width(self):
+        return 19 * BASE_INC + self.ampeln.width()
+
+    def height(self):
+        return BASE_INC
 
 
 def correction_device_overview_scene(device_id, schema):
@@ -416,3 +428,27 @@ def correction_device_overview_scene(device_id, schema):
         children=subscenes,
     )
     return write_scene(scene)
+
+
+def manager_device_overview_scene(
+    manager_device_id, correction_device_schema, correction_device_ids
+):
+    if isinstance(correction_device_schema, karathon.Schema):
+        schema_hash = correction_device_schema.getParameterHash()
+    else:
+        schema_hash = correction_device_schema.hash
+
+    x = PADDING
+    y = PADDING
+    subscenes = []
+    for device_id in correction_device_ids:
+        ccdo = CompactCorrectionDeviceOverview(device_id, schema_hash)
+        subscenes.extend(ccdo.render(x, y))
+        y += ccdo.height()
+
+    scene = SceneModel(
+        height=y + 2 * PADDING,
+        width=ccdo.width() + 2 * PADDING,
+        children=subscenes,
+    )
+    return write_scene(scene)
-- 
GitLab