Commit d3faf32762e70e45cfa9fb1bcc1aabadbf32fc3e

Authored by Quentin Durand
1 parent 4daa4c30
Exists in dev

Command control DDRAGO r et b cagire a venir

simulators/config/grammar.json
... ... @@ -142,7 +142,7 @@
142 142 "name": "DOME SHUTTER CLOSE",
143 143 "label": "Close the dome shutter",
144 144 "input_label": [],
145   - "help": "Close the rotator motion."
  145 + "help": "Close the dome shutter"
146 146 },
147 147 {
148 148 "name": "DOME PARK",
... ... @@ -164,6 +164,167 @@
164 164 }
165 165  
166 166 ]
  167 + },
  168 + "CameraVIS" : {
  169 + "set": [
  170 + {
  171 + "name": "WINDOW",
  172 + "label": "Set the window coordinates",
  173 + "input_label": [
  174 + {
  175 + "x1":[10, "Int", "x left bottom"],
  176 + "x2":[10, "Int", "y left bottom"],
  177 + "y1":[10, "Int", "x right top corner"],
  178 + "y2":[10, "Int", "y right top corner"]
  179 + }
  180 + ],
  181 + "help": "Coordinates of window corners (left bot, right top)"
  182 + },
  183 + {
  184 + "name": "READMODE [MODE 1]",
  185 + "label": "Set Mode of observation (ramp, ...)",
  186 + "input_label": [],
  187 + "help": "Set the Mode of observation (ramp, ...)"
  188 + },
  189 + {
  190 + "name": "READMODE [MODE 2]",
  191 + "label": "Set Mode of observation (ramp, ...)",
  192 + "input_label": [],
  193 + "help": "Set the Mode of observation (ramp, ...)"
  194 + },
  195 + {
  196 + "name": "READMODE [MODE 3]",
  197 + "label": "Set Mode of observation (ramp, ...)",
  198 + "input_label": [],
  199 + "help": "Set the Mode of observation (ramp, ...)"
  200 + },
  201 + {
  202 + "name": "FILENAME",
  203 + "label": "Change the used file",
  204 + "input_label": [
  205 + {
  206 + "filename" : [256, "Str", "filename"]
  207 + }
  208 + ],
  209 + "help": "Optional, not wanting default file name (reset between each image)"
  210 + },
  211 + {
  212 + "name": "HEADER",
  213 + "label": "Set particular values in the header",
  214 + "input_label": [
  215 + {
  216 + "header values" : [1024, "Str (dict)", "header values"]
  217 + }
  218 + ],
  219 + "help": "Set particular values in the header"
  220 + },
  221 + {
  222 + "name": "READOUT_FREQUENCY",
  223 + "label": "Readout frequency in pix/s (~= Hz)",
  224 + "input_label": [
  225 + {
  226 + "readout freq" : [15, "Float", "readout freq pix/s ~= Hz"]
  227 + }
  228 + ],
  229 + "help": "Readout frequency in pix/s (~= Hz)"
  230 + },
  231 + {
  232 + "name": "FILTER [FILTER 1]",
  233 + "label": "Change the wanted filter",
  234 + "input_label": [],
  235 + "help": "Change the wanted filter"
  236 + },
  237 + {
  238 + "name": "FILTER [FILTER 2]",
  239 + "label": "Change the wanted filter",
  240 + "input_label": [],
  241 + "help": "Change the wanted filter"
  242 + },
  243 + {
  244 + "name": "FILTER [FILTER 3]",
  245 + "label": "Change the wanted filter",
  246 + "input_label": [],
  247 + "help": "Change the wanted filter"
  248 + }
  249 + ],
  250 + "get": [
  251 + {
  252 + "name": "STATUS",
  253 + "label": "Get camera status values (dict)",
  254 + "input_label": [],
  255 + "help": "Get camera status values (dict): struct(key, value, type, unit, comment)"
  256 + },
  257 + {
  258 + "name": "SETUP",
  259 + "label": "Get static values for config (dict)",
  260 + "input_label": [],
  261 + "help": "Get static values for config (eg. limit speed)"
  262 + },
  263 + {
  264 + "name": "TIMER",
  265 + "label": "Get the ime before end of pose",
  266 + "input_label": [],
  267 + "help": "Time before end of pose (-1 == idle / finished, 0 == readout (recup-ing img))"
  268 + }
  269 +
  270 + ],
  271 + "do": [
  272 + {
  273 + "name": "COOLER ON",
  274 + "label": "Turn On the cooler with the given temperature",
  275 + "input_label": [
  276 + {
  277 + "temp":[15, "Float", "temperature"]
  278 + }
  279 + ],
  280 + "help": "Turn On the cooler with the given temperature."
  281 + },
  282 + {
  283 + "name": "COOLER OFF",
  284 + "label": "Turn off the cooler",
  285 + "input_label": [],
  286 + "help": "Turn off the cooler."
  287 + },
  288 + {
  289 + "name": "DOME SHUTTER OPEN",
  290 + "label": "Open the dome shutter",
  291 + "input_label": [],
  292 + "help": "Open the dome shutter."
  293 + },
  294 + {
  295 + "name": "DOME SHUTTER CLOSE",
  296 + "label": "Close the dome shutter",
  297 + "input_label": [],
  298 + "help": "Close the dome shutter"
  299 + },
  300 + {
  301 + "name": "DOME SHUTTER SYNCHRO",
  302 + "label": "Dome Shutter Synchro",
  303 + "input_label": [],
  304 + "help": "Dome Shutter Synchro"
  305 + },
  306 + {
  307 + "name": "START",
  308 + "label": "Start Pose",
  309 + "input_label": [],
  310 + "help": "Start Pose"
  311 + },
  312 + {
  313 + "name": "ABORT",
  314 + "label": "Stop Pose",
  315 + "input_label": [],
  316 + "help": "Stop Pose"
  317 + },
  318 + {
  319 + "name": "STOP",
  320 + "label": "End image then stop pose",
  321 + "input_label": [],
  322 + "help": "End image then stop pose"
  323 + }
  324 +
  325 + ]
  326 +
  327 +
167 328 }
168 329  
169 330 }
... ...
src/dashboard/templates/dashboard/observation_status.html
... ... @@ -96,7 +96,7 @@
96 96 background-color: black;
97 97 }
98 98  
99   - #send_command_tel
  99 + .send_command_button
