Commit bd83eb17322571a0b26d3be2db5b47602e530881
1 parent
1179175f
Exists in
dev
Control command Cagire web + back
Showing
10 changed files
with
668 additions
and
2 deletions
Show diff stats
simulators/config/grammar.json
... | ... | @@ -245,6 +245,197 @@ |
245 | 245 | "label": "Change the wanted filter", |
246 | 246 | "input_label": [], |
247 | 247 | "help": "Change the wanted filter" |
248 | + }, | |
249 | + { | |
250 | + "name": "EXPOSURE", | |
251 | + "label": "Exposure time for 1 image in seconds", | |
252 | + "input_label": [ | |
253 | + { | |
254 | + "exposure" : [15, "Int", "Exposure time"] | |
255 | + } | |
256 | + ], | |
257 | + "help": "Exposure time for 1 image in seconds" | |
258 | + }, | |
259 | + { | |
260 | + "name": "BINNING", | |
261 | + "label": "Binning of cells", | |
262 | + "input_label": [ | |
263 | + { | |
264 | + "binning" : [15, "Int", "Binning"] | |
265 | + } | |
266 | + ], | |
267 | + "help": "Set the Binning of cells." | |
268 | + } | |
269 | + ], | |
270 | + "get": [ | |
271 | + { | |
272 | + "name": "STATUS", | |
273 | + "label": "Get camera status values (dict)", | |
274 | + "input_label": [], | |
275 | + "help": "Get camera status values (dict): struct(key, value, type, unit, comment)" | |
276 | + }, | |
277 | + { | |
278 | + "name": "SETUP", | |
279 | + "label": "Get static values for config (dict)", | |
280 | + "input_label": [], | |
281 | + "help": "Get static values for config (eg. limit speed)" | |
282 | + }, | |
283 | + { | |
284 | + "name": "TIMER", | |
285 | + "label": "Get the ime before end of pose", | |
286 | + "input_label": [], | |
287 | + "help": "Time before end of pose (-1 == idle / finished, 0 == readout (recup-ing img))" | |
288 | + } | |
289 | + | |
290 | + ], | |
291 | + "do": [ | |
292 | + { | |
293 | + "name": "COOLER ON", | |
294 | + "label": "Turn On the cooler with the given temperature", | |
295 | + "input_label": [ | |
296 | + { | |
297 | + "temp":[15, "Float", "temperature"] | |
298 | + } | |
299 | + ], | |
300 | + "help": "Turn On the cooler with the given temperature." | |
301 | + }, | |
302 | + { | |
303 | + "name": "COOLER OFF", | |
304 | + "label": "Turn off the cooler", | |
305 | + "input_label": [], | |
306 | + "help": "Turn off the cooler." | |
307 | + }, | |
308 | + { | |
309 | + "name": "DOME SHUTTER OPEN", | |
310 | + "label": "Open the dome shutter", | |
311 | + "input_label": [], | |
312 | + "help": "Open the dome shutter." | |
313 | + }, | |
314 | + { | |
315 | + "name": "DOME SHUTTER CLOSE", | |
316 | + "label": "Close the dome shutter", | |
317 | + "input_label": [], | |
318 | + "help": "Close the dome shutter" | |
319 | + }, | |
320 | + { | |
321 | + "name": "DOME SHUTTER SYNCHRO", | |
322 | + "label": "Dome Shutter Synchro", | |
323 | + "input_label": [], | |
324 | + "help": "Dome Shutter Synchro" | |
325 | + }, | |
326 | + { | |
327 | + "name": "START", | |
328 | + "label": "Start Pose", | |
329 | + "input_label": [], | |
330 | + "help": "Start Pose" | |
331 | + }, | |
332 | + { | |
333 | + "name": "ABORT", | |
334 | + "label": "Stop Pose", | |
335 | + "input_label": [], | |
336 | + "help": "Stop Pose" | |
337 | + }, | |
338 | + { | |
339 | + "name": "STOP", | |
340 | + "label": "End image then stop pose", | |
341 | + "input_label": [], | |
342 | + "help": "End image then stop pose" | |
343 | + } | |
344 | + | |
345 | + ] | |
346 | + | |
347 | + | |
348 | + }, | |
349 | + "CameraNIR" : { | |
350 | + "set": [ | |
351 | + { | |
352 | + "name": "WINDOW", | |
353 | + "label": "Set the window coordinates", | |
354 | + "input_label": [ | |
355 | + { | |
356 | + "x1":[10, "Int", "x left bottom"], | |
357 | + "x2":[10, "Int", "y left bottom"], | |
358 | + "y1":[10, "Int", "x right top corner"], | |
359 | + "y2":[10, "Int", "y right top corner"] | |
360 | + } | |
361 | + ], | |
362 | + "help": "Coordinates of window corners (left bot, right top)" | |
363 | + }, | |
364 | + { | |
365 | + "name": "READMODE [MODE 1]", | |
366 | + "label": "Set Mode of observation (ramp, ...)", | |
367 | + "input_label": [], | |
368 | + "help": "Set the Mode of observation (ramp, ...)" | |
369 | + }, | |
370 | + { | |
371 | + "name": "READMODE [MODE 2]", | |
372 | + "label": "Set Mode of observation (ramp, ...)", | |
373 | + "input_label": [], | |
374 | + "help": "Set the Mode of observation (ramp, ...)" | |
375 | + }, | |
376 | + { | |
377 | + "name": "READMODE [MODE 3]", | |
378 | + "label": "Set Mode of observation (ramp, ...)", | |
379 | + "input_label": [], | |
380 | + "help": "Set the Mode of observation (ramp, ...)" | |
381 | + }, | |
382 | + { | |
383 | + "name": "FILENAME", | |
384 | + "label": "Change the used file", | |
385 | + "input_label": [ | |
386 | + { | |
387 | + "filename" : [256, "Str", "filename"] | |
388 | + } | |
389 | + ], | |
390 | + "help": "Optional, not wanting default file name (reset between each image)" | |
391 | + }, | |
392 | + { | |
393 | + "name": "HEADER", | |
394 | + "label": "Set particular values in the header", | |
395 | + "input_label": [ | |
396 | + { | |
397 | + "header values" : [1024, "Str (dict)", "header values"] | |
398 | + } | |
399 | + ], | |
400 | + "help": "Set particular values in the header" | |
401 | + }, | |
402 | + { | |
403 | + "name": "READOUT_FREQUENCY", | |
404 | + "label": "Readout frequency in pix/s (~= Hz)", | |
405 | + "input_label": [ | |
406 | + { | |
407 | + "readout freq" : [15, "Float", "readout freq pix/s ~= Hz"] | |
408 | + } | |
409 | + ], | |
410 | + "help": "Readout frequency in pix/s (~= Hz)" | |
411 | + }, | |
412 | + { | |
413 | + "name": "FILTER [FILTER 1]", | |
414 | + "label": "Change the wanted filter", | |
415 | + "input_label": [], | |
416 | + "help": "Change the wanted filter" | |
417 | + }, | |
418 | + { | |
419 | + "name": "FILTER [FILTER 2]", | |
420 | + "label": "Change the wanted filter", | |
421 | + "input_label": [], | |
422 | + "help": "Change the wanted filter" | |
423 | + }, | |
424 | + { | |
425 | + "name": "FILTER [FILTER 3]", | |
426 | + "label": "Change the wanted filter", | |
427 | + "input_label": [], | |
428 | + "help": "Change the wanted filter" | |
429 | + }, | |
430 | + { | |
431 | + "name": "NB_IMAGES", | |
432 | + "label": "Number of images in the ramp (x1.4s)", | |
433 | + "input_label": [ | |
434 | + { | |
435 | + "nb_imgs" : [15, "Int", "nb images"] | |
436 | + } | |
437 | + ], | |
438 | + "help": "Set the number of images in the ramp (x1.4s)" | |
248 | 439 | } |
249 | 440 | ], |
250 | 441 | "get": [ | ... | ... |
src/dashboard/templates/dashboard/observation_status.html
... | ... | @@ -125,6 +125,11 @@ |
125 | 125 | {% for log in cagire_logs %} |
126 | 126 | <li>{{log.created}} : {{log.message}}</li> {% endfor %} |
127 | 127 | </ul> |
128 | + {% if not config.global_mode %} | |
129 | + <form action={% url "send_command_to_cameraNIR" %}> | |
130 | + <input class="send_command_button" id="send_command_cameraNIR" type="submit" value="Send Command" /> | |
131 | + </form> | |
132 | + {% endif %} | |
128 | 133 | </div> |
129 | 134 | <div class="element" id=DDRAGORED> |
130 | 135 | <h2><button id="ddrago_r_button">DDRAGO RED</button></h2> | ... | ... |
src/dashboard/templates/dashboard/send_command_cameraNIR.html
0 โ 100644
... | ... | @@ -0,0 +1,124 @@ |
1 | +{% extends "base.html" %} | |
2 | +{% load staticfiles%} | |
3 | + | |
4 | +{% block title %} | |
5 | + Send Command to CAGIRE | |
6 | +{% endblock %} | |
7 | + | |
8 | +{% block content %} | |
9 | +<html lang="en"> | |
10 | +<head> | |
11 | + <meta charset="UTF-8"> | |
12 | + | |
13 | +</head> | |
14 | +<body> | |
15 | + <style> | |
16 | + | |
17 | + .conteneur | |
18 | + { | |
19 | + display: flex; | |
20 | + flex-wrap: wrap-reverse; | |
21 | + justify-content: space-between; | |
22 | + } | |
23 | + .element | |
24 | + { | |
25 | + | |
26 | + margin: auto; | |
27 | + list-style-image: none; | |
28 | + font-family: 'Montserra', sans-serif; | |
29 | + | |
30 | + } | |
31 | + | |
32 | + .element h2 | |
33 | + { | |
34 | + text-align: center; | |
35 | + font-weight: normal; | |
36 | + } | |
37 | + .log | |
38 | + { | |
39 | + font-size: 1.13em; | |
40 | + list-style-image: none; | |
41 | + list-style-type: none; | |
42 | + color: green; | |
43 | + font-weight: bold; | |
44 | + font-family: "Arial"; | |
45 | + height: 500px; | |
46 | + width: 650px; | |
47 | + overflow: scroll; | |
48 | + background-color: black; | |
49 | + } | |
50 | + | |
51 | + #id_first_command | |
52 | + { | |
53 | + font-size: 19px; | |
54 | + } | |
55 | + | |
56 | + | |
57 | + #submit_button | |
58 | + { | |
59 | + display: block; | |
60 | + font-size: 20px; | |
61 | + margin: auto; | |
62 | + } | |
63 | + #expert_mode | |
64 | + { | |
65 | + font-size: 15px; | |
66 | + } | |
67 | +</style> | |
68 | + | |
69 | + <!-- TODO:Passer aux django forms une fois que la grammaire sera fixรฉe --> | |
70 | + | |
71 | + <div class="conteneur"> | |
72 | + <div id="command" class="element"> | |
73 | + <form id=command_form method="POST" action={% url "submit_command_to_cameraNIR" %}> | |
74 | + | |
75 | + <label for="Command"><h2>Select the command</h2></label><br/> | |
76 | + | |
77 | + <select name="first_command" id="id_first_command"> | |
78 | + <option value="Command" selected>Command :</option> | |
79 | + <option value="SET">SET</option> | |
80 | + <option value="GET">GET</option> | |
81 | + <option value="DO">DO</option> | |
82 | + </select> | |
83 | + | |
84 | + </form> | |
85 | + <br><br> | |
86 | + <form id="command_form_expert" method="POST" action="{% url "submit_command_to_cameraNIR_expert" %}"> | |
87 | + <label for="Command"><h2>Enter the command in expert mode</h2></label><br/> | |
88 | + <button id="expert_mode" type="button">Expert Mode</button> | |
89 | + {% csrf_token %} | |
90 | + </form> | |
91 | + </div> | |
92 | + <div id="logs" class="element"> | |
93 | + <div id="cagire"> | |
94 | + <h2>CAGIRE</h2> | |
95 | + <ul class="log" id="cagire_logs"> | |
96 | + <br> | |
97 | + </ul> | |
98 | + </div> | |
99 | + </div> | |
100 | + </div> | |
101 | + <script> var data = {{ json_str | safe }}</script> | |
102 | + <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> | |
103 | + <script src="{% static "/js/command_control_cameraNIR.js" %}" type=text/javascript></script> | |
104 | + <script> | |
105 | + | |
106 | + $( "#command_form" ).submit(function( event ) { | |
107 | + alert( "Handler for .submit() called." ); | |
108 | + event.preventDefault(); | |
109 | + var inputElem = document.createElement('input'); | |
110 | + inputElem.type = 'hidden'; | |
111 | + inputElem.name = 'csrfmiddlewaretoken'; | |
112 | + inputElem.value = '{{ csrf_token }}'; | |
113 | + | |
114 | + document.getElementById("command_form").appendChild(inputElem); | |
115 | + $( "#command_form" ).submit(); | |
116 | +}); | |
117 | + | |
118 | + | |
119 | + </script> | |
120 | + | |
121 | + | |
122 | +</body> | |
123 | +</html> | |
124 | +{% endblock %} | |
0 | 125 | \ No newline at end of file | ... | ... |
src/dashboard/urls.py
... | ... | @@ -24,6 +24,9 @@ urlpatterns = [ |
24 | 24 | path('observation_status/send_command_to_telescope/submit_expert', views.submit_command_to_telescope_expert, name='submit_command_to_telescope_expert'), |
25 | 25 | path('observation_status/send_command_to_telescope/submit', views.submit_command_to_telescope, name='submit_command_to_telescope'), |
26 | 26 | path('observation_status/send_command_to_telescope', views.send_command_to_telescope, name='send_command_to_telescope'), |
27 | + path('observation_status/send_command_to_cameraNIR/submit_expert', views.submit_command_to_cameraNIR_expert, name='submit_command_to_cameraNIR_expert'), | |
28 | + path('observation_status/send_command_to_cameraNIR/submit', views.submit_command_to_cameraNIR, name='submit_command_to_cameraNIR'), | |
29 | + path('observation_status/send_command_to_cameraNIR', views.send_command_to_cameraNIR, name='send_command_to_cameraNIR'), | |
27 | 30 | path('observation_status/send_command_to_cameraVIS_1/submit_expert', views.submit_command_to_cameraVIS_1_expert, name='submit_command_to_cameraVIS_1_expert'), |
28 | 31 | path('observation_status/send_command_to_cameraVIS_1/submit', views.submit_command_to_cameraVIS_1, name='submit_command_to_cameraVIS_1'), |
29 | 32 | path('observation_status/send_command_to_cameraVIS_1', views.send_command_to_cameraVIS_1, name='send_command_to_cameraVIS_1'), | ... | ... |
src/dashboard/views.py
... | ... | @@ -19,6 +19,7 @@ from random import randint |
19 | 19 | from devices.Telescope import TelescopeController |
20 | 20 | from devices.TelescopeRemoteControlDefault import TelescopeRemoteControlDefault |
21 | 21 | from devices.CameraVISRemoteControlDefault import CameraVISRemoteControlDefault |
22 | +from devices.CameraNIRRemoteControlDefault import CameraNIRRemoteControlDefault | |
22 | 23 | from django.core.mail import send_mail |
23 | 24 | import time |
24 | 25 | import utils.celme as celme |
... | ... | @@ -361,6 +362,53 @@ def submit_command_to_cameraVIS_1_expert(request): |
361 | 362 | |
362 | 363 | |
363 | 364 | |
365 | +@login_required | |
366 | +@level_required(3) | |
367 | +def send_command_to_cameraNIR(request): | |
368 | + data = "" | |
369 | + with open('../simulators/config/grammar.json') as f: | |
370 | + data = json.load(f, object_pairs_hook=OrderedDict) | |
371 | + json_str = json.dumps(data) | |
372 | + return render(request, "dashboard/send_command_cameraNIR.html", locals()) | |
373 | + | |
374 | + | |
375 | +@login_required | |
376 | +@level_required(3) | |
377 | +def submit_command_to_cameraNIR(request): | |
378 | + if request.method == 'POST': | |
379 | + commands = [request.POST.get("first_command"), request.POST.get("first_param")] | |
380 | + try: #TODO faire un truc plus joli pour gรฉrer les params queqlue soit leur nombre | |
381 | + input_0 = request.POST.get("input_number_0") | |
382 | + input_1 = request.POST.get("input_number_1") | |
383 | + input_2 = request.POST.get("input_number_2") | |
384 | + if input_0: | |
385 | + commands.append(input_0) | |
386 | + if input_1: | |
387 | + commands.append(input_1) | |
388 | + if input_2: | |
389 | + commands.append(input_2) | |
390 | + except Exception: | |
391 | + pass | |
392 | + response = CameraNIRRemoteControlDefault(commands, expert_mode=False).exec_command() | |
393 | + #TODO passer en JS pour send les rรฉponses en AJAX | |
394 | + return redirect('send_command_to_cameraNIR') | |
395 | + | |
396 | +@login_required | |
397 | +@level_required(3) | |
398 | +def submit_command_to_cameraNIR_expert(request): | |
399 | + #import os | |
400 | + if request.method == 'POST': | |
401 | + param = request.POST.get("commande_expert") | |
402 | + if param: | |
403 | + response = CameraNIRRemoteControlDefault(param, expert_mode=True).exec_command() | |
404 | + #os.system("echo \"status :" + response + "\" >> /home/portos/IRAP/pyros/src/status") | |
405 | + return HttpResponse(json.dumps({'message': "Command send OK", 'response': response})) | |
406 | + return HttpResponse(json.dumps({'message': "Missing command data"})) | |
407 | + return redirect('submit_command_to_cameraNIR') | |
408 | + | |
409 | + | |
410 | + | |
411 | + | |
364 | 412 | |
365 | 413 | |
366 | 414 | ... | ... |
src/devices/CameraNIR.py
... | ... | @@ -5,7 +5,11 @@ from .Device import DeviceController |
5 | 5 | ''' |
6 | 6 | Device controller for NIRCamera. |
7 | 7 | This class must implement set, get and do functions (DeviceController is an abstract) |
8 | + | |
8 | 9 | ''' |
10 | + | |
11 | +#TODO: refactoriser cette classe, la seule mรฉthode utilisรฉe est sendMessage, les autres sont obsolรจtes | |
12 | + | |
9 | 13 | class NIRCameraController(DeviceController): |
10 | 14 | |
11 | 15 | def __init__(self): |
... | ... | @@ -34,3 +38,7 @@ class NIRCameraController(DeviceController): |
34 | 38 | def open_shutter(self): |
35 | 39 | self.do("OPEN SHUTTER") |
36 | 40 | return 0 |
41 | + | |
42 | + def send_command(self, command): | |
43 | + self.sendMessage(command) | |
44 | + return self.blockAndReadMessage() | ... | ... |
... | ... | @@ -0,0 +1,78 @@ |
1 | +from devices.CameraRemoteControlAbstract import CameraRemoteControlAbstract | |
2 | +from devices import CameraNIR | |
3 | + | |
4 | +''' | |
5 | + Class binding method for real grammar corresponding to the generic command received in the command_matchers | |
6 | +''' | |
7 | + | |
8 | +class CameraNIRRemoteControlDefault(CameraRemoteControlAbstract): | |
9 | + def __init__(self, command, expert_mode): | |
10 | + super().__init__(command, expert_mode) | |
11 | + self._camera = CameraNIR.NIRCameraController() | |
12 | + | |
13 | + self._command_matcher_set = { | |
14 | + "WINDOW": self.set, | |
15 | + "READMODE [MODE 1]": self.set, | |
16 | + "READMODE [MODE 2]": self.set, | |
17 | + "READMODE [MODE 3]": self.set, | |
18 | + "FILENAME": self.set, | |
19 | + "HEADER": self.set, | |
20 | + "READOUT_FREQUENCY": self.set, | |
21 | + "FILTER [FILTER 1]": self.set, | |
22 | + "FILTER [FILTER 2]": self.set, | |
23 | + "FILTER [FILTER 3]": self.set, | |
24 | + "NB_IMAGES": self.set, | |
25 | + } | |
26 | + self._command_matcher_get = { | |
27 | + "STATUS": self.get, | |
28 | + "SETUP": self.get, | |
29 | + "TIMER": self.get | |
30 | + } | |
31 | + self._command_matcher_do = { | |
32 | + "COOLER ON": self.do, | |
33 | + "COOLER OFF": self.do, | |
34 | + "DOME SHUTTER OPEN": self.do, | |
35 | + "DOME SHUTTER CLOSE": self.do, | |
36 | + "DOME SHUTTER SYNCHRO": self.do, | |
37 | + "START": self.do, | |
38 | + "ABORT": self.do, | |
39 | + "STOP": self.do | |
40 | + } | |
41 | + | |
42 | + | |
43 | + | |
44 | + | |
45 | + def exec_command(self): | |
46 | + | |
47 | + #os.system("echo \"status :" + str(self._command) + "\" >> /home/portos/IRAP/pyros/src/commande_recu") | |
48 | + if self._command[0] == "GET": | |
49 | + self._current_matcher = self._command_matcher_get | |
50 | + elif self._command[0] == "SET": | |
51 | + self._current_matcher = self._command_matcher_set | |
52 | + elif self._command[0] == "DO": | |
53 | + self._current_matcher = self._command_matcher_do | |
54 | + else: return "KO: Unknown command" | |
55 | + if self._command[1] in self._current_matcher: | |
56 | + return self._current_matcher[self._command[1]]() | |
57 | + else: | |
58 | + return "KO: Unknown command" | |
59 | + | |
60 | + | |
61 | + ''' | |
62 | + Locals methods for the generic grammar | |
63 | + ''' | |
64 | + | |
65 | + def do(self): | |
66 | + definitive_command = "DO " + self._command[1] + ' ' + ' '.join(self._command[2:]) | |
67 | + response = self._camera.send_command(definitive_command) | |
68 | + return response | |
69 | + | |
70 | + def set(self): | |
71 | + definitive_command = "SET " + self._command[1] + ' ' + ' '.join(self._command[2:]) | |
72 | + response = self._camera.send_command(definitive_command) | |
73 | + return response | |
74 | + | |
75 | + def get(self): | |
76 | + definitive_command = "GET " + self._command[1] #+ ' ' + ' '.join(self._command[2:]) | |
77 | + response = self._camera.send_command(definitive_command) | |
78 | + return response | |
0 | 79 | \ No newline at end of file | ... | ... |
src/devices/CameraVISRemoteControlDefault.py
1 | 1 | from devices.CameraRemoteControlAbstract import CameraRemoteControlAbstract |
2 | 2 | from devices import CameraVIS |
3 | 3 | |
4 | +''' | |
5 | + Class binding method for real grammar corresponding to the generic command received in the command_matchers | |
6 | +''' | |
7 | + | |
4 | 8 | class CameraVISRemoteControlDefault(CameraRemoteControlAbstract): |
5 | 9 | def __init__(self, command, expert_mode, chosen_camera): |
6 | 10 | super().__init__(command, expert_mode) |
... | ... | @@ -19,7 +23,9 @@ class CameraVISRemoteControlDefault(CameraRemoteControlAbstract): |
19 | 23 | "READOUT_FREQUENCY": self.set, |
20 | 24 | "FILTER [FILTER 1]": self.set, |
21 | 25 | "FILTER [FILTER 2]": self.set, |
22 | - "FILTER [FILTER 3]": self.set | |
26 | + "FILTER [FILTER 3]": self.set, | |
27 | + "BINNING": self.set, | |
28 | + "EXPOSURE": self.set | |
23 | 29 | } |
24 | 30 | self._command_matcher_get = { |
25 | 31 | "STATUS": self.get, | ... | ... |
src/devices/Device.py
... | ... | @@ -104,7 +104,7 @@ class DeviceController(): |
104 | 104 | readable, writable, exceptional = select.select([self.sock], [], [self.sock], 0) |
105 | 105 | if not (readable or exceptional): |
106 | 106 | #ret = self.sock.recv(size).decode() |
107 | - raise (Exception("KO: socket error")) | |
107 | + raise (Exception("KO: socket error or not implemented command")) | |
108 | 108 | |
109 | 109 | ret = self.sock.recv(size).decode() |
110 | 110 | if (not ret): | ... | ... |
... | ... | @@ -0,0 +1,203 @@ |
1 | +var LOGS_REFRESH_FREQUENCE = 2000; //in milliseconds | |
2 | +var expert_mode = false; | |
3 | + | |
4 | +jQuery(document).ready(function(){ | |
5 | + | |
6 | + var current_command = data; | |
7 | + var help = null; | |
8 | + | |
9 | + /** | |
10 | + These functions are event watchers on the img_display_help | |
11 | + **/ | |
12 | + | |
13 | + $(document).on("mouseenter", "#img_display_help", function() { | |
14 | + $('#img_display_help').attr('width','40px'); | |
15 | + $('#img_display_help').attr('height','40px'); | |
16 | + }); | |
17 | + | |
18 | + $(document).on("mouseleave", "#img_display_help", function() { | |
19 | + $('#img_display_help').attr('width','30px'); | |
20 | + $('#img_display_help').attr('height','30px'); | |
21 | +}); | |
22 | + | |
23 | + | |
24 | +$(document).on('click','#img_display_help', function() { | |
25 | + alert(help); | |
26 | +}); | |
27 | + | |
28 | + | |
29 | +/** | |
30 | + This function detete the childs of command_form after the child nยฐ start_position | |
31 | +**/ | |
32 | + | |
33 | +function delete_childs_after(start_position) | |
34 | +{ | |
35 | + var form = $("#command_form"); | |
36 | + var length = form.children().length; | |
37 | + | |
38 | + for (var i = start_position; i < length; i++) { | |
39 | + form.children().last().remove(); | |
40 | + } | |
41 | +} | |
42 | + | |
43 | +/** | |
44 | + This function create the select item with the commands in grammar.json | |
45 | +**/ | |
46 | +function init_first_param(corresponding_data) | |
47 | +{ | |
48 | + var sel = $('<select>', {name: "first_param", id:"id_first_param"}).appendTo('#command_form'); | |
49 | + sel.append($("<option>").attr('value', "Choose Value").text("Choose Value: ")); | |
50 | + for (var tmp in corresponding_data) | |
51 | + { | |
52 | + sel.append($("<option>").attr('value', corresponding_data[tmp]["name"]).text(corresponding_data[tmp]["name"])); | |
53 | + } | |
54 | + sel.css("font-size", "20px"); | |
55 | +} | |
56 | + | |
57 | +/** | |
58 | + This event watcher is triggered when the first_param (second submit element) is changed, it creates the inputs fields, desc, help and the submit button | |
59 | + with the corresponding values in grammar.json with current_command previously defined | |
60 | +**/ | |
61 | + | |
62 | + $(document).on('change','#id_first_param', function() { | |
63 | + delete_childs_after(4); | |
64 | + var form = $("#command_form"); | |
65 | + var selected_command = $("#id_first_param").find(":selected").val(); | |
66 | + var input = null; | |
67 | + var label = null; | |
68 | + for (var tmp in current_command)ย | |
69 | + { | |
70 | + if (current_command[tmp]["name"] === selected_command) | |
71 | + { | |
72 | + input = current_command[tmp]["input_label"][0]; | |
73 | + help = current_command[tmp]["help"]; | |
74 | + label = current_command[tmp]["label"]; | |
75 | + } | |
76 | + } | |
77 | + | |
78 | + var number = 0; | |
79 | + for (var input_field in input) | |
80 | + { | |
81 | + var maxlength = input[input_field][0]; | |
82 | + var type_input = input[input_field][1]; | |
83 | + var desc = input[input_field][2]; | |
84 | + var id = "input_number_" + number; | |
85 | + var name = "input_number_" + number; | |
86 | + var title = desc + ". value type: " + type_input; | |
87 | + number++; | |
88 | + input_element = $("<label>" + input_field + " </label><input title=\"" + title + "\" type=\"text\" id=\"" + id + "\" name=\"" + id + "\" maxlength=\"" + maxlength + "\" size=\"10\" text=\"" + input_field + "\"/>"); | |
89 | + form.append(input_element); | |
90 | + } | |
91 | + | |
92 | + var img_display_help = document.createElement('img'); | |
93 | + img_display_help.src = "/public/static/media/question-mark.png"; | |
94 | + img_display_help.width = 30; | |
95 | + img_display_help.height = 30; | |
96 | + img_display_help.title = "Click to display help for this command"; | |
97 | + img_display_help.id ="img_display_help"; | |
98 | + img_display_help.alt="html5"; | |
99 | + | |
100 | + form.append(img_display_help); | |
101 | + $("#img_display_help").css("margin-left", "10px"); | |
102 | + form.append("<br><br><p id=\"command_label\">Command description: " + label + "</p>"); | |
103 | + //$("#command_label").css("text-align", "center"); | |
104 | + $("#command_label").css({ | |
105 | + 'font-size' : '15px', | |
106 | + 'text-align' : 'center', | |
107 | + 'font-weight' : 'bold' | |
108 | + }); | |
109 | + form.append("<br>") | |
110 | + $('<input>', {id:"submit_button", type:"submit", value:"SEND"}).appendTo(form); | |
111 | + | |
112 | + }); | |
113 | + | |
114 | + | |
115 | + /** | |
116 | + This event watcher is triggered when the first select element is changed, it set the json current_command to SET, GET or DO, it | |
117 | + calls init_first_param | |
118 | + **/ | |
119 | + $("#id_first_command").change(function() { | |
120 | + delete_childs_after(3); | |
121 | + var selected_command = $("#id_first_command").find(":selected").val(); | |
122 | + if (selected_command !== "Command") | |
123 | + { | |
124 | + current_command = data["CameraNIR"][selected_command.toLowerCase()]; | |
125 | + init_first_param(data["CameraNIR"][selected_command.toLowerCase()]); | |
126 | + } | |
127 | + }); | |
128 | + | |
129 | + | |
130 | + /** | |
131 | + This event watcher is triggered when the expert mode is activated, it generates the corresponding input field and submit_button | |
132 | + **/ | |
133 | + | |
134 | +$("#expert_mode").click(function(){ | |
135 | + if (!expert_mode) | |
136 | + { | |
137 | + expert_mode = true; | |
138 | + $("#command_form_expert").append("<input id='input_command_expert' type='text' name='commande_expert'>"); | |
139 | + $('<input>', {id:"submit_button_expert", type:"submit", value:"SEND"}).appendTo('#command_form_expert'); | |
140 | + } | |
141 | + else { | |
142 | + $("#input_command_expert").remove(); | |
143 | + $("#submit_button_expert").remove(); | |
144 | + expert_mode = false; | |
145 | + } | |
146 | + //$("#command_form").remove(); | |
147 | +}); | |
148 | + | |
149 | +/** | |
150 | + This event watcher is triggered when the expert form is submitted, it's and AJAX POST request, the response is displayed in the console | |
151 | +**/ | |
152 | + | |
153 | +$("#command_form_expert").submit(function(event){ | |
154 | + | |
155 | + event.preventDefault(); | |
156 | + $.post('observation_status/send_command_to_cameraNIR/submit_expert', $(this).serialize(), function(data){ | |
157 | + var obj = JSON.parse(data); | |
158 | + console.log(obj.message); | |
159 | + console.log(obj.response); | |
160 | + if (obj.response === "KO: Unknown command") | |
161 | + alert("Unknown command"); | |
162 | + else if (obj.response.startsWith("KO")) | |
163 | + alert(obj.response); | |
164 | + }) | |
165 | + .fail(function() { | |
166 | + alert( "An error occured" ); | |
167 | + }) | |
168 | + }); | |
169 | + | |
170 | + | |
171 | +/** | |
172 | + This AJAX refreshed request is a get retrieving the Logs of the telescope | |
173 | +**/ | |
174 | + | |
175 | + interval_camera = setInterval(function() {ajax_request();}, LOGS_REFRESH_FREQUENCE); | |
176 | + | |
177 | + function ajax_request(){ | |
178 | + var camera_url ="/devices/update_cagire_logs"; | |
179 | + $.ajax({ | |
180 | + url: camera_url, | |
181 | + type: 'get', | |
182 | + dataType: 'text', | |
183 | + success: function(data) | |
184 | + { | |
185 | + var obj = JSON.parse(data); | |
186 | + if (obj) { | |
187 | + var listDiv = document.getElementById('cagire_logs'); | |
188 | + listDiv.innerHTML = ''; | |
189 | + for (var tmp in obj) { | |
190 | + var li = document.createElement('li'); | |
191 | + li.innerHTML = obj[tmp]['fields']['created'] + ": " + obj[tmp]['fields']['message']; // Use innerHTML to set the text | |
192 | + listDiv.appendChild(li); | |
193 | + } | |
194 | + } | |
195 | + }, | |
196 | + error: function() | |
197 | + { | |
198 | + console.log('Ajax error: GET request failed\n'); | |
199 | + } | |
200 | + | |
201 | + }); | |
202 | + } | |
203 | +}); | ... | ... |