Commit 76dfa189fa4a53d9911859922f118cfaef100bc7
1 parent
94ac51a7
Exists in
dev
Adding devices log on dashboard and several changes on web
Showing
33 changed files
with
807 additions
and
29 deletions
Show diff stats
simulators/camera/cameraVISSimulator.py
... | ... | @@ -10,6 +10,7 @@ sys.path.append(os.path.normpath(os.path.join(SCRIPT_DIR, PACKAGE_PARENT))) |
10 | 10 | from utils.DeviceSim import DeviceSim |
11 | 11 | from utils.StatusManager import StatusManager |
12 | 12 | |
13 | + | |
13 | 14 | #(EP) class CameraVISSimulator(Device, StatusManager): |
14 | 15 | class CameraVISSimulator(DeviceSim, StatusManager): |
15 | 16 | status = {"status" : "VALID"} |
... | ... | @@ -21,7 +22,7 @@ class CameraVISSimulator(DeviceSim, StatusManager): |
21 | 22 | super().__init__(argv) |
22 | 23 | self.setDevice("CameraVIS") |
23 | 24 | self.setStatusManager("cameraVISSimulator", argv) |
24 | - | |
25 | + self.cameraVISPrint("COUCOU CECI EST UN TEST") | |
25 | 26 | def cameraVISPrint(self, string: str): |
26 | 27 | if DEBUG_FILE: |
27 | 28 | print("cameraVISSimulator : " + string) | ... | ... |
simulators/utils/DeviceSim.py
... | ... | @@ -4,7 +4,6 @@ import select |
4 | 4 | import abc |
5 | 5 | import sys |
6 | 6 | from . import settings |
7 | - | |
8 | 7 | DEBUG_FILE = True |
9 | 8 | |
10 | 9 | ''' |
... | ... | @@ -70,9 +69,10 @@ class DeviceSim(object): |
70 | 69 | print(str(e)) |
71 | 70 | print(self.name, "No connection established") |
72 | 71 | self.log(self.name, "No connection established") |
72 | + | |
73 | 73 | return False |
74 | 74 | self.connections.append({"connection": connection, "address": address}) |
75 | - | |
75 | + self.log(self.name, "Connection successfully established") | |
76 | 76 | return True |
77 | 77 | |
78 | 78 | def close(self, connection_address): |
... | ... | @@ -93,6 +93,7 @@ class DeviceSim(object): |
93 | 93 | co["connection"].send(bytes(message, "UTF-8")) |
94 | 94 | #self.forceLog(self.name, "Message sent [" + message + "] to " + str(co["address"])) |
95 | 95 | self.forceLog(self.name, "Message sent to " + str(co["address"]) +" : [" + message + "]") |
96 | + self.log(self.name, "Message sent to " + str(co["address"]) +" : [" + message + "]") | |
96 | 97 | except Exception as e: |
97 | 98 | if (settings.DEBUG): |
98 | 99 | print(self.name, "Could not send message on socket "+ str(co["address"]) +" : " + message + " -> " + str(e)) |
... | ... | @@ -128,6 +129,7 @@ class DeviceSim(object): |
128 | 129 | #(EP) return ("DISCONNECTED") |
129 | 130 | raise Exception("DISCONNECTED") |
130 | 131 | self.forceLog(self.name, "Message received on " + str(co["address"]) +" : [" + ret + "]") |
132 | + self.log(self.name, "Message received on " + str(co["address"]) + " : [" + ret + "]") | |
131 | 133 | except Exception as e: |
132 | 134 | if (settings.DEBUG): |
133 | 135 | print(self.name, "Socket not readable : " + str(e)) |
... | ... | @@ -172,6 +174,7 @@ class DeviceSim(object): |
172 | 174 | return (0) |
173 | 175 | |
174 | 176 | def listen(self): |
177 | + | |
175 | 178 | if (self.ip is None or self.port is None): |
176 | 179 | self.log(self.name, "Ip or Port not initialized") |
177 | 180 | # (EP) It's a serious bug, so raise exception !!! |
... | ... | @@ -179,6 +182,7 @@ class DeviceSim(object): |
179 | 182 | raise Exception(self.name +" has no ip or port") |
180 | 183 | |
181 | 184 | try: |
185 | + | |
182 | 186 | self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
183 | 187 | self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) |
184 | 188 | self.sock.settimeout(1) | ... | ... |
src/dashboard/templates/dashboard/index.html
... | ... | @@ -114,7 +114,7 @@ |
114 | 114 | </li> |
115 | 115 | <li> |
116 | 116 | <div class="all-box all-img-telescope"> |
117 | - <a href="#"> | |
117 | + <a href="{% url "observation_status" %}"> | |
118 | 118 | <div class="all-info"> |
119 | 119 | <h3>Tele & Inst</h3> |
120 | 120 | <img src="{% static "media/telescope.png" %}" alt="html5" height="200" width="200" /> | ... | ... |
src/dashboard/templates/dashboard/observation_status.html
0 โ 100644
... | ... | @@ -0,0 +1,238 @@ |
1 | + | |
2 | + | |
3 | +{% extends "base.html" %} | |
4 | +{% load staticfiles%} | |
5 | + | |
6 | +{% block title %} | |
7 | + Observation System Status : | |
8 | +{% endblock %} | |
9 | + | |
10 | +{% block content %} | |
11 | +<html> | |
12 | + <head> | |
13 | + <meta charset="utf-8" /> | |
14 | + <link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet"> | |
15 | + </head> | |
16 | + | |
17 | + <body> | |
18 | + <!--/*function retrieve_logs() { | |
19 | + $('#logs').load(""); | |
20 | + } | |
21 | + | |
22 | + | |
23 | + $(document).ready(function() { | |
24 | + retrieve_logs(); | |
25 | + setInterval(retrieve_logs, 1000); | |
26 | + });*/ | |
27 | + --> | |
28 | + <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> | |
29 | + <script> | |
30 | + function retrieve_env() { | |
31 | + $('#env').load("{% url 'retrieve_env' %}"); | |
32 | + } | |
33 | + | |
34 | + | |
35 | + $(document).ready(function() { | |
36 | + retrieve_env(); | |
37 | + setInterval(retrieve_env, 5000); | |
38 | + }); | |
39 | + </script> | |
40 | + {% block environnment %} | |
41 | + <div id="env" class="container-fluid"> | |
42 | + | |
43 | + </div> | |
44 | + {% endblock %} | |
45 | + <div id="logs" class="container-fluid"> | |
46 | + <style type="text/css"> | |
47 | + #title | |
48 | + { | |
49 | + font-size: 4em; | |
50 | + font-family: 'Montserra', sans-serif; | |
51 | + | |
52 | + color: black; | |
53 | + } | |
54 | + | |
55 | + body | |
56 | + { | |
57 | + background-color: rgb(250,250,250); | |
58 | + } | |
59 | + </style> | |
60 | + | |
61 | + <div id="conteneur"> | |
62 | + <style type="text/css"> | |
63 | + #conteneur | |
64 | + { | |
65 | + display : flex; | |
66 | + flex-wrap: wrap; | |
67 | + justify-content: space-around; | |
68 | + align-items: center; | |
69 | + padding-top: 50px; | |
70 | + } | |
71 | + | |
72 | + .element | |
73 | + { | |
74 | + margin: auto; | |
75 | + list-style-image: none; | |
76 | + font-family: 'Montserra', sans-serif; | |
77 | + | |
78 | + } | |
79 | + | |
80 | + .element h2 | |
81 | + { | |
82 | + text-align: center; | |
83 | + font-weight: normal; | |
84 | + } | |
85 | + .log | |
86 | + { | |
87 | + display: none; | |
88 | + font-size: 1.13em; | |
89 | + list-style-image: none; | |
90 | + list-style-type: none; | |
91 | + color: green; | |
92 | + font-weight: bold; | |
93 | + font-family: "Arial"; | |
94 | + height: 500px; | |
95 | + width: 700px; | |
96 | + overflow: scroll; | |
97 | + background-color: black; | |
98 | + } | |
99 | + </style> | |
100 | + <div class="element" id=Telescope> | |
101 | + <h2><button id="Telescope_button">TELESCOPE</button></h2> | |
102 | + <ul class="log" id="telescope_list"> | |
103 | + <br> | |
104 | + {% for log in object.cagire_logs.all %} | |
105 | + <li>{{log.created}} : {{log.message}}</li> {% endfor %} | |
106 | + </ul> | |
107 | + | |
108 | + </div> | |
109 | + <div class="element" id=Cagire> | |
110 | + <h2><button id="Cagire_button">CAGIRE</button></h2> | |
111 | + <ul class="log" id="cagire_list"> | |
112 | + <br> | |
113 | + {% for log in cagire_logs %} | |
114 | + <li>{{log.created}} : {{log.message}}</li> {% endfor %} | |
115 | + </ul> | |
116 | + </div> | |
117 | + <div class="element" id=DDRAGORED> | |
118 | + <h2><button id="ddrago_r_button">DDRAGO RED</button></h2> | |
119 | + <ul class="log" id="ddrago_r_list"> | |
120 | + <br> | |
121 | + {% for log in ddrago_r_logs %} | |
122 | + <li>{{log.created}} : {{log.message}}</li> {% endfor %} | |
123 | + </ul> | |
124 | + | |
125 | + </div> | |
126 | + <div class="element" id=DDRAGOBLUE> | |
127 | + <h2><button id="ddrago_b_button">DDRAGO BLUE</button></h2> | |
128 | + <ul class="log" id="ddrago_b_list"> | |
129 | + <br> | |
130 | + {% for log in ddrago_b_logs %} | |
131 | + <li>{{log.created}} : {{log.message}}</li> {% endfor %} | |
132 | + </ul> | |
133 | + </div> | |
134 | + </div> | |
135 | + </div> | |
136 | + | |
137 | + | |
138 | + <!-- <section id=sectionmode> | |
139 | + <style type="text/css"> | |
140 | + #sectionmode | |
141 | + { | |
142 | + padding-top: 50px; | |
143 | + } | |
144 | + .mode | |
145 | + { | |
146 | + display: inline-block; | |
147 | + margin: 10px 10px; | |
148 | + width: 100px; | |
149 | + height: 50px; | |
150 | + text-align: center; | |
151 | + border: 1px solid #30a818; | |
152 | + border-radius: 3px; | |
153 | + box-shadow: 0 1px 2px rgba(0,0,0,0.3); | |
154 | + background: linear-gradient(top, #fff 0%, #2ae199 2% ,#1db245 100%); | |
155 | + background:-webkit-linear-gradient(top, #fff 0%, #2ae199 2% ,#1db245 100%); | |
156 | + background:-moz-linear-gradient(top, #fff 0%, #2ae199 2% ,#1db245 100%); | |
157 | + background:-o-linear-gradient(top, #fff 0%, #2ae199 2% ,#1db245 100%); | |
158 | + background:-ms-linear-gradient(top, #fff 0%, #2ae199 2% ,#1db245 100%); | |
159 | + | |
160 | + } | |
161 | + | |
162 | + | |
163 | + .mode:hover | |
164 | + { | |
165 | + padding: 6px 4px; | |
166 | + background: linear-gradient(top, #fff 0%, #2ae205 2% ,#1db245 100%); | |
167 | + background:-webkit-linear-gradient(top, #fff 0%, #2ae205 2% ,#1db245 100%); | |
168 | + background:-moz-linear-gradient(top, #fff 0%, #2ae205 2% ,#1db245 100%); | |
169 | + background:-o-linear-gradient(top, #fff 0%, #2ae205 2% ,#1db245 100%); | |
170 | + background:-ms-linear-gradient(top, #fff 0%, #2ae205 2% ,#1db245 100%); | |
171 | + } | |
172 | + | |
173 | + .mode a | |
174 | + { | |
175 | + display: block; | |
176 | + line-height: 50px; | |
177 | + height: 50px; | |
178 | + color: white; | |
179 | + padding-top: 15px; | |
180 | + font: 19px "Tahoma", sans-serif; | |
181 | + font-weight: bold; | |
182 | + text-decoration:none; | |
183 | + text-shadow: 0 -1px 0 rgba(0,0,0,0.4); | |
184 | + } | |
185 | + | |
186 | + #Mode h3 | |
187 | + { | |
188 | + font-size: 1.5em; | |
189 | + font-family: 'Montserra', sans-serif; | |
190 | + } | |
191 | + </style> | |
192 | + <center><div id="Mode"> | |
193 | + <h3>Pyros Mode: </h3> | |
194 | + <div class="mode" id="auto"><a href="page.html">Auto</a></div> | |
195 | + <div class="mode" id="manuel"><a href="page.html">Manuel</a></div> | |
196 | + <div class="mode" id="demo"><a href="page.html">Demo</a></div> | |
197 | + </div></center> | |
198 | + </section> --> | |
199 | + <footer> | |
200 | + | |
201 | + <script src="{% static "/js/observation_status.js" %}" type=text/javascript></script> | |
202 | + | |
203 | + <style type="text/css"> | |
204 | + footer{ | |
205 | + height: 100px; | |
206 | + width: 200px; | |
207 | + margin: auto; | |
208 | + padding-top: 50px; | |
209 | + } | |
210 | + | |
211 | + .back | |
212 | + { | |
213 | + background-color: rgb(75,75,75); | |
214 | + margin: auto; | |
215 | + | |
216 | + padding: 10px 10px 10px 10px; | |
217 | + border: 1px solid rgb(75,75,75); | |
218 | + border-radius: 3px; | |
219 | + } | |
220 | + | |
221 | + .back:hover | |
222 | + { | |
223 | + padding: 15px 15px 15px 15px; | |
224 | + } | |
225 | + | |
226 | + .back a | |
227 | + { | |
228 | + color: white; | |
229 | + font: 17px "Tahoma", sans-serif; | |
230 | + font-weight:bold; | |
231 | + text-decoration:none; | |
232 | + } | |
233 | + </style> | |
234 | + <center><div class="back"><a href={% url "index" %}>Back to Dashboard</a></div></center> | |
235 | + </footer> | |
236 | + </body> | |
237 | +{% endblock %} | |
238 | + | ... | ... |
src/dashboard/templates/dashboard/observation_status_env.html
0 โ 100644
... | ... | @@ -0,0 +1,89 @@ |
1 | +{% load static %} | |
2 | + | |
3 | +<style> | |
4 | + #weather | |
5 | + { | |
6 | + display: flex; | |
7 | + flex-wrap: wrap; | |
8 | + justify-content: space-around; | |
9 | + } | |
10 | + | |
11 | + figure { | |
12 | + text-align: center; | |
13 | + display: inline-block; | |
14 | + border: 1px dotted gray; | |
15 | + margin: 20px; | |
16 | +} | |
17 | +figure img { | |
18 | + vertical-align: top; | |
19 | + padding: 5px; | |
20 | +} | |
21 | +figure figcaption { | |
22 | + border: 1px dotted black; | |
23 | + text-align: center; | |
24 | +} | |
25 | + | |
26 | + #time | |
27 | + { | |
28 | + text-align: center; | |
29 | + color: darkblue; | |
30 | + } | |
31 | +</style> | |
32 | + <h1 id="time"> Current site time : {{ t.hour }}h {{ t.minute }}min {{ t.second }}s</h1> | |
33 | +<div id="weather"> | |
34 | + | |
35 | + <div class="element" id="day_night"> | |
36 | + | |
37 | + {% if isDay %} | |
38 | + <figure> | |
39 | + <img src="{% static "media/rising_sun.png" %}" alt="" width="150" height="150"> | |
40 | + <figcaption>The Sun is Up</figcaption> | |
41 | + </figure> | |
42 | + {% else %} | |
43 | + <figure> | |
44 | + <img src="{% static "media/moon.png" %}" alt="" width="150" height="150"> | |
45 | + <figcaption>The Sun is Down</figcaption> | |
46 | + </figure> | |
47 | + {% endif %} | |
48 | + | |
49 | + | |
50 | + </div> | |
51 | + | |
52 | +<div class="element" id="sky_state"> | |
53 | + {% if weather_status.rain > 10 %} | |
54 | + <figure> | |
55 | + <img src="{% static "media/rain.svg" %}" alt="" width="150" height="150"> | |
56 | + <figcaption>Raining</figcaption> | |
57 | + </figure> | |
58 | + {% elif weather_status.cloud >= 1 %} | |
59 | + <figure> | |
60 | + <img src="{% static "media/cloud.png" %}" alt="" width="150" height="150"> | |
61 | + <figcaption>The sky is Cloudy</figcaption> | |
62 | + </figure> | |
63 | + {% else %} | |
64 | + <figure> | |
65 | + <img src="{% static "media/sun.png" %}" alt="" width="150" height="150"> | |
66 | + <figcaption>The sky is Clear</figcaption> | |
67 | + </figure> | |
68 | + {% endif %} | |
69 | + | |
70 | + | |
71 | + </div> | |
72 | + | |
73 | + <div class="element" id="wind"> | |
74 | + | |
75 | + {% if weather_status.wind >= 60 %} | |
76 | + <figure> | |
77 | + <img src="{% static "media/wind.png" %}" alt="" width="150" height="150"> | |
78 | + <figcaption>The Wind is too strong : {{ weather_status.wind }}km/h</figcaption> | |
79 | + </figure> | |
80 | + {% else %} | |
81 | + <figure> | |
82 | + <img src="{% static "media/no_wind.png" %}" alt="" width="150" height="150"> | |
83 | + <figcaption>The Wind is acceptable : {{ weather_status.wind }}km/h</figcaption> | |
84 | + </figure> | |
85 | + {% endif %} | |
86 | + | |
87 | + | |
88 | + </div> | |
89 | +</div> | |
0 | 90 | \ No newline at end of file | ... | ... |
src/dashboard/templates/dashboard/retrieve_observation_status.html
0 โ 100644
... | ... | @@ -0,0 +1,106 @@ |
1 | + | |
2 | + | |
3 | + | |
4 | + <style type="text/css"> | |
5 | + #title | |
6 | + { | |
7 | + font-size: 4em; | |
8 | + font-family: 'Montserra', sans-serif; | |
9 | + | |
10 | + color: black; | |
11 | + } | |
12 | + | |
13 | + body | |
14 | + { | |
15 | + background-color: rgb(250,250,250); | |
16 | + } | |
17 | + </style> | |
18 | + <script> | |
19 | + | |
20 | + $(".linkk").show(); | |
21 | + | |
22 | + $('.linkk').on('click', function() | |
23 | + { | |
24 | + $(".element").show() | |
25 | + }); | |
26 | + | |
27 | + </script> | |
28 | + <div id="conteneur"> | |
29 | + <style type="text/css"> | |
30 | + #conteneur | |
31 | + { | |
32 | + display : flex; | |
33 | + flex-wrap: wrap; | |
34 | + justify-content: space-around; | |
35 | + align-items: center; | |
36 | + } | |
37 | + | |
38 | + .element | |
39 | + { | |
40 | + | |
41 | + margin: auto; | |
42 | + list-style-image: none; | |
43 | + font-family: 'Montserra', sans-serif; | |
44 | + | |
45 | + } | |
46 | + | |
47 | + .element h2 | |
48 | + { | |
49 | + text-align: center; | |
50 | + font-weight: normal; | |
51 | + } | |
52 | + .log | |
53 | + { | |
54 | + font-size: 1.13em; | |
55 | + list-style-image: none; | |
56 | + list-style-type: none; | |
57 | + color: green; | |
58 | + font-weight: bold; | |
59 | + font-family: "Arial"; | |
60 | + height: 500px; | |
61 | + width: 700px; | |
62 | + overflow: scroll; | |
63 | + background-color: black; | |
64 | + } | |
65 | + </style> | |
66 | + <h2><button class="button_tele" type="button">Telescope</button></h2> | |
67 | + <div class="element" id=tele> | |
68 | + <h2>TELESCOPE</h2> | |
69 | + <ul class="log"> | |
70 | + <br> | |
71 | + {% for log in telescope_logs %} | |
72 | + <li>{{log.created}} : {{log.message}}</li> {% endfor %} | |
73 | + </ul> | |
74 | + | |
75 | + </div> | |
76 | + <h2><button class="button_tele" type="button">Telescope</button></h2> | |
77 | + <div class="element" id=Cagire> | |
78 | + <h2>CAGIRE</h2> | |
79 | + <ul class="log"> | |
80 | + <br> | |
81 | + {% for log in cagire_logs %} | |
82 | + <li>{{log.created}} : {{log.message}}</li> {% endfor %} | |
83 | + </ul> | |
84 | + </div> | |
85 | + <h2><button class="button_tele" type="button">Telescope</button></h2> | |
86 | + <div class="element" id=DDRAGORED> | |
87 | + <h2><button>DDRAGO RED</button></h2> | |
88 | + <ul class="log"> | |
89 | + <br> | |
90 | + {% for log in ddrago_r_logs %} | |
91 | + <li>{{log.created}} : {{log.message}}</li> {% endfor %} | |
92 | + </ul> | |
93 | + | |
94 | + </div> | |
95 | + <h2><button class="button_tele" type="button">Telescope</button></h2> | |
96 | + <div class="element" id=DDRAGOBLUE> | |
97 | + <h2>DDRAGO BLUE</h2> | |
98 | + <ul class="log"> | |
99 | + <br> | |
100 | + {% for log in ddrago_b_logs %} | |
101 | + <li>{{log.created}} : {{log.message}}</li> {% endfor %} | |
102 | + </ul> | |
103 | + </div> | |
104 | + </div> | |
105 | + | |
106 | + | ... | ... |
src/dashboard/urls.py
... | ... | @@ -13,4 +13,8 @@ urlpatterns = [ |
13 | 13 | name="system_retrieve_logs"), |
14 | 14 | url(r'^schedule$', views.schedule, name="schedule"), |
15 | 15 | url(r'^quotas$', views.quotas, name="quotas"), |
16 | + url(r'^observation_status/retrieve_env', views.retrieve_env, name='retrieve_env'), | |
17 | + url(r'^retrieve_env_navbar', views.retrieve_env_navbar, name='retrieve_env_navbar'), | |
18 | + | |
19 | + #url(r'^retrieve_observation_status$', views.retrieve_observation_status, name="retrieve_observation_status"), | |
16 | 20 | ] | ... | ... |
src/dashboard/views.py
1 | +from django.http import HttpResponse | |
1 | 2 | from django.shortcuts import render, redirect |
2 | 3 | from django.core import urlresolvers |
3 | 4 | from django.contrib.auth.decorators import login_required |
4 | -from common.models import Log | |
5 | - | |
5 | +import datetime | |
6 | +from common.models import Log, WeatherWatch | |
7 | +from django.core import serializers | |
6 | 8 | import utils.Logger as l |
7 | 9 | log = l.setupLogger("dashboard", "dashboard") |
8 | 10 | |
11 | + | |
12 | + | |
9 | 13 | @login_required |
10 | 14 | def index(request): |
11 | 15 | return render(request, 'dashboard/index.html') |
12 | 16 | |
17 | +#@login_required | |
18 | +#def observation_status(request): | |
19 | + # return render(request, 'dashboard/observation_status.html') | |
20 | + | |
21 | +@login_required | |
22 | +def retrieve_env(request): | |
23 | + weather_status = WeatherWatch.objects.latest('updated') | |
24 | + t = datetime.datetime.now() + datetime.timedelta(hours=-7) #temporary method to demonstrate the day/night display | |
25 | + isDay = False | |
26 | + if t.hour > 5 and t.hour < 20: | |
27 | + isDay = True | |
28 | + return render(request, 'dashboard/observation_status_env.html', locals()) | |
29 | + | |
30 | +@login_required | |
31 | +def retrieve_env_navbar(request): | |
32 | + if request.is_ajax(): | |
33 | + weather_status = WeatherWatch.objects.latest('updated') | |
34 | + weather = serializers.serialize('json', [weather_status]) | |
35 | + return HttpResponse(weather, content_type="application/json") | |
36 | + | |
13 | 37 | @login_required |
14 | 38 | def users(request): |
15 | 39 | url_ = urlresolvers.reverse('admin:auth_user_changelist') | ... | ... |
src/devices/Device.py
... | ... | @@ -6,6 +6,7 @@ import select |
6 | 6 | import utils.Logger as L |
7 | 7 | import time |
8 | 8 | import os |
9 | +from common.models import Log | |
9 | 10 | |
10 | 11 | DEBUG_FILE = True |
11 | 12 | RECONNECT_TIMEOUT_SECONDS = 20 |
... | ... | @@ -76,6 +77,7 @@ class DeviceController(): |
76 | 77 | return False |
77 | 78 | # (EP) NON, 0 = false !!! |
78 | 79 | #return (0) |
80 | + Log.objects.create(agent=self.name, message='Message send : ' + message) | |
79 | 81 | return True |
80 | 82 | |
81 | 83 | def isError(self, message: str): |
... | ... | @@ -142,6 +144,7 @@ class DeviceController(): |
142 | 144 | return (0) |
143 | 145 | |
144 | 146 | def log(self, device_name: str, message: str): |
147 | + Log.objects.create(agent=self.name, message=message) | |
145 | 148 | if DEBUG_FILE and settings.DEBUG: |
146 | 149 | self.logger.info("From device : " + device_name + " -> " + message) |
147 | 150 | return (0) | ... | ... |
... | ... | @@ -0,0 +1,11 @@ |
1 | +from django.conf.urls import url | |
2 | +from . import views | |
3 | + | |
4 | + | |
5 | +urlpatterns = [ | |
6 | +url(r'^observation_status$', views.observation_status, name="observation_status"), | |
7 | +url(r'^update_cagire_logs$', views.update_cagire_logs, name="update_cagire_logs"), | |
8 | +url(r'^update_telescope_logs$', views.update_telescope_logs, name="update_telescope_logs"), | |
9 | +url(r'^update_ddrago_r_logs$', views.update_ddrago_r_logs, name="update_ddrago_r_logs"), | |
10 | +url(r'^update_ddrago_b_logs$', views.update_ddrago_b_logs, name="update_ddrago_b_logs"), | |
11 | +] | |
0 | 12 | \ No newline at end of file | ... | ... |
src/devices/views.py
1 | 1 | from django.shortcuts import render |
2 | +from common.models import Log | |
3 | +from django.http import HttpResponse | |
4 | +from django.core import urlresolvers | |
5 | +from django.core import serializers | |
6 | +from django.contrib.auth.decorators import login_required | |
2 | 7 | |
8 | +MAX_LOGS_LINES = 200 | |
3 | 9 | # Create your views here. |
10 | +@login_required | |
11 | +def update_cagire_logs(request): | |
12 | + if request.is_ajax(): | |
13 | + cagire_logs = Log.objects.filter(agent='CameraNIR').order_by('-created')[:MAX_LOGS_LINES] | |
14 | + logs = serializers.serialize('json', cagire_logs) | |
15 | + return HttpResponse(logs, content_type="application/json") | |
16 | + #return render("dashboard/observation_status.html", logs, content_type="application/json") | |
17 | + | |
18 | + | |
19 | +@login_required | |
20 | +def update_telescope_logs(request): | |
21 | + if request.is_ajax(): | |
22 | + telescope_logs = Log.objects.filter(agent='Telescope').order_by('-created')[:MAX_LOGS_LINES] | |
23 | + logs = serializers.serialize('json', telescope_logs) | |
24 | + return HttpResponse(logs, content_type="application/json") | |
25 | + | |
26 | +@login_required | |
27 | +def update_ddrago_r_logs(request): | |
28 | + if request.is_ajax(): | |
29 | + ddrago_r_logs = Log.objects.filter(agent='CameraVIS').order_by('-created')[:MAX_LOGS_LINES] | |
30 | + logs = serializers.serialize('json', ddrago_r_logs) | |
31 | + return HttpResponse(logs, content_type="application/json") | |
32 | + | |
33 | +@login_required | |
34 | +def update_ddrago_b_logs(request): | |
35 | + if request.is_ajax(): | |
36 | + ddrago_b_logs = Log.objects.filter(agent='CameraVIS').order_by('-created')[:MAX_LOGS_LINES] | |
37 | + logs = serializers.serialize('json', ddrago_b_logs) | |
38 | + return HttpResponse(logs, content_type="application/json") | |
39 | + | |
40 | + | |
41 | +@login_required | |
42 | +def observation_status(request): | |
43 | + ''' | |
44 | + Called by the dashboard system page with ajax request every seconds, to get the logs and print them | |
45 | + ''' | |
46 | + if request.is_ajax(): | |
47 | + telescope_logs = Log.objects.filter(agent='Telescope').order_by('-created') | |
48 | + cagire_logs = Log.objects.filter(agent='CameraNIR').order_by('-created') | |
49 | + ddrago_b_logs = Log.objects.filter(agent='CameraVIS').order_by('-created') | |
50 | + ddrago_r_logs = Log.objects.filter(agent='CameraVIS').order_by('-created') | |
51 | + logs = telescope_logs + cagire_logs + ddrago_r_logs + ddrago_b_logs | |
52 | + return render('dashboard/observation_status.html', {logs: object}) | |
53 | + else: | |
54 | + return render(request, "dashboard/observation_status.html") | |
4 | 55 | \ No newline at end of file | ... | ... |
... | ... | @@ -0,0 +1,122 @@ |
1 | +var LOGS_REFRESH_FREQUENCE = 2000; //in milliseconds | |
2 | + | |
3 | +var show_cagire = false; | |
4 | +var show_telescope = false; | |
5 | +var show_ddrago_b = false; | |
6 | +var show_ddrago_r = false; | |
7 | +var interval_cagire =-1; | |
8 | +var interval_ddrago_r=-1; | |
9 | +var interval_ddrago_b=-1; | |
10 | +var interval_telescope=-1; | |
11 | + | |
12 | +jQuery(document).ready(function(){ | |
13 | + | |
14 | +$("#Telescope_button").click(function () { | |
15 | + show_telescope= !show_telescope; | |
16 | + | |
17 | + if (show_telescope) | |
18 | + { | |
19 | + $("#telescope_list").show(); | |
20 | + interval_telescope = setInterval(function() {ajax_request("telescope", "telescope_list");}, LOGS_REFRESH_FREQUENCE); | |
21 | + } | |
22 | + else { $("#telescope_list").hide(); | |
23 | + if (interval_telescope !== -1){clearInterval(interval_telescope);} | |
24 | + } | |
25 | + | |
26 | +}); | |
27 | + | |
28 | +$("#Cagire_button").click(function () { | |
29 | + show_cagire = !show_cagire; | |
30 | + | |
31 | + | |
32 | + if (show_cagire) | |
33 | + { | |
34 | + $("#cagire_list").show(); | |
35 | + interval_cagire = setInterval(function() {ajax_request("cagire", "cagire_list");}, LOGS_REFRESH_FREQUENCE); | |
36 | + } | |
37 | + else { | |
38 | + $("#cagire_list").hide(); | |
39 | + if (interval_cagire !== -1){clearInterval(interval_cagire);} | |
40 | + } | |
41 | + | |
42 | +}); | |
43 | + | |
44 | +$("#ddrago_r_button").click(function () { | |
45 | + show_ddrago_r= !show_ddrago_r; | |
46 | + | |
47 | + if (show_ddrago_r) | |
48 | + { | |
49 | + $("#ddrago_r_list").show(); | |
50 | + interval_ddrago_r = setInterval(function() {ajax_request("ddrago_r", "ddrago_r_list");}, LOGS_REFRESH_FREQUENCE); | |
51 | + } | |
52 | + else { | |
53 | + $("#ddrago_r_list").hide(); | |
54 | + if (interval_ddrago_r !== -1){clearInterval(interval_ddrago_r);} | |
55 | + } | |
56 | +}); | |
57 | + | |
58 | +$("#ddrago_b_button").click(function () { | |
59 | + show_ddrago_b= !show_ddrago_b; | |
60 | + | |
61 | + if (show_ddrago_b) | |
62 | + { | |
63 | + $("#ddrago_b_list").show(); | |
64 | + interval_ddrago_b = setInterval(function() {ajax_request("ddrago_b", "ddrago_b_list");}, LOGS_REFRESH_FREQUENCE); | |
65 | + } | |
66 | + else { $("#ddrago_b_list").hide(); | |
67 | + if (interval_ddrago_b !== -1){clearInterval(interval_ddrago_b);} | |
68 | + } | |
69 | +}); | |
70 | + | |
71 | + /* | |
72 | + function retriving logs for tools with show variable equal True, called every LOGS_REFRESH_FREQUENCE | |
73 | + */ | |
74 | + | |
75 | +function ajax_request(cam, id_list){ | |
76 | + var cagire_url ="/devices/update_cagire_logs"; | |
77 | + var telescope_url ="/devices/update_telescope_logs"; | |
78 | + var ddrago_r_url ="/devices/update_ddrago_r_logs"; | |
79 | + var ddrago_b_url ="/devices/update_ddrago_b_logs"; | |
80 | + var url_txt = ""; | |
81 | + if (cam === 'cagire') | |
82 | + url_txt = cagire_url; | |
83 | + else if (cam === "telescope") | |
84 | + url_txt = telescope_url; | |
85 | + else if (cam === "ddrago_r") | |
86 | + url_txt = ddrago_r_url; | |
87 | + else if (cam === "ddrago_b") | |
88 | + url_txt = ddrago_b_url; | |
89 | + $.ajax({ | |
90 | + url: url_txt, | |
91 | + type: 'get', | |
92 | + dataType: 'text', | |
93 | + success: function(data) | |
94 | + { | |
95 | + var obj = JSON.parse(data); | |
96 | + if (obj) { | |
97 | + var listDiv = document.getElementById(id_list); | |
98 | + listDiv.innerHTML = ''; | |
99 | + for (var tmp in obj) { | |
100 | + var li = document.createElement('li'); | |
101 | + li.innerHTML = obj[tmp]['fields']['created'] + ": " + obj[tmp]['fields']['message']; // Use innerHTML to set the text | |
102 | + listDiv.appendChild(li); | |
103 | + } | |
104 | + } | |
105 | + }, | |
106 | + error: function() | |
107 | + { | |
108 | + console.log('Ajax error: GET request failed\n'); | |
109 | + } | |
110 | + | |
111 | + }); | |
112 | + | |
113 | + } | |
114 | + | |
115 | + | |
116 | +}); | |
117 | + | |
118 | + $(window).unload(function(){ | |
119 | + alert("bye") | |
120 | + if (interval_cagire != -1){clearInterval(interval_cagire);} | |
121 | + if (interval_telescope !== -1){clearInterval(interval_telescope);} | |
122 | +}); | ... | ... |
1.79 KB
3.52 KB
4.41 KB
2.24 KB
... | ... | @@ -0,0 +1,59 @@ |
1 | +<?xml version="1.0" encoding="iso-8859-1"?> | |
2 | +<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> | |
3 | +<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" | |
4 | + viewBox="0 0 320.192 320.192" style="enable-background:new 0 0 320.192 320.192;" xml:space="preserve"> | |
5 | +<g> | |
6 | + <g id="Dibujo_35_"> | |
7 | + <g> | |
8 | + <path d="M259.466,82.808c-2.799,0-6.139,0.436-9.319,1.016c-11.566-39.593-47.747-67.262-90.051-67.262 | |
9 | + S81.605,44.231,70.05,83.824c-3.185-0.58-6.525-1.016-9.324-1.016C27.244,82.808,0,110.052,0,143.534 | |
10 | + s27.244,60.726,60.726,60.726c6.095,0,11.041-4.946,11.041-11.041s-4.946-11.041-11.041-11.041 | |
11 | + c-21.309,0-38.644-17.34-38.644-38.644s17.335-38.644,38.644-38.644c1.529,0,3.991,0.375,6.586,0.894v10.147 | |
12 | + c0,6.095,4.946,11.041,11.041,11.041s11.041-4.946,11.041-11.041V98.15c5.929-34.514,35.536-59.506,70.702-59.506 | |
13 | + s64.767,24.992,70.702,59.506v17.782c0,6.095,4.946,11.041,11.041,11.041s11.041-4.946,11.041-11.041v-10.147 | |
14 | + c2.595-0.519,5.051-0.894,6.586-0.894c21.304,0,38.644,17.34,38.644,38.644s-17.34,38.644-38.644,38.644 | |
15 | + c-6.095,0-11.041,4.946-11.041,11.041s4.946,11.041,11.041,11.041c33.482,0,60.726-27.244,60.726-60.726 | |
16 | + S292.948,82.808,259.466,82.808z"/> | |
17 | + <path d="M168.294,149.386c-5.924-1.491-11.913,2.12-13.393,8.032l-33.123,132.493c-1.48,5.918,2.12,11.908,8.032,13.393 | |
18 | + c0.9,0.221,1.8,0.326,2.688,0.326c4.946,0,9.446-3.345,10.704-8.364l33.123-132.493 | |
19 | + C177.806,156.855,174.212,150.866,168.294,149.386z"/> | |
20 | + <path d="M212.453,182.509c-5.918-1.496-11.908,2.12-13.387,8.032l-16.562,66.247c-1.48,5.918,2.12,11.913,8.038,13.393 | |
21 | + c0.9,0.226,1.8,0.331,2.683,0.331c4.946,0,9.451-3.345,10.704-8.364l16.556-66.247 | |
22 | + C221.97,189.979,218.371,183.983,212.453,182.509z"/> | |
23 | + <path d="M107.562,182.509c-5.901-1.496-11.908,2.12-13.387,8.032l-16.562,66.247c-1.48,5.918,2.12,11.913,8.038,13.393 | |
24 | + c0.9,0.226,1.8,0.331,2.683,0.331c4.946,0,9.451-3.345,10.704-8.364l16.562-66.247 | |
25 | + C117.08,189.979,113.48,183.983,107.562,182.509z"/> | |
26 | + </g> | |
27 | + </g> | |
28 | +</g> | |
29 | +<g> | |
30 | +</g> | |
31 | +<g> | |
32 | +</g> | |
33 | +<g> | |
34 | +</g> | |
35 | +<g> | |
36 | +</g> | |
37 | +<g> | |
38 | +</g> | |
39 | +<g> | |
40 | +</g> | |
41 | +<g> | |
42 | +</g> | |
43 | +<g> | |
44 | +</g> | |
45 | +<g> | |
46 | +</g> | |
47 | +<g> | |
48 | +</g> | |
49 | +<g> | |
50 | +</g> | |
51 | +<g> | |
52 | +</g> | |
53 | +<g> | |
54 | +</g> | |
55 | +<g> | |
56 | +</g> | |
57 | +<g> | |
58 | +</g> | |
59 | +</svg> | ... | ... |
5.78 KB
14.5 KB
1.76 KB
660 Bytes
890 Bytes
890 Bytes
12.8 KB
12.8 KB
786 Bytes
2.32 KB
5.03 KB
1.83 KB
3.14 KB
src/misc/templates/base.html
... | ... | @@ -34,7 +34,16 @@ |
34 | 34 | </head> |
35 | 35 | |
36 | 36 | <body> |
37 | - | |
37 | +<style> | |
38 | + #wrapper{ | |
39 | + padding-left: 0px; | |
40 | + } | |
41 | + | |
42 | + #profile | |
43 | + { | |
44 | + font-size: 20px; | |
45 | + } | |
46 | +</style> | |
38 | 47 | <div id="wrapper"> |
39 | 48 | |
40 | 49 | <!-- Sidebar --> |
... | ... | @@ -43,30 +52,24 @@ |
43 | 52 | <div class="navbar-header"> |
44 | 53 | <a class="navbar-brand" href={% url "index" %}>SVOM French GFT Control Center</a> |
45 | 54 | </div> |
46 | - | |
47 | - | |
55 | + <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> | |
56 | + | |
57 | + | |
58 | + | |
48 | 59 | <!-- Collect the nav links, forms, and other content for toggling --> |
49 | 60 | <div class="collapse navbar-collapse navbar-ex1-collapse"> |
50 | - | |
51 | - <ul class="nav navbar-nav side-nav"> | |
52 | - <li><a href="{% url "current_schedule" %}">Schedule</a></li> | |
53 | - <li><a href="{% url "system" %}">System</a></li> | |
54 | - <li><a href="{% url "alerts_list" %}">Alerts</a></li> | |
55 | - <li><a href="{% url "requests_list" %}">Routines</a></li> | |
56 | - <li><a href="{% url "weather" %}">Weather</a></li> | |
57 | - <li><a href="{% url "site" %}">Site</a></li> | |
58 | - <li><a href="{% url "devices" %}">Devices</a></li> | |
59 | - <li><a href="{% url "users" %}">Users</a></li> | |
60 | - </ul> | |
61 | 61 | |
62 | 62 | <ul class="nav navbar-nav navbar-right navbar-user"> |
63 | - | |
64 | - <li class="dropdown alerts-dropdown"> | |
65 | - <a href="{% url "profile" %}"><i class="fas fa-cog"></i></a> | |
63 | + <li><a id="day_night" href="{% url "weather" %}"><img id="day_night_img"></a></li> | |
64 | + <li><a id="wind" href="{% url "weather" %}"><img id="wind_img"></a></li> | |
65 | + <li><a id="weather" href="{% url "weather" %}"><img id="weather_img"></a></li> | |
66 | + <li> | |
67 | + <a href="{% url "profile" %}"><i id="profile" class="fas fa-cog "></i></a> | |
66 | 68 | </li> |
67 | - <li class="dropdown user-dropdown"> | |
69 | + <li> | |
68 | 70 | <a href="{% url "user_logout" %}" ><i class="fa fa-power-off"></i> Log Out</a> |
69 | 71 | </li> |
72 | + | |
70 | 73 | </ul> |
71 | 74 | |
72 | 75 | </div><!-- /.navbar-collapse --> |
... | ... | @@ -91,7 +94,69 @@ |
91 | 94 | |
92 | 95 | </div><!-- /#wrapper --> |
93 | 96 | |
94 | - | |
97 | + <!-- Javascript function refreshing weather icons on the navbar --> | |
98 | + | |
99 | + <script> | |
100 | + var TOO_STRONG_WIND = 60; //Totally arbitrary values, just for demonstration | |
101 | + var MAX_CLOUD_VALUE = 1; | |
102 | + var REFRESH_ICONS_FREQUENCE_MILLISECONDS = 60000; | |
103 | + var MAX_RAIN_RATE = 10; | |
104 | + | |
105 | + ajax_request(); | |
106 | + interval = setInterval(function() {ajax_request();}, REFRESH_ICONS_FREQUENCE_MILLISECONDS); | |
107 | + | |
108 | + function ajax_request() { | |
109 | + $.get("{% url 'retrieve_env_navbar' %}", function (weather_status) { | |
110 | + if (weather_status) | |
111 | + { | |
112 | + /* | |
113 | + *** totally arbitrary method for day/night cycle, just for demonstration | |
114 | + */ | |
115 | + var hour = new Date().getTime(); | |
116 | + var site_time = new Date(hour - 9 * 3600 * 1000).getHours(); | |
117 | + var _img_day_night =document.createElement('img'); | |
118 | + if (site_time > 5 && site_time < 20) | |
119 | + _img_day_night.src ="{% static 'media/white_rising_sun_new.png' %}"; | |
120 | + else | |
121 | + _img_day_night.src ="{% static 'media/white_moon_new.png' %}"; | |
122 | + _img_day_night.width = 30; | |
123 | + _img_day_night.height = 30; | |
124 | + _img_day_night.id ="day_night_img"; | |
125 | + _img_day_night.alt="html5"; | |
126 | + $("#day_night_img").replaceWith(_img_day_night); | |
127 | + | |
128 | + var _img = document.createElement('img'); | |
129 | + _img.width = 30; | |
130 | + _img.height = 30; | |
131 | + _img.id ="weather_img"; | |
132 | + console.log(weather_status[0]['fields']['global_status']); | |
133 | + if(parseInt(weather_status[0]['fields']['rain']) > MAX_RAIN_RATE) | |
134 | + _img.src = "{% static 'media/rain_new.png' %}"; | |
135 | + else if (parseInt(weather_status[0]['fields']['cloud']) > MAX_CLOUD_VALUE) | |
136 | + _img.src = "{% static 'media/white_cloud.png' %}"; | |
137 | + else | |
138 | + _img.src = "{% static 'media/white_sun.png' %}"; | |
139 | + _img.width = 25; | |
140 | + _img.height = 25; | |
141 | + _img.alt = "html5"; | |
142 | + $("#weather_img").replaceWith(_img); | |
143 | + | |
144 | + var _im = document.createElement('img'); | |
145 | + _im.width = 25; | |
146 | + _im.height = 25; | |
147 | + _im.id="wind_img"; | |
148 | + if (parseInt(weather_status[0]['fields']['wind']) >= TOO_STRONG_WIND) | |
149 | + _im.src = "{% static 'media/white_wind.png' %}"; | |
150 | + else | |
151 | + _im.src= "{% static 'media/white_windsock_nowind_new.png' %}"; | |
152 | + $("#wind_img").replaceWith(_im); | |
153 | + } | |
154 | + }, 'json') | |
155 | + .fail(function () { | |
156 | + console.log('Ajax error: GET request failed\n'); | |
157 | + }) | |
158 | + } | |
159 | + </script> | |
95 | 160 | |
96 | 161 | <!-- Bootstrap core JavaScript |
97 | 162 | ================================================== --> | ... | ... |
src/pyros/settings.py
... | ... | @@ -126,11 +126,11 @@ LOGIN_URL = "/" |
126 | 126 | "$ pyros.py simulator_development" will automatically set them to "True" |
127 | 127 | ''' |
128 | 128 | # FOR SIMULATOR (TODO: remove because not used) |
129 | -SIMULATOR = False | |
129 | +SIMULATOR = True | |
130 | 130 | # FOR SIMULATOR (and TESTS) |
131 | -CELERY_TEST = False | |
131 | +CELERY_TEST = True | |
132 | 132 | |
133 | -# CELERY_TEST = False ==> DEFAULT (NORMAL) RUN MODE, use pyros (normal) database | |
133 | +# CELERY_TEST = True ==> DEFAULT (NORMAL) RUN MODE, use pyros (normal) database | |
134 | 134 | if not CELERY_TEST: |
135 | 135 | if not MYSQL: |
136 | 136 | DATABASES = { |
... | ... | @@ -149,7 +149,7 @@ if not CELERY_TEST: |
149 | 149 | } |
150 | 150 | } |
151 | 151 | |
152 | -# CELERY_TEST = False ==> 'TEST' RUN MODE, use pyros_test database | |
152 | +# CELERY_TEST = True ==> 'TEST' RUN MODE, use pyros_test database | |
153 | 153 | else: |
154 | 154 | DATABASES = { |
155 | 155 | 'default': { | ... | ... |
src/pyros/urls.py
... | ... | @@ -29,6 +29,7 @@ urlpatterns = [ |
29 | 29 | urlpatterns = [ |
30 | 30 | url(r'^admin/', admin.site.urls), |
31 | 31 | url(r'^dashboard/', include('dashboard.urls')), |
32 | + url(r'^devices/', include('devices.urls')), | |
32 | 33 | url(r'^scheduler/', include('scheduler.urls')), |
33 | 34 | url(r'^alert_manager/', include('alert_manager.urls')), |
34 | 35 | url(r'^analyzer/', include('analyzer.urls')), | ... | ... |