100 100 {
101 101 margin: auto;
102 102 display: block;
... ... @@ -113,7 +113,7 @@
113 113 </ul>
114 114 {% if not config.global_mode %}
115 115 <form action={% url "send_command_to_telescope" %}>
116   - <input id="send_command_tel" type="submit" value="Send Command" />
  116 + <input class="send_command_button" id="send_command_tel" type="submit" value="Send Command" />
117 117 </form>
118 118 {% endif %}
119 119  
... ... @@ -133,6 +133,11 @@
133 133 {% for log in ddrago_r_logs %}
134 134 <li>{{log.created}} : {{log.message}}</li> {% endfor %}
135 135 </ul>
  136 + {% if not config.global_mode %}
  137 + <form action={% url "send_command_to_cameraVIS_1" %}>
  138 + <input class="send_command_button" id="send_command_cameraVIS_1" type="submit" value="Send Command" />
  139 + </form>
  140 + {% endif %}
136 141 </div>
137 142 <div class="element" id=DDRAGOBLUE>
138 143 <h2><button id="ddrago_b_button">DDRAGO BLUE</button></h2>
... ... @@ -141,6 +146,11 @@
141 146 {% for log in ddrago_b_logs %}
142 147 <li>{{log.created}} : {{log.message}}</li> {% endfor %}
143 148 </ul>
  149 + {% if not config.global_mode %}
  150 + <form action={% url "send_command_to_cameraVIS_2" %}>
  151 + <input class="send_command_button" id="send_command_cameraVIS_2" type="submit" value="Send Command" />
  152 + </form>
  153 + {% endif %}
144 154 </div>
145 155 </div>
146 156 </div>
... ...
src/dashboard/templates/dashboard/send_command_cameraVIS_1.html 0 โ†’ 100644
... ... @@ -0,0 +1,124 @@
  1 +{% extends "base.html" %}
  2 +{% load staticfiles%}
  3 +
  4 +{% block title %}
  5 + Send Command to DDRAGO 1
  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_cameraVIS_1" %}>
  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_cameraVIS_1_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=ddrago>
  94 + <h2>DDRAGO</h2>
  95 + <ul class="log" id="ddrago_r_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_cameraVIS_1.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/templates/dashboard/send_command_cameraVIS_2.html 0 โ†’ 100644
... ... @@ -0,0 +1,124 @@
  1 +{% extends "base.html" %}
  2 +{% load staticfiles%}
  3 +
  4 +{% block title %}
  5 + Send Command to DDRAGO 2
  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_cameraVIS_2" %}>
  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_cameraVIS_2_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=ddrago>
  94 + <h2>DDRAGO</h2>
  95 + <ul class="log" id="ddrago_b_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_cameraVIS_2.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,12 @@ 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_cameraVIS_1/submit_expert', views.submit_command_to_cameraVIS_1_expert, name='submit_command_to_cameraVIS_1_expert'),
  28 + path('observation_status/send_command_to_cameraVIS_1/submit', views.submit_command_to_cameraVIS_1, name='submit_command_to_cameraVIS_1'),
  29 + path('observation_status/send_command_to_cameraVIS_1', views.send_command_to_cameraVIS_1, name='send_command_to_cameraVIS_1'),
  30 + path('observation_status/send_command_to_cameraVIS_2/submit_expert', views.submit_command_to_cameraVIS_2_expert, name='submit_command_to_cameraVIS_2_expert'),
  31 + path('observation_status/send_command_to_cameraVIS_2/submit', views.submit_command_to_cameraVIS_2, name='submit_command_to_cameraVIS_2'),
  32 + path('observation_status/send_command_to_cameraVIS_2', views.send_command_to_cameraVIS_2, name='send_command_to_cameraVIS_2'),
27 33 path('users/<int:pk>', views.user_detail_view, name='user-detail'),
28 34 path('users/<int:pk>/edit', views.user_detail_edit, name='user-edit'),
29 35 path('user-status/<int:pk>', views.change_activate, name='change_activate'),
... ...
src/dashboard/views.py
... ... @@ -18,6 +18,7 @@ import json
18 18 from random import randint
19 19 from devices.Telescope import TelescopeController
20 20 from devices.TelescopeRemoteControlDefault import TelescopeRemoteControlDefault
  21 +from devices.CameraVISRemoteControlDefault import CameraVISRemoteControlDefault
21 22 from django.core.mail import send_mail
22 23 import time
23 24 import utils.celme as celme
... ... @@ -286,6 +287,104 @@ def change_activate(request, pk):
286 287 except PyrosUser.DoesNotExist:
287 288 return redirect('user-detail', pk=pk)
288 289  
  290 +
  291 +
  292 +@login_required
  293 +@level_required(3)
  294 +def send_command_to_cameraVIS_1(request):
  295 + data = ""
  296 + with open('../simulators/config/grammar.json') as f:
  297 + data = json.load(f, object_pairs_hook=OrderedDict)
  298 + json_str = json.dumps(data)
  299 + return render(request, "dashboard/send_command_cameraVIS_1.html", locals())
  300 +
  301 +@login_required
  302 +@level_required(3)
  303 +def submit_command_to_cameraVIS_1(request):
  304 + if request.method == 'POST':
  305 + commands = [request.POST.get("first_command"), request.POST.get("first_param")]
  306 + try: #TODO faire un truc plus joli pour gรฉrer les params queqlue soit leur nombre
  307 + input_0 = request.POST.get("input_number_0")
  308 + input_1 = request.POST.get("input_number_1")
  309 + input_2 = request.POST.get("input_number_2")
  310 + if input_0:
  311 + commands.append(input_0)
  312 + if input_1:
  313 + commands.append(input_1)
  314 + if input_2:
  315 + commands.append(input_2)
  316 + except Exception:
  317 + pass
  318 + response = CameraVISRemoteControlDefault(commands, expert_mode=False, chosen_camera="ddrago_r").exec_command()
  319 + #TODO passer en JS pour send les rรฉponses en AJAX
  320 + return redirect('send_command_to_cameraVIS_1')
  321 +
  322 +@login_required
  323 +@level_required(3)
  324 +def submit_command_to_cameraVIS_1_expert(request):
  325 + #import os
  326 + if request.method == 'POST':
  327 + param = request.POST.get("commande_expert")
  328 + if param:
  329 + response = CameraVISRemoteControlDefault(param, expert_mode=True, chosen_camera="ddrago_r").exec_command()
  330 + #os.system("echo \"status :" + response + "\" >> /home/portos/IRAP/pyros/src/status")
  331 + return HttpResponse(json.dumps({'message': "Command send OK", 'response': response}))
  332 + return HttpResponse(json.dumps({'message': "Missing command data"}))
  333 + return redirect('submit_command_to_telescope')
  334 +
  335 +
  336 +
  337 +
  338 +
  339 +
  340 +
  341 +
  342 +@login_required
  343 +@level_required(3)
  344 +def send_command_to_cameraVIS_2(request):
  345 + data = ""
  346 + with open('../simulators/config/grammar.json') as f:
  347 + data = json.load(f, object_pairs_hook=OrderedDict)
  348 + json_str = json.dumps(data)
  349 + return render(request, "dashboard/send_command_cameraVIS_2.html", locals())
  350 +
  351 +@login_required
  352 +@level_required(3)
  353 +def submit_command_to_cameraVIS_2(request):
  354 + if request.method == 'POST':
  355 + commands = [request.POST.get("first_command"), request.POST.get("first_param")]
  356 + try: #TODO faire un truc plus joli pour gรฉrer les params queqlue soit leur nombre
  357 + input_0 = request.POST.get("input_number_0")
  358 + input_1 = request.POST.get("input_number_1")
  359 + input_2 = request.POST.get("input_number_2")
  360 + if input_0:
  361 + commands.append(input_0)
  362 + if input_1:
  363 + commands.append(input_1)
  364 + if input_2:
  365 + commands.append(input_2)
  366 + except Exception:
  367 + pass
  368 + response = CameraVISRemoteControlDefault(commands, expert_mode=False, chosen_camera="ddrago_b").exec_command()
  369 + #TODO passer en JS pour send les rรฉponses en AJAX
  370 + return redirect('send_command_to_cameraVIS_2')
  371 +
  372 +@login_required
  373 +@level_required(3)
  374 +def submit_command_to_cameraVIS_2_expert(request):
  375 + #import os
  376 + if request.method == 'POST':
  377 + param = request.POST.get("commande_expert")
  378 + if param:
  379 + response = CameraVISRemoteControlDefault(param, expert_mode=True, chosen_camera="ddrago_b").exec_command()
  380 + #os.system("echo \"status :" + response + "\" >> /home/portos/IRAP/pyros/src/status")
  381 + return HttpResponse(json.dumps({'message': "Command send OK", 'response': response}))
  382 + return HttpResponse(json.dumps({'message': "Missing command data"}))
  383 + return redirect('submit_command_to_cameraVIS_2')
  384 +
  385 +
  386 +
  387 +
289 388 @login_required
290 389 @level_required(3)
291 390 def send_command_to_telescope(request):
... ...
src/devices/CameraRemoteControlAbstract.py 0 โ†’ 100644
... ... @@ -0,0 +1,21 @@
  1 +'''
  2 + Class managing the input from the remote commands sent by the dashboard
  3 + the command is parsed and sent to the Camera via an instance of CameraController
  4 + defined in the implementation of the class
  5 +'''
  6 +
  7 +class CameraRemoteControlAbstract():
  8 + _command = []
  9 + _command_matcher_set = {}
  10 + _command_matcher_get = {}
  11 + _command_matcher_do = {}
  12 + _current_matcher = None
  13 + _camera = None
  14 +
  15 + def __init__(self, command, expert_mode):
  16 + self._command = command
  17 + if expert_mode:
  18 + self._command = str(command).split()
  19 +
  20 + def exec_command(self):
  21 + raise NotImplementedError("You must implement %s method" % type(self).__name__)
0 22 \ No newline at end of file
... ...
src/devices/CameraVIS.py
... ... @@ -34,3 +34,7 @@ class VISCameraController(DeviceController):
34 34 def open_shutter(self):
35 35 self.do("OPEN SHUTTER")
36 36 return 0
  37 +
  38 + def send_command(self, command):
  39 + self.sendMessage(command)
  40 + return self.blockAndReadMessage()
... ...
src/devices/CameraVISRemoteControlDefault.py 0 โ†’ 100644
... ... @@ -0,0 +1,76 @@
  1 +from devices.CameraRemoteControlAbstract import CameraRemoteControlAbstract
  2 +from devices import CameraVIS
  3 +
  4 +class CameraVISRemoteControlDefault(CameraRemoteControlAbstract):
  5 + def __init__(self, command, expert_mode, chosen_camera):
  6 + super().__init__(command, expert_mode)
  7 + if chosen_camera == "ddrago_r":
  8 + self._camera = CameraVIS.VISCameraController()
  9 + else: #TODO: Pour l'instant pas de diffรฉrence DRRAGO RED et BLUE a vor plus tard
  10 + self._camera = CameraVIS.VISCameraController()
  11 +
  12 + self._command_matcher_set = {
  13 + "WINDOW": self.set,
  14 + "READMODE [MODE 1]": self.set,
  15 + "READMODE [MODE 2]": self.set,
  16 + "READMODE [MODE 3]": self.set,
  17 + "FILENAME": self.set,
  18 + "HEADER": self.set,
  19 + "READOUT_FREQUENCY": self.set,
  20 + "FILTER [FILTER 1]": self.set,
  21 + "FILTER [FILTER 2]": self.set,
  22 + "FILTER [FILTER 3]": self.set
  23 + }
  24 + self._command_matcher_get = {
  25 + "STATUS": self.get,
  26 + "SETUP": self.get,
  27 + "TIMER": self.get
  28 + }
  29 + self._command_matcher_do = {
  30 + "COOLER ON": self.do,
  31 + "COOLER OFF": self.do,
  32 + "DOME SHUTTER OPEN": self.do,
  33 + "DOME SHUTTER CLOSE": self.do,
  34 + "DOME SHUTTER SYNCHRO": self.do,
  35 + "START": self.do,
  36 + "ABORT": self.do,
  37 + "STOP": self.do
  38 + }
  39 +
  40 +
  41 +
  42 +
  43 + def exec_command(self):
  44 +
  45 + #os.system("echo \"status :" + str(self._command) + "\" >> /home/portos/IRAP/pyros/src/commande_recu")
  46 + if self._command[0] == "GET":
  47 + self._current_matcher = self._command_matcher_get
  48 + elif self._command[0] == "SET":
  49 + self._current_matcher = self._command_matcher_set
  50 + elif self._command[0] == "DO":
  51 + self._current_matcher = self._command_matcher_do
  52 + else: return "KO: Unknown command"
  53 + if self._command[1] in self._current_matcher:
  54 + return self._current_matcher[self._command[1]]()
  55 + else:
  56 + return "KO: Unknown command"
  57 +
  58 +
  59 + '''
  60 + Locals methods for the generic grammar
  61 + '''
  62 +
  63 + def do(self):
  64 + definitive_command = "DO " + self._command[1] + ' ' + ' '.join(self._command[2:])
  65 + response = self._camera.send_command(definitive_command)
  66 + return response
  67 +
  68 + def set(self):
  69 + definitive_command = "SET " + self._command[1] + ' ' + ' '.join(self._command[2:])
  70 + response = self._camera.send_command(definitive_command)
  71 + return response
  72 +
  73 + def get(self):
  74 + definitive_command = "GET " + self._command[1] #+ ' ' + ' '.join(self._command[2:])
  75 + response = self._camera.send_command(definitive_command)
  76 + return response
0 77 \ No newline at end of file
... ...
src/devices/Device.py
... ... @@ -132,7 +132,7 @@ class DeviceController():
132 132 self.sock.setblocking(flag)
133 133 return (0)
134 134  
135   - # TODO maybe read more than 1024 bytes ?????
  135 + # TODO: maybe read more than 1024 bytes ?????
136 136 def readMessage(self) -> str:
137 137 message = str(self.readBytes(1024))
138 138 #os.system("echo lol >> /home/portos/IRAP/pyros/src/POURKOICAMARCHPA")
... ...
src/devices/TelescopeRemoteControlAbstract.py
... ... @@ -14,6 +14,7 @@ class TelescopeRemoteControlAbstract():
14 14 _command_matcher_set = {}
15 15 _command_matcher_get = {}
16 16 _command_matcher_do = {}
  17 + _current_matcher = None
17 18 _telescope = None
18 19  
19 20 def __init__(self, command, expert_mode):
... ... @@ -28,27 +29,4 @@ class TelescopeRemoteControlAbstract():
28 29 # response = self._command_matcher[self._command[0]]()
29 30 # else:
30 31 # return "KO: Unknown command"
31   - # return response
32   -
33   - def get(self):
34   - # param_a = {"POSITION", "STATUS", "SETUP"}
35   - # if self._command[1] in param_a:
36   - # response = self._telescope.get(self._command[1])
37   - # return response
38   - # return "KO: Unknown command"
39   - raise NotImplementedError("You must implement %s method" % type(self).__name__)
40   -
41   - def set(self):
42   - # response = self._telescope.set(' '.join(self._command[1:]))
43   - # return "OK Command sent"
44   - raise NotImplementedError("You must implement %s method" % type(self).__name__)
45   -
46   - def do(self):
47   - #response = self._telescope.do(' '.join(self._command[1:]))
48   - #return "OK command sent"
49   - raise NotImplementedError("You must implement %s method" % type(self).__name__)
50   -
51   -
52   - def expert_command(self):
53   - raise NotImplementedError("You must implement %s method" % type(self).__name__)
54   - #return True
  32 + # return response
55 33 \ No newline at end of file
... ...
src/devices/TelescopeRemoteControlDefault.py
... ... @@ -5,60 +5,69 @@ from devices.Telescope import TelescopeController
5 5 import os
6 6  
7 7 class TelescopeRemoteControlDefault(TelescopeRemoteControlAbstract):
8   - _command_matcher_set = {
9   - "COORD_RADEC": "COORD_RADEC",
10   - "COORD_HADEC": "COORD_HADEC",
11   - "COORD_ALTAZ": "COORD_ALTAZ",
12   - "DRIFT_HADEC": "DRIFT_HADEC",
13   - "ROTATOR_ANGLE": "ROTATOR_ANGLE"
14   - }
15   - _command_matcher_get = {
16   - "INFORMATIONS": "INFORMATIONS",
17   - "COORD_RADEC": "COORD_RADEC",
18   - "COORD_HADEC": "COORD_HADEC",
19   - "COORD_ALTAZ": "COORD_ALTAZ"
20   - }
21   - _command_matcher_do = {
22   - "EVAL": "EVAL",
23   - "HOMING": "HOMING",
24   - "ZENITH": "ZENITH",
25   - "GOTO": "GOTO",
26   - "STOP": "STOP",
27   - "DRIFT_ON": "DRIFT_ON",
28   - "DRIFT_OFF": "DRIFT_OFF",
29   - "ROTATOR_GOTO": "ROTATOR_GOTO"
30   - }
  8 + #
  9 + ## Pour les classes a venir qui implรฉmenteront des grammaires outils les commands matchers pointeront sur des mรฉthodes fournies par AK
  10 + ## et le exec_command appellera la mรฉthode correspondante
  11 + #
  12 +
31 13 def __init__(self, command, expert_mode):
32 14 super().__init__(command, expert_mode)
  15 + self._command_matcher_set = {
  16 + "COORD_RADEC": self.set,
  17 + "COORD_HADEC": self.set,
  18 + "COORD_ALTAZ": self.set,
  19 + "DRIFT_HADEC": self.set,
  20 + "ROTATOR_ANGLE": self.set
  21 + }
  22 + self._command_matcher_get = {
  23 + "INFORMATIONS": self.get,
  24 + "COORD_RADEC": self.get,
  25 + "COORD_HADEC": self.get,
  26 + "COORD_ALTAZ": self.get
  27 + }
  28 + self._command_matcher_do = {
  29 + "EVAL": self.do,
  30 + "HOMING": self.do,
  31 + "ZENITH": self.do,
  32 + "GOTO": self.do,
  33 + "STOP": self.do,
  34 + "DRIFT_ON": self.do,
  35 + "DRIFT_OFF": self.do,
  36 + "ROTATOR_GOTO": self.do
  37 + }
33 38  
34 39 def exec_command(self):
35 40  
36   - os.system("echo \"status :" + str(self._command) + "\" >> /home/portos/IRAP/pyros/src/commande_recu")
37   - if self._command[0] == "GET": return self.get()
38   - elif self._command[0] == "SET": return self.set()
39   - elif self._command[0] == "DO": return self.do()
  41 + #os.system("echo \"status :" + str(self._command) + "\" >> /home/portos/IRAP/pyros/src/commande_recu")
  42 + if self._command[0] == "GET":
  43 + self._current_matcher = self._command_matcher_get
  44 + elif self._command[0] == "SET":
  45 + self._current_matcher = self._command_matcher_set
  46 + elif self._command[0] == "DO":
  47 + self._current_matcher = self._command_matcher_do
40 48 else: return "KO: Unknown command"
  49 + if self._command[1] in self._current_matcher:
  50 + return self._current_matcher[self._command[1]]()
  51 + else:
  52 + return "KO: Unknown command"
  53 +
  54 +
  55 + '''
  56 + Locals methods for the generic grammar
  57 + '''
41 58  
42 59 def do(self):
43   - if self._command[1] in self._command_matcher_do:
44   - definitive_command = "DO " + self._command_matcher_do[self._command[1]] + ' ' + ' '.join(self._command[2:])
45   - response = self._telescope.send_command(definitive_command)
46   - else:
47   - response = "KO: Unknown command"
  60 + definitive_command = "DO " + self._command[1] + ' ' + ' '.join(self._command[2:])
  61 + response = self._telescope.send_command(definitive_command)
48 62 return response
49 63  
50 64 def set(self):
51   - if self._command[1] in self._command_matcher_set:
52   - definitive_command = "SET " + self._command_matcher_set[self._command[1]] + ' ' + ' '.join(self._command[2:])
53   - response = self._telescope.send_command(definitive_command)
54   - else:
55   - response = "KO: Unknown command"
  65 + definitive_command = "SET " + self._command[1] + ' ' + ' '.join(self._command[2:])
  66 + response = self._telescope.send_command(definitive_command)
56 67 return response
57 68  
58 69 def get(self):
59   - if self._command[1] in self._command_matcher_get:
60   - definitive_command = "GET " + self._command_matcher_get[self._command[1]] #+ " " + self._command[2:]
61   - response = self._telescope.send_command(definitive_command)
62   - else:
63   - response = "KO: Unknown command"
64   - return response
65 70 \ No newline at end of file
  71 + definitive_command = "GET " + self._command[1] #+ ' ' + ' '.join(self._command[2:])
  72 + response = self._telescope.send_command(definitive_command)
  73 + return response
  74 +
... ...
src/misc/static/js/command_control_backup.js 0 โ†’ 100644
... ... @@ -0,0 +1,231 @@
  1 +var LOGS_REFRESH_FREQUENCE = 2000; //in milliseconds
  2 +var expert_mode = false;
  3 +
  4 +jQuery(document).ready(function(){
  5 +
  6 + var t = data["Telescope"]["set"][0]["input_label"][0];
  7 +
  8 + //console.log(t);
  9 + for (var i in t)
  10 + {
  11 + console.log(i);
  12 + //console.log(t[i][2]);
  13 + }
  14 +
  15 + function command_set()
  16 + {
  17 + var form = $("#command_form");
  18 + var arr = [
  19 + {val : "COORDS_FRAME", text: 'COORDS_FRAME'},
  20 + {val : 'FOCUS', text: 'FOCUS'},
  21 + {val : 'ROTATOR', text: 'ROTATOR'},
  22 + {val : 'MOVE_MODE', text: 'MOVE_MODE'}
  23 + ];
  24 +
  25 + var sel = $('<select>', {name: "param1", id:"param1"}).appendTo('#command_form');
  26 + $(arr).each(function() {
  27 + sel.append($("<option>").attr('value',this.val).text(this.text));
  28 + sel.css("font-size", "25px");
  29 + });
  30 +
  31 + var arr = [
  32 + {val: "Hadec", text: 'Hadec'},
  33 + {val: 'Radec', text: 'Radec'},
  34 + {val: 'Altaz', text: 'Altaz'}
  35 + ];
  36 + var type = "<select>";
  37 +
  38 + var sel = $(type, {id:"param2", name:"param2"}).appendTo('#command_form');
  39 + $(arr).each(function() {
  40 + sel.append($("<option>").attr('value',this.val).text(this.text));
  41 + sel.css("font-size", "25px");
  42 + });
  43 +
  44 + $("#param1").change(function () {
  45 + var length = form.children().length;
  46 + for (var i = 4; i < length; i++) {
  47 + $("#command_form").children().last().remove();
  48 + }
  49 +
  50 + if ($("#param1").find(":selected").text() === "ROTATOR") {
  51 + var arr = [
  52 + {val: "NONE", text: 'NONE'},
  53 + {val: 'SYNCHRO', text: 'SYNCHRO'},
  54 + {val: 'TRACKING', text: 'TRACKING'}
  55 + ];
  56 + }
  57 +
  58 + else if ($("#param1").find(":selected").text() === "MOVE_MODE") {
  59 + var arr = [
  60 + {val: "Goto", text: 'Goto'},
  61 + {val: 'Track', text: 'Track'},
  62 + {val: 'GotoTrack', text: 'GotoTrack'}
  63 + ];
  64 + }
  65 + else if ($("#param1").find(":selected").text() === "COORDS_FRAME") {
  66 + var arr = [
  67 + {val: "Hadec", text: 'Hadec'},
  68 + {val: 'Radec', text: 'Radec'},
  69 + {val: 'Altaz', text: 'Altaz'}
  70 + ];
  71 + }
  72 +
  73 + var type = '<select name=param2">';
  74 + if ($("#param1").find(":selected").text() === "FOCUS")
  75 + type = "<input name='param2' type='number' step='any' />";
  76 +
  77 + var sel = $(type, {id:"param2"}).appendTo('#command_form');
  78 + $(arr).each(function() {
  79 + sel.append($("<option>").attr('value',this.val).text(this.text));
  80 + sel.css("font-size", "25px");
  81 + });
  82 + $('<br><br>').appendTo("#command_form");
  83 + $('<input>', {id:"submit_button", type:"submit", value:"SEND"}).appendTo('#command_form');
  84 +
  85 + });
  86 + }
  87 +
  88 +
  89 + function command_get()
  90 + {
  91 + var arr = [
  92 + {val: "POSITION", text: 'POSITION'},
  93 + {val: 'STATUS', text: 'STATUS'},
  94 + {val: 'SETUP', text: 'SETUP'}
  95 + ];
  96 + var sel = $('<select>', {id:"param1", name:"param1"}).appendTo('#command_form');
  97 + $(arr).each(function() {
  98 + sel.append($("<option>").attr('value',this.val).text(this.text));
  99 + sel.css("font-size", "25px");
  100 + });
  101 + }
  102 +
  103 + function command_do()
  104 + {
  105 + var arr = [
  106 + {val: "START", text: 'START'},
  107 + {val: 'ABORT', text: 'ABORT'},
  108 + {val: 'HOMING', text: 'HOMING'},
  109 + {val: 'DOORS', text: 'DOORS'},
  110 + {val: 'GOTO', text: 'GOTO'},
  111 + {val: 'STOP', text: 'STOP'},
  112 + {val: 'OPEN DOME SHUTTER', text: 'OPEN DOME SHUTTER'},
  113 + {val: 'CLOSE DOME SHUTTER', text: 'CLOSE DOME SHUTTER'}
  114 + ];
  115 +
  116 + var sel = $('<select>', {id:"param1", name:"param1"}).appendTo('#command_form');
  117 + $(arr).each(function() {
  118 + sel.append($("<option>").attr('value',this.val).text(this.text));
  119 + sel.css("font-size", "25px");
  120 + });
  121 +
  122 + $("#param1").change(function () {
  123 + var length = $("#command_form").children().length;
  124 + for (var i = 4; i < length; i++) {
  125 + $("#command_form").children().last().remove();
  126 + }
  127 + if ($("#param1").find(":selected").text() === "DOORS")
  128 + {
  129 + var selected = $('<select>', {id:"param2", name:"param2"}).appendTo('#command_form');
  130 + selected.append($("<option>").attr('value','OPEN').text('OPEN'));
  131 + selected.append($("<option>").attr('value','CLOSE').text('CLOSE'));
  132 + selected.css("font-size", "25px");
  133 + }
  134 + if ($("#param1").find(":selected").text() === "GOTO")
  135 + {
  136 + var selected = $('<input size="10">', {id:"param2", name:"param2", placeholder:"Coords"}).appendTo('#command_form');
  137 + selected.css("font-size", "25px");
  138 + }
  139 +
  140 +
  141 + $('<br><br>').appendTo("#command_form");
  142 + $('<input>', {id:"submit_button", type:"submit", value:"SEND"}).appendTo('#command_form');
  143 +
  144 + });
  145 +
  146 + }
  147 +
  148 + $("#commande").change(function() {
  149 +
  150 + var form = $("#command_form");
  151 + var length = form.children().length;
  152 +
  153 + for (var i = 3; i < length; i++) {
  154 + form.children().last().remove();
  155 + }
  156 +
  157 + var selected_command = $("#commande").find(":selected").val();
  158 + if ( selected_command === "SET")
  159 + command_set();
  160 + else if (selected_command === "GET")
  161 + command_get();
  162 + else if (selected_command === "DO")
  163 + command_do();
  164 + $('<br><br>').appendTo("#command_form");
  165 + $('<input>', {id:"submit_button", type:"submit", value:"SEND"}).appendTo('#command_form');
  166 +
  167 + });
  168 + //$("#command_form").append(param1);
  169 +
  170 +$("#expert_mode").click(function(){
  171 + if (!expert_mode)
  172 + {
  173 + expert_mode = true;
  174 + $("#command_form_expert").append("<input id='input_command_expert' type='text' name='commande_expert'>");
  175 + $('<input>', {id:"submit_button_expert", type:"submit", value:"SEND"}).appendTo('#command_form_expert');
  176 + }
  177 + else {
  178 + $("#input_command_expert").remove();
  179 + $("#submit_button_expert").remove();
  180 + expert_mode = false;
  181 + }
  182 + //$("#command_form").remove();
  183 +});
  184 +
  185 +$("#command_form_expert").submit(function(event){
  186 +
  187 + event.preventDefault();
  188 + $.post('/dashboard/observation_status/send_command_to_telescope/submit_expert', $(this).serialize(), function(data){
  189 + var obj = JSON.parse(data);
  190 + console.log(obj.message);
  191 + console.log(obj.response);
  192 + if (obj.response === "KO: Unknown command")
  193 + alert("Unknown command");
  194 + })
  195 + .fail(function() {
  196 + alert( "An error occured" );
  197 + })
  198 + });
  199 +
  200 +
  201 +
  202 +
  203 + interval_telescope = setInterval(function() {ajax_request("telescope", "telescope_list");}, LOGS_REFRESH_FREQUENCE);
  204 +
  205 + function ajax_request(){
  206 + var telescope_url ="/devices/update_telescope_logs";
  207 + $.ajax({
  208 + url: telescope_url,
  209 + type: 'get',
  210 + dataType: 'text',
  211 + success: function(data)
  212 + {
  213 + var obj = JSON.parse(data);
  214 + if (obj) {
  215 + var listDiv = document.getElementById('telescope_logs');
  216 + listDiv.innerHTML = '';
  217 + for (var tmp in obj) {
  218 + var li = document.createElement('li');
  219 + li.innerHTML = obj[tmp]['fields']['created'] + ": " + obj[tmp]['fields']['message']; // Use innerHTML to set the text
  220 + listDiv.appendChild(li);
  221 + }
  222 + }
  223 + },
  224 + error: function()
  225 + {
  226 + console.log('Ajax error: GET request failed\n');
  227 + }
  228 +
  229 + });
  230 + }
  231 +});
... ...
src/misc/static/js/command_control_cameraVIS_1.js 0 โ†’ 100644
... ... @@ -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["CameraVIS"][selected_command.toLowerCase()];
  125 + init_first_param(data["CameraVIS"][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_cameraVIS_1/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_ddrago_r_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('ddrago_r_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 +});
... ...
src/misc/static/js/command_control_cameraVIS_2.js 0 โ†’ 100644
... ... @@ -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["CameraVIS"][selected_command.toLowerCase()];
  125 + init_first_param(data["CameraVIS"][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_cameraVIS_2/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_ddrago_b_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('ddrago_b_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 +});
... ...