Commit a2f47fb61e74ef97114f4ceebabda42ac4aa2d73
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
Showing
5 changed files
with
163 additions
and
39 deletions
Show diff stats
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 = {} | ... | ... |