Commit a2f47fb61e74ef97114f4ceebabda42ac4aa2d73

Authored by Alexis Koralewski
1 parent 7eec3077
Exists in dev

updating display of hardware (global and detailled view), news functions in conf…

…ig class in order to display those informations, renaming config class name
src/core/pyros_django/obsconfig/configpyros_v2.py renamed to src/core/pyros_django/obsconfig/configpyros.py
... ... @@ -3,10 +3,10 @@ import pykwalify.core
3 3 import yaml,sys,logging,os
4 4 from pykwalify.errors import PyKwalifyException,SchemaError
5 5  
6   -class ConfigPyrosV2:
  6 +class ConfigPyros:
7 7 # (AKo) : Config file path is checked on the settings file, if the file isn't valid (i.e not found) the error will be launched by the settings file when starting the application
8 8 # read_files is an history of which config files has been read, where the key is the source file which is linked to a list of files associated to this key
9   - read_files = {}
  9 + devices_links = {}
10 10 current_file = None
11 11 COMPONENT_PATH = "../../../../config/components/"
12 12  
... ... @@ -117,7 +117,20 @@ class ConfigPyrosV2:
117 117  
118 118  
119 119  
120   -
  120 + def get_devices_names_and_file(self)->dict:
  121 + """
  122 +
  123 +
  124 + Returns:
  125 + dict: [description]
  126 + """
  127 + devices_names_and_files = {}
  128 + for device in self.content["OBSERVATORY"]["DEVICES"]:
  129 + device = device["DEVICE"]
  130 +
  131 + devices_names_and_files[device["name"]] = device["file"]
  132 + return devices_names_and_files
  133 +
121 134 def read_device_config_file(self,config_file_name:str)->dict:
122 135 """
123 136  
... ... @@ -151,16 +164,37 @@ class ConfigPyrosV2:
151 164  
152 165 device["CAPABILITIES"] = capabilities
153 166 if "ATTACHED_DEVICES" in device.keys():
  167 +
  168 + devices_name_and_file = self.get_devices_names_and_file()
  169 + active_devices = self.get_active_devices()
154 170 for attached_device in device["ATTACHED_DEVICES"]:
155   -
156   - config_of_attached_device = self.read_device_config_file(self.CONFIG_PATH+attached_device["file"])
157   -
158   - capabilities_of_attached_device = None
159   - if "CAPABILITIES" in config_of_attached_device["DEVICE"].keys():
160   - capabilities_of_attached_device = config_of_attached_device["DEVICE"]["CAPABILITIES"]
161   - if capabilities_of_attached_device is not None:
162   - for capability in capabilities_of_attached_device:
163   - result["DEVICE"]["CAPABILITIES"].append(capability)
  171 + print(attached_device["file"])
  172 + is_attached_device_link_to_agent = False
  173 + for active_device in active_devices:
  174 +
  175 + print(devices_name_and_file[active_device])
  176 + print(devices_name_and_file[active_device] == attached_device["file"])
  177 + if devices_name_and_file[active_device] == attached_device["file"]:
  178 + is_attached_device_link_to_agent = True
  179 + break
  180 +
  181 + if self.CONFIG_PATH+attached_device["file"] != config_file_name and not is_attached_device_link_to_agent:
  182 + config_of_attached_device = self.read_device_config_file(self.CONFIG_PATH+attached_device["file"])
  183 +
  184 + capabilities_of_attached_device = None
  185 + if "CAPABILITIES" in config_of_attached_device["DEVICE"].keys():
  186 + capabilities_of_attached_device = config_of_attached_device["DEVICE"]["CAPABILITIES"]
  187 + if capabilities_of_attached_device is not None:
  188 + # get name of device corresponding to the config file name
  189 + parent_device_name = [device for device,file_name in devices_name_and_file.items() if file_name == config_file_name[len(self.CONFIG_PATH):] ][0]
  190 +
  191 + attached_device_name = [device for device,file_name in devices_name_and_file.items() if file_name == attached_device["file"]][0]
  192 + print("parrent device name : ",parent_device_name)
  193 + print("attached device name : ",attached_device_name)
  194 +
  195 + self.devices_links[attached_device_name] = parent_device_name
  196 + for capability in capabilities_of_attached_device:
  197 + result["DEVICE"]["CAPABILITIES"].append(capability)
164 198 return result
165 199 except yaml.YAMLError as exc:
166 200 print(exc)
... ... @@ -587,7 +621,7 @@ class ConfigPyrosV2:
587 621  
588 622  
589 623 def main():
590   - config = ConfigPyrosV2("../../../../privatedev/config/guitalens/observatory_guitalens.yml")
  624 + config = ConfigPyros("../../../../privatedev/config/guitalens/observatory_guitalens.yml")
591 625 # print(config.content)
592 626 print(config.get_devices()["FLI-Kepler4040"]["device_config"]["CAPABILITIES"][1]["attributes"]["manufacturer"])
593 627 print(config.get_devices()["FLI-Kepler4040"]["device_config"]["CAPABILITIES"])
... ...
src/core/pyros_django/obsconfig/templates/obsconfig/device_details.html
... ... @@ -7,17 +7,34 @@
7 7 {% comment %}
8 8 <pre>{{ device_detail }}</pre>
9 9 {% endcomment %}
10   - {% for element in test %}
11   - <p> {{element|first}} : {{element|last}}</p>
12   - {% endfor %}
13   -
14   -
  10 +<style>
  11 +th,td{
  12 + padding: 1rem;
  13 +}
  14 +</style>
  15 + {% with device_detail|get_item:"name" as device_name %}
15 16 {% for key,value in device_detail.items %}
16 17 <div>
17 18 {% if key == "device_config" %}
18 19 {% with device_detail|get_item:key as device_config %}
19 20 {% for key,value in device_config.items %}
20   - <p>{{ key }} : {{ value }}</p>
  21 + {% if key == "ATTACHED_DEVICES" and devices_links|get_item:device_name != None %}
  22 + <p> Attached to : <a href="{% url 'device_details' devices_links|get_item:device_name %}">{{ devices_links|get_item:device_name }} </p></a>
  23 + {% elif key == "ATTACHED_DEVICES" and device_name in active_devices %}
  24 + <b> Attached devices : </b>
  25 + {% for element in device_config|get_item:"ATTACHED_DEVICES" %}
  26 +
  27 + {% with element|get_item:"file" as attached_device_file %}
  28 +
  29 +
  30 + {% with file_name_to_device_name|get_item:attached_device_file as attached_device %}
  31 + <p> <a href="{% url 'device_details' attached_device %}">{{ attached_device }} </a> is attached to this device </p>
  32 + {% endwith %}
  33 + {% endwith %}
  34 + {% endfor %}
  35 + {% else %}
  36 + <p>{{ key }} : {{ value }}</p>
  37 + {% endif %}
21 38 {% endfor %}
22 39 {% endwith %}
23 40 {% else %}
... ... @@ -48,7 +65,7 @@
48 65 <b>Capabilities : </b>
49 66 <ul>
50 67 {% for capability in capabilities %}
51   - <li> Capability : </li><br>
  68 +
52 69 {% comment %}
53 70  
54 71 {% for information,information_value in capability.items %}
... ... @@ -57,20 +74,82 @@
57 74  
58 75 {% endfor %}
59 76 {% endcomment %}
60   - Component : {{capability.component}}
  77 +
  78 + <li> <h3> Component : {{capability.component}} </h3> </li>
61 79 <br>
62 80 <b> attributes : </b>
63 81 <ul>
64 82  
65 83 {% for attribute in capability.attributes %}
66 84 {% with capability.attributes|get_item:attribute as attribute %}
  85 + {% if attribute.is_container %}
  86 + <li><b>{{ attribute.label }} :</li></b>
  87 + <table class="table-bordered table-hover table-striped" >
  88 + <thead>
  89 + <tr>
  90 + <th> Variable </th>
  91 + <th> Unit </th>
  92 + <th colspan="20"> Values </th>
  93 + </tr>
  94 + </thead>
  95 + <tbody>
  96 + {% for val_name in attribute.value %}
  97 + <tr>
  98 + <td> {{ val_name }} </td>
  99 + <td>{{ attribute.unit|get_item:val_name}} </td>
  100 + {% for value in attribute.value|get_item:val_name %}
  101 +
  102 + {% if value|get_type == 'list' %}
  103 + <td>
  104 + <table class="table-bordered">
  105 + <tbody>
  106 + {% with value as values %}
  107 + <tr>
  108 + {% for value in values %}
  109 + <td> {{value}} </td>
  110 + {% endfor %}
  111 + </tr>
  112 + </tbody>
  113 + </table>
  114 + {% endwith %}
  115 + </td>
  116 +
  117 + {% else %}
  118 + <td> {{value}} </td>
  119 + {% endif %}
  120 + {% endfor %}
  121 + </tr>
  122 + {% endfor %}
  123 + </tbody>
  124 + </table>
  125 + {% elif attribute.is_enum %}
  126 + <li><b>{{ attribute.label }} :</li></b>
  127 + <table class="table-bordered table-hover table-striped" >
  128 + <thead>
  129 + <tr>
  130 + <tr>
  131 + <th> Variable </th>
  132 + <th colspan="20"> Values (One of the following values)</th>
  133 + </tr>
  134 + </thead>
  135 + <tbody>
  136 + <tr>
  137 + <td> {{ attribute.label}} </td>
  138 + {% for val in attribute.value %}
  139 + <td> {{ val }} </td>
  140 + {% endfor %}
  141 + </tr>
  142 + </tbody>
  143 + </table>
  144 + {% else %}
67 145 <li>{{ attribute.label }} : {{ attribute.value}} {{ attribute.unit}} </li>
  146 + {% endif %}
68 147 {% endwith %}
69 148 {% endfor %}
70 149 </ul>
71 150 {% endfor %}
72 151 </ul>
73 152 {% endif %}
74   -
  153 + {% endwith %}
75 154  
76 155 {% endblock %}
77 156 \ No newline at end of file
... ...
src/core/pyros_django/obsconfig/templates/obsconfig/obs_hardware_configuration.html
... ... @@ -5,6 +5,7 @@
5 5  
6 6 <div class="devices">
7 7 <h1> Devices </h1>
  8 +
8 9 <table class="table table-bordered table-hover table-striped tablesorter" style="font-family: 'Montserra', sans-serif;">
9 10 <thead>
10 11 <tr>
... ... @@ -26,9 +27,16 @@
26 27 {% if device in active_devices %}
27 28 <td class="in_use"> Yes </td>
28 29 <td> {{ device_to_unit|get_item:device }}</td>
  30 + {% elif devices_links|get_item:device in active_devices %}
  31 + <td class="in_use"> Yes </td>
  32 + {% with devices_links|get_item:device as parent_device %}
  33 + <td> {{ device_to_unit|get_item:parent_device }}</td>
  34 + {% endwith %}
29 35 {% else %}
30   - <td class="not_in_use"> No </td>
31   - <td></td>
  36 + <td colspan="2" class="not_in_use"> No </td>
  37 +
  38 +
  39 +
32 40 {% endif %}
33 41 </div>
34 42 {% endfor %}
... ... @@ -56,8 +64,8 @@
56 64 <td class="in_use"> Yes </td>
57 65 <td> {{ computer_to_unit|get_item:computer }}</td>
58 66 {% else %}
59   - <td class="not_in_use"> No </td>
60   - <td></td>
  67 + <td colspan="2" class="not_in_use"> No </td>
  68 +
61 69 {% endif %}
62 70 </div>
63 71 {% endfor %}
... ...
src/core/pyros_django/obsconfig/urls.py
... ... @@ -8,5 +8,5 @@ urlpatterns = [
8 8 path("obs_agents_config",views.obs_agents_config,name="obs_agents_config"),
9 9 path('unit_hardware_configuration/<str:unit_name>', views.unit_hardware_configuration, name='unit_hardware_configuration'),
10 10 path('computer_details/<str:computer_name>', views.computer_details, name='computer_details'),
11   - path('device_detail/<str:device_name>', views.device_details, name='device_details'),
  11 + path('device_details/<str:device_name>', views.device_details, name='device_details'),
12 12 ]
13 13 \ No newline at end of file
... ...
src/core/pyros_django/obsconfig/views.py
1 1 from django import conf
2 2 from django.shortcuts import render
3   -from .configpyros_v2 import ConfigPyrosV2
  3 +from .configpyros import ConfigPyros
4 4 from django.conf import settings
5 5 from src.core.pyros_django.dashboard.decorator import level_required
6 6 from django.contrib.auth.decorators import login_required
... ... @@ -27,7 +27,7 @@ def get_nested_dictionaries_as_list(dic,result=[]):
27 27 @login_required
28 28 @level_required("Admin","Observer","Management","Operator","Unit-PI")
29 29 def obs_global_config(request):
30   - config = ConfigPyrosV2(settings.PATH_TO_OBSCONF_FILE)
  30 + config = ConfigPyros(settings.PATH_TO_OBSCONF_FILE)
31 31 units_names = list(config.get_units().keys())
32 32 return render(request,"obsconfig/global_obs_configuration.html",{"units_names" : units_names, "obs_name": config.get_obs_name()})
33 33  
... ... @@ -35,7 +35,7 @@ def obs_global_config(request):
35 35 @login_required
36 36 @level_required("Admin","Unit-PI","Operator")
37 37 def obs_hardware_config(request):
38   - config = ConfigPyrosV2(settings.PATH_TO_OBSCONF_FILE)
  38 + config = ConfigPyros(settings.PATH_TO_OBSCONF_FILE)
39 39 devices = config.get_devices()
40 40 active_devices = config.get_active_devices()
41 41 computers = config.get_computers()
... ... @@ -48,13 +48,13 @@ def obs_hardware_config(request):
48 48 device_to_unit[device] = config.get_unit_of_device(device)
49 49 for computer in active_computers:
50 50 computer_to_unit[computer] = config.get_unit_of_computer(computer)
51   -
52   - return render(request, 'obsconfig/obs_hardware_configuration.html', {'devices':devices,"active_devices":active_devices,"computers":computers,"active_computers":active_computers, "device_to_unit" : device_to_unit, "computer_to_unit" : computer_to_unit})
  51 + devices_links = config.devices_links
  52 + return render(request, 'obsconfig/obs_hardware_configuration.html', {'devices':devices,"active_devices":active_devices,"computers":computers,"active_computers":active_computers, "device_to_unit" : device_to_unit, "computer_to_unit" : computer_to_unit,"devices_links":devices_links})
53 53  
54 54 @login_required
55 55 @level_required("Admin","Unit-PI","Operator")
56 56 def unit_hardware_configuration(request,unit_name):
57   - config = ConfigPyrosV2(settings.PATH_TO_OBSCONF_FILE)
  57 + config = ConfigPyros(settings.PATH_TO_OBSCONF_FILE)
58 58 devices = config.get_devices()
59 59  
60 60 return render(request, 'obsconfig/unit_hardware_configuration.html', {'config':config})
... ... @@ -62,7 +62,7 @@ def unit_hardware_configuration(request,unit_name):
62 62 @login_required
63 63 @level_required("Admin","Unit-PI","Operator")
64 64 def computer_details(request,computer_name):
65   - config = ConfigPyrosV2(settings.PATH_TO_OBSCONF_FILE)
  65 + config = ConfigPyros(settings.PATH_TO_OBSCONF_FILE)
66 66 computer_detail = yaml.dump(config.get_computers()[computer_name])
67 67 """
68 68 computer_detail = { re.sub("^_","",key):value for key,value in config.get_computers()[computer_name].items() }
... ... @@ -84,12 +84,15 @@ def computer_details(request,computer_name):
84 84 @login_required
85 85 @level_required("Admin","Unit-PI","Operator")
86 86 def device_details(request,device_name):
87   - config = ConfigPyrosV2(settings.PATH_TO_OBSCONF_FILE)
  87 + config = ConfigPyros(settings.PATH_TO_OBSCONF_FILE)
88 88 # We're removing "_" at the beginning of each key :
89 89 device = config.get_devices()[device_name]
90 90 #device_detail = yaml.dump(device)
91 91 #config_device = open(config.CONFIG_PATH+device["file"],"r").read()
92   -
  92 + devices_links = config.devices_links
  93 + file_name_to_device_name = {v:k for k,v in config.get_devices_names_and_file().items()}
  94 + print(file_name_to_device_name)
  95 + active_devices = config.get_active_devices()
93 96 """
94 97 Alternative solutions:
95 98 - test_device -> we're using a recursive function to get all nested dicitonaries but we loose a level of
... ... @@ -131,14 +134,14 @@ def device_details(request,device_name):
131 134 device_detail["device_config"].pop("connector")
132 135 if len(capabilities)!= 0:
133 136 device_detail["device_config"].pop("CAPABILITIES")
134   - return render(request,"obsconfig/device_details.html", { "device_detail" : device_detail, "power" : power, "connector" : connector, "capabilities" : capabilities} )
  137 + return render(request,"obsconfig/device_details.html", { "device_detail" : device_detail, "power" : power, "connector" : connector, "capabilities" : capabilities,"devices_links":devices_links,"file_name_to_device_name": file_name_to_device_name,"active_devices":active_devices} )
135 138  
136 139 #return render(request,"obsconfig/device_details.html", { "device_detail" : device_detail, "config" : config_device })
137 140  
138 141 @login_required
139 142 @level_required("Admin","Observer","Management","Operator","Unit-PI","TAC")
140 143 def obs_astronomer_config(request):
141   - config = ConfigPyrosV2(settings.PATH_TO_OBSCONF_FILE)
  144 + config = ConfigPyros(settings.PATH_TO_OBSCONF_FILE)
142 145 units = config.get_units()
143 146 units_topologies = {}
144 147 # for each unit
... ... @@ -175,7 +178,7 @@ def obs_astronomer_config(request):
175 178 @login_required
176 179 @level_required("Admin")
177 180 def obs_agents_config(request):
178   - config = ConfigPyrosV2(settings.PATH_TO_OBSCONF_FILE)
  181 + config = ConfigPyros(settings.PATH_TO_OBSCONF_FILE)
179 182 units = config.get_units()
180 183 units_topologies = {}
181 184 active_agents_by_unit = {}
... ...