##// END OF EJS Templates
Se añadió y corrigió la aplicación de colores por change beam
Renato Huallpa -
r394:63661266e9fd
parent child
Show More
@@ -0,0 +1,414
1 {% extends "dev_conf.html" %} {% load static %} {% load django_bootstrap5 %} {% load main_tags %}
2 {% block extra-head %}
3 <style>
4 .abs {
5 width: auto;
6 display: inline-block;
7 text-align: center;
8 }
9
10 .abs td {
11 padding: 4px;
12 }
13
14 .module td {
15 padding: 4px 15px 4px 15px;
16 font-weight: bold;
17 border: 1px solid
18 }
19
20 .legend {
21 margin-left: 15px;
22 display: inline-block;
23 border: 2px solid;
24 vertical-align: top;
25 }
26
27 .legend th {
28 border-bottom: 1px dashed;
29 font-weight: bold;
30 vertical-align: center;
31 text-align: center;
32 }
33
34 .legend td {
35 padding: 2px;
36 text-align: center;
37 font-weight: bold;
38 }
39
40 </style>
41 {% endblock %}
42
43
44 {% block extra-menu-actions %}
45 <li>
46 <a href="{{ dev_conf.get_absolute_url_plot }}" target="_blank">
47 <span class="far fa-image" aria-hidden="true"></span> View Patterns </a>
48 </li>
49 {% endblock %}
50
51
52 {% block extra-content %}
53 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
54 <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/4.4.1/socket.io.min.js">
55 </script>
56
57
58 {% if beams %}
59 <h4>Beams:</h4>
60 <div class="container">
61 <ul class="nav nav-pills">
62 {% for beam in beams %}
63 <li class="nav-item">
64 <a {%if beam.pk == active_beam %} class="nav-link active" {% else %} class="nav-link" {% endif %} data-toggle="pill" href="#menu{{forloop.counter}}">{{forloop.counter}}</a>
65 </li>
66 {% endfor %}
67 </ul>
68
69 <div class="tab-content">
70 {% for beam in beams %}
71 <div id="menu{{forloop.counter}}" class="tab-pane fade {%if beam.pk == active_beam %}in active show{% endif %}">
72 <h3>{%if beam.pk == active_beam %}Active Beam: {%endif%}{{beam.name}}</h3>
73 <table id="abs_pattern{{forloop.counter}}" class="abs">
74 <tr>
75 <td>
76 <b>North Quarter</b>
77 <table class="module">
78 <tr>
79 <td title='{{module_messages.1}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="1" {%else%} {{color_status.1}} {%endif%}{%endif%}> {{beam.get_upvalues.0}}</span></td>
80 <td title='{{module_messages.2}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="2" {%else%} {{color_status.2}} {%endif%}{%endif%}> {{beam.get_upvalues.1}}</span></td>
81 <td title='{{module_messages.3}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="3" {%else%} {{color_status.3}} {%endif%}{%endif%}> {{beam.get_upvalues.2}}</span></td>
82 <td title='{{module_messages.4}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="4" {%else%} {{color_status.4}} {%endif%}{%endif%}> {{beam.get_upvalues.3}}</span></td>
83 </tr>
84 <tr>
85 <td title='{{module_messages.1}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="101" {%else%} {{color_status.1}} {%endif%}{%endif%}> {{beam.get_downvalues.0}}</span></td>
86 <td title='{{module_messages.2}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="102" {%else%} {{color_status.2}} {%endif%}{%endif%}> {{beam.get_downvalues.1}}</span></td>
87 <td title='{{module_messages.3}}'> <span {%if beam.pk == active_beam %} {%if mqtt%} id="103" {%else%} {{color_status.3}} {%endif%}{%endif%}> {{beam.get_downvalues.2}}</span></td>
88 <td title='{{module_messages.4}}'> <span {%if beam.pk == active_beam %} {%if mqtt%} id="104" {%else%} {{color_status.4}} {%endif%}{%endif%}> {{beam.get_downvalues.3}}</span></td>
89 </tr>
90 <tr>
91 <td title='{{module_messages.9}}'> <span {%if beam.pk == active_beam %} {%if mqtt%} id="9" {%else%} {{color_status.9}} {%endif%}{%endif%}> {{beam.get_upvalues.8}}</span></td>
92 <td title='{{module_messages.10}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="10" {%else%} {{color_status.10}} {%endif%} {%endif%}>{{beam.get_upvalues.9}}</span></td>
93 <td title='{{module_messages.11}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="11" {%else%} {{color_status.11}} {%endif%} {%endif%}>{{beam.get_upvalues.10}}</span></td>
94 <td title='{{module_messages.12}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="12" {%else%} {{color_status.12}} {%endif%} {%endif%}>{{beam.get_upvalues.11}}</span></td>
95 </tr>
96 <tr>
97 <td title='{{module_messages.9}}'> <span {%if beam.pk == active_beam %} {%if mqtt%} id="109" {%else%} {{color_status.9}} {%endif%}{%endif%}> {{beam.get_downvalues.8}}</span></td>
98 <td title='{{module_messages.10}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="110" {%else%} {{color_status.10}} {%endif%} {%endif%}>{{beam.get_downvalues.9}}</span></td>
99 <td title='{{module_messages.11}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="111" {%else%} {{color_status.11}} {%endif%} {%endif%}>{{beam.get_downvalues.10}}</span></td>
100 <td title='{{module_messages.12}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="112" {%else%} {{color_status.12}} {%endif%} {%endif%}>{{beam.get_downvalues.11}}</span></td>
101 </tr>
102 <tr>
103 <td title='{{module_messages.17}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="17" {%else%} {{color_status.17}} {%endif%} {%endif%}>{{beam.get_upvalues.16}}</span></td>
104 <td title='{{module_messages.18}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="18" {%else%} {{color_status.18}} {%endif%} {%endif%}>{{beam.get_upvalues.17}}</span></td>
105 <td title='{{module_messages.19}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="19" {%else%} {{color_status.19}} {%endif%} {%endif%}>{{beam.get_upvalues.18}}</span></td>
106 <td title='{{module_messages.20}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="20" {%else%} {{color_status.20}} {%endif%} {%endif%}>{{beam.get_upvalues.19}}</span></td>
107 </tr>
108 <tr>
109 <td title='{{module_messages.17}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="117" {%else%} {{color_status.17}} {%endif%} {%endif%}>{{beam.get_downvalues.16}}</span></td>
110 <td title='{{module_messages.18}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="118" {%else%} {{color_status.18}} {%endif%} {%endif%}>{{beam.get_downvalues.17}}</span></td>
111 <td title='{{module_messages.19}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="119" {%else%} {{color_status.19}} {%endif%} {%endif%}>{{beam.get_downvalues.18}}</span></td>
112 <td title='{{module_messages.20}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="120" {%else%} {{color_status.20}} {%endif%} {%endif%}>{{beam.get_downvalues.19}}</span></td>
113 </tr>
114 <tr>
115 <td title='{{module_messages.25}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="25" {%else%} {{color_status.25}} {%endif%} {%endif%}>{{beam.get_upvalues.24}}</span></td>
116 <td title='{{module_messages.26}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="26" {%else%} {{color_status.26}} {%endif%} {%endif%}>{{beam.get_upvalues.25}}</span></td>
117 <td title='{{module_messages.27}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="27" {%else%} {{color_status.27}} {%endif%} {%endif%}>{{beam.get_upvalues.26}}</span></td>
118 <td title='{{module_messages.28}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="28" {%else%} {{color_status.28}} {%endif%} {%endif%}>{{beam.get_upvalues.27}}</span></td>
119 </tr>
120 <tr>
121 <td title='{{module_messages.25}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="125" {%else%} {{color_status.25}} {%endif%} {%endif%}>{{beam.get_downvalues.24}}</span></td>
122 <td title='{{module_messages.26}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="126" {%else%} {{color_status.26}} {%endif%} {%endif%}>{{beam.get_downvalues.25}}</span></td>
123 <td title='{{module_messages.27}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="127" {%else%} {{color_status.27}} {%endif%} {%endif%}>{{beam.get_downvalues.26}}</span></td>
124 <td title='{{module_messages.28}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="128" {%else%} {{color_status.28}} {%endif%} {%endif%}>{{beam.get_downvalues.27}}</span></td>
125 </tr>
126 </table>
127 </td>
128 <td>
129 <b>East Quarter</b>
130 <table class="module">
131 <tr>
132 <td title='{{module_messages.5}}'> <span {%if beam.pk == active_beam %} {%if mqtt%} id="5" {%else%} {{color_status.5}} {%endif%}{%endif%}> {{beam.get_upvalues.4}}</span></td>
133 <td title='{{module_messages.6}}'> <span {%if beam.pk == active_beam %} {%if mqtt%} id="6" {%else%} {{color_status.6}} {%endif%}{%endif%}> {{beam.get_upvalues.5}}</span></td>
134 <td title='{{module_messages.7}}'> <span {%if beam.pk == active_beam %} {%if mqtt%} id="7" {%else%} {{color_status.7}} {%endif%}{%endif%}> {{beam.get_upvalues.6}}</span></td>
135 <td title='{{module_messages.8}}'> <span {%if beam.pk == active_beam %} {%if mqtt%} id="8" {%else%} {{color_status.8}} {%endif%}{%endif%}> {{beam.get_upvalues.7}}</span></td>
136 </tr>
137 <tr>
138 <td title='{{module_messages.5}}'> <span {%if beam.pk == active_beam %} {%if mqtt%} id="105" {%else%} {{color_status.5}} {%endif%}{%endif%}> {{beam.get_downvalues.4}}</span></td>
139 <td title='{{module_messages.6}}'> <span {%if beam.pk == active_beam %} {%if mqtt%} id="106" {%else%} {{color_status.6}} {%endif%}{%endif%}> {{beam.get_downvalues.5}}</span></td>
140 <td title='{{module_messages.7}}'> <span {%if beam.pk == active_beam %} {%if mqtt%} id="107" {%else%} {{color_status.7}} {%endif%}{%endif%}> {{beam.get_downvalues.6}}</span></td>
141 <td title='{{module_messages.8}}'> <span {%if beam.pk == active_beam %} {%if mqtt%} id="108" {%else%} {{color_status.8}} {%endif%}{%endif%}> {{beam.get_downvalues.7}}</span></td>
142 </tr>
143 <tr>
144 <td title='{{module_messages.13}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="13" {%else%} {{color_status.13}} {%endif%} {%endif%}>{{beam.get_upvalues.12}}</span></td>
145 <td title='{{module_messages.14}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="14" {%else%} {{color_status.14}} {%endif%} {%endif%}>{{beam.get_upvalues.13}}</span></td>
146 <td title='{{module_messages.15}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="15" {%else%} {{color_status.15}} {%endif%} {%endif%}>{{beam.get_upvalues.14}}</span></td>
147 <td title='{{module_messages.16}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="16" {%else%} {{color_status.16}} {%endif%} {%endif%}>{{beam.get_upvalues.15}}</span></td>
148 </tr>
149 <tr>
150 <td title='{{module_messages.13}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="113" {%else%} {{color_status.13}} {%endif%} {%endif%}>{{beam.get_downvalues.12}}</span></td>
151 <td title='{{module_messages.14}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="114" {%else%} {{color_status.14}} {%endif%} {%endif%}>{{beam.get_downvalues.13}}</span></td>
152 <td title='{{module_messages.15}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="115" {%else%} {{color_status.15}} {%endif%} {%endif%}>{{beam.get_downvalues.14}}</span></td>
153 <td title='{{module_messages.16}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="116" {%else%} {{color_status.16}} {%endif%} {%endif%}>{{beam.get_downvalues.15}}</span></td>
154 </tr>
155 <tr>
156 <td title='{{module_messages.21}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="21" {%else%} {{color_status.21}} {%endif%} {%endif%}>{{beam.get_upvalues.20}}</span></td>
157 <td title='{{module_messages.22}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="22" {%else%} {{color_status.22}} {%endif%} {%endif%}>{{beam.get_upvalues.21}}</span></td>
158 <td title='{{module_messages.23}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="23" {%else%} {{color_status.23}} {%endif%} {%endif%}>{{beam.get_upvalues.22}}</span></td>
159 <td title='{{module_messages.24}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="24" {%else%} {{color_status.24}} {%endif%} {%endif%}>{{beam.get_upvalues.23}}</span></td>
160 </tr>
161 <tr>
162 <td title='{{module_messages.21}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="121" {%else%} {{color_status.21}} {%endif%} {%endif%}>{{beam.get_downvalues.20}}</span></td>
163 <td title='{{module_messages.22}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="122" {%else%} {{color_status.22}} {%endif%} {%endif%}>{{beam.get_downvalues.21}}</span></td>
164 <td title='{{module_messages.23}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="123" {%else%} {{color_status.23}} {%endif%} {%endif%}>{{beam.get_downvalues.22}}</span></td>
165 <td title='{{module_messages.24}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="124" {%else%} {{color_status.24}} {%endif%} {%endif%}>{{beam.get_downvalues.23}}</span></td>
166 </tr>
167 <tr>
168 <td title='{{module_messages.29}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="29" {%else%} {{color_status.29}} {%endif%} {%endif%}>{{beam.get_upvalues.28}}</span></td>
169 <td title='{{module_messages.30}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="30" {%else%} {{color_status.30}} {%endif%} {%endif%}>{{beam.get_upvalues.29}}</span></td>
170 <td title='{{module_messages.31}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="31" {%else%} {{color_status.31}} {%endif%} {%endif%}>{{beam.get_upvalues.30}}</span></td>
171 <td title='{{module_messages.32}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="32" {%else%} {{color_status.32}} {%endif%} {%endif%}>{{beam.get_upvalues.31}}</span></td>
172 </tr>
173 <tr>
174 <td title='{{module_messages.29}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="129" {%else%} {{color_status.29}} {%endif%} {%endif%}>{{beam.get_downvalues.28}}</span></td>
175 <td title='{{module_messages.30}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="130" {%else%} {{color_status.30}} {%endif%} {%endif%}>{{beam.get_downvalues.29}}</span></td>
176 <td title='{{module_messages.31}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="131" {%else%} {{color_status.31}} {%endif%} {%endif%}>{{beam.get_downvalues.30}}</span></td>
177 <td title='{{module_messages.32}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="132" {%else%} {{color_status.32}} {%endif%} {%endif%}>{{beam.get_downvalues.31}}</span></td>
178 </tr>
179 </table>
180 </td>
181 </tr>
182 <tr>
183 <td>
184 <b>West Quarter</b>
185 <table class="module">
186 <tr>
187 <td title='{{module_messages.33}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="33" {%else%} {{color_status.33}} {%endif%} {%endif%}>{{beam.get_upvalues.32}}</span></td>
188 <td title='{{module_messages.34}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="34" {%else%} {{color_status.34}} {%endif%} {%endif%}>{{beam.get_upvalues.33}}</span></td>
189 <td title='{{module_messages.35}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="35" {%else%} {{color_status.35}} {%endif%} {%endif%}>{{beam.get_upvalues.34}}</span></td>
190 <td title='{{module_messages.36}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="36" {%else%} {{color_status.36}} {%endif%} {%endif%}>{{beam.get_upvalues.35}}</span></td>
191 </tr>
192 <tr>
193 <td title='{{module_messages.33}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="133" {%else%} {{color_status.33}} {%endif%} {%endif%}>{{beam.get_downvalues.32}}</span></td>
194 <td title='{{module_messages.34}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="134" {%else%} {{color_status.34}} {%endif%} {%endif%}>{{beam.get_downvalues.33}}</span></td>
195 <td title='{{module_messages.35}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="135" {%else%} {{color_status.35}} {%endif%} {%endif%}>{{beam.get_downvalues.34}}</span></td>
196 <td title='{{module_messages.36}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="136" {%else%} {{color_status.36}} {%endif%} {%endif%}>{{beam.get_downvalues.35}}</span></td>
197 </tr>
198 <tr>
199 <td title='{{module_messages.41}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="41" {%else%} {{color_status.41}} {%endif%} {%endif%}>{{beam.get_upvalues.40}}</span></td>
200 <td title='{{module_messages.42}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="42" {%else%} {{color_status.42}} {%endif%} {%endif%}>{{beam.get_upvalues.41}}</span></td>
201 <td title='{{module_messages.43}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="43" {%else%} {{color_status.43}} {%endif%} {%endif%}>{{beam.get_upvalues.42}}</span></td>
202 <td title='{{module_messages.44}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="44" {%else%} {{color_status.44}} {%endif%} {%endif%}>{{beam.get_upvalues.43}}</span></td>
203 </tr>
204 <tr>
205 <td title='{{module_messages.41}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="141" {%else%} {{color_status.41}} {%endif%} {%endif%}>{{beam.get_downvalues.40}}</span></td>
206 <td title='{{module_messages.42}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="142" {%else%} {{color_status.42}} {%endif%} {%endif%}>{{beam.get_downvalues.41}}</span></td>
207 <td title='{{module_messages.43}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="143" {%else%} {{color_status.43}} {%endif%} {%endif%}>{{beam.get_downvalues.42}}</span></td>
208 <td title='{{module_messages.44}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="144" {%else%} {{color_status.44}} {%endif%} {%endif%}>{{beam.get_downvalues.43}}</span></td>
209 </tr>
210 <tr>
211 <td title='{{module_messages.49}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="49" {%else%} {{color_status.49}} {%endif%} {%endif%}>{{beam.get_upvalues.48}}</span></td>
212 <td title='{{module_messages.51}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="50" {%else%} {{color_status.50}} {%endif%} {%endif%}>{{beam.get_upvalues.49}}</span></td>
213 <td title='{{module_messages.52}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="51" {%else%} {{color_status.51}} {%endif%} {%endif%}>{{beam.get_upvalues.50}}</span></td>
214 <td title='{{module_messages.53}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="52" {%else%} {{color_status.52}} {%endif%} {%endif%}>{{beam.get_upvalues.51}}</span></td>
215 </tr>
216 <tr>
217 <td title='{{module_messages.49}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="149" {%else%} {{color_status.49}} {%endif%} {%endif%}>{{beam.get_downvalues.48}}</span></td>
218 <td title='{{module_messages.50}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="150" {%else%} {{color_status.50}} {%endif%} {%endif%}>{{beam.get_downvalues.49}}</span></td>
219 <td title='{{module_messages.51}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="151" {%else%} {{color_status.51}} {%endif%} {%endif%}>{{beam.get_downvalues.50}}</span></td>
220 <td title='{{module_messages.52}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="152" {%else%} {{color_status.52}} {%endif%} {%endif%}>{{beam.get_downvalues.51}}</span></td>
221 </tr>
222 <tr>
223 <td title='{{module_messages.57}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="57" {%else%} {{color_status.57}} {%endif%} {%endif%}>{{beam.get_upvalues.56}}</span></td>
224 <td title='{{module_messages.58}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="58" {%else%} {{color_status.58}} {%endif%} {%endif%}>{{beam.get_upvalues.57}}</span></td>
225 <td title='{{module_messages.59}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="59" {%else%} {{color_status.59}} {%endif%} {%endif%}>{{beam.get_upvalues.58}}</span></td>
226 <td title='{{module_messages.60}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="60" {%else%} {{color_status.60}} {%endif%} {%endif%}>{{beam.get_upvalues.59}}</span></td>
227 </tr>
228 <tr>
229 <td title='{{module_messages.57}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="157" {%else%} {{color_status.57}} {%endif%} {%endif%}>{{beam.get_downvalues.56}}</span></td>
230 <td title='{{module_messages.58}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="158" {%else%} {{color_status.58}} {%endif%} {%endif%}>{{beam.get_downvalues.57}}</span></td>
231 <td title='{{module_messages.59}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="159" {%else%} {{color_status.59}} {%endif%} {%endif%}>{{beam.get_downvalues.58}}</span></td>
232 <td title='{{module_messages.60}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="160" {%else%} {{color_status.60}} {%endif%} {%endif%}>{{beam.get_downvalues.59}}</span></td>
233 </tr>
234 </table>
235 </td>
236 <td>
237 <b>South Quarter</b>
238 <table class="module">
239 <tr>
240 <td title='{{module_messages.37}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="37" {%else%} {{color_status.37}} {%endif%} {%endif%}>{{beam.get_upvalues.36}}</span></td>
241 <td title='{{module_messages.38}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="38" {%else%} {{color_status.38}} {%endif%} {%endif%}>{{beam.get_upvalues.37}}</span></td>
242 <td title='{{module_messages.39}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="39" {%else%} {{color_status.39}} {%endif%} {%endif%}>{{beam.get_upvalues.38}}</span></td>
243 <td title='{{module_messages.40}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="40" {%else%} {{color_status.40}} {%endif%} {%endif%}>{{beam.get_upvalues.39}}</span></td>
244 </tr>
245 <tr>
246 <td title='{{module_messages.37}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="137" {%else%} {{color_status.37}} {%endif%} {%endif%}>{{beam.get_downvalues.36}}</span></td>
247 <td title='{{module_messages.38}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="138" {%else%} {{color_status.38}} {%endif%} {%endif%}>{{beam.get_downvalues.37}}</span></td>
248 <td title='{{module_messages.39}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="139" {%else%} {{color_status.39}} {%endif%} {%endif%}>{{beam.get_downvalues.38}}</span></td>
249 <td title='{{module_messages.40}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="140" {%else%} {{color_status.40}} {%endif%} {%endif%}>{{beam.get_downvalues.39}}</span></td>
250 </tr>
251 <tr>
252 <td title='{{module_messages.45}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="45" {%else%} {{color_status.45}} {%endif%} {%endif%}>{{beam.get_upvalues.44}}</span></td>
253 <td title='{{module_messages.46}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="46" {%else%} {{color_status.46}} {%endif%} {%endif%}>{{beam.get_upvalues.45}}</span></td>
254 <td title='{{module_messages.47}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="47" {%else%} {{color_status.47}} {%endif%} {%endif%}>{{beam.get_upvalues.46}}</span></td>
255 <td title='{{module_messages.48}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="48" {%else%} {{color_status.48}} {%endif%} {%endif%}>{{beam.get_upvalues.47}}</span></td>
256 </tr>
257 <tr>
258 <td title='{{module_messages.45}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="145" {%else%} {{color_status.45}} {%endif%} {%endif%}>{{beam.get_downvalues.44}}</span></td>
259 <td title='{{module_messages.46}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="146" {%else%} {{color_status.46}} {%endif%} {%endif%}>{{beam.get_downvalues.45}}</span></td>
260 <td title='{{module_messages.47}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="147" {%else%} {{color_status.47}} {%endif%} {%endif%}>{{beam.get_downvalues.46}}</span></td>
261 <td title='{{module_messages.48}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="148" {%else%} {{color_status.48}} {%endif%} {%endif%}>{{beam.get_downvalues.47}}</span></td>
262 </tr>
263 <tr>
264 <td title='{{module_messages.53}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="53" {%else%} {{color_status.53}} {%endif%} {%endif%}>{{beam.get_upvalues.52}}</span></td>
265 <td title='{{module_messages.54}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="54" {%else%} {{color_status.54}} {%endif%} {%endif%}>{{beam.get_upvalues.53}}</span></td>
266 <td title='{{module_messages.55}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="55" {%else%} {{color_status.55}} {%endif%} {%endif%}>{{beam.get_upvalues.54}}</span></td>
267 <td title='{{module_messages.56}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="56" {%else%} {{color_status.56}} {%endif%} {%endif%}>{{beam.get_upvalues.55}}</span></td>
268 </tr>
269 <tr>
270 <td title='{{module_messages.53}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="153" {%else%} {{color_status.53}} {%endif%} {%endif%}>{{beam.get_downvalues.52}}</span></td>
271 <td title='{{module_messages.54}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="154" {%else%} {{color_status.54}} {%endif%} {%endif%}>{{beam.get_downvalues.53}}</span></td>
272 <td title='{{module_messages.55}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="155" {%else%} {{color_status.55}} {%endif%} {%endif%}>{{beam.get_downvalues.54}}</span></td>
273 <td title='{{module_messages.56}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="156" {%else%} {{color_status.56}} {%endif%} {%endif%}>{{beam.get_downvalues.55}}</span></td>
274 </tr>
275 <tr>
276 <td title='{{module_messages.61}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="61" {%else%} {{color_status.61}} {%endif%} {%endif%}>{{beam.get_upvalues.60}}</span></td>
277 <td title='{{module_messages.62}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="62" {%else%} {{color_status.62}} {%endif%} {%endif%}>{{beam.get_upvalues.61}}</span></td>
278 <td title='{{module_messages.63}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="63" {%else%} {{color_status.63}} {%endif%} {%endif%}>{{beam.get_upvalues.62}}</span></td>
279 <td title='{{module_messages.64}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="64" {%else%} {{color_status.64}} {%endif%} {%endif%}>{{beam.get_upvalues.63}}</span></td>
280 </tr>
281 <tr>
282 <td title='{{module_messages.61}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="161" {%else%} {{color_status.61}} {%endif%} {%endif%}>{{beam.get_downvalues.60}}</span></td>
283 <td title='{{module_messages.62}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="162" {%else%} {{color_status.62}} {%endif%} {%endif%}>{{beam.get_downvalues.61}}</span></td>
284 <td title='{{module_messages.63}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="163" {%else%} {{color_status.63}} {%endif%} {%endif%}>{{beam.get_downvalues.62}}</span></td>
285 <td title='{{module_messages.64}}'><span {%if beam.pk == active_beam %} {%if mqtt%} id="164" {%else%} {{color_status.64}} {%endif%} {%endif%}>{{beam.get_downvalues.63}}</span></td>
286 </tr>
287 </table>
288 </td>
289 </tr>
290 </table>
291
292 <!-- <meta id="configuraciones_down" data-playlist="{{ beam.get_downvalues }}">
293 <meta id="configuraciones_up" data-playlist="{{ beam.get_upvalues }}">
294 <meta id="sda" data-toggle="" -->
295
296 {% if beam.id == active_beam %}
297 <table class="legend">
298 <tr>
299 <th>Legend</th>
300 </tr>
301 <tr>
302 <td class="text-warning">Connected</td>
303 </tr>
304 <tr>
305 <td class="text-success">Running</td>
306 </tr>
307 <tr>
308 <td class="text-info">Mismath</td>
309 </tr>
310 <tr>
311 <td class="text-danger">Disconnected</td>
312 </tr>
313 </table>
314 {% else %}
315 <div style="vertical-align: top; display:inline-block;">
316 <button id="send_beam{{forloop.counter}}" type="button" class="btn btn-default">
317 <span class="fas fa-external-link-square-alt" aria-hidden="true"></span>
318 Change Beam</button>
319 <br><br><br>
320 <button id="change_beam_mqtt{{forloop.counter}}" type="button" class="btn btn-default">
321 <span class="fas fa-external-link-square-alt" aria-hidden="true"></span>
322 Change Beam MQTT</button>
323 </div>
324 {% endif %}
325 </div>
326 {% endfor %}
327 </div>
328 </div>
329
330
331 {% else %}
332 <p style="color:#b4bcc2; margin-left: 5%;">
333 <i>No Beams...</i>
334 </p>
335 {% endif %}
336 {% endblock extra-content %}
337
338 {% block extra-js%}
339 <script>
340 $(document).ready(function () {
341
342 var socket = io.connect('http://' + document.domain + ':' + location.port);
343
344 socket.on('connect', function(data) {
345 console.log('Connecting... OK');
346 })
347
348 socket.on('abs_ws', function(data) {
349 console.log('ingresamos');
350 console.log(data.msg);
351 var text = data['msg'];
352 // $('#chatLog').val(text);
353
354 if(data.msg=="b\'Hola\'"){console.log('Hola_amigo')};
355 })
356
357 socket.on('beams_ack', function(data) {
358 // console.log('beams_ack');
359 var text = data['msg'];
360
361 for (let i=1; i<=64;i++){
362
363 var elemento = document.getElementById(text[i-1]);
364 var elemento2 = document.getElementById(text[i-1]+100);
365 if (text[i-1]<=64){
366 // console.log("1")
367 // elemento=document.getElementById(text[i-1]);
368 elemento.style.color="green";
369 elemento.style.fontWeight = "bold";
370 elemento2.style.color="green";
371 elemento2.style.fontWeight = "bold";}
372 else if (text[i-1]>64){
373 elemento=document.getElementById(text[i-1]-64);
374 elemento2=document.getElementById(text[i-1]-64+100);
375 elemento.style.color="blue";
376 elemento.style.fontWeight = "bold";
377 elemento2.style.color="blue";
378 elemento2.style.fontWeight = "bold"}
379 else {
380 elemento.style.color="red";
381 elemento.style.fontWeight = "bold";
382 elemento2.style.color="red";
383 elemento2.style.fontWeight = "bold"}
384 }
385 if(data.msg=="b\'Hola\'"){console.log('Hola_amigo')};
386 })
387
388
389 {% for beam in beams %}
390
391 {% if dev_conf.operation_mode == 1 %}
392 $("#send_beam{{forloop.counter}}").prop('disabled', true)
393 $("#change_beam_mqtt{{forloop.counter}}").prop('disabled', true)
394 {% else %}
395 $("#send_beam{{forloop.counter}}").click(function () {
396 document.location = "{% url 'url_send_beam' dev_conf.id beam.id %}";
397 });
398
399 change_beam_mqtt_btn=$("#change_beam_mqtt{{forloop.counter}}")
400 change_beam_mqtt_btn.click(function () {
401 document.location = "{% url 'url_change_beam_mqtt' dev_conf.id beam.id %}";
402 });
403
404 {% endif %}
405
406 {% endfor %}
407
408
409 });
410
411 </script>
412
413
414 {% endblock %}
@@ -1,1190 +1,1190
1 1 from django.db import models
2 2 from apps.main.models import Configuration , User
3 3 from django.urls import reverse
4 4 from celery.execute import send_task
5 5 from datetime import datetime
6 6 import ast
7 7 import socket
8 8 import json
9 9 import requests
10 10 import struct
11 11 import os, sys, time
12 12
13 13 from .mqtt import client as mqtt_client
14 14 from radarsys.socketconfig import sio as sio
15 15 import json
16 16
17 17 antenna_default = json.dumps({
18 18 "antenna_up": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
19 19 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
20 20 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
21 21 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
22 22 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
23 23 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
24 24 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
25 25 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0]
26 26 ]
27 27 ,
28 28 "antenna_down": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
29 29 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
30 30 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
31 31 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
32 32 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
33 33 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
34 34 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
35 35 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0]],
36 36 })
37 37
38 38
39 39 tx_default = json.dumps({
40 40 "up": [[1,1,1,1,0,0,0,0],
41 41 [1,1,1,1,0,0,0,0],
42 42 [1,1,1,1,0,0,0,0],
43 43 [1,1,1,1,0,0,0,0],
44 44 [0,0,0,0,1,1,1,1],
45 45 [0,0,0,0,1,1,1,1],
46 46 [0,0,0,0,1,1,1,1],
47 47 [0,0,0,0,1,1,1,1]],
48 48
49 49 "down": [[1,1,1,1,0,0,0,0],
50 50 [1,1,1,1,0,0,0,0],
51 51 [1,1,1,1,0,0,0,0],
52 52 [1,1,1,1,0,0,0,0],
53 53 [0,0,0,0,1,1,1,1],
54 54 [0,0,0,0,1,1,1,1],
55 55 [0,0,0,0,1,1,1,1],
56 56 [0,0,0,0,1,1,1,1]],
57 57 })
58 58
59 59 rx_default = json.dumps({
60 60 "up": [[1,1,1,1,0,0,0,0],
61 61 [1,1,1,1,0,0,0,0],
62 62 [1,1,1,1,0,0,0,0],
63 63 [1,1,1,1,0,0,0,0],
64 64 [0,0,0,0,1,1,1,1],
65 65 [0,0,0,0,1,1,1,1],
66 66 [0,0,0,0,1,1,1,1],
67 67 [0,0,0,0,1,1,1,1]],
68 68
69 69 "down": [[1,1,1,1,0,0,0,0],
70 70 [1,1,1,1,0,0,0,0],
71 71 [1,1,1,1,0,0,0,0],
72 72 [1,1,1,1,0,0,0,0],
73 73 [0,0,0,0,1,1,1,1],
74 74 [0,0,0,0,1,1,1,1],
75 75 [0,0,0,0,1,1,1,1],
76 76 [0,0,0,0,1,1,1,1]],
77 77 })
78 78
79 79 status_default = '0000000000000000000000000000000000000000000000000000000000000000'
80 80 default_messages = {}
81 81
82 82 for i in range(1,65):
83 83 default_messages[str(i)] = "Module "+str(i)
84 84
85 85
86 86 ues_default = json.dumps({
87 87 "up": [0.533333,0.00000,1.06667,0.00000],
88 88 "down": [0.533333,0.00000,1.06667,0.00000]
89 89 })
90 90
91 91 onlyrx_default = json.dumps({
92 92 "up": False,
93 93 "down": False
94 94 })
95 95
96 96 def up_convertion(cadena):
97 97 valores = []
98 98 for c in cadena:
99 99 if c == 1.0: valores=valores+['000']
100 100 if c == 2.0: valores=valores+['001']
101 101 if c == 3.0: valores=valores+['010']
102 102 if c == 0.0: valores=valores+['011']
103 103 if c == 0.5: valores=valores+['100']
104 104 if c == 1.5: valores=valores+['101']
105 105 if c == 2.5: valores=valores+['110']
106 106 if c == 3.5: valores=valores+['111']
107 107
108 108 return valores
109 109
110 110 def up_conv_bits(value):
111 111
112 112 if value == 1.0: bits="000"
113 113 if value == 2.0: bits="001"
114 114 if value == 3.0: bits="010"
115 115 if value == 0.0: bits="011"
116 116 if value == 0.5: bits="100"
117 117 if value == 1.5: bits="101"
118 118 if value == 2.5: bits="110"
119 119 if value == 3.5: bits="111"
120 120
121 121 return bits
122 122
123 123 def down_convertion(cadena):
124 124 valores = []
125 125 for c in cadena:
126 126 if c == 1.0: valores=valores+['000']
127 127 if c == 2.0: valores=valores+['001']
128 128 if c == 3.0: valores=valores+['010']
129 129 if c == 0.0: valores=valores+['011']
130 130 if c == 0.5: valores=valores+['100']
131 131 if c == 1.5: valores=valores+['101']
132 132 if c == 2.5: valores=valores+['110']
133 133 if c == 3.5: valores=valores+['111']
134 134
135 135 return valores
136 136
137 137 def down_conv_bits(value):
138 138
139 139 if value == 1.0: bits="000"
140 140 if value == 2.0: bits="001"
141 141 if value == 3.0: bits="010"
142 142 if value == 0.0: bits="011"
143 143 if value == 0.5: bits="100"
144 144 if value == 1.5: bits="101"
145 145 if value == 2.5: bits="110"
146 146 if value == 3.5: bits="111"
147 147
148 148 return bits
149 149
150 150 def up_conv_value(bits):
151 151
152 152 if bits == "000": value=1.0
153 153 if bits == "001": value=2.0
154 154 if bits == "010": value=3.0
155 155 if bits == "011": value=0.0
156 156 if bits == "100": value=0.5
157 157 if bits == "101": value=1.5
158 158 if bits == "110": value=2.5
159 159 if bits == "111": value=3.5
160 160
161 161 return value
162 162
163 163 def down_conv_value(bits):
164 164
165 165 if bits == "000": value=1.0
166 166 if bits == "001": value=2.0
167 167 if bits == "010": value=3.0
168 168 if bits == "011": value=0.0
169 169 if bits == "100": value=0.5
170 170 if bits == "101": value=1.5
171 171 if bits == "110": value=2.5
172 172 if bits == "111": value=3.5
173 173
174 174 return value
175 175
176 176 def ip2position(module_number):
177 177 j=0
178 178 i=0
179 179 for x in range(0,module_number-1):
180 180 j=j+1
181 181 if j==8:
182 182 i=i+1
183 183 j=0
184 184
185 185 pos = [i,j]
186 186 return pos
187 187
188 188
189 189 def fromBinary2Char(binary_string):
190 190 number = int(binary_string, 2)
191 191 #Plus 33 to avoid more than 1 characters values such as: '\x01'-'\x1f'
192 192 number = number + 33
193 193 char = chr(number)
194 194 return char
195 195
196 196 def fromChar2Binary(char):
197 197 number = ord(char) - 33
198 198 #Minus 33 to get the real value
199 199 bits = bin(number)[2:]
200 200 #To ensure we have a string with 6bits
201 201 if len(bits) < 6:
202 202 bits = bits.zfill(6)
203 203 return bits
204 204
205 205 OPERATION_MODES = (
206 206 (0, 'Manual'),
207 207 (1, 'Automatic'),
208 208 )
209 209
210 210 class ABSConfiguration(Configuration):
211 211 active_beam = models.PositiveSmallIntegerField(verbose_name='Active Beam', default=0)
212 212 module_status = models.CharField(verbose_name='Module Status', max_length=10000, default=status_default)
213 213 operation_mode = models.PositiveSmallIntegerField(verbose_name='Operation Mode', choices=OPERATION_MODES, default = 0)
214 214 operation_value = models.FloatField(verbose_name='Periodic (seconds)', default="10", null=True, blank=True)
215 215 module_messages = models.CharField(verbose_name='Modules Messages', max_length=10000, default=json.dumps(default_messages))
216 216
217 217 class Meta:
218 218 db_table = 'abs_configurations'
219 219
220 220 def get_absolute_url_plot(self):
221 221 return reverse('url_plot_abs_patterns', args=[str(self.id)])
222 222
223 223
224 224 def parms_to_dict(self):
225 225
226 226 parameters = {}
227 227
228 228 parameters['device_id'] = self.device.id
229 229 parameters['label'] = self.label
230 230 parameters['device_type'] = self.device.device_type.name
231 231 parameters['beams'] = {}
232 232
233 233 beams = ABSBeam.objects.filter(abs_conf=self)
234 234 b=1
235 235 for beam in beams:
236 236 #absbeam = ABSBeam.objects.get(pk=beams[beam])
237 237 parameters['beams']['beam'+str(b)] = beam.parms_to_dict()#absbeam.parms_to_dict()
238 238 b+=1
239 239
240 240 return parameters
241 241
242 242
243 243 def dict_to_parms(self, parameters):
244 244
245 245 self.label = parameters['label']
246 246
247 247 absbeams = ABSBeam.objects.filter(abs_conf=self)
248 248 beams = parameters['beams']
249 249
250 250 if absbeams:
251 251 beams_number = len(beams)
252 252 absbeams_number = len(absbeams)
253 253 if beams_number==absbeams_number:
254 254 i = 1
255 255 for absbeam in absbeams:
256 256 absbeam.dict_to_parms(beams['beam'+str(i)])
257 257 i = i+1
258 258 elif beams_number > absbeams_number:
259 259 i = 1
260 260 for absbeam in absbeams:
261 261 absbeam.dict_to_parms(beams['beam'+str(i)])
262 262 i=i+1
263 263 for x in range(i,beams_number+1):
264 264 new_beam = ABSBeam(
265 265 name =beams['beam'+str(i)]['name'],
266 266 antenna =json.dumps(beams['beam'+str(i)]['antenna']),
267 267 abs_conf = self,
268 268 tx =json.dumps(beams['beam'+str(i)]['tx']),
269 269 rx =json.dumps(beams['beam'+str(i)]['rx']),
270 270 ues =json.dumps(beams['beam'+str(i)]['ues']),
271 271 only_rx =json.dumps(beams['beam'+str(i)]['only_rx'])
272 272 )
273 273 new_beam.save()
274 274 i=i+1
275 275 else: #beams_number < absbeams_number:
276 276 i = 1
277 277 for absbeam in absbeams:
278 278 if i <= beams_number:
279 279 absbeam.dict_to_parms(beams['beam'+str(i)])
280 280 i=i+1
281 281 else:
282 282 absbeam.delete()
283 283 else:
284 284 for beam in beams:
285 285 new_beam = ABSBeam(
286 286 name =beams[beam]['name'],
287 287 antenna =json.dumps(beams[beam]['antenna']),
288 288 abs_conf = self,
289 289 tx =json.dumps(beams[beam]['tx']),
290 290 rx =json.dumps(beams[beam]['rx']),
291 291 ues =json.dumps(beams[beam]['ues']),
292 292 only_rx =json.dumps(beams[beam]['only_rx'])
293 293 )
294 294 new_beam.save()
295 295
296 296
297 297
298 298 def update_from_file(self, parameters):
299 299
300 300 self.dict_to_parms(parameters)
301 301 self.save()
302 302
303 303
304 304 def get_beams(self, **kwargs):
305 305 '''
306 306 This function returns ABS Configuration beams
307 307 '''
308 308 return ABSBeam.objects.filter(abs_conf=self.pk, **kwargs)
309 309
310 310 def clone(self, **kwargs):
311 311
312 312 beams = self.get_beams()
313 313 self.pk = None
314 314 self.id = None
315 315 for attr, value in kwargs.items():
316 316 setattr(self, attr, value)
317 317 self.save()
318 318
319 319 for beam in beams:
320 320 beam.clone(abs_conf=self)
321 321
322 322 #-----For Active Beam-----
323 323 new_beams = ABSBeam.objects.filter(abs_conf=self)
324 324 self.active_beam = new_beams[0].id
325 325 self.save()
326 326 #-----For Active Beam-----
327 327 #-----For Device Status---
328 328 self.device.status = 3
329 329 self.device.save()
330 330 #-----For Device Status---
331 331
332 332 return self
333 333
334 334
335 335 def start_device(self):
336 336
337 337 if self.device.status == 3:
338 338
339 339 try:
340 340 #self.write_device()
341 341 send_task('task_change_beam', [self.id],)
342 342 # print("*************************RUNNING ABS**************************",flush=True)
343 343 self.message = 'ABS running'
344 344
345 345 except Exception as e:
346 346 self.message = str(e)
347 347 return False
348 348
349 349 return True
350 350
351 351 else:
352 352 self.message = 'Please, select Write ABS Device first.'
353 353 return False
354 354
355 355
356 356 def stop_device(self):
357 357 self.device.status = 2
358 358 self.active_beam = 0
359 359 self.device.save()
360 360 self.message = 'ABS has been stopped.'
361 361 self.save()
362 362
363 363 return True
364 364
365 365 def stop_device_mqtt(self):
366 366
367 367 self.device.status = 2
368 368 self.active_beam = 0
369 369 # conf_active = None
370 370 # conf_active.save()
371 371 self.device.save()
372 372 self.message = 'ABS has been stopped.'
373 373 self.save()
374 374
375 375 mqtt_client.publish(os.environ.get('TOPIC_ABS', 'abs/beams'),"STOP")
376 376
377 377 return True
378 378
379 379 def write_device(self):
380 380
381 381 """
382 382 This function sends the beams list to every abs module.
383 383 It needs 'module_conf' function
384 384 """
385 385
386 386 beams = ABSBeam.objects.filter(abs_conf=self)
387 387 nbeams = len(beams)
388 388
389 389 # Se manda a cero RC para poder realizar cambio de beam
390 390 if self.experiment is None:
391 391 confs = []
392 392 else:
393 393 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
394 394 confdds = ''
395 395 confjars = ''
396 396 confrc = ''
397 397 #TO STOP DEVICES: DDS-JARS-RC
398 398 for i in range(0,len(confs)):
399 399 if i==0:
400 400 for conf in confs:
401 401 if conf.device.device_type.name == 'dds':
402 402 confdds = conf
403 403 confdds.stop_device()
404 404 break
405 405 if i==1:
406 406 for conf in confs:
407 407 if conf.device.device_type.name == 'jars':
408 408 confjars = conf
409 409 confjars.stop_device()
410 410 break
411 411 if i==2:
412 412 for conf in confs:
413 413 if conf.device.device_type.name == 'rc':
414 414 confrc = conf
415 415 confrc.stop_device()
416 416 break
417 417
418 418 '''
419 419 if self.connected_modules() == 0 :
420 420 print("No encuentra modulos")
421 421 self.message = "No ABS Module detected."
422 422 return False
423 423 '''
424 424 #-------------Write each abs module-----------
425 425
426 426 if beams:
427 427 block_id = 0
428 428 message = 'SNDF{:03d}{:02d}{:02d}'.format(nbeams, nbeams, block_id)
429 429 for i, status in enumerate(self.module_status):
430 430 message += ''.join([fromBinary2Char(beam.module_6bits(i)) for beam in beams])
431 431 status = ['0'] * 64
432 432 n = 0
433 433 print("Estoy en write_device normal",flush=True)
434 434 sock = self.send_multicast(message)
435 435
436 436 while True:
437 437 #for i in range(32):
438 438 try:
439 439 data, address = sock.recvfrom(1024)
440 440 print (address, data)
441 441 data = data.decode("utf-8")
442 442 if data == '1':
443 443 status[int(address[0][10:])-1] = '3'
444 444 #print (int(address[0][10:])-1)
445 445 elif data == '0':
446 446 status[int(address[0][10:])-1] = '1'
447 447 except socket.timeout:
448 448 print('Timeout')
449 449 break
450 450 except Exception as e:
451 451 print ('Error {}'.format(e))
452 452 n += 1
453 453 sock.close()
454 454 else:
455 455 self.message = "ABS Configuration does not have beams"
456 456 # print('No beams')
457 457 #Start DDS-RC-JARS
458 458 if confdds:
459 459 confdds.start_device()
460 460 if confrc:
461 461 #print confrc
462 462 confrc.start_device()
463 463 if confjars:
464 464 confjars.start_device()
465 465 return False
466 466
467 467 if n == 64:
468 468 self.message = "Could not write ABS Modules"
469 469 self.device.status = 0
470 470 self.module_status = ''.join(status)
471 471 self.save()
472 472 # print('Could not write ABS')
473 473 #Start DDS-RC-JARS
474 474 if confdds:
475 475 confdds.start_device()
476 476 if confrc:
477 477 #print confrc
478 478 confrc.start_device()
479 479 if confjars:
480 480 confjars.start_device()
481 481 return False
482 482 else:
483 483 self.message = "ABS Beams List have been sent to ABS Modules"
484 484 print('ABS beams list sent')
485 485 self.active_beam = beams[0].pk
486 486
487 487 #Start DDS-RC-JARS
488 488 if confdds:
489 489 confdds.start_device()
490 490 if confrc:
491 491 #print confrc
492 492 confrc.start_device()
493 493 if confjars:
494 494 confjars.start_device()
495 495
496 496 # print('Inicia intento de salvar device.status')
497 497 self.device.status = 3
498 498 self.module_status = ''.join(status)
499 499 #print(status)
500 500 self.save()
501 501 # print('Estatus salvado')
502 502 conf_active, __ = ABSActive.objects.get_or_create(pk=1)
503 503 conf_active.conf = self
504 504 conf_active.save()
505 505 return True
506 506
507 507
508 508 # DEV_STATES = (
509 509 # (0, 'No connected'),
510 510 # (1, 'Connected'),
511 511 # (2, 'Configured'),
512 512 # (3, 'Running'),
513 513 # (4, 'Unknown'),
514 514 # (5, 'Busy')
515 515 # )
516 516
517 517 def write_device_mqtt(self):
518 518
519 519 if self.experiment is None:
520 520 confs = []
521 521 else:
522 522 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
523 523 confdds = ''
524 524 confjars = ''
525 525 confrc = ''
526 526 #TO STOP DEVICES: DDS-JARS-RC
527 527 for i in range(0,len(confs)):
528 528 if i==0:
529 529 for conf in confs:
530 530 if conf.device.device_type.name == 'dds':
531 531 confdds = conf
532 532 confdds.stop_device()
533 533 break
534 534 if i==1:
535 535 for conf in confs:
536 536 if conf.device.device_type.name == 'jars':
537 537 confjars = conf
538 538 confjars.stop_device()
539 539 break
540 540 if i==2:
541 541 for conf in confs:
542 542 if conf.device.device_type.name == 'rc':
543 543 confrc = conf
544 544 confrc.stop_device()
545 545 break
546 546
547 547 apuntes_up_down=''
548 548 beams = ABSBeam.objects.filter(abs_conf=self)
549 549
550 550 inicializacion="{\"beams\":["
551 551 finalizacion="]}"
552 552
553 553 for beam in beams:
554 554 beam.antenna=beam.antenna[1:]
555 555 info="{\"id\":"+str(beam.id)+","+beam.antenna + ","
556 556 apuntes_up_down=apuntes_up_down+info
557 557
558 558 apuntes_up_down=apuntes_up_down[:len(apuntes_up_down)-1]
559 559 apuntes_up_down=inicializacion+ apuntes_up_down+finalizacion
560 560 mqtt_client.publish(os.environ.get('TOPIC_ABS', 'abs/beams'),apuntes_up_down)
561 561
562 562 self.active_beam = beams[0].pk
563 563
564 564 #Start DDS-RC-JARS
565 565 if confdds:
566 566 confdds.start_device()
567 567 if confrc:
568 568 #print confrc
569 569 confrc.start_device()
570 570 if confjars:
571 571 confjars.start_device()
572 572
573 573 self.device.status = 3
574 574 self.save()
575 575
576 576 conf_active, __ = ABSActive.objects.get_or_create(pk=1)
577 577 conf_active.conf = self
578 578 conf_active.save()
579 579 return True
580 580
581 581 def read_module(self, module):
582 582
583 583 """
584 584 Read out-bits (up-down) of 1 abs module NOT for Configuration
585 585 """
586 586
587 587 ip_address = self.device.ip_address
588 588 ip_address = ip_address.split('.')
589 589 module_seq = (ip_address[0],ip_address[1],ip_address[2])
590 590 dot = '.'
591 591 module_ip = dot.join(module_seq)+'.'+str(module)
592 592 module_port = self.device.port_address
593 593 read_route = 'http://'+module_ip+':'+str(module_port)+'/read'
594 594
595 595 module_status = json.loads(self.module_status)
596 596 print(read_route)
597 597
598 598 module_bits = ''
599 599
600 600 try:
601 601 r_read = requests.get(read_route, timeout=0.5)
602 602 answer = r_read.json()
603 603 module_bits = answer['allbits']
604 604 except:
605 605 return {}
606 606
607 607 return module_bits
608 608
609 609 def read_device(self):
610 610
611 611 parms = {}
612 612 # Reads active modules.
613 613 module_status = json.loads(self.module_status)
614 614 total = 0
615 615 for status in module_status:
616 616 if module_status[status] != 0:
617 617 module_bits = self.read_module(int(status))
618 618 bits={}
619 619 if module_bits:
620 620 bits = (str(module_bits['um2']) + str(module_bits['um1']) + str(module_bits['um0']) +
621 621 str(module_bits['dm2']) + str(module_bits['dm1']) + str(module_bits['dm0']) )
622 622 parms[str(status)] = bits
623 623
624 624 total +=1
625 625
626 626 if total==0:
627 627 self.message = "No ABS Module detected. Please select 'Status'."
628 628 return False
629 629
630 630
631 631
632 632 self.message = "ABS Modules have been read"
633 633 #monitoreo_tx = JROABSClnt_01CeCnMod000000MNTR10
634 634 return parms
635 635
636 636
637 637 def connected_modules(self):
638 638 """
639 639 This function returns the number of connected abs-modules without updating.
640 640 """
641 641 num = 0
642 642 print(self.module_status)
643 643 for i, status in enumerate(self.module_status):
644 644 if status != '0':
645 645 num += 1
646 646 #print('status {}:{}'.format(i+1, status))
647 647 return num
648 648
649 649 def send_multicast(self, message):
650 650 #print("Send multicast")
651 651 multicast_group = ('224.3.29.71', 10000)
652 652 # Create the datagram socket
653 653 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
654 654 sock.settimeout(1)
655 655 local_ip = os.environ.get('LOCAL_IP', '0.0.0.0')
656 656 local_ip = '0.0.0.0'
657 657 print("He llegado a IP local")
658 658
659 659 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(local_ip))
660 660 sock.sendto(message.encode(), multicast_group)
661 661 print('Sending ' + message)
662 662 return sock
663 663
664 664 def status_device(self):
665 665 """
666 666 This function returns the status of all abs-modules as one.
667 667 If at least one module is connected, its answer is "1"
668 668 """
669 669 print ('Status device')
670 670 print (self.active_beam)
671 671 beams = ABSBeam.objects.filter(abs_conf=self)
672 672 #print beams[self.active_beam-1].module_6bits(0)
673 673 active = ABSActive.objects.get(pk=1)
674 674 if active.conf != self:
675 675 self.message = 'La configuracion actual es la del siguiente enlace %s.' % active.conf.get_absolute_url()
676 676 self.message += "\n"
677 677 self.message += 'Se debe realizar un write en esta configuracion para luego obtener un status valido.'
678 678
679 679 return False
680 680
681 681 sock = self.send_multicast('MNTR')
682 682 print("Estoy en status_deice",flush=True)
683 683
684 684 n = 0
685 685 status = ['0'] * 64
686 686
687 687 while True:
688 688 #for i in range(32):
689 689 #if True:
690 690 try:
691 691 print("Recibiendo")
692 692 address = None
693 693 data, address = sock.recvfrom(2)
694 694 print (address, data)
695 695 print("!!!!")
696 696 data = data.decode()
697 697 aux_mon = "1"
698 698 aux_expected = aux_mon
699 699 if(len(data)==2):
700 700 print ("data[1]: ")
701 701 print (data[1])
702 702 aux_mon = fromChar2Binary(data[1])
703 703 print (aux_mon)
704 704 aux_i = (str(address[0]).split('.'))[3]
705 705 print (aux_i)
706 706 print ('Active beam')
707 707 beam_active = ABSBeam.objects.get(pk=self.active_beam)
708 708 print (beam_active)
709 709 aux_expected = beam_active.module_6bits(int(aux_i)-1)
710 710 print (aux_expected)
711 711
712 712 print ("data[0]: ")
713 713 print (data[0])
714 714
715 715 if data[0] == '1':
716 716 status[int(address[0][10:])-1] = '3'
717 717 if aux_mon == aux_expected:
718 718 print ('Es igual')
719 719 else:
720 720 print ('Es diferente')
721 721 status[int(address[0][10:])-1] = '2'
722 722
723 723 elif data[0] == '0':
724 724 status[int(address[0][10:])-1] = '1'
725 725 n += 1
726 726 print('Module: {} connected'.format(address))
727 727 except socket.timeout:
728 728 print('Timeout')
729 729 break
730 730 except:
731 731 print('Module: {} error'.format(address))
732 732 pass
733 733
734 734 sock.close()
735 735
736 736 if n > 0:
737 737 self.message = 'ABS modules Status have been updated.'
738 738 self.device.status = 1
739 739 else:
740 740 self.device.status = 0
741 741 self.message = 'No ABS module is connected.'
742 742 self.module_status = ''.join(status)
743 743 self.save()
744 744
745 745 return self.device.status
746 746
747 747
748 748 def send_beam(self, beam_pos):
749 749 """
750 750 This function connects to a multicast group and sends the beam number
751 751 to all abs modules.
752 752 """
753 753 print ('Send beam')
754 754 print (self.active_beam)
755 755 beams = ABSBeam.objects.filter(abs_conf=self)
756 756 #print beams[self.active_beam-1].module_6bits(0)
757 757 active = ABSActive.objects.get(pk=1)
758 758 if active.conf != self:
759 759 self.message = 'La configuracion actual es la del siguiente enlace %s.' % active.conf.get_absolute_url()
760 760 self.message += "\n"
761 761 self.message += 'Se debe realizar un write en esta configuracion para luego obtener un status valido.'
762 762
763 763 return False
764 764
765 765 # Se manda a cero RC para poder realizar cambio de beam
766 766 if self.experiment is None:
767 767 confs = []
768 768 else:
769 769 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
770 770 confdds = ''
771 771 confjars = ''
772 772 confrc = ''
773 773 #TO STOP DEVICES: DDS-JARS-RC
774 774 for i in range(0,len(confs)):
775 775 if i==0:
776 776 for conf in confs:
777 777 if conf.device.device_type.name == 'dds':
778 778 confdds = conf
779 779 confdds.stop_device()
780 780 break
781 781 if i==1:
782 782 for conf in confs:
783 783 if conf.device.device_type.name == 'jars':
784 784 confjars = conf
785 785 confjars.stop_device()
786 786 break
787 787 if i==2:
788 788 for conf in confs:
789 789 if conf.device.device_type.name == 'rc':
790 790 confrc = conf
791 791 confrc.stop_device()
792 792 break
793 793 if beam_pos > 0:
794 794 beam_pos = beam_pos - 1
795 795 else:
796 796 beam_pos = 0
797 797
798 798 #El indice del apunte debe ser menor que el numero total de apuntes
799 799 #El servidor tcp en el embebido comienza a contar desde 0
800 800 status = ['0'] * 64
801 801 message = 'CHGB{}'.format(beam_pos)
802 802 sock = self.send_multicast(message)
803 803 print("Estoy en send_beam ",flush=True)
804 804 while True:
805 805 #for i in range(32):
806 806 try:
807 807 data, address = sock.recvfrom(1024)
808 808 print (address, data)
809 809 data = data.decode()
810 810 if data == '1':
811 811 status[int(address[0][10:])-1] = '3'
812 812 elif data == '0':
813 813 status[int(address[0][10:])-1] = '1'
814 814 except socket.timeout:
815 815 print('Timeout')
816 816 break
817 817 except Exception as e:
818 818 print ('Error {}'.format(e))
819 819 pass
820 820
821 821 sock.close()
822 822
823 823 #Start DDS-RC-JARS
824 824 if confdds:
825 825 confdds.start_device()
826 826 if confrc:
827 827 #print confrc
828 828 confrc.start_device()
829 829 if confjars:
830 830 confjars.start_device()
831 831
832 832 self.message = "ABS Beam has been changed"
833 833 self.module_status = ''.join(status)
834 834 self.save()
835 835 return True
836 836
837 837 def change_beam_mqtt(self, beam_pos):
838 838 """
839 This function connects to a multicast group and sends the beam number
840 to all abs modules.
839 This function connects send through mqtt the order of change_beam (id of beam).
841 840 """
842 print ('Send beam')
841 print ('Change beam MQTT')
843 842 print (self.active_beam)
844 843 beams = ABSBeam.objects.filter(abs_conf=self)
845 844 #print beams[self.active_beam-1].module_6bits(0)
846 845 active = ABSActive.objects.get(pk=1)
847 846 if active.conf != self:
848 self.message = 'La configuracion actual es la del siguiente enlace %s.' % active.conf.get_absolute_url()
847 self.message = 'La configuracion actual es la del siguiente enlace %s.' % active.conf.get_absolute_mqtt_url()
849 848 self.message += "\n"
850 849 self.message += 'Se debe realizar un write en esta configuracion para luego obtener un status valido.'
851 850
852 851 return False
853 852
854 853 # Se manda a cero RC para poder realizar cambio de beam
855 854 if self.experiment is None:
856 855 confs = []
857 856 else:
858 857 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
859 858 confdds = ''
860 859 confjars = ''
861 860 confrc = ''
862 861 #TO STOP DEVICES: DDS-JARS-RC
863 862 for i in range(0,len(confs)):
864 863 if i==0:
865 864 for conf in confs:
866 865 if conf.device.device_type.name == 'dds':
867 866 confdds = conf
868 867 confdds.stop_device()
869 868 break
870 869 if i==1:
871 870 for conf in confs:
872 871 if conf.device.device_type.name == 'jars':
873 872 confjars = conf
874 873 confjars.stop_device()
875 874 break
876 875 if i==2:
877 876 for conf in confs:
878 877 if conf.device.device_type.name == 'rc':
879 878 confrc = conf
880 879 confrc.stop_device()
881 880 break
882 881 if beam_pos > 0:
883 882 beam_pos = beam_pos - 1
884 883 else:
885 884 beam_pos = 0
886 885
887 886 #El indice del apunte debe ser menor que el numero total de apuntes
888 887 #El servidor tcp en el embebido comienza a contar desde 0
889 888 # status = ['0'] * 64
890 889 # message = 'CHGB{}'.format(beam_pos)
891 890 # sock = self.send_multicast(message)
892 891 # while True:
893 892 # #for i in range(32):
894 893 # try:
895 894 # data, address = sock.recvfrom(1024)
896 895 # print (address, data)
897 896 # data = data.decode()
898 897 # if data == '1':
899 898 # status[int(address[0][10:])-1] = '3'
900 899 # elif data == '0':
901 900 # status[int(address[0][10:])-1] = '1'
902 901 # except socket.timeout:
903 902 # print('Timeout')
904 903 # break
905 904 # except Exception as e:
906 905 # print ('Error {}'.format(e))
907 906 # pass
908 907
909 908 # sock.close()
909 mqtt_client.publish('abs/change_beam',str(beam_pos))
910
910 911
911 912 #Start DDS-RC-JARS
912 913 if confdds:
913 914 confdds.start_device()
914 915 if confrc:
915 916 #print confrc
916 917 confrc.start_device()
917 918 if confjars:
918 919 confjars.start_device()
919 920
920 921 self.message = "ABS Beam has been changed"
921 self.module_status = ''.join(status)
922 922 self.save()
923 923 return True
924 924
925 925 def get_absolute_url_import(self):
926 926 return reverse('url_import_abs_conf', args=[str(self.id)])
927 927
928 928 class ABSActive(models.Model):
929 929 conf = models.ForeignKey(ABSConfiguration, null=True, verbose_name='ABS Configuration', on_delete=models.CASCADE)
930 930
931 931 class Meta:
932 932 db_table = 'abs_absactive'
933 933
934 934 class ABSBeam(models.Model):
935 935
936 936 name = models.CharField(max_length=60, default='Beam')
937 937 antenna = models.CharField(verbose_name='Antenna', max_length=1000, default=antenna_default)
938 938 abs_conf = models.ForeignKey('ABSConfiguration', null=True,
939 939 verbose_name='ABS Configuration', on_delete=models.CASCADE)
940 940 tx = models.CharField(verbose_name='Tx', max_length=1000, default=tx_default)
941 941 rx = models.CharField(verbose_name='Rx', max_length=1000, default=rx_default)
942 942 s_time = models.TimeField(verbose_name='Star Time', default='00:00:00')
943 943 e_time = models.TimeField(verbose_name='End Time', default='23:59:59')
944 944 ues = models.CharField(verbose_name='Ues', max_length=100, default=ues_default)
945 945 only_rx = models.CharField(verbose_name='Only RX', max_length=40, default=onlyrx_default)
946 946
947 947 class Meta:
948 948 db_table = 'abs_beams'
949 949
950 950 def __unicode__(self):
951 951 return u'%s' % (self.name)
952 952
953 953 def parms_to_dict(self):
954 954
955 955 parameters = {}
956 956 parameters['name'] = self.name
957 957 parameters['antenna'] = ast.literal_eval(self.antenna)
958 958 parameters['abs_conf'] = self.abs_conf.name
959 959 parameters['tx'] = ast.literal_eval(self.tx)
960 960 parameters['rx'] = ast.literal_eval(self.rx)
961 961 parameters['s_time'] = self.s_time.strftime("%H:%M:%S")
962 962 parameters['e_time'] = self.e_time.strftime("%H:%M:%S")
963 963 parameters['ues'] = ast.literal_eval(self.ues)
964 964 parameters['only_rx'] = json.loads(self.only_rx)
965 965
966 966 return parameters
967 967
968 968 def dict_to_parms(self, parameters):
969 969
970 970 self.name = parameters['name']
971 971 self.antenna = json.dumps(parameters['antenna'])
972 972 #self.abs_conf = parameters['abs_conf']
973 973 self.tx = json.dumps(parameters['tx'])
974 974 self.rx = json.dumps(parameters['rx'])
975 975 #self.s_time = parameters['s_time']
976 976 #self.e_time = parameters['e_time']
977 977 self.ues = json.dumps(parameters['ues'])
978 978 self.only_rx = json.dumps(parameters['only_rx'])
979 979 self.save()
980 980
981 981
982 982 def clone(self, **kwargs):
983 983
984 984 self.pk = None
985 985 self.id = None
986 986 for attr, value in kwargs.items():
987 987 setattr(self, attr, value)
988 988
989 989 self.save()
990 990
991 991 return self
992 992
993 993
994 994 def module_6bits(self, module):
995 995 """
996 996 This function reads antenna pattern and choose 6bits (upbits-downbits) for one abs module
997 997 """
998 998 module += 1
999 999 if module > 64:
1000 1000 beam_bits = ""
1001 1001 return beam_bits
1002 1002
1003 1003 data = ast.literal_eval(self.antenna)
1004 1004 up_data = data['antenna_up']
1005 1005 down_data = data['antenna_down']
1006 1006
1007 1007 pos = ip2position(module)
1008 1008 up_value = up_data[pos[0]][pos[1]]
1009 1009 down_value = down_data[pos[0]][pos[1]]
1010 1010
1011 1011 up_bits = up_conv_bits(up_value)
1012 1012 down_bits = down_conv_bits(down_value)
1013 1013 beam_bits = up_bits+down_bits
1014 1014
1015 1015 return beam_bits
1016 1016
1017 1017
1018 1018 @property
1019 1019 def get_upvalues(self):
1020 1020 """
1021 1021 This function reads antenna pattern and show the up-value of one abs module
1022 1022 """
1023 1023
1024 1024 data = ast.literal_eval(self.antenna)
1025 1025 up_data = data['antenna_up']
1026 1026
1027 1027 up_values = []
1028 1028 for data in up_data:
1029 1029 for i in range(0,8):
1030 1030 up_values.append(data[i])
1031 1031
1032 1032 return up_values
1033 1033
1034 1034 @property
1035 1035 def antenna_upvalues(self):
1036 1036 """
1037 1037 This function reads antenna pattern and show the up - values of one abs beam
1038 1038 in a particular order
1039 1039 """
1040 1040 data = ast.literal_eval(self.antenna)
1041 1041 up_data = data['antenna_up']
1042 1042
1043 1043 return up_data
1044 1044
1045 1045 @property
1046 1046 def antenna_downvalues(self):
1047 1047 """
1048 1048 This function reads antenna pattern and show the down - values of one abs beam
1049 1049 in a particular order
1050 1050 """
1051 1051 data = ast.literal_eval(self.antenna)
1052 1052 down_data = data['antenna_down']
1053 1053
1054 1054 return down_data
1055 1055
1056 1056 @property
1057 1057 def get_downvalues(self):
1058 1058 """
1059 1059 This function reads antenna pattern and show the down-value of one abs module
1060 1060 """
1061 1061
1062 1062 data = ast.literal_eval(self.antenna)
1063 1063 down_data = data['antenna_down']
1064 1064
1065 1065 down_values = []
1066 1066 for data in down_data:
1067 1067 for i in range(0,8):
1068 1068 down_values.append(data[i])
1069 1069
1070 1070 return down_values
1071 1071
1072 1072 @property
1073 1073 def get_up_ues(self):
1074 1074 """
1075 1075 This function shows the up-ues-value of one beam
1076 1076 """
1077 1077 data = ast.literal_eval(self.ues)
1078 1078 up_ues = data['up']
1079 1079
1080 1080 return up_ues
1081 1081
1082 1082 @property
1083 1083 def get_down_ues(self):
1084 1084 """
1085 1085 This function shows the down-ues-value of one beam
1086 1086 """
1087 1087 data = ast.literal_eval(self.ues)
1088 1088 down_ues = data['down']
1089 1089
1090 1090 return down_ues
1091 1091
1092 1092 @property
1093 1093 def get_up_onlyrx(self):
1094 1094 """
1095 1095 This function shows the up-onlyrx-value of one beam
1096 1096 """
1097 1097 data = json.loads(self.only_rx)
1098 1098 up_onlyrx = data['up']
1099 1099
1100 1100 return up_onlyrx
1101 1101
1102 1102 @property
1103 1103 def get_down_onlyrx(self):
1104 1104 """
1105 1105 This function shows the down-onlyrx-value of one beam
1106 1106 """
1107 1107 data = json.loads(self.only_rx)
1108 1108 down_onlyrx = data['down']
1109 1109
1110 1110 return down_onlyrx
1111 1111
1112 1112 @property
1113 1113 def get_tx(self):
1114 1114 """
1115 1115 This function shows the tx-values of one beam
1116 1116 """
1117 1117 data = json.loads(self.tx)
1118 1118
1119 1119 return data
1120 1120
1121 1121 @property
1122 1122 def get_uptx(self):
1123 1123 """
1124 1124 This function shows the up-tx-values of one beam
1125 1125 """
1126 1126 data = json.loads(self.tx)
1127 1127 up_data = data['up']
1128 1128
1129 1129 up_values = []
1130 1130 for data in up_data:
1131 1131 for i in range(0,8):
1132 1132 up_values.append(data[i])
1133 1133
1134 1134 return up_values
1135 1135
1136 1136 @property
1137 1137 def get_downtx(self):
1138 1138 """
1139 1139 This function shows the down-tx-values of one beam
1140 1140 """
1141 1141 data = json.loads(self.tx)
1142 1142 down_data = data['down']
1143 1143
1144 1144 down_values = []
1145 1145 for data in down_data:
1146 1146 for i in range(0,8):
1147 1147 down_values.append(data[i])
1148 1148
1149 1149 return down_values
1150 1150
1151 1151
1152 1152
1153 1153 @property
1154 1154 def get_rx(self):
1155 1155 """
1156 1156 This function shows the rx-values of one beam
1157 1157 """
1158 1158 data = json.loads(self.rx)
1159 1159
1160 1160 return data
1161 1161
1162 1162 @property
1163 1163 def get_uprx(self):
1164 1164 """
1165 1165 This function shows the up-rx-values of one beam
1166 1166 """
1167 1167 data = json.loads(self.rx)
1168 1168 up_data = data['up']
1169 1169
1170 1170 up_values = []
1171 1171 for data in up_data:
1172 1172 for i in range(0,8):
1173 1173 up_values.append(data[i])
1174 1174
1175 1175 return up_values
1176 1176
1177 1177 @property
1178 1178 def get_downrx(self):
1179 1179 """
1180 1180 This function shows the down-rx-values of one beam
1181 1181 """
1182 1182 data = json.loads(self.rx)
1183 1183 down_data = data['down']
1184 1184
1185 1185 down_values = []
1186 1186 for data in down_data:
1187 1187 for i in range(0,8):
1188 1188 down_values.append(data[i])
1189 1189
1190 1190 return down_values
@@ -1,426 +1,425
1 1 {% extends "dev_conf.html" %} {% load static %} {% load django_bootstrap5 %} {% load main_tags %}
2 2 {% block extra-head %}
3 3 <style>
4 4 .abs {
5 5 width: auto;
6 6 display: inline-block;
7 7 text-align: center;
8 8 }
9 9
10 10 .abs td {
11 11 padding: 4px;
12 12 }
13 13
14 14 .module td {
15 15 padding: 4px 15px 4px 15px;
16 16 font-weight: bold;
17 17 border: 1px solid
18 18 }
19 19
20 20 .legend {
21 21 margin-left: 15px;
22 22 display: inline-block;
23 23 border: 2px solid;
24 24 vertical-align: top;
25 25 }
26 26
27 27 .legend th {
28 28 border-bottom: 1px dashed;
29 29 font-weight: bold;
30 30 vertical-align: center;
31 31 text-align: center;
32 32 }
33 33
34 34 .legend td {
35 35 padding: 2px;
36 36 text-align: center;
37 37 font-weight: bold;
38 38 }
39 39
40 40 </style>
41 41 {% endblock %}
42 42
43 43
44 44 {% block extra-menu-actions %}
45 45 <li>
46 46 <a href="{{ dev_conf.get_absolute_url_plot }}" target="_blank">
47 47 <span class="far fa-image" aria-hidden="true"></span> View Patterns </a>
48 48 </li>
49 49 {% endblock %}
50 50
51 51
52 52 {% block extra-content %}
53 53 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
54 54 <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/4.4.1/socket.io.min.js">
55 55 </script>
56 56
57 57
58 58 {% if beams %}
59 <h4>Beams:</h4>
59 <h4>Beams MQTT:</h4>
60 60 <div class="container">
61 61 <ul class="nav nav-pills">
62 62 {% for beam in beams %}
63 63 <li class="nav-item">
64 64 <a {%if beam.pk == active_beam %} class="nav-link active" {% else %} class="nav-link" {% endif %} data-toggle="pill" href="#menu{{forloop.counter}}">{{forloop.counter}}</a>
65 65 </li>
66 66 {% endfor %}
67 67 </ul>
68 68
69 69 <div class="tab-content">
70 70 {% for beam in beams %}
71 71 <div id="menu{{forloop.counter}}" class="tab-pane fade {%if beam.pk == active_beam %}in active show{% endif %}">
72 72 <h3>{%if beam.pk == active_beam %}Active Beam: {%endif%}{{beam.name}}</h3>
73 73 <table id="abs_pattern{{forloop.counter}}" class="abs">
74 74 <tr>
75 75 <td>
76 76 <b>North Quarter</b>
77 77 <table class="module">
78 78 <tr>
79 <td title='{{module_messages.1}}'><span id="1" {%if beam.pk == active_beam %} {{color_status.1}} {%endif%}>{{beam.get_upvalues.0}}</span></td>
80 <td title='{{module_messages.2}}'><span id="2" {%if beam.pk == active_beam %} {{color_status.2}} {%endif%}>{{beam.get_upvalues.1}}</span></td>
81 <td title='{{module_messages.3}}'><span id="3" {%if beam.pk == active_beam %} {{color_status.3}} {%endif%}>{{beam.get_upvalues.2}}</span></td>
82 <td title='{{module_messages.4}}'><span id="4" {%if beam.pk == active_beam %} {{color_status.4}} {%endif%}>{{beam.get_upvalues.3}}</span></td>
79 <td title='{{module_messages.1}}'><span {%if beam.pk == active_beam %} id="1" {%endif%}>{{beam.get_upvalues.0}}</span></td>
80 <td title='{{module_messages.2}}'><span {%if beam.pk == active_beam %} id="2" {%endif%}>{{beam.get_upvalues.1}}</span></td>
81 <td title='{{module_messages.3}}'><span {%if beam.pk == active_beam %} id="3" {%endif%}>{{beam.get_upvalues.2}}</span></td>
82 <td title='{{module_messages.4}}'><span {%if beam.pk == active_beam %} id="4" {%endif%}>{{beam.get_upvalues.3}}</span></td>
83 83 </tr>
84 84 <tr>
85 <td title='{{module_messages.1}}'><span id="101" {%if beam.pk == active_beam %} {{color_status.1}} {%endif%}>{{beam.get_downvalues.0}}</span></td>
86 <td title='{{module_messages.2}}'><span id="102" {%if beam.pk == active_beam %} {{color_status.2}} {%endif%}>{{beam.get_downvalues.1}}</span></td>
87 <td title='{{module_messages.3}}'> <span id="103" {%if beam.pk == active_beam %} {{color_status.3}} {%endif%}>{{beam.get_downvalues.2}}</span></td>
88 <td title='{{module_messages.4}}'> <span id="104" {%if beam.pk == active_beam %} {{color_status.4}} {%endif%}>{{beam.get_downvalues.3}}</span></td>
85 <td title='{{module_messages.1}}'><span {%if beam.pk == active_beam %} id="101" {%endif%}>{{beam.get_downvalues.0}}</span></td>
86 <td title='{{module_messages.2}}'><span {%if beam.pk == active_beam %} id="102" {%endif%}>{{beam.get_downvalues.1}}</span></td>
87 <td title='{{module_messages.3}}'> <span {%if beam.pk == active_beam %} id="103" {%endif%}>{{beam.get_downvalues.2}}</span></td>
88 <td title='{{module_messages.4}}'> <span {%if beam.pk == active_beam %} id="104" {%endif%}>{{beam.get_downvalues.3}}</span></td>
89 89 </tr>
90 90 <tr>
91 <td title='{{module_messages.9}}'> <span id="9" {%if beam.pk == active_beam %} {{color_status.9}} {%endif%}>{{beam.get_upvalues.8}}</span></td>
92 <td title='{{module_messages.10}}'><span id="10" {%if beam.pk == active_beam %} {{color_status.10}} {%endif%}>{{beam.get_upvalues.9}}</span></td>
93 <td title='{{module_messages.11}}'><span id="11" {%if beam.pk == active_beam %} {{color_status.11}} {%endif%}>{{beam.get_upvalues.10}}</span></td>
94 <td title='{{module_messages.12}}'><span id="12" {%if beam.pk == active_beam %} {{color_status.12}} {%endif%}>{{beam.get_upvalues.11}}</span></td>
91 <td title='{{module_messages.9}}'> <span {%if beam.pk == active_beam %} id="9" {%endif%}>{{beam.get_upvalues.8}}</span></td>
92 <td title='{{module_messages.10}}'><span {%if beam.pk == active_beam %} id="10" {%endif%}>{{beam.get_upvalues.9}}</span></td>
93 <td title='{{module_messages.11}}'><span {%if beam.pk == active_beam %} id="11" {%endif%}>{{beam.get_upvalues.10}}</span></td>
94 <td title='{{module_messages.12}}'><span {%if beam.pk == active_beam %} id="12" {%endif%}>{{beam.get_upvalues.11}}</span></td>
95 95 </tr>
96 96 <tr>
97 <td title='{{module_messages.9}}'> <span id="109" {%if beam.pk == active_beam %} {{color_status.9}} {%endif%}>{{beam.get_downvalues.8}}</span></td>
98 <td title='{{module_messages.10}}'><span id="110" {%if beam.pk == active_beam %} {{color_status.10}} {%endif%}>{{beam.get_downvalues.9}}</span></td>
99 <td title='{{module_messages.11}}'><span id="111" {%if beam.pk == active_beam %} {{color_status.11}} {%endif%}>{{beam.get_downvalues.10}}</span></td>
100 <td title='{{module_messages.12}}'><span id="112" {%if beam.pk == active_beam %} {{color_status.12}} {%endif%}>{{beam.get_downvalues.11}}</span></td>
97 <td title='{{module_messages.9}}'> <span {%if beam.pk == active_beam %} id="109" {%endif%}>{{beam.get_downvalues.8}}</span></td>
98 <td title='{{module_messages.10}}'><span {%if beam.pk == active_beam %} id="110" {%endif%}>{{beam.get_downvalues.9}}</span></td>
99 <td title='{{module_messages.11}}'><span {%if beam.pk == active_beam %} id="111" {%endif%}>{{beam.get_downvalues.10}}</span></td>
100 <td title='{{module_messages.12}}'><span {%if beam.pk == active_beam %} id="112" {%endif%}>{{beam.get_downvalues.11}}</span></td>
101 101 </tr>
102 102 <tr>
103 <td title='{{module_messages.17}}'><span id="17" {%if beam.pk == active_beam %} {{color_status.17}} {%endif%}>{{beam.get_upvalues.16}}</span></td>
104 <td title='{{module_messages.18}}'><span id="18" {%if beam.pk == active_beam %} {{color_status.18}} {%endif%}>{{beam.get_upvalues.17}}</span></td>
105 <td title='{{module_messages.19}}'><span id="19" {%if beam.pk == active_beam %} {{color_status.19}} {%endif%}>{{beam.get_upvalues.18}}</span></td>
106 <td title='{{module_messages.20}}'><span id="20" {%if beam.pk == active_beam %} {{color_status.20}} {%endif%}>{{beam.get_upvalues.19}}</span></td>
103 <td title='{{module_messages.17}}'><span {%if beam.pk == active_beam %} id="17" {%endif%}>{{beam.get_upvalues.16}}</span></td>
104 <td title='{{module_messages.18}}'><span {%if beam.pk == active_beam %} id="18" {%endif%}>{{beam.get_upvalues.17}}</span></td>
105 <td title='{{module_messages.19}}'><span {%if beam.pk == active_beam %} id="19" {%endif%}>{{beam.get_upvalues.18}}</span></td>
106 <td title='{{module_messages.20}}'><span {%if beam.pk == active_beam %} id="20" {%endif%}>{{beam.get_upvalues.19}}</span></td>
107 107 </tr>
108 108 <tr>
109 <td title='{{module_messages.17}}'><span id="117" {%if beam.pk == active_beam %} {{color_status.17}} {%endif%}>{{beam.get_downvalues.16}}</span></td>
110 <td title='{{module_messages.18}}'><span id="118" {%if beam.pk == active_beam %} {{color_status.18}} {%endif%}>{{beam.get_downvalues.17}}</span></td>
111 <td title='{{module_messages.19}}'><span id="119" {%if beam.pk == active_beam %} {{color_status.19}} {%endif%}>{{beam.get_downvalues.18}}</span></td>
112 <td title='{{module_messages.20}}'><span id="120" {%if beam.pk == active_beam %} {{color_status.20}} {%endif%}>{{beam.get_downvalues.19}}</span></td>
109 <td title='{{module_messages.17}}'><span {%if beam.pk == active_beam %} id="117" {%endif%}>{{beam.get_downvalues.16}}</span></td>
110 <td title='{{module_messages.18}}'><span {%if beam.pk == active_beam %} id="118" {%endif%}>{{beam.get_downvalues.17}}</span></td>
111 <td title='{{module_messages.19}}'><span {%if beam.pk == active_beam %} id="119" {%endif%}>{{beam.get_downvalues.18}}</span></td>
112 <td title='{{module_messages.20}}'><span {%if beam.pk == active_beam %} id="120" {%endif%}>{{beam.get_downvalues.19}}</span></td>
113 113 </tr>
114 114 <tr>
115 <td title='{{module_messages.25}}'><span id="25" {%if beam.pk == active_beam %} {{color_status.25}} {%endif%}>{{beam.get_upvalues.24}}</span></td>
116 <td title='{{module_messages.26}}'><span id="26" {%if beam.pk == active_beam %} {{color_status.26}} {%endif%}>{{beam.get_upvalues.25}}</span></td>
117 <td title='{{module_messages.27}}'><span id="27" {%if beam.pk == active_beam %} {{color_status.27}} {%endif%}>{{beam.get_upvalues.26}}</span></td>
118 <td title='{{module_messages.28}}'><span id="28" {%if beam.pk == active_beam %} {{color_status.28}} {%endif%}>{{beam.get_upvalues.27}}</span></td>
115 <td title='{{module_messages.25}}'><span {%if beam.pk == active_beam %} id="25" {%endif%}>{{beam.get_upvalues.24}}</span></td>
116 <td title='{{module_messages.26}}'><span {%if beam.pk == active_beam %} id="26" {%endif%}>{{beam.get_upvalues.25}}</span></td>
117 <td title='{{module_messages.27}}'><span {%if beam.pk == active_beam %} id="27" {%endif%}>{{beam.get_upvalues.26}}</span></td>
118 <td title='{{module_messages.28}}'><span {%if beam.pk == active_beam %} id="28" {%endif%}>{{beam.get_upvalues.27}}</span></td>
119 119 </tr>
120 120 <tr>
121 <td title='{{module_messages.25}}'><span id="125" {%if beam.pk == active_beam %} {{color_status.25}} {%endif%}>{{beam.get_downvalues.24}}</span></td>
122 <td title='{{module_messages.26}}'><span id="126" {%if beam.pk == active_beam %} {{color_status.26}} {%endif%}>{{beam.get_downvalues.25}}</span></td>
123 <td title='{{module_messages.27}}'><span id="127" {%if beam.pk == active_beam %} {{color_status.27}} {%endif%}>{{beam.get_downvalues.26}}</span></td>
124 <td title='{{module_messages.28}}'><span id="128" {%if beam.pk == active_beam %} {{color_status.28}} {%endif%}>{{beam.get_downvalues.27}}</span></td>
121 <td title='{{module_messages.25}}'><span {%if beam.pk == active_beam %} id="125" {%endif%}>{{beam.get_downvalues.24}}</span></td>
122 <td title='{{module_messages.26}}'><span {%if beam.pk == active_beam %} id="126" {%endif%}>{{beam.get_downvalues.25}}</span></td>
123 <td title='{{module_messages.27}}'><span {%if beam.pk == active_beam %} id="127" {%endif%}>{{beam.get_downvalues.26}}</span></td>
124 <td title='{{module_messages.28}}'><span {%if beam.pk == active_beam %} id="128" {%endif%}>{{beam.get_downvalues.27}}</span></td>
125 125 </tr>
126 126 </table>
127 127 </td>
128 128 <td>
129 129 <b>East Quarter</b>
130 130 <table class="module">
131 131 <tr>
132 <td title='{{module_messages.5}}'> <span id="5" {%if beam.pk == active_beam %} {{color_status.5}} {%endif%}>{{beam.get_upvalues.4}}</span></td>
133 <td title='{{module_messages.6}}'> <span id="6" {%if beam.pk == active_beam %} {{color_status.6}} {%endif%}>{{beam.get_upvalues.5}}</span></td>
134 <td title='{{module_messages.7}}'> <span id="7" {%if beam.pk == active_beam %} {{color_status.7}} {%endif%}>{{beam.get_upvalues.6}}</span></td>
135 <td title='{{module_messages.8}}'> <span id="8" {%if beam.pk == active_beam %} {{color_status.8}} {%endif%}>{{beam.get_upvalues.7}}</span></td>
132 <td title='{{module_messages.5}}'> <span {%if beam.pk == active_beam %} id="5" {%endif%}>{{beam.get_upvalues.4}}</span></td>
133 <td title='{{module_messages.6}}'> <span {%if beam.pk == active_beam %} id="6" {%endif%}>{{beam.get_upvalues.5}}</span></td>
134 <td title='{{module_messages.7}}'> <span {%if beam.pk == active_beam %} id="7" {%endif%}>{{beam.get_upvalues.6}}</span></td>
135 <td title='{{module_messages.8}}'> <span {%if beam.pk == active_beam %} id="8" {%endif%}>{{beam.get_upvalues.7}}</span></td>
136 136 </tr>
137 137 <tr>
138 <td title='{{module_messages.5}}'> <span id="105" {%if beam.pk == active_beam %} {{color_status.5}} {%endif%}>{{beam.get_downvalues.4}}</span></td>
139 <td title='{{module_messages.6}}'> <span id="106" {%if beam.pk == active_beam %} {{color_status.6}} {%endif%}>{{beam.get_downvalues.5}}</span></td>
140 <td title='{{module_messages.7}}'> <span id="107" {%if beam.pk == active_beam %} {{color_status.7}} {%endif%}>{{beam.get_downvalues.6}}</span></td>
141 <td title='{{module_messages.8}}'> <span id="108" {%if beam.pk == active_beam %} {{color_status.8}} {%endif%}>{{beam.get_downvalues.7}}</span></td>
138 <td title='{{module_messages.5}}'> <span {%if beam.pk == active_beam %} id="105" {%endif%}>{{beam.get_downvalues.4}}</span></td>
139 <td title='{{module_messages.6}}'> <span {%if beam.pk == active_beam %} id="106" {%endif%}>{{beam.get_downvalues.5}}</span></td>
140 <td title='{{module_messages.7}}'> <span {%if beam.pk == active_beam %} id="107" {%endif%}>{{beam.get_downvalues.6}}</span></td>
141 <td title='{{module_messages.8}}'> <span {%if beam.pk == active_beam %} id="108" {%endif%}>{{beam.get_downvalues.7}}</span></td>
142 142 </tr>
143 143 <tr>
144 <td title='{{module_messages.13}}'><span id="13" {%if beam.pk == active_beam %} {{color_status.13}} {%endif%}>{{beam.get_upvalues.12}}</span></td>
145 <td title='{{module_messages.14}}'><span id="14" {%if beam.pk == active_beam %} {{color_status.14}} {%endif%}>{{beam.get_upvalues.13}}</span></td>
146 <td title='{{module_messages.15}}'><span id="15" {%if beam.pk == active_beam %} {{color_status.15}} {%endif%}>{{beam.get_upvalues.14}}</span></td>
147 <td title='{{module_messages.16}}'><span id="16" {%if beam.pk == active_beam %} {{color_status.16}} {%endif%}>{{beam.get_upvalues.15}}</span></td>
144 <td title='{{module_messages.13}}'><span {%if beam.pk == active_beam %} id="13" {%endif%}>{{beam.get_upvalues.12}}</span></td>
145 <td title='{{module_messages.14}}'><span {%if beam.pk == active_beam %} id="14" {%endif%}>{{beam.get_upvalues.13}}</span></td>
146 <td title='{{module_messages.15}}'><span {%if beam.pk == active_beam %} id="15" {%endif%}>{{beam.get_upvalues.14}}</span></td>
147 <td title='{{module_messages.16}}'><span {%if beam.pk == active_beam %} id="16" {%endif%}>{{beam.get_upvalues.15}}</span></td>
148 148 </tr>
149 149 <tr>
150 <td title='{{module_messages.13}}'><span id="113" {%if beam.pk == active_beam %} {{color_status.13}} {%endif%}>{{beam.get_downvalues.12}}</span></td>
151 <td title='{{module_messages.14}}'><span id="114" {%if beam.pk == active_beam %} {{color_status.14}} {%endif%}>{{beam.get_downvalues.13}}</span></td>
152 <td title='{{module_messages.15}}'><span id="115" {%if beam.pk == active_beam %} {{color_status.15}} {%endif%}>{{beam.get_downvalues.14}}</span></td>
153 <td title='{{module_messages.16}}'><span id="116" {%if beam.pk == active_beam %} {{color_status.16}} {%endif%}>{{beam.get_downvalues.15}}</span></td>
150 <td title='{{module_messages.13}}'><span {%if beam.pk == active_beam %} id="113" {%endif%}>{{beam.get_downvalues.12}}</span></td>
151 <td title='{{module_messages.14}}'><span {%if beam.pk == active_beam %} id="114" {%endif%}>{{beam.get_downvalues.13}}</span></td>
152 <td title='{{module_messages.15}}'><span {%if beam.pk == active_beam %} id="115" {%endif%}>{{beam.get_downvalues.14}}</span></td>
153 <td title='{{module_messages.16}}'><span {%if beam.pk == active_beam %} id="116" {%endif%}>{{beam.get_downvalues.15}}</span></td>
154 154 </tr>
155 155 <tr>
156 <td title='{{module_messages.21}}'><span id="21" {%if beam.pk == active_beam %} {{color_status.21}} {%endif%}>{{beam.get_upvalues.20}}</span></td>
157 <td title='{{module_messages.22}}'><span id="22" {%if beam.pk == active_beam %} {{color_status.22}} {%endif%}>{{beam.get_upvalues.21}}</span></td>
158 <td title='{{module_messages.23}}'><span id="23" {%if beam.pk == active_beam %} {{color_status.23}} {%endif%}>{{beam.get_upvalues.22}}</span></td>
159 <td title='{{module_messages.24}}'><span id="24" {%if beam.pk == active_beam %} {{color_status.24}} {%endif%}>{{beam.get_upvalues.23}}</span></td>
156 <td title='{{module_messages.21}}'><span {%if beam.pk == active_beam %} id="21" {%endif%}>{{beam.get_upvalues.20}}</span></td>
157 <td title='{{module_messages.22}}'><span {%if beam.pk == active_beam %} id="22" {%endif%}>{{beam.get_upvalues.21}}</span></td>
158 <td title='{{module_messages.23}}'><span {%if beam.pk == active_beam %} id="23" {%endif%}>{{beam.get_upvalues.22}}</span></td>
159 <td title='{{module_messages.24}}'><span {%if beam.pk == active_beam %} id="24" {%endif%}>{{beam.get_upvalues.23}}</span></td>
160 160 </tr>
161 161 <tr>
162 <td title='{{module_messages.21}}'><span id="121" {%if beam.pk == active_beam %} {{color_status.21}} {%endif%}>{{beam.get_downvalues.20}}</span></td>
163 <td title='{{module_messages.22}}'><span id="122" {%if beam.pk == active_beam %} {{color_status.22}} {%endif%}>{{beam.get_downvalues.21}}</span></td>
164 <td title='{{module_messages.23}}'><span id="123" {%if beam.pk == active_beam %} {{color_status.23}} {%endif%}>{{beam.get_downvalues.22}}</span></td>
165 <td title='{{module_messages.24}}'><span id="124" {%if beam.pk == active_beam %} {{color_status.24}} {%endif%}>{{beam.get_downvalues.23}}</span></td>
162 <td title='{{module_messages.21}}'><span {%if beam.pk == active_beam %} id="121" {%endif%}>{{beam.get_downvalues.20}}</span></td>
163 <td title='{{module_messages.22}}'><span {%if beam.pk == active_beam %} id="122" {%endif%}>{{beam.get_downvalues.21}}</span></td>
164 <td title='{{module_messages.23}}'><span {%if beam.pk == active_beam %} id="123" {%endif%}>{{beam.get_downvalues.22}}</span></td>
165 <td title='{{module_messages.24}}'><span {%if beam.pk == active_beam %} id="124" {%endif%}>{{beam.get_downvalues.23}}</span></td>
166 166 </tr>
167 167 <tr>
168 <td title='{{module_messages.29}}'><span id="29" {%if beam.pk == active_beam %} {{color_status.29}} {%endif%}>{{beam.get_upvalues.28}}</span></td>
169 <td title='{{module_messages.30}}'><span id="30" {%if beam.pk == active_beam %} {{color_status.30}} {%endif%}>{{beam.get_upvalues.29}}</span></td>
170 <td title='{{module_messages.31}}'><span id="31" {%if beam.pk == active_beam %} {{color_status.31}} {%endif%}>{{beam.get_upvalues.30}}</span></td>
171 <td title='{{module_messages.32}}'><span id="32" {%if beam.pk == active_beam %} {{color_status.32}} {%endif%}>{{beam.get_upvalues.31}}</span></td>
168 <td title='{{module_messages.29}}'><span {%if beam.pk == active_beam %} id="29" {%endif%}>{{beam.get_upvalues.28}}</span></td>
169 <td title='{{module_messages.30}}'><span {%if beam.pk == active_beam %} id="30" {%endif%}>{{beam.get_upvalues.29}}</span></td>
170 <td title='{{module_messages.31}}'><span {%if beam.pk == active_beam %} id="31" {%endif%}>{{beam.get_upvalues.30}}</span></td>
171 <td title='{{module_messages.32}}'><span {%if beam.pk == active_beam %} id="32" {%endif%}>{{beam.get_upvalues.31}}</span></td>
172 172 </tr>
173 173 <tr>
174 <td title='{{module_messages.29}}'><span id="129" {%if beam.pk == active_beam %} {{color_status.29}} {%endif%}>{{beam.get_downvalues.28}}</span></td>
175 <td title='{{module_messages.30}}'><span id="130" {%if beam.pk == active_beam %} {{color_status.30}} {%endif%}>{{beam.get_downvalues.29}}</span></td>
176 <td title='{{module_messages.31}}'><span id="131" {%if beam.pk == active_beam %} {{color_status.31}} {%endif%}>{{beam.get_downvalues.30}}</span></td>
177 <td title='{{module_messages.32}}'><span id="132" {%if beam.pk == active_beam %} {{color_status.32}} {%endif%}>{{beam.get_downvalues.31}}</span></td>
174 <td title='{{module_messages.29}}'><span {%if beam.pk == active_beam %} id="129" {%endif%}>{{beam.get_downvalues.28}}</span></td>
175 <td title='{{module_messages.30}}'><span {%if beam.pk == active_beam %} id="130" {%endif%}>{{beam.get_downvalues.29}}</span></td>
176 <td title='{{module_messages.31}}'><span {%if beam.pk == active_beam %} id="131" {%endif%}>{{beam.get_downvalues.30}}</span></td>
177 <td title='{{module_messages.32}}'><span {%if beam.pk == active_beam %} id="132" {%endif%}>{{beam.get_downvalues.31}}</span></td>
178 178 </tr>
179 179 </table>
180 180 </td>
181 181 </tr>
182 182 <tr>
183 183 <td>
184 184 <b>West Quarter</b>
185 185 <table class="module">
186 186 <tr>
187 <td title='{{module_messages.33}}'><span id="33" {%if beam.pk == active_beam %} {{color_status.33}} {%endif%}>{{beam.get_upvalues.32}}</span></td>
188 <td title='{{module_messages.34}}'><span id="34" {%if beam.pk == active_beam %} {{color_status.34}} {%endif%}>{{beam.get_upvalues.33}}</span></td>
189 <td title='{{module_messages.35}}'><span id="35" {%if beam.pk == active_beam %} {{color_status.35}} {%endif%}>{{beam.get_upvalues.34}}</span></td>
190 <td title='{{module_messages.36}}'><span id="36" {%if beam.pk == active_beam %} {{color_status.36}} {%endif%}>{{beam.get_upvalues.35}}</span></td>
187 <td title='{{module_messages.33}}'><span {%if beam.pk == active_beam %} id="33" {%endif%}>{{beam.get_upvalues.32}}</span></td>
188 <td title='{{module_messages.34}}'><span {%if beam.pk == active_beam %} id="34" {%endif%}>{{beam.get_upvalues.33}}</span></td>
189 <td title='{{module_messages.35}}'><span {%if beam.pk == active_beam %} id="35" {%endif%}>{{beam.get_upvalues.34}}</span></td>
190 <td title='{{module_messages.36}}'><span {%if beam.pk == active_beam %} id="36" {%endif%}>{{beam.get_upvalues.35}}</span></td>
191 191 </tr>
192 192 <tr>
193 <td title='{{module_messages.33}}'><span id="133" {%if beam.pk == active_beam %} {{color_status.33}} {%endif%}>{{beam.get_downvalues.32}}</span></td>
194 <td title='{{module_messages.34}}'><span id="134" {%if beam.pk == active_beam %} {{color_status.34}} {%endif%}>{{beam.get_downvalues.33}}</span></td>
195 <td title='{{module_messages.35}}'><span id="135" {%if beam.pk == active_beam %} {{color_status.35}} {%endif%}>{{beam.get_downvalues.34}}</span></td>
196 <td title='{{module_messages.36}}'><span id="136" {%if beam.pk == active_beam %} {{color_status.36}} {%endif%}>{{beam.get_downvalues.35}}</span></td>
193 <td title='{{module_messages.33}}'><span {%if beam.pk == active_beam %} id="133" {%endif%}>{{beam.get_downvalues.32}}</span></td>
194 <td title='{{module_messages.34}}'><span {%if beam.pk == active_beam %} id="134" {%endif%}>{{beam.get_downvalues.33}}</span></td>
195 <td title='{{module_messages.35}}'><span {%if beam.pk == active_beam %} id="135" {%endif%}>{{beam.get_downvalues.34}}</span></td>
196 <td title='{{module_messages.36}}'><span {%if beam.pk == active_beam %} id="136" {%endif%}>{{beam.get_downvalues.35}}</span></td>
197 197 </tr>
198 198 <tr>
199 <td title='{{module_messages.41}}'><span id="41" {%if beam.pk == active_beam %} {{color_status.41}} {%endif%}>{{beam.get_upvalues.40}}</span></td>
200 <td title='{{module_messages.42}}'><span id="42" {%if beam.pk == active_beam %} {{color_status.42}} {%endif%}>{{beam.get_upvalues.41}}</span></td>
201 <td title='{{module_messages.43}}'><span id="43" {%if beam.pk == active_beam %} {{color_status.43}} {%endif%}>{{beam.get_upvalues.42}}</span></td>
202 <td title='{{module_messages.44}}'><span id="44" {%if beam.pk == active_beam %} {{color_status.44}} {%endif%}>{{beam.get_upvalues.43}}</span></td>
199 <td title='{{module_messages.41}}'><span {%if beam.pk == active_beam %} id="41" {%endif%}>{{beam.get_upvalues.40}}</span></td>
200 <td title='{{module_messages.42}}'><span {%if beam.pk == active_beam %} id="42" {%endif%}>{{beam.get_upvalues.41}}</span></td>
201 <td title='{{module_messages.43}}'><span {%if beam.pk == active_beam %} id="43" {%endif%}>{{beam.get_upvalues.42}}</span></td>
202 <td title='{{module_messages.44}}'><span {%if beam.pk == active_beam %} id="44" {%endif%}>{{beam.get_upvalues.43}}</span></td>
203 203 </tr>
204 204 <tr>
205 <td title='{{module_messages.41}}'><span id="141" {%if beam.pk == active_beam %} {{color_status.41}} {%endif%}>{{beam.get_downvalues.40}}</span></td>
206 <td title='{{module_messages.42}}'><span id="142" {%if beam.pk == active_beam %} {{color_status.42}} {%endif%}>{{beam.get_downvalues.41}}</span></td>
207 <td title='{{module_messages.43}}'><span id="143" {%if beam.pk == active_beam %} {{color_status.43}} {%endif%}>{{beam.get_downvalues.42}}</span></td>
208 <td title='{{module_messages.44}}'><span id="144" {%if beam.pk == active_beam %} {{color_status.44}} {%endif%}>{{beam.get_downvalues.43}}</span></td>
205 <td title='{{module_messages.41}}'><span {%if beam.pk == active_beam %} id="141" {%endif%}>{{beam.get_downvalues.40}}</span></td>
206 <td title='{{module_messages.42}}'><span {%if beam.pk == active_beam %} id="142" {%endif%}>{{beam.get_downvalues.41}}</span></td>
207 <td title='{{module_messages.43}}'><span {%if beam.pk == active_beam %} id="143" {%endif%}>{{beam.get_downvalues.42}}</span></td>
208 <td title='{{module_messages.44}}'><span {%if beam.pk == active_beam %} id="144" {%endif%}>{{beam.get_downvalues.43}}</span></td>
209 209 </tr>
210 210 <tr>
211 <td title='{{module_messages.49}}'><span id="49" {%if beam.pk == active_beam %} {{color_status.49}} {%endif%}>{{beam.get_upvalues.48}}</span></td>
212 <td title='{{module_messages.51}}'><span id="50" {%if beam.pk == active_beam %} {{color_status.50}} {%endif%}>{{beam.get_upvalues.49}}</span></td>
213 <td title='{{module_messages.52}}'><span id="51" {%if beam.pk == active_beam %} {{color_status.51}} {%endif%}>{{beam.get_upvalues.50}}</span></td>
214 <td title='{{module_messages.53}}'><span id="52" {%if beam.pk == active_beam %} {{color_status.52}} {%endif%}>{{beam.get_upvalues.51}}</span></td>
211 <td title='{{module_messages.49}}'><span {%if beam.pk == active_beam %} id="49" {%endif%}>{{beam.get_upvalues.48}}</span></td>
212 <td title='{{module_messages.51}}'><span {%if beam.pk == active_beam %} id="50" {%endif%}>{{beam.get_upvalues.49}}</span></td>
213 <td title='{{module_messages.52}}'><span {%if beam.pk == active_beam %} id="51" {%endif%}>{{beam.get_upvalues.50}}</span></td>
214 <td title='{{module_messages.53}}'><span {%if beam.pk == active_beam %} id="52" {%endif%}>{{beam.get_upvalues.51}}</span></td>
215 215 </tr>
216 216 <tr>
217 <td title='{{module_messages.49}}'><span id="149" {%if beam.pk == active_beam %} {{color_status.49}} {%endif%}>{{beam.get_downvalues.48}}</span></td>
218 <td title='{{module_messages.50}}'><span id="150" {%if beam.pk == active_beam %} {{color_status.50}} {%endif%}>{{beam.get_downvalues.49}}</span></td>
219 <td title='{{module_messages.51}}'><span id="151" {%if beam.pk == active_beam %} {{color_status.51}} {%endif%}>{{beam.get_downvalues.50}}</span></td>
220 <td title='{{module_messages.52}}'><span id="152" {%if beam.pk == active_beam %} {{color_status.52}} {%endif%}>{{beam.get_downvalues.51}}</span></td>
217 <td title='{{module_messages.49}}'><span {%if beam.pk == active_beam %} id="149" {%endif%}>{{beam.get_downvalues.48}}</span></td>
218 <td title='{{module_messages.50}}'><span {%if beam.pk == active_beam %} id="150" {%endif%}>{{beam.get_downvalues.49}}</span></td>
219 <td title='{{module_messages.51}}'><span {%if beam.pk == active_beam %} id="151" {%endif%}>{{beam.get_downvalues.50}}</span></td>
220 <td title='{{module_messages.52}}'><span {%if beam.pk == active_beam %} id="152" {%endif%}>{{beam.get_downvalues.51}}</span></td>
221 221 </tr>
222 222 <tr>
223 <td title='{{module_messages.57}}'><span id="57" {%if beam.pk == active_beam %} {{color_status.57}} {%endif%}>{{beam.get_upvalues.56}}</span></td>
224 <td title='{{module_messages.58}}'><span id="58" {%if beam.pk == active_beam %} {{color_status.58}} {%endif%}>{{beam.get_upvalues.57}}</span></td>
225 <td title='{{module_messages.59}}'><span id="59" {%if beam.pk == active_beam %} {{color_status.59}} {%endif%}>{{beam.get_upvalues.58}}</span></td>
226 <td title='{{module_messages.60}}'><span id="60" {%if beam.pk == active_beam %} {{color_status.60}} {%endif%}>{{beam.get_upvalues.59}}</span></td>
223 <td title='{{module_messages.57}}'><span {%if beam.pk == active_beam %} id="57" {%endif%}>{{beam.get_upvalues.56}}</span></td>
224 <td title='{{module_messages.58}}'><span {%if beam.pk == active_beam %} id="58" {%endif%}>{{beam.get_upvalues.57}}</span></td>
225 <td title='{{module_messages.59}}'><span {%if beam.pk == active_beam %} id="59" {%endif%}>{{beam.get_upvalues.58}}</span></td>
226 <td title='{{module_messages.60}}'><span {%if beam.pk == active_beam %} id="60" {%endif%}>{{beam.get_upvalues.59}}</span></td>
227 227 </tr>
228 228 <tr>
229 <td title='{{module_messages.57}}'><span id="157" {%if beam.pk == active_beam %} {{color_status.57}} {%endif%}>{{beam.get_downvalues.56}}</span></td>
230 <td title='{{module_messages.58}}'><span id="158" {%if beam.pk == active_beam %} {{color_status.58}} {%endif%}>{{beam.get_downvalues.57}}</span></td>
231 <td title='{{module_messages.59}}'><span id="159" {%if beam.pk == active_beam %} {{color_status.59}} {%endif%}>{{beam.get_downvalues.58}}</span></td>
232 <td title='{{module_messages.60}}'><span id="160" {%if beam.pk == active_beam %} {{color_status.60}} {%endif%}>{{beam.get_downvalues.59}}</span></td>
229 <td title='{{module_messages.57}}'><span {%if beam.pk == active_beam %} id="157" {%endif%}>{{beam.get_downvalues.56}}</span></td>
230 <td title='{{module_messages.58}}'><span {%if beam.pk == active_beam %} id="158" {%endif%}>{{beam.get_downvalues.57}}</span></td>
231 <td title='{{module_messages.59}}'><span {%if beam.pk == active_beam %} id="159" {%endif%}>{{beam.get_downvalues.58}}</span></td>
232 <td title='{{module_messages.60}}'><span {%if beam.pk == active_beam %} id="160" {%endif%}>{{beam.get_downvalues.59}}</span></td>
233 233 </tr>
234 234 </table>
235 235 </td>
236 236 <td>
237 237 <b>South Quarter</b>
238 238 <table class="module">
239 239 <tr>
240 <td title='{{module_messages.37}}'><span id="37" {%if beam.pk == active_beam %} {{color_status.37}} {%endif%}>{{beam.get_upvalues.36}}</span></td>
241 <td title='{{module_messages.38}}'><span id="38" {%if beam.pk == active_beam %} {{color_status.38}} {%endif%}>{{beam.get_upvalues.37}}</span></td>
242 <td title='{{module_messages.39}}'><span id="39" {%if beam.pk == active_beam %} {{color_status.39}} {%endif%}>{{beam.get_upvalues.38}}</span></td>
243 <td title='{{module_messages.40}}'><span id="40" {%if beam.pk == active_beam %} {{color_status.40}} {%endif%}>{{beam.get_upvalues.39}}</span></td>
240 <td title='{{module_messages.37}}'><span {%if beam.pk == active_beam %} id="37" {%endif%}>{{beam.get_upvalues.36}}</span></td>
241 <td title='{{module_messages.38}}'><span {%if beam.pk == active_beam %} id="38" {%endif%}>{{beam.get_upvalues.37}}</span></td>
242 <td title='{{module_messages.39}}'><span {%if beam.pk == active_beam %} id="39" {%endif%}>{{beam.get_upvalues.38}}</span></td>
243 <td title='{{module_messages.40}}'><span {%if beam.pk == active_beam %} id="40" {%endif%}>{{beam.get_upvalues.39}}</span></td>
244 244 </tr>
245 245 <tr>
246 <td title='{{module_messages.37}}'><span id="137" {%if beam.pk == active_beam %} {{color_status.37}} {%endif%}>{{beam.get_downvalues.36}}</span></td>
247 <td title='{{module_messages.38}}'><span id="138" {%if beam.pk == active_beam %} {{color_status.38}} {%endif%}>{{beam.get_downvalues.37}}</span></td>
248 <td title='{{module_messages.39}}'><span id="139" {%if beam.pk == active_beam %} {{color_status.39}} {%endif%}>{{beam.get_downvalues.38}}</span></td>
249 <td title='{{module_messages.40}}'><span id="140" {%if beam.pk == active_beam %} {{color_status.40}} {%endif%}>{{beam.get_downvalues.39}}</span></td>
246 <td title='{{module_messages.37}}'><span {%if beam.pk == active_beam %} id="137" {%endif%}>{{beam.get_downvalues.36}}</span></td>
247 <td title='{{module_messages.38}}'><span {%if beam.pk == active_beam %} id="138" {%endif%}>{{beam.get_downvalues.37}}</span></td>
248 <td title='{{module_messages.39}}'><span {%if beam.pk == active_beam %} id="139" {%endif%}>{{beam.get_downvalues.38}}</span></td>
249 <td title='{{module_messages.40}}'><span {%if beam.pk == active_beam %} id="140" {%endif%}>{{beam.get_downvalues.39}}</span></td>
250 250 </tr>
251 251 <tr>
252 <td title='{{module_messages.45}}'><span id="45" {%if beam.pk == active_beam %} {{color_status.45}} {%endif%}>{{beam.get_upvalues.44}}</span></td>
253 <td title='{{module_messages.46}}'><span id="46" {%if beam.pk == active_beam %} {{color_status.46}} {%endif%}>{{beam.get_upvalues.45}}</span></td>
254 <td title='{{module_messages.47}}'><span id="47" {%if beam.pk == active_beam %} {{color_status.47}} {%endif%}>{{beam.get_upvalues.46}}</span></td>
255 <td title='{{module_messages.48}}'><span id="48" {%if beam.pk == active_beam %} {{color_status.48}} {%endif%}>{{beam.get_upvalues.47}}</span></td>
252 <td title='{{module_messages.45}}'><span {%if beam.pk == active_beam %} id="45" {%endif%}>{{beam.get_upvalues.44}}</span></td>
253 <td title='{{module_messages.46}}'><span {%if beam.pk == active_beam %} id="46" {%endif%}>{{beam.get_upvalues.45}}</span></td>
254 <td title='{{module_messages.47}}'><span {%if beam.pk == active_beam %} id="47" {%endif%}>{{beam.get_upvalues.46}}</span></td>
255 <td title='{{module_messages.48}}'><span {%if beam.pk == active_beam %} id="48" {%endif%}>{{beam.get_upvalues.47}}</span></td>
256 256 </tr>
257 257 <tr>
258 <td title='{{module_messages.45}}'><span id="145" {%if beam.pk == active_beam %} {{color_status.45}} {%endif%}>{{beam.get_downvalues.44}}</span></td>
259 <td title='{{module_messages.46}}'><span id="146" {%if beam.pk == active_beam %} {{color_status.46}} {%endif%}>{{beam.get_downvalues.45}}</span></td>
260 <td title='{{module_messages.47}}'><span id="147" {%if beam.pk == active_beam %} {{color_status.47}} {%endif%}>{{beam.get_downvalues.46}}</span></td>
261 <td title='{{module_messages.48}}'><span id="148" {%if beam.pk == active_beam %} {{color_status.48}} {%endif%}>{{beam.get_downvalues.47}}</span></td>
258 <td title='{{module_messages.45}}'><span {%if beam.pk == active_beam %} id="145" {%endif%}>{{beam.get_downvalues.44}}</span></td>
259 <td title='{{module_messages.46}}'><span {%if beam.pk == active_beam %} id="146" {%endif%}>{{beam.get_downvalues.45}}</span></td>
260 <td title='{{module_messages.47}}'><span {%if beam.pk == active_beam %} id="147" {%endif%}>{{beam.get_downvalues.46}}</span></td>
261 <td title='{{module_messages.48}}'><span {%if beam.pk == active_beam %} id="148" {%endif%}>{{beam.get_downvalues.47}}</span></td>
262 262 </tr>
263 263 <tr>
264 <td title='{{module_messages.53}}'><span id="53" {%if beam.pk == active_beam %} {{color_status.53}} {%endif%}>{{beam.get_upvalues.52}}</span></td>
265 <td title='{{module_messages.54}}'><span id="54" {%if beam.pk == active_beam %} {{color_status.54}} {%endif%}>{{beam.get_upvalues.53}}</span></td>
266 <td title='{{module_messages.55}}'><span id="55" {%if beam.pk == active_beam %} {{color_status.55}} {%endif%}>{{beam.get_upvalues.54}}</span></td>
267 <td title='{{module_messages.56}}'><span id="56" {%if beam.pk == active_beam %} {{color_status.56}} {%endif%}>{{beam.get_upvalues.55}}</span></td>
264 <td title='{{module_messages.53}}'><span {%if beam.pk == active_beam %} id="53" {%endif%}>{{beam.get_upvalues.52}}</span></td>
265 <td title='{{module_messages.54}}'><span {%if beam.pk == active_beam %} id="54" {%endif%}>{{beam.get_upvalues.53}}</span></td>
266 <td title='{{module_messages.55}}'><span {%if beam.pk == active_beam %} id="55" {%endif%}>{{beam.get_upvalues.54}}</span></td>
267 <td title='{{module_messages.56}}'><span {%if beam.pk == active_beam %} id="56" {%endif%}>{{beam.get_upvalues.55}}</span></td>
268 268 </tr>
269 269 <tr>
270 <td title='{{module_messages.53}}'><span id="153" {%if beam.pk == active_beam %} {{color_status.53}} {%endif%}>{{beam.get_downvalues.52}}</span></td>
271 <td title='{{module_messages.54}}'><span id="154" {%if beam.pk == active_beam %} {{color_status.54}} {%endif%}>{{beam.get_downvalues.53}}</span></td>
272 <td title='{{module_messages.55}}'><span id="155" {%if beam.pk == active_beam %} {{color_status.55}} {%endif%}>{{beam.get_downvalues.54}}</span></td>
273 <td title='{{module_messages.56}}'><span id="156" {%if beam.pk == active_beam %} {{color_status.56}} {%endif%}>{{beam.get_downvalues.55}}</span></td>
270 <td title='{{module_messages.53}}'><span {%if beam.pk == active_beam %} id="153" {%endif%}>{{beam.get_downvalues.52}}</span></td>
271 <td title='{{module_messages.54}}'><span {%if beam.pk == active_beam %} id="154" {%endif%}>{{beam.get_downvalues.53}}</span></td>
272 <td title='{{module_messages.55}}'><span {%if beam.pk == active_beam %} id="155" {%endif%}>{{beam.get_downvalues.54}}</span></td>
273 <td title='{{module_messages.56}}'><span {%if beam.pk == active_beam %} id="156" {%endif%}>{{beam.get_downvalues.55}}</span></td>
274 274 </tr>
275 275 <tr>
276 <td title='{{module_messages.61}}'><span id="61" {%if beam.pk == active_beam %} {{color_status.61}} {%endif%}>{{beam.get_upvalues.60}}</span></td>
277 <td title='{{module_messages.62}}'><span id="62" {%if beam.pk == active_beam %} {{color_status.62}} {%endif%}>{{beam.get_upvalues.61}}</span></td>
278 <td title='{{module_messages.63}}'><span id="63" {%if beam.pk == active_beam %} {{color_status.63}} {%endif%}>{{beam.get_upvalues.62}}</span></td>
279 <td title='{{module_messages.64}}'><span id="64" {%if beam.pk == active_beam %} {{color_status.64}} {%endif%}>{{beam.get_upvalues.63}}</span></td>
276 <td title='{{module_messages.61}}'><span {%if beam.pk == active_beam %} id="61" {%endif%}>{{beam.get_upvalues.60}}</span></td>
277 <td title='{{module_messages.62}}'><span {%if beam.pk == active_beam %} id="62" {%endif%}>{{beam.get_upvalues.61}}</span></td>
278 <td title='{{module_messages.63}}'><span {%if beam.pk == active_beam %} id="63" {%endif%}>{{beam.get_upvalues.62}}</span></td>
279 <td title='{{module_messages.64}}'><span {%if beam.pk == active_beam %} id="64" {%endif%}>{{beam.get_upvalues.63}}</span></td>
280 280 </tr>
281 281 <tr>
282 <td title='{{module_messages.61}}'><span id="161" {%if beam.pk == active_beam %} {{color_status.61}} {%endif%}>{{beam.get_downvalues.60}}</span></td>
283 <td title='{{module_messages.62}}'><span id="162" {%if beam.pk == active_beam %} {{color_status.62}} {%endif%}>{{beam.get_downvalues.61}}</span></td>
284 <td title='{{module_messages.63}}'><span id="163" {%if beam.pk == active_beam %} {{color_status.63}} {%endif%}>{{beam.get_downvalues.62}}</span></td>
285 <td title='{{module_messages.64}}'><span id="164" {%if beam.pk == active_beam %} {{color_status.64}} {%endif%}>{{beam.get_downvalues.63}}</span></td>
282 <td title='{{module_messages.61}}'><span {%if beam.pk == active_beam %} id="161" {%endif%}>{{beam.get_downvalues.60}}</span></td>
283 <td title='{{module_messages.62}}'><span {%if beam.pk == active_beam %} id="162" {%endif%}>{{beam.get_downvalues.61}}</span></td>
284 <td title='{{module_messages.63}}'><span {%if beam.pk == active_beam %} id="163" {%endif%}>{{beam.get_downvalues.62}}</span></td>
285 <td title='{{module_messages.64}}'><span {%if beam.pk == active_beam %} id="164" {%endif%}>{{beam.get_downvalues.63}}</span></td>
286 286 </tr>
287 287 </table>
288 288 </td>
289 289 </tr>
290 290 </table>
291 291
292 292 <!-- <meta id="configuraciones_down" data-playlist="{{ beam.get_downvalues }}">
293 293 <meta id="configuraciones_up" data-playlist="{{ beam.get_upvalues }}">
294 294 <meta id="sda" data-toggle="" -->
295 295
296 296 {% if beam.id == active_beam %}
297 297 <table class="legend">
298 298 <tr>
299 299 <th>Legend</th>
300 300 </tr>
301 301 <tr>
302 <td class="text-warning">Connected</td>
302 <td class="text-success">Running and Match</td>
303 303 </tr>
304 304 <tr>
305 <td class="text-success">Running</td>
306 </tr>
307 <tr>
308 <td class="text-info">Mismath</td>
305 <td class="text-info">Mismatch</td>
309 306 </tr>
310 307 <tr>
311 308 <td class="text-danger">Disconnected</td>
312 309 </tr>
313 310 </table>
314 311 {% else %}
315 312 <div style="vertical-align: top; display:inline-block;">
316 313 <button id="send_beam{{forloop.counter}}" type="button" class="btn btn-default">
317 314 <span class="fas fa-external-link-square-alt" aria-hidden="true"></span>
318 315 Change Beam</button>
319 316 <br><br><br>
320 317 <button id="change_beam_mqtt{{forloop.counter}}" type="button" class="btn btn-default">
321 318 <span class="fas fa-external-link-square-alt" aria-hidden="true"></span>
322 319 Change Beam MQTT</button>
323 320 </div>
324 321 {% endif %}
325 322 </div>
326 323 {% endfor %}
327 324 </div>
328 325 </div>
329 326
330 327
331 328 {% else %}
332 329 <p style="color:#b4bcc2; margin-left: 5%;">
333 330 <i>No Beams...</i>
334 331 </p>
335 332 {% endif %}
336 333 {% endblock extra-content %}
337 334
338 335 {% block extra-js%}
339 336 <script>
340 337 $(document).ready(function () {
341 338
342 339 // var elemento = document.getElementById("4");
340 // console.log(beam.pk);
341 // console.log(active_beam);
343 342
344 343 var socket = io.connect('http://' + document.domain + ':' + location.port);
345 344
346 345 socket.on('connect', function(data) {
347 346 console.log('Connecting... OK');
348 347 })
349 348
350 349 socket.on('abs_ws', function(data) {
351 350 console.log('ingresamos');
352 351 console.log(data.msg);
353 352 var text = data['msg'];
354 353 // $('#chatLog').val(text);
355 354
356 355 if(data.msg=="b\'Hola\'"){console.log('Hola_amigo')};
357 356 })
358 357
359 358 socket.on('beams_ack', function(data) {
360 console.log('beams_ack');
359 // console.log('beams_ack');
361 360 var text = data['msg'];
362 361
363 362 for (let i=1; i<=64;i++){
364 363
365 364 var elemento = document.getElementById(text[i-1]);
366 365 var elemento2 = document.getElementById(text[i-1]+100);
367 366 if (text[i-1]<=64){
368 console.log("1")
367 // console.log("1")
369 368 // elemento=document.getElementById(text[i-1]);
370 369 elemento.style.color="green";
371 370 elemento.style.fontWeight = "bold";
372 371 elemento2.style.color="green";
373 372 elemento2.style.fontWeight = "bold";}
374 373 else if (text[i-1]>64){
375 374 elemento=document.getElementById(text[i-1]-64);
376 375 elemento2=document.getElementById(text[i-1]-64+100);
377 elemento.style.color="yellow";
376 elemento.style.color="blue";
378 377 elemento.style.fontWeight = "bold";
379 elemento2.style.color="yellow";
378 elemento2.style.color="blue";
380 379 elemento2.style.fontWeight = "bold"}
381 380 else {
382 381 elemento.style.color="red";
383 382 elemento.style.fontWeight = "bold";
384 383 elemento2.style.color="red";
385 384 elemento2.style.fontWeight = "bold"}
386 385 }
387 386
388 387
389 388
390 console.log(text[0])
389 // console.log(text[0])
391 390
392 391
393 392 // $('#chatLog').val(text);
394 393
395 394 if(data.msg=="b\'Hola\'"){console.log('Hola_amigo')};
396 395 })
397 396
398 397
399 398 {% for beam in beams %}
400 399
401 400 {% if dev_conf.operation_mode == 1 %}
402 401 $("#send_beam{{forloop.counter}}").prop('disabled', true)
403 402 $("#change_beam_mqtt{{forloop.counter}}").prop('disabled', true)
404 403 {% else %}
405 404 $("#send_beam{{forloop.counter}}").click(function () {
406 405 document.location = "{% url 'url_send_beam' dev_conf.id beam.id %}";
407 406 });
408 407
409 408 change_beam_mqtt_btn=$("#change_beam_mqtt{{forloop.counter}}")
410 409 change_beam_mqtt_btn.click(function () {
411 info="change_beam_mqtt{{forloop.counter}}"
412 socket.emit('change_beam',{data:info});
413 document.location = "{% url 'url_send_beam_mqtt' dev_conf.id beam.id %}";
410 // info="change_beam_mqtt{{forloop.counter}}"
411 // socket.emit('change_beam',{data:info});
412 document.location = "{% url 'url_change_beam_mqtt' dev_conf.id beam.id %}";
414 413 });
415 414
416 415 {% endif %}
417 416
418 417 {% endfor %}
419 418
420 419
421 420 });
422 421
423 422 </script>
424 423
425 424
426 425 {% endblock %}
@@ -1,19 +1,20
1 1 from django.urls import path
2 2
3 3 from apps.abs import views
4 4
5 5 urlpatterns = (
6 6 path('<int:id_conf>/', views.abs_conf, name='url_abs_conf'),
7 path('<int:id_conf>/mqtt', views.abs_conf_mqtt, name='url_abs_conf_mqtt'),
7 8 path('<int:id_conf>/edit/', views.abs_conf_edit, name='url_edit_abs_conf'),
8 9 path('alert/', views.abs_conf_alert, name='url_alert_abs_conf'),
9 10 path('<int:id_conf>/import/', views.import_file, name='url_import_abs_conf'),
10 11 #url(r'^(?P<id_conf>-?\d+)/status/', views.abs_conf, {'status_request':True},name='url_status_abs_conf'),
11 12 path('<int:id_conf>/change_beam/<int:id_beam>/', views.send_beam, name='url_send_beam'),
12 path('<int:id_conf>/change_beam/<int:id_beam>/', views.change_beam_mqtt, name='url_send_beam_mqtt'),
13 path('<int:id_conf>/change_beam_mqtt/<int:id_beam>/', views.change_beam_mqtt, name='url_change_beam_mqtt'),
13 14 path('<int:id_conf>/plot/', views.plot_patterns, name='url_plot_abs_patterns'),
14 15 path('<int:id_conf>/plot/<int:id_beam>/', views.plot_patterns, name='url_plot_abs_patterns2'),
15 16 path('<int:id_conf>/plot/<int:id_beam>/<slug:antenna>/pattern.png/', views.plot_pattern, name='url_plot_beam'),
16 17 path('<int:id_conf>/add_beam/', views.add_beam, name='url_add_abs_beam'),
17 18 path('<int:id_conf>/beam/<int:id_beam>/delete/', views.remove_beam, name='url_remove_abs_beam'),
18 19 path('<int:id_conf>/beam/<int:id_beam>/edit/', views.edit_beam, name='url_edit_abs_beam'),
19 20 )
@@ -1,560 +1,574
1 1 from django.shortcuts import render
2 2 from django.template import RequestContext
3 3 from django.shortcuts import redirect, render, get_object_or_404
4 4 from django.contrib import messages
5 5 from django.conf import settings
6 6 from django.http import HttpResponse
7 7 from django.urls import reverse
8 8 from django.views.decorators.csrf import csrf_exempt
9 9 from django.utils.safestring import mark_safe
10 10
11 11 from datetime import datetime
12 12 from time import sleep
13 13 import os
14 14 import io
15 15
16 16 from apps.main.models import Device, Configuration, Experiment
17 17 from apps.main.views import sidebar
18 18
19 19 from .models import ABSConfiguration, ABSBeam
20 20 from .forms import ABSConfigurationForm, ABSBeamEditForm, ABSBeamAddForm, ABSImportForm
21 21
22 22 from .utils.overJroShow import overJroShow
23 23 #from .utils.OverJRO import OverJRO
24 24 #Create your views here.
25 25 import json, ast
26 26
27 27 from .mqtt import client as mqtt_client
28 28 from radarsys.socketconfig import sio as sio
29 29
30 30 def get_values_from_form(form_data):
31 31
32 32 sublistup = []
33 33 sublistdown = []
34 34 subtxlistup = []
35 35 subtxlistdown = []
36 36 subrxlistup = []
37 37 subrxlistdown = []
38 38
39 39 up_values_list = []
40 40 down_values_list = []
41 41 up_txvalues_list = []
42 42 down_txvalues_list = []
43 43 up_rxvalues_list = []
44 44 down_rxvalues_list = []
45 45
46 46 values_list = {}
47 47 cont = 1
48 48
49 49 for i in range(1,65):
50 50 x = float(form_data['abs_up'+str(i)])
51 51 y = float(form_data['abs_down'+str(i)])
52 52 sublistup.append(x)
53 53 sublistdown.append(y)
54 54
55 55 if str(i) in form_data.getlist('uptx_checks'):
56 56 subtxlistup.append(1)
57 57 else:
58 58 subtxlistup.append(0)
59 59 if str(i) in form_data.getlist('downtx_checks'):
60 60 subtxlistdown.append(1)
61 61 else:
62 62 subtxlistdown.append(0)
63 63
64 64 if str(i) in form_data.getlist('uprx_checks'):
65 65 subrxlistup.append(1)
66 66 else:
67 67 subrxlistup.append(0)
68 68 if str(i) in form_data.getlist('downrx_checks'):
69 69 subrxlistdown.append(1)
70 70 else:
71 71 subrxlistdown.append(0)
72 72
73 73 cont = cont+1
74 74
75 75 if cont == 9:
76 76 up_values_list.append(sublistup)
77 77 down_values_list.append(sublistdown)
78 78 sublistup = []
79 79 sublistdown = []
80 80
81 81 up_txvalues_list.append(subtxlistup)
82 82 down_txvalues_list.append(subtxlistdown)
83 83 subtxlistup = []
84 84 subtxlistdown = []
85 85 up_rxvalues_list.append(subrxlistup)
86 86 down_rxvalues_list.append(subrxlistdown)
87 87 subrxlistup = []
88 88 subrxlistdown = []
89 89 cont = 1
90 90
91 91
92 92 list_uesup = []
93 93 list_uesdown = []
94 94 for i in range(1,5):
95 95 if form_data['ues_up'+str(i)] == '':
96 96 list_uesup.append(0.0)
97 97 else:
98 98 list_uesup.append(float(form_data['ues_up'+str(i)]))
99 99
100 100 if form_data['ues_down'+str(i)] == '':
101 101 list_uesdown.append(0.0)
102 102 else:
103 103 list_uesdown.append(float(form_data['ues_down'+str(i)]))
104 104
105 105 onlyrx_list = form_data.getlist('onlyrx')
106 106 only_rx = {}
107 107 if '1' in onlyrx_list:
108 108 only_rx['up'] = True
109 109 else:
110 110 only_rx['up'] = False
111 111 if '2' in onlyrx_list:
112 112 only_rx['down'] = True
113 113 else:
114 114 only_rx['down'] = False
115 115
116 116 antenna = {'antenna_up': up_values_list, 'antenna_down': down_values_list}
117 117 tx = {'up': up_txvalues_list, 'down': down_txvalues_list}
118 118 rx = {'up': up_rxvalues_list, 'down': down_rxvalues_list}
119 119 ues = {'up': list_uesup, 'down': list_uesdown}
120 120 name = str(form_data['beam_name'])
121 121
122 122 beam_data = {'name': name, 'antenna': antenna, 'tx': tx, 'rx': rx, 'ues': ues, 'only_rx': only_rx}
123 123
124 124 return beam_data
125 125
126 126
127 127 def abs_conf(request, id_conf):
128 128
129 129 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
130 130 beams = ABSBeam.objects.filter(abs_conf=conf)
131 131 #------------Colors for Active Beam:-------------
132 132 all_status = {}
133 133 module_messages = json.loads(conf.module_messages)
134 134
135 135 color_status = {}
136 136 for i, status in enumerate(conf.module_status):
137 137 if status == '3': #Running background-color: #00cc00;
138 138 all_status['{}'.format(i+1)] = 2
139 139 color_status['{}'.format(i+1)] = 'class=text-success'#'bgcolor=#00cc00'
140 140 elif status == '2':
141 141 all_status['{}'.format(i+1)] = 1
142 142 color_status['{}'.format(i+1)] = 'class=text-info'
143 143 elif status == '1': #Connected background-color: #ee902c;
144 144 all_status['{}'.format(i+1)] = 1
145 145 color_status['{}'.format(i+1)] = 'class=text-warning'#'bgcolor=#ee902c'
146 146 else: #Disconnected background-color: #ff0000;
147 147 all_status['{}'.format(i+1)] = 0
148 148 color_status['{}'.format(i+1)] = 'class=text-danger'#'bgcolor=#FF0000'
149 149 #------------------------------------------------
150 150
151 151 kwargs = {}
152 152 kwargs['connected_modules'] = str(conf.connected_modules())+'/64'
153 153 kwargs['dev_conf'] = conf
154 154
155 155 if conf.operation_mode == 0:
156 156 kwargs['dev_conf_keys'] = ['label', 'operation_mode']
157 157 else:
158 158 kwargs['dev_conf_keys'] = ['label', 'operation_mode', 'operation_value']
159 159
160 160 kwargs['title'] = 'ABS Configuration'
161 161 kwargs['suptitle'] = 'Details'
162 162 kwargs['button'] = 'Edit Configuration'
163 163
164 164 if conf.active_beam != 0:
165 165 kwargs['active_beam'] = int(conf.active_beam)
166 166
167 167 kwargs['beams'] = beams
168 168 kwargs['modules_status'] = all_status
169 169 kwargs['color_status'] = color_status
170 170 kwargs['module_messages'] = module_messages
171 171 ###### SIDEBAR ######
172 172 kwargs.update(sidebar(conf=conf))
173 173
174 174 return render(request, 'abs_conf.html', kwargs)
175 175
176 def abs_conf_mqtt(request, id_conf):
177 print("Estoy en abs_conf_mqtt",flush=True)
178 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
179 beams = ABSBeam.objects.filter(abs_conf=conf)
180 #------------Colors for Active Beam:-------------
181 all_status = {}
182 module_messages = json.loads(conf.module_messages)
183
184 kwargs = {}
185 kwargs['connected_modules'] = str(conf.connected_modules())+'/64'
186 kwargs['dev_conf'] = conf
187
188 if conf.operation_mode == 0:
189 kwargs['dev_conf_keys'] = ['label', 'operation_mode']
190 else:
191 kwargs['dev_conf_keys'] = ['label', 'operation_mode', 'operation_value']
192
193 kwargs['title'] = 'ABS Configuration'
194 kwargs['suptitle'] = 'Details'
195 kwargs['button'] = 'Edit Configuration'
196
197 if conf.active_beam != 0:
198 kwargs['active_beam'] = int(conf.active_beam)
176 199
200 kwargs['mqtt']=True
201 kwargs['beams'] = beams
202 kwargs['modules_status'] = all_status
203 kwargs['module_messages'] = module_messages
204 ###### SIDEBAR ######
205 kwargs.update(sidebar(conf=conf))
206 print("conf.active_beam: {}",format(conf.active_beam))
207
208 # print(conf.beam.pk)
209
210 return render(request, 'abs_conf_mqtt.html', kwargs)
211 # // console.log(beam.pk);
212 # // console.log(active_beam);
177 213 # def abs_conf_mqtt(request, id_conf):
178 214 # # socket.on('beams_ack',function(data){
179 215 # ack=data;
180 216 # console.log("ack")
181 217 # console.log(ack)
182 218 # })
183 219
184 220
185 221 def abs_conf_edit(request, id_conf):
186 222
187 223 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
188 224
189 225 beams = ABSBeam.objects.filter(abs_conf=conf)
190 226
191 227 if request.method=='GET':
192 228 form = ABSConfigurationForm(instance=conf)
193 229
194 230 if request.method=='POST':
195 231 form = ABSConfigurationForm(request.POST, instance=conf)
196 232
197 233 if form.is_valid():
198 234 conf = form.save(commit=False)
199 235 conf.save()
200 return redirect('url_abs_conf', id_conf=conf.id)
236 return redirect('url_abs_conf_mqtt', id_conf=conf.id)
201 237
202 238 ###### SIDEBAR ######
203 239 kwargs = {}
204 240
205 241 kwargs['dev_conf'] = conf
206 242 #kwargs['id_dev'] = conf.id
207 243 kwargs['id_conf'] = conf.id
208 244 kwargs['form'] = form
209 245 kwargs['abs_beams'] = beams
210 246 kwargs['title'] = 'Device Configuration'
211 247 kwargs['suptitle'] = 'Edit'
212 248 kwargs['button'] = 'Save'
249 kwargs['mqtt']=True
213 250
214 251 kwargs['edit'] = True
215 252
216 253 return render(request, 'abs_conf_edit.html', kwargs)
217 254
218 255 @csrf_exempt
219 256 def abs_conf_alert(request):
220 257
221 258 if request.method == 'POST':
222 259 print (request.POST)
223 260 return HttpResponse(json.dumps({'result':1}), content_type='application/json')
224 261 else:
225 262 return redirect('index')
226 263
227 264
228 265 def import_file(request, id_conf):
229 266
230 267 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
231 268 if request.method=='POST':
232 269 form = ABSImportForm(request.POST, request.FILES)
233 270 if form.is_valid():
234 271 try:
235 272 parms = conf.import_from_file(request.FILES['file_name'])
236 273
237 274 if parms:
238 275 conf.update_from_file(parms)
239 276 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
240 277 return redirect(conf.get_absolute_url_edit())
241 278
242 279 except Exception as e:
243 280 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], e))
244 281
245 282 else:
246 283 messages.warning(request, 'Your current configuration will be replaced')
247 284 form = ABSImportForm()
248 285
249 286 kwargs = {}
250 287 kwargs['form'] = form
251 288 kwargs['title'] = 'ABS Configuration'
252 289 kwargs['suptitle'] = 'Import file'
253 290 kwargs['button'] = 'Upload'
254 291 kwargs['previous'] = conf.get_absolute_url()
255 292
256 293 return render(request, 'abs_import.html', kwargs)
257 294
258 295
259 296 def send_beam(request, id_conf, id_beam):
260 297
261 298 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
262 299
263 300 abs = Configuration.objects.filter(pk=conf.device.conf_active).first()
264 301 if abs!=conf:
265 302 url = '#' if abs is None else abs.get_absolute_url()
266 303 label = 'None' if abs is None else abs.label
267 304 messages.warning(
268 305 request,
269 306 mark_safe('The current configuration has not been written in the modules, the active configuration is <a href="{}">{}</a>'.format(
270 307 url,
271 308 label
272 309 ))
273 310 )
274 311 return redirect(conf.get_absolute_url())
275 312
276 313 beam = get_object_or_404(ABSBeam, pk=id_beam)
277 314
278 315 if request.method == 'POST':
279 316
280 317 beams_list = ABSBeam.objects.filter(abs_conf=conf)
281 318 conf.active_beam = id_beam
282 319
283 320 i = 0
284 321 for b in beams_list:
285 322 if b.id == int(id_beam):
286 323 break
287 324 else:
288 325 i += 1
289 326 beam_pos = i + 1 #Estandarizar
290 327 print('{} Position {}'.format(beam.name,str(beam_pos)))
291 328 conf.send_beam(beam_pos)
292 329
293 330 return redirect('url_abs_conf', conf.id)
294 331
295 332 kwargs = {
296 333 'title': 'ABS',
297 334 'suptitle': conf.label,
298 'message': 'Are you sure you want to change ABS Beam to: {}?'.format(beam.name),
335 'message': 'Are you sure you want to change ABS Beam through SEND BEAM to: {}?'.format(beam.name),
299 336 'delete': False
300 337 }
301 338 kwargs['menu_configurations'] = 'active'
302 339
303 340 return render(request, 'confirm.html', kwargs)
304 341
305 342 def change_beam_mqtt(request, id_conf, id_beam):
306 343
307 344 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
345 print("conf: {}".format(conf),flush=True)
308 346
309 347 abs = Configuration.objects.filter(pk=conf.device.conf_active).first()
348 print("abs: {}".format(abs),flush=True)
310 349 if abs!=conf:
311 350 url = '#' if abs is None else abs.get_absolute_url()
312 351 label = 'None' if abs is None else abs.label
313 352 messages.warning(
314 353 request,
315 354 mark_safe('The current configuration has not been written in the modules, the active configuration is <a href="{}">{}</a>'.format(
316 355 url,
317 356 label
318 357 ))
319 358 )
320 return redirect(conf.get_absolute_url())
359 return redirect(conf.get_absolute_mqtt_url())
321 360
322 361 beams = ABSBeam.objects.filter(abs_conf=conf)
323 362 beam = get_object_or_404(ABSBeam, pk=id_beam)
324 363
325 364 if request.method == 'POST':
326 365
327 366 beams_list = ABSBeam.objects.filter(abs_conf=conf)
328 367 conf.active_beam = id_beam
329
368
330 369 i = 0
331 370 for b in beams_list:
332 371 if b.id == int(id_beam):
333 372 break
334 373 else:
335 374 i += 1
336 375 beam_pos = i + 1 #Estandarizar
337 376
338 print('{} Position {}'.format(beam.name,str(beam_pos)))
377 print('{} Position {}'.format(beam.name,str(beam_pos)),flush=True)
339 378 conf.change_beam_mqtt(beam_pos)
340
341 module_messages = json.loads(conf.module_messages)
342 kwargs = {}
343 kwargs['connected_modules'] = str(conf.connected_modules())+'/64'
344 kwargs['dev_conf'] = conf
345
346 if conf.operation_mode == 0:
347 kwargs['dev_conf_keys'] = ['label', 'operation_mode']
348 else:
349 kwargs['dev_conf_keys'] = ['label', 'operation_mode', 'operation_value']
350
351 kwargs['title'] = 'ABS Configuration'
352 kwargs['suptitle'] = 'Details'
353 kwargs['button'] = 'Edit Configuration'
354 if conf.active_beam != 0:
355 kwargs['active_beam'] = int(conf.active_beam)
356
357
358 kwargs['beams'] = beams
359 # kwargs['modules_status'] = all_status
360 # kwargs['color_status'] = color_status
361
362
363 kwargs['module_messages'] = module_messages
364
365 ###### SIDEBAR ######
366 kwargs.update(sidebar(conf=conf))
367 379
368 380 # return redirect('url_abs_conf', conf.id)
369 return render(request, 'abs_conf_mqtt.html',kwargs)
381 return redirect('url_abs_conf_mqtt', conf.id)
382 # return render(request, 'abs_conf_mqtt.html',kwargs)
370 383
371 384 kwargs = {
372 385 'title': 'ABS',
386 'mqtt':True,
373 387 'suptitle': conf.label,
374 388 'message': 'Are you sure you want to change ABS Beam through MQTT to: {}?'.format(beam.name),
375 389 'delete': False
376 390 }
377 391 kwargs['menu_configurations'] = 'active'
378 392
379 393 return render(request, 'confirm.html', kwargs)
380 394
381 395 def add_beam(request, id_conf):
382 396
383 397 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
384 398 confs = Configuration.objects.all()
385 399
386 400 if request.method=='GET':
387 401 form = ABSBeamAddForm()
388 402
389 403 if request.method=='POST':
390 404 form = ABSBeamAddForm(request.POST)
391 405
392 406 beam_data = get_values_from_form(request.POST)
393 407
394 408 new_beam = ABSBeam(
395 409 name = beam_data['name'],
396 410 antenna = json.dumps(beam_data['antenna']),
397 411 abs_conf = conf,
398 412 tx = json.dumps(beam_data['tx']),
399 413 rx = json.dumps(beam_data['rx']),
400 414 ues = json.dumps(beam_data['ues']),
401 415 only_rx = json.dumps(beam_data['only_rx'])
402 416 )
403 417 new_beam.save()
404 418 messages.success(request, 'Beam: "%s" has been added.' % new_beam.name)
405 419
406 420 return redirect('url_edit_abs_conf', conf.id)
407 421
408 422 ###### SIDEBAR ######
409 423 kwargs = {}
410 424
411 425 #kwargs['dev_conf'] = conf.device
412 426 #kwargs['id_dev'] = conf.device
413 427 #kwargs['previous'] = conf.get_absolute_url_edit()
414 428 kwargs['id_conf'] = conf.id
415 429 kwargs['form'] = form
416 430 kwargs['title'] = 'ABS Beams'
417 431 kwargs['suptitle'] = 'Add Beam'
418 432 kwargs['button'] = 'Add'
419 433 kwargs['no_sidebar'] = True
420 434 kwargs['edit'] = True
421 435
422 436 return render(request, 'abs_add_beam.html', kwargs)
423 437
424 438
425 439 def edit_beam(request, id_conf, id_beam):
426 440
427 441 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
428 442 beam = get_object_or_404(ABSBeam, pk=id_beam)
429 443
430 444 if request.method=='GET':
431 445 form = ABSBeamEditForm(initial={'beam': beam})
432 446
433 447 if request.method=='POST':
434 448 form = ABSBeamEditForm(request.POST)
435 449
436 450 beam_data = get_values_from_form(request.POST)
437 451
438 452 beam.dict_to_parms(beam_data)
439 453 beam.save()
440 454
441 455 messages.success(request, 'Beam: "%s" has been updated.' % beam.name)
442 456
443 457 return redirect('url_edit_abs_conf', conf.id)
444 458
445 459 ###### SIDEBAR ######
446 460 kwargs = {}
447 461
448 462 kwargs['id_conf'] = conf.id
449 463 kwargs['form'] = form
450 464 kwargs['title'] = 'ABS Beams'
451 465 kwargs['suptitle'] = 'Edit Beam'
452 466 kwargs['button'] = 'Save'
453 467 kwargs['no_sidebar'] = True
454 468
455 469 #kwargs['previous'] = conf.get_absolute_url_edit()
456 470 kwargs['edit'] = True
457 471
458 472 return render(request, 'abs_edit_beam.html', kwargs)
459 473
460 474
461 475
462 476 def remove_beam(request, id_conf, id_beam):
463 477
464 478 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
465 479 beam = get_object_or_404(ABSBeam, pk=id_beam)
466 480
467 481 if request.method=='POST':
468 482 if beam:
469 483 try:
470 484 beam.delete()
471 485 messages.success(request, 'Beam: "%s" has been deleted.' % beam)
472 486 except:
473 487 messages.error(request, 'Unable to delete beam: "%s".' % beam)
474 488
475 489 return redirect('url_edit_abs_conf', conf.id)
476 490
477 491 ###### SIDEBAR ######
478 492 kwargs = {}
479 493
480 494 kwargs['object'] = beam
481 495 kwargs['delete'] = True
482 496 kwargs['title'] = 'Delete'
483 497 kwargs['suptitle'] = 'Beam'
484 498 kwargs['previous'] = conf.get_absolute_url_edit()
485 499 return render(request, 'confirm.html', kwargs)
486 500
487 501
488 502
489 503 def plot_patterns(request, id_conf, id_beam=None):
490 504
491 505 kwargs = {}
492 506 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
493 507 beams = ABSBeam.objects.filter(abs_conf=conf)
494 508
495 509 if id_beam:
496 510 beam = get_object_or_404(ABSBeam, pk=id_beam)
497 511 kwargs['beam'] = beam
498 512
499 513 ###### SIDEBAR ######
500 514
501 515 kwargs['dev_conf'] = conf.device
502 516 kwargs['id_dev'] = conf.device
503 517 kwargs['id_conf'] = conf.id
504 518 kwargs['abs_beams'] = beams
505 519 kwargs['title'] = 'ABS Patterns'
506 520 kwargs['suptitle'] = conf.name
507 521 kwargs['no_sidebar'] = True
508 522
509 523 return render(request, 'abs_patterns.html', kwargs)
510 524
511 525
512 526 def plot_pattern(request, id_conf, id_beam, antenna):
513 527
514 528 if antenna=='down':
515 529 sleep(3)
516 530
517 531 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
518 532 beam = get_object_or_404(ABSBeam, pk=id_beam)
519 533 just_rx = 1 if json.loads(beam.only_rx)[antenna] else 0
520 534 phases = json.loads(beam.antenna)['antenna_{}'.format(antenna)]
521 535 gain_tx = json.loads(beam.tx)[antenna]
522 536 gain_rx = json.loads(beam.rx)[antenna]
523 537 ues = json.loads(beam.ues)[antenna]
524 538 newOverJro = overJroShow(beam.name)
525 539 fig = newOverJro.plotPattern2(datetime.today(), phases, gain_tx, gain_rx, ues, just_rx)
526 540 buf = io.BytesIO()
527 541 fig.savefig(buf, format='png')
528 542 response = HttpResponse(buf.getvalue(), content_type='image/png')
529 543 return response
530 544
531 545 import os
532 546 from django.http import HttpResponse
533 547
534 548 @sio.on('connection-bind')
535 549 def abs_connection_bind(sid, data):
536 550 print("sid:",sid,"data",data)
537 551
538 552 @sio.on('disconnect')
539 553 def abs_test_disconnect(sid):
540 554 print("Disconnected")
541 555
542 556 @sio.event
543 557 def abs_send_beam_up(sid, message):
544 558 mqtt_client.publish('abs/beams_up', message['data'])
545 559
546 560 @sio.event
547 561 def abs_send_beam_down(sid, message):
548 562 mqtt_client.publish('abs/beams_down', message['data'])
549 563
550 @sio.event
551 def change_beam(sid,message):
552 data=str(message['data'])
553 data=data[16]
554 mqtt_client.publish('abs/change_beam',data)
564 # @sio.event
565 # def change_beam(sid,message):
566 # data=str(message['data'])
567 # data=data[16]
568 # mqtt_client.publish('abs/change_beam',data)
555 569
556 570
557 571
558 572
559 573
560 574
@@ -1,850 +1,856
1 1
2 2 import os
3 3 import json
4 4 import requests
5 5 import time
6 6 from datetime import datetime
7 7
8 8 try:
9 9 from polymorphic.models import PolymorphicModel
10 10 except:
11 11 from polymorphic import PolymorphicModel
12 12
13 13 from django.template.base import kwarg_re
14 14 from django.db import models
15 15 from django.urls import reverse
16 16 from django.core.validators import MinValueValidator, MaxValueValidator
17 17 from django.shortcuts import get_object_or_404
18 18 from django.contrib.auth.models import User
19 19 from django.db.models.signals import post_save
20 20 from django.dispatch import receiver
21 21
22 22 from apps.main.utils import Params
23 23 from apps.rc.utils import RCFile
24 24 from apps.jars.utils import RacpFile
25 25 from devices.dds import api as dds_api
26 26 from devices.dds import data as dds_data
27 27
28 28
29 29 DEV_PORTS = {
30 30 'rc' : 2000,
31 31 'dds' : 2000,
32 32 'jars' : 2000,
33 33 'usrp' : 2000,
34 34 'cgs' : 8080,
35 35 'abs' : 8080,
36 36 'dds_rest': 80
37 37 }
38 38
39 39 RADAR_STATES = (
40 40 (0, 'No connected'),
41 41 (1, 'Connected'),
42 42 (2, 'Configured'),
43 43 (3, 'Running'),
44 44 (4, 'Scheduled'),
45 45 )
46 46
47 47 EXPERIMENT_TYPE = (
48 48 (0, 'RAW_DATA'),
49 49 (1, 'PDATA'),
50 50 )
51 51
52 52 DECODE_TYPE = (
53 53 (0, 'None'),
54 54 (1, 'TimeDomain'),
55 55 (2, 'FreqDomain'),
56 56 (3, 'InvFreqDomain'),
57 57 )
58 58
59 59 DEV_STATES = (
60 60 (0, 'No connected'),
61 61 (1, 'Connected'),
62 62 (2, 'Configured'),
63 63 (3, 'Running'),
64 64 (4, 'Unknown'),
65 65 (5, 'Busy')
66 66 )
67 67
68 68 DEV_TYPES = (
69 69 ('', 'Select a device type'),
70 70 ('rc', 'Radar Controller'),
71 71 ('dds', 'Direct Digital Synthesizer'),
72 72 ('jars', 'Jicamarca Radar Acquisition System'),
73 73 ('usrp', 'Universal Software Radio Peripheral'),
74 74 ('cgs', 'Clock Generator System'),
75 75 ('abs', 'Automatic Beam Switching'),
76 76 ('dds_rest', 'Direct Digital Synthesizer_REST'),
77 77 ('atrad', 'Transmitter ATRAD'),
78 78 )
79 79
80 80 EXP_STATES = (
81 81 (0,'Error'), #RED
82 82 (1,'Cancelled'), #YELLOW
83 83 (2,'Running'), #GREEN
84 84 (3,'Scheduled'), #BLUE
85 85 (4,'Unknown'), #WHITE
86 86 )
87 87
88 88 CONF_TYPES = (
89 89 (0, 'Active'),
90 90 (1, 'Historical'),
91 91 )
92 92
93 93 class Profile(models.Model):
94 94 user = models.OneToOneField(User, on_delete=models.CASCADE)
95 95 theme = models.CharField(max_length=30, default='spacelab')
96 96
97 97
98 98 @receiver(post_save, sender=User)
99 99 def create_user_profile(sender, instance, created, **kwargs):
100 100 if created:
101 101 Profile.objects.create(user=instance)
102 102
103 103 @receiver(post_save, sender=User)
104 104 def save_user_profile(sender, instance, **kwargs):
105 105 instance.profile.save()
106 106
107 107
108 108 class Location(models.Model):
109 109
110 110 name = models.CharField(max_length = 30)
111 111 description = models.TextField(blank=True, null=True)
112 112
113 113 class Meta:
114 114 db_table = 'db_location'
115 115
116 116 def __str__(self):
117 117 return u'%s' % self.name
118 118
119 119 def get_absolute_url(self):
120 120 return reverse('url_location', args=[str(self.id)])
121 121
122 122
123 123 class DeviceType(models.Model):
124 124
125 125 name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'dds_rest')
126 126 sequence = models.PositiveSmallIntegerField(default=55)
127 127 description = models.TextField(blank=True, null=True)
128 128
129 129 class Meta:
130 130 db_table = 'db_device_types'
131 131
132 132 def __str__(self):
133 133 return u'%s' % self.get_name_display()
134 134
135 135 class Device(models.Model):
136 136
137 137 device_type = models.ForeignKey('DeviceType', on_delete=models.CASCADE)
138 138 location = models.ForeignKey('Location', on_delete=models.CASCADE)
139 139 ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0')
140 140 port_address = models.PositiveSmallIntegerField(default=2000)
141 141 description = models.TextField(blank=True, null=True)
142 142 status = models.PositiveSmallIntegerField(default=4, choices=DEV_STATES)
143 143 conf_active = models.PositiveIntegerField(default=0, verbose_name='Current configuration')
144 144
145 145 class Meta:
146 146 db_table = 'db_devices'
147 147
148 148 def __str__(self):
149 149 ret = u'{} [{}]'.format(self.device_type.name.upper(), self.location.name)
150 150
151 151 return ret
152 152
153 153 @property
154 154 def name(self):
155 155 return str(self)
156 156
157 157 def get_status(self):
158 158 return self.status
159 159
160 160 @property
161 161 def status_color(self):
162 162 color = 'muted'
163 163 if self.status == 0:
164 164 color = "danger"
165 165 elif self.status == 1:
166 166 color = "warning"
167 167 elif self.status == 2:
168 168 color = "info"
169 169 elif self.status == 3:
170 170 color = "success"
171 171
172 172 return color
173 173
174 174 def url(self, path=None):
175 175
176 176 if path:
177 177 return 'http://{}:{}/{}/'.format(self.ip_address, self.port_address, path)
178 178 else:
179 179 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
180 180
181 181 def get_absolute_url(self):
182 182 return reverse('url_device', args=[str(self.id)])
183 183
184 184 def get_absolute_url_edit(self):
185 185 return reverse('url_edit_device', args=[str(self.id)])
186 186
187 187 def get_absolute_url_delete(self):
188 188 return reverse('url_delete_device', args=[str(self.id)])
189 189
190 190 def change_ip(self, ip_address, mask, gateway, dns, **kwargs):
191 191
192 192 if self.device_type.name=='dds':
193 193 try:
194 194 answer = dds_api.change_ip(ip = self.ip_address,
195 195 port = self.port_address,
196 196 new_ip = ip_address,
197 197 mask = mask,
198 198 gateway = gateway)
199 199 if answer[0]=='1':
200 200 self.message = '25|DDS - {}'.format(answer)
201 201 self.ip_address = ip_address
202 202 self.save()
203 203 else:
204 204 self.message = '30|DDS - {}'.format(answer)
205 205 return False
206 206 except Exception as e:
207 207 self.message = '40|{}'.format(str(e))
208 208 return False
209 209
210 210 elif self.device_type.name=='rc':
211 211 headers = {'content-type': "application/json",
212 212 'cache-control': "no-cache"}
213 213
214 214 ip = [int(x) for x in ip_address.split('.')]
215 215 dns = [int(x) for x in dns.split('.')]
216 216 gateway = [int(x) for x in gateway.split('.')]
217 217 subnet = [int(x) for x in mask.split('.')]
218 218
219 219 payload = {
220 220 "ip": ip,
221 221 "dns": dns,
222 222 "gateway": gateway,
223 223 "subnet": subnet
224 224 }
225 225
226 226 req = requests.post(self.url('changeip'), data=json.dumps(payload), headers=headers)
227 227 try:
228 228 answer = req.json()
229 229 if answer['changeip']=='ok':
230 230 self.message = '25|IP succesfully changed'
231 231 self.ip_address = ip_address
232 232 self.save()
233 233 else:
234 234 self.message = '30|An error ocuur when changing IP'
235 235 except Exception as e:
236 236 self.message = '40|{}'.format(str(e))
237 237 else:
238 238 self.message = 'Not implemented'
239 239 return False
240 240
241 241 return True
242 242
243 243
244 244 class Campaign(models.Model):
245 245
246 246 template = models.BooleanField(default=False)
247 247 name = models.CharField(max_length=60, unique=True)
248 248 start_date = models.DateTimeField(blank=True, null=True)
249 249 end_date = models.DateTimeField(blank=True, null=True)
250 250 tags = models.CharField(max_length=40, blank=True, null=True)
251 251 description = models.TextField(blank=True, null=True)
252 252 experiments = models.ManyToManyField('Experiment', blank=True)
253 253 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
254 254
255 255 class Meta:
256 256 db_table = 'db_campaigns'
257 257 ordering = ('name',)
258 258
259 259 def __str__(self):
260 260 if self.template:
261 261 return u'{} (template)'.format(self.name)
262 262 else:
263 263 return u'{}'.format(self.name)
264 264
265 265 def jsonify(self):
266 266
267 267 data = {}
268 268
269 269 ignored = ('template')
270 270
271 271 for field in self._meta.fields:
272 272 if field.name in ignored:
273 273 continue
274 274 data[field.name] = field.value_from_object(self)
275 275
276 276 data['start_date'] = data['start_date'].strftime('%Y-%m-%d')
277 277 data['end_date'] = data['end_date'].strftime('%Y-%m-%d')
278 278
279 279 return data
280 280
281 281 def parms_to_dict(self):
282 282
283 283 params = Params({})
284 284 params.add(self.jsonify(), 'campaigns')
285 285
286 286 for exp in Experiment.objects.filter(campaign = self):
287 287 params.add(exp.jsonify(), 'experiments')
288 288 configurations = Configuration.objects.filter(experiment=exp, type=0)
289 289
290 290 for conf in configurations:
291 291 params.add(conf.jsonify(), 'configurations')
292 292 if conf.device.device_type.name=='rc':
293 293 for line in conf.get_lines():
294 294 params.add(line.jsonify(), 'lines')
295 295
296 296 return params.data
297 297
298 298 def dict_to_parms(self, parms, CONF_MODELS):
299 299
300 300 experiments = Experiment.objects.filter(campaign = self)
301 301
302 302 if experiments:
303 303 for experiment in experiments:
304 304 experiment.delete()
305 305
306 306 for id_exp in parms['experiments']['allIds']:
307 307 exp_parms = parms['experiments']['byId'][id_exp]
308 308 dum = (datetime.now() - datetime(1970, 1, 1)).total_seconds()
309 309 exp = Experiment(name='{}'.format(dum))
310 310 exp.save()
311 311 exp.dict_to_parms(parms, CONF_MODELS, id_exp=id_exp)
312 312 self.experiments.add(exp)
313 313
314 314 camp_parms = parms['campaigns']['byId'][parms['campaigns']['allIds'][0]]
315 315
316 316 self.name = '{}-{}'.format(camp_parms['name'], datetime.now().strftime('%y%m%d'))
317 317 self.start_date = camp_parms['start_date']
318 318 self.end_date = camp_parms['end_date']
319 319 self.tags = camp_parms['tags']
320 320 self.save()
321 321
322 322 return self
323 323
324 324 def get_experiments_by_radar(self, radar=None):
325 325
326 326 ret = []
327 327 if radar:
328 328 locations = Location.objects.filter(pk=radar)
329 329 else:
330 330 locations = set([e.location for e in self.experiments.all()])
331 331
332 332 for loc in locations:
333 333 dum = {}
334 334 dum['name'] = loc.name
335 335 dum['id'] = loc.pk
336 336 dum['experiments'] = [e for e in self.experiments.all() if e.location==loc]
337 337 ret.append(dum)
338 338 return ret
339 339
340 340 def get_absolute_url(self):
341 341 return reverse('url_campaign', args=[str(self.id)])
342 342
343 343 def get_absolute_url_edit(self):
344 344 return reverse('url_edit_campaign', args=[str(self.id)])
345 345
346 346 def get_absolute_url_delete(self):
347 347 return reverse('url_delete_campaign', args=[str(self.id)])
348 348
349 349 def get_absolute_url_export(self):
350 350 return reverse('url_export_campaign', args=[str(self.id)])
351 351
352 352 def get_absolute_url_import(self):
353 353 return reverse('url_import_campaign', args=[str(self.id)])
354 354
355 355
356 356 class RunningExperiment(models.Model):
357 357 radar = models.OneToOneField('Location', on_delete=models.CASCADE)
358 358 running_experiment = models.ManyToManyField('Experiment', blank = True)
359 359 status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
360 360
361 361
362 362 class Experiment(models.Model):
363 363
364 364 template = models.BooleanField(default=False)
365 365 name = models.CharField(max_length=40, default='', unique=True)
366 366 location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE)
367 367 freq = models.FloatField(verbose_name='Operating Freq. (MHz)', validators=[MinValueValidator(1), MaxValueValidator(10000)], default=49.9200)
368 368 start_time = models.TimeField(default='00:00:00')
369 369 end_time = models.TimeField(default='23:59:59')
370 370 task = models.CharField(max_length=36, default='', blank=True, null=True)
371 371 status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES)
372 372 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
373 373 hash = models.CharField(default='', max_length=64, null=True, blank=True)
374 374
375 375 class Meta:
376 376 db_table = 'db_experiments'
377 377 ordering = ('template', 'name')
378 378
379 379 def __str__(self):
380 380 if self.template:
381 381 return u'%s (template)' % (self.name)
382 382 else:
383 383 return u'%s' % (self.name)
384 384
385 385 def jsonify(self):
386 386
387 387 data = {}
388 388
389 389 ignored = ('template')
390 390
391 391 for field in self._meta.fields:
392 392 if field.name in ignored:
393 393 continue
394 394 data[field.name] = field.value_from_object(self)
395 395
396 396 data['start_time'] = data['start_time'].strftime('%H:%M:%S')
397 397 data['end_time'] = data['end_time'].strftime('%H:%M:%S')
398 398 data['location'] = self.location.name
399 399 data['configurations'] = ['{}'.format(conf.pk) for
400 400 conf in Configuration.objects.filter(experiment=self, type=0)]
401 401
402 402 return data
403 403
404 404 @property
405 405 def radar_system(self):
406 406 return self.location
407 407
408 408 def clone(self, **kwargs):
409 409
410 410 confs = Configuration.objects.filter(experiment=self, type=0)
411 411 self.pk = None
412 412 self.name = '{}_{:%y%m%d%H%M%S}'.format(self.name, datetime.now())
413 413 for attr, value in kwargs.items():
414 414 setattr(self, attr, value)
415 415
416 416 self.save()
417 417
418 418 for conf in confs:
419 419 conf.clone(experiment=self, template=False)
420 420
421 421 return self
422 422
423 423 def start(self):
424 424 '''
425 425 Configure and start experiments's devices
426 426 ABS-CGS-DDS-RC-JARS
427 427 '''
428 428 self.status=5 #Busy
429 429 self.save()
430 430 # print("Guardando STATUS: {}".format(self.status))
431 431
432 432 confs = []
433 433 allconfs = Configuration.objects.filter(experiment=self, type = 0).order_by('-device__device_type__sequence')
434 434 rc_mix = [conf for conf in allconfs if conf.device.device_type.name=='rc' and conf.mix]
435 435 if rc_mix:
436 436 for conf in allconfs:
437 437 if conf.device.device_type.name == 'rc' and not conf.mix:
438 438 continue
439 439 confs.append(conf)
440 440 else:
441 441 confs = allconfs
442 442
443 443
444 444 for conf in confs:
445 445 print("conf->",conf)
446 446 print(conf.device)
447 447 print(conf.device.status)
448 448 print("--------------",flush=True)
449 449 print("Stop ",conf.name,flush=True)
450 450 if conf.stop_device() ==False:
451 451 print("Falló Stop ",conf.name)
452 452 print("Cancelando Campaña...",flush=True)
453 453 return 0
454 454 print("Write ",conf.name,flush=True)
455 455 if conf.write_device() ==False:
456 456 print("Falló Write ",conf.name)
457 457 print("Cancelando Campaña...",flush=True)
458 458 return 0
459 459 print("Save",conf.name,flush=True)
460 460 conf.device.conf_active = conf.pk
461 461 conf.device.save()
462 462 print("Start",conf.name,flush=True)
463 463 if conf.start_device()==False:
464 464 print("Falló Start ",conf.name)
465 465 print("Cancelando Campaña...",flush=True)
466 466 return 0
467 467 print("--- CONFIGURACIÓN EXITOSA ---",flush=True)
468 468 time.sleep(1)
469 469
470 470 return 2
471 471
472 472
473 473 def stop(self):
474 474 '''
475 475 Stop experiments's devices
476 476 DDS-JARS-RC-CGS-ABS
477 477 '''
478 478
479 479 confs = Configuration.objects.filter(experiment=self, type = 0).order_by('device__device_type__sequence')
480 480 confs = confs.exclude(device__device_type__name='cgs')
481 481 try:
482 482 for conf in confs:
483 483 conf.stop_device()
484 484 except:
485 485 return 0
486 486 return 1
487 487
488 488 def get_status(self):
489 489
490 490 if self.status == 3:
491 491 return
492 492
493 493 confs = Configuration.objects.filter(experiment=self, type=0)
494 494
495 495 for conf in confs:
496 496 conf.status_device()
497 497
498 498 total = confs.aggregate(models.Sum('device__status'))['device__status__sum']
499 499
500 500 if total==2*confs.count():
501 501 status = 1
502 502 elif total == 3*confs.count():
503 503 status = 2
504 504 else:
505 505 status = 0
506 506
507 507 self.status = status
508 508 self.save()
509 509
510 510 def status_color(self):
511 511 color = 'muted'
512 512 if self.status == 0:
513 513 color = "danger"
514 514 elif self.status == 1:
515 515 color = "warning"
516 516 elif self.status == 2:
517 517 color = "success"
518 518 elif self.status == 3:
519 519 color = "info"
520 520
521 521 return color
522 522
523 523 def parms_to_dict(self):
524 524
525 525 params = Params({})
526 526 params.add(self.jsonify(), 'experiments')
527 527
528 528 configurations = Configuration.objects.filter(experiment=self, type=0)
529 529
530 530 for conf in configurations:
531 531 params.add(conf.jsonify(), 'configurations')
532 532 if conf.device.device_type.name=='rc':
533 533 for line in conf.get_lines():
534 534 params.add(line.jsonify(), 'lines')
535 535
536 536 return params.data
537 537
538 538 def dict_to_parms(self, parms, CONF_MODELS, id_exp=None):
539 539
540 540 configurations = Configuration.objects.filter(experiment=self)
541 541
542 542 if id_exp is not None:
543 543 exp_parms = parms['experiments']['byId'][id_exp]
544 544 else:
545 545 exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]]
546 546
547 547 if configurations:
548 548 for configuration in configurations:
549 549 configuration.delete()
550 550
551 551 for id_conf in exp_parms['configurations']:
552 552 conf_parms = parms['configurations']['byId'][id_conf]
553 553 device = Device.objects.filter(device_type__name=conf_parms['device_type'])[0]
554 554 model = CONF_MODELS[conf_parms['device_type']]
555 555 conf = model(
556 556 experiment = self,
557 557 device = device,
558 558 )
559 559 conf.dict_to_parms(parms, id=id_conf)
560 560
561 561
562 562 location, created = Location.objects.get_or_create(name=exp_parms['location'])
563 563 self.name = '{}-{}'.format(exp_parms['name'], datetime.now().strftime('%y%m%d'))
564 564 self.location = location
565 565 self.start_time = exp_parms['start_time']
566 566 self.end_time = exp_parms['end_time']
567 567 self.save()
568 568
569 569 return self
570 570
571 571 def get_absolute_url(self):
572 572 return reverse('url_experiment', args=[str(self.id)])
573 573
574 574 def get_absolute_url_edit(self):
575 575 return reverse('url_edit_experiment', args=[str(self.id)])
576 576
577 577 def get_absolute_url_delete(self):
578 578 return reverse('url_delete_experiment', args=[str(self.id)])
579 579
580 580 def get_absolute_url_import(self):
581 581 return reverse('url_import_experiment', args=[str(self.id)])
582 582
583 583 def get_absolute_url_export(self):
584 584 return reverse('url_export_experiment', args=[str(self.id)])
585 585
586 586 def get_absolute_url_start(self):
587 587 return reverse('url_start_experiment', args=[str(self.id)])
588 588
589 589 def get_absolute_url_stop(self):
590 590 return reverse('url_stop_experiment', args=[str(self.id)])
591 591
592 592
593 593 class Configuration(PolymorphicModel):
594 594
595 595 template = models.BooleanField(default=False)
596 596 # name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
597 597 device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE)
598 598 label = models.CharField(verbose_name="Label", max_length=40, default='', blank=True, null=True)
599 599 experiment = models.ForeignKey('Experiment', verbose_name='Experiment', null=True, blank=True, on_delete=models.CASCADE)
600 600 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
601 601 created_date = models.DateTimeField(auto_now_add=True)
602 602 programmed_date = models.DateTimeField(auto_now=True)
603 603 parameters = models.TextField(default='{}')
604 604 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
605 605 hash = models.CharField(default='', max_length=64, null=True, blank=True)
606 606 message = ""
607 607
608 608 class Meta:
609 609 db_table = 'db_configurations'
610 610 ordering = ('device__device_type__name',)
611 611
612 612 def __str__(self):
613 613
614 614 ret = u'{} '.format(self.device.device_type.name.upper())
615 615
616 616 if 'mix' in [f.name for f in self._meta.get_fields()]:
617 617 if self.mix:
618 618 ret = '{} MIX '.format(self.device.device_type.name.upper())
619 619
620 620 if 'label' in [f.name for f in self._meta.get_fields()]:
621 621 ret += '{}'.format(self.label)
622 622
623 623 if self.template:
624 624 ret += ' (template)'
625 625
626 626 return ret
627 627
628 628 @property
629 629 def name(self):
630 630
631 631 return str(self)
632 632
633 633 def jsonify(self):
634 634
635 635 data = {}
636 636
637 637 ignored = ('type', 'polymorphic_ctype', 'configuration_ptr',
638 638 'created_date', 'programmed_date', 'template', 'device',
639 639 'experiment')
640 640
641 641 for field in self._meta.fields:
642 642 if field.name in ignored:
643 643 continue
644 644 data[field.name] = field.value_from_object(self)
645 645
646 646 data['device_type'] = self.device.device_type.name
647 647
648 648 if self.device.device_type.name == 'rc':
649 649 data['lines'] = ['{}'.format(line.pk) for line in self.get_lines()]
650 650 data['delays'] = self.get_delays()
651 651 data['pulses'] = self.get_pulses()
652 652
653 653 elif self.device.device_type.name == 'jars':
654 654 data['decode_type'] = DECODE_TYPE[self.decode_data][1]
655 655
656 656 elif self.device.device_type.name == 'dds':
657 657 data['frequencyA_Mhz'] = float(data['frequencyA_Mhz'])
658 658 data['frequencyB_Mhz'] = float(data['frequencyB_Mhz'])
659 659 data['phaseA'] = dds_data.phase_to_binary(data['phaseA_degrees'])
660 660 data['phaseB'] = dds_data.phase_to_binary(data['phaseB_degrees'])
661 661
662 662 elif self.device.device_type.name == 'dds_rest':
663 663 data['frequencyA_Mhz'] = float(data['frequencyA_Mhz'])
664 664 data['frequencyB_Mhz'] = float(data['frequencyB_Mhz'])
665 665 data['phaseA'] = dds_data.phase_to_binary(data['phaseA_degrees'])
666 666 data['phaseB'] = dds_data.phase_to_binary(data['phaseB_degrees'])
667 667 data['delta_frequency_Mhz'] = float(data['delta_frequency_Mhz'] or 0.00)
668 668 data['update_clock_Mhz'] = float(data['update_clock_Mhz'] or 0.00)
669 669 data['ramp_rate_clock_Mhz'] = float(data['ramp_rate_clock_Mhz'] or 0.0)
670 670 return data
671 671
672 672 def clone(self, **kwargs):
673 673
674 674 self.pk = None
675 675 self.id = None
676 676 for attr, value in kwargs.items():
677 677 setattr(self, attr, value)
678 678
679 679 self.save()
680 680
681 681 return self
682 682
683 683 def parms_to_dict(self):
684 684
685 685 params = Params({})
686 686 params.add(self.jsonify(), 'configurations')
687 687
688 688 if self.device.device_type.name=='rc':
689 689 for line in self.get_lines():
690 690 params.add(line.jsonify(), 'lines')
691 691
692 692 return params.data
693 693
694 694 def parms_to_text(self):
695 695
696 696 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
697 697
698 698
699 699 def parms_to_binary(self):
700 700
701 701 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
702 702
703 703
704 704 def dict_to_parms(self, parameters, id=None):
705 705
706 706 params = Params(parameters)
707 707
708 708 if id:
709 709 data = params.get_conf(id_conf=id)
710 710 else:
711 711 data = params.get_conf(dtype=self.device.device_type.name)
712 712
713 713 if data['device_type']=='rc':
714 714 self.clean_lines()
715 715 lines = data.pop('lines', None)
716 716 for line_id in lines:
717 717 pass
718 718
719 719 for key, value in data.items():
720 720 if key not in ('id', 'device_type'):
721 721 setattr(self, key, value)
722 722
723 723 self.save()
724 724
725 725
726 726 def export_to_file(self, format="json"):
727 727
728 728 content_type = ''
729 729
730 730 if format == 'racp':
731 731 content_type = 'text/plain'
732 732 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, 'racp')
733 733 content = self.parms_to_text(file_format = 'racp')
734 734
735 735 if format == 'text':
736 736 content_type = 'text/plain'
737 737 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
738 738 content = self.parms_to_text()
739 739
740 740 if format == 'binary':
741 741 content_type = 'application/octet-stream'
742 742 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
743 743 content = self.parms_to_binary()
744 744
745 745 if not content_type:
746 746 content_type = 'application/json'
747 747 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
748 748 content = json.dumps(self.parms_to_dict(), indent=2)
749 749
750 750 fields = {'content_type':content_type,
751 751 'filename':filename,
752 752 'content':content
753 753 }
754 754
755 755 return fields
756 756
757 757 def import_from_file(self, fp):
758 758
759 759 parms = {}
760 760
761 761 path, ext = os.path.splitext(fp.name)
762 762
763 763 if ext == '.json':
764 764 parms = json.load(fp)
765 765
766 766 if ext == '.dds':
767 767 lines = fp.readlines()
768 768 parms = dds_data.text_to_dict(lines)
769 769
770 770 if ext == '.racp':
771 771 if self.device.device_type.name == 'jars':
772 772 parms = RacpFile(fp).to_dict()
773 773 parms['filter_parms'] = json.loads(self.filter_parms)
774 774 return parms
775 775 parms = RCFile(fp).to_dict()
776 776
777 777 return parms
778 778
779 779 def status_device(self):
780 780
781 781 self.message = 'Function not implemented'
782 782 return False
783 783
784 784
785 785 def stop_device(self):
786 786
787 787 self.message = 'Function not implemented'
788 788 print("BUENAS SEÑALES??? NO LO CREO2",flush=True)
789 789 return False
790 790
791 791
792 792 def start_device(self):
793 793
794 794 self.message = 'Function not implemented'
795 795 print("BUENAS SEÑALES??? NO LO CREO",flush=True)
796 796 return False
797 797
798 798
799 799 def write_device(self, parms):
800 800
801 801 self.message = 'Function not implemented'
802 802 print("BUENAS SEÑALES??? NO LO CREO3",flush=True)
803 803 return False
804 804
805 805 def write_device_mqtt(self, parms):
806 806
807 807 self.message = 'Function not implemented'
808 808 return False
809 809
810 810 def read_device(self):
811 811
812 812 self.message = 'Function not implemented'
813 813 return False
814 814
815 815
816 816 def get_absolute_url(self):
817 817 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
818
819 def get_absolute_mqtt_url(self):
820 if self.device.device_type.name=='abs':
821 return reverse('url_%s_conf_mqtt' % self.device.device_type.name, args=[str(self.id)])
822 else:
823 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
818 824
819 825 def get_absolute_url_edit(self):
820 826 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
821 827
822 828 def get_absolute_url_delete(self):
823 829 return reverse('url_delete_dev_conf', args=[str(self.id)])
824 830
825 831 def get_absolute_url_import(self):
826 832 return reverse('url_import_dev_conf', args=[str(self.id)])
827 833
828 834 def get_absolute_url_export(self):
829 835 return reverse('url_export_dev_conf', args=[str(self.id)])
830 836
831 837 def get_absolute_url_write(self):
832 838 return reverse('url_write_dev_conf', args=[str(self.id)])
833 839
834 840 def get_absolute_url_write_mqtt(self):
835 841 return reverse('url_write_mqtt_dev_conf', args=[str(self.id)])
836 842
837 843 def get_absolute_url_read(self):
838 844 return reverse('url_read_dev_conf', args=[str(self.id)])
839 845
840 846 def get_absolute_url_start(self):
841 847 return reverse('url_start_dev_conf', args=[str(self.id)])
842 848
843 849 def get_absolute_url_stop(self):
844 850 return reverse('url_stop_dev_conf', args=[str(self.id)])
845 851
846 852 def get_absolute_url_stop_mqtt(self):
847 853 return reverse('url_stop_mqtt_dev_conf', args=[str(self.id)])
848 854
849 855 def get_absolute_url_status(self):
850 856 return reverse('url_status_dev_conf', args=[str(self.id)])
@@ -1,99 +1,99
1 1 {% extends "base.html" %}
2 2 {% load django_bootstrap5 %}
3 3 {% load static %}
4 4 {% load main_tags %}
5 5
6 6 {% block extra-head %}
7 7 <link href="{% static 'css/bootstrap-datetimepicker.min.css' %}" media="screen" rel="stylesheet">
8 8 {% endblock %}
9 9 {% block content-title %}{{title}}{% endblock %}
10 10 {% block content-suptitle %}{{suptitle}}{% endblock %}
11 11
12 12 {% block content %}
13 13
14 14 {% block content-filter %}
15 15 {% if form %}
16 16 <form class="form" method="get">
17 17 {% bootstrap_form form layout='horizontal' size='md' %}
18 18 <div class="pull-right">
19 19 <br>
20 20 <button type="button" class="btn btn-primary btn-sm" onclick="window.location.replace('?');"><span class="fas fa-sync-alt" aria-hidden="true"></span></button>
21 21 <button type="submit" class="btn btn-primary btn-sm"><span class="fas fa-search" aria-hidden="true"></span></button>
22 22 {% if add_url %}
23 23 <a class="btn btn-sm btn-info" href="{{add_url}}"><span class="fas fa-plus" aria-hidden="true"></span></a>
24 24 {% endif %}
25 25 </div>
26 26 </form>
27 27 {% endif %}
28 28 {% endblock %}
29 29 <div style="clear: both;"></div>
30 30 <br>
31 31 <table class="table table-hover">
32 32 <tr>
33 33 <th>#</th>
34 34 {% for key in keys %}
35 35 {% if key == 'location'%}
36 36 <th>System</th>
37 37 {% else %}
38 38 <th>{{ key|title }}</th>
39 39 {% endif %}
40 40 {% endfor%}
41 41 </tr>
42 42 {% for object in objects %}
43 <tr class="clickable-row" data-href="{{object.get_absolute_url}}">
43 <tr class="clickable-row" data-href="{{object.get_absolute_mqtt_url}}">
44 44 <td>{{ forloop.counter|add:offset }}</td>
45 45 {% for key in keys %}
46 46 {% if key == 'actions' %}
47 47 <td>
48 48 <a class="btn btn-sm btn-danger" href="{{object.get_absolute_url_delete}}"><span class="fas fa-times" aria-hidden="true"></span></a>
49 49 <a class="btn btn-sm btn-primary" href="{{object.get_absolute_url_edit}}"><span class="fa fa-pencil" aria-hidden="true"></span></a>
50 50 </td>
51 51 {% else %}
52 52 <td>{{ object|attr:key }}</td>
53 53 {% endif %}
54 54 {% endfor %}
55 55 </tr>
56 56 {% endfor %}
57 57 </table>
58 58
59 59 <div class="pagination">
60 60 <span class="step-links">
61 61 {% if objects.has_previous %}
62 62 <a href="?page={{ objects.previous_page_number }}&{{q}}"><span class="fas fa-chevron-left" aria-hidden="true"></span></a>
63 63 {% endif %}
64 64 <span class="current">
65 65 Page {{ objects.number }} of {{ objects.paginator.num_pages }}.
66 66 </span>
67 67 {% if objects.has_next %}
68 68 <a href="?page={{ objects.next_page_number }}&{{q}}"><span class="fas fa-chevron-right" aria-hidden="true"></span></a>
69 69 {% endif %}
70 70 </span>
71 71 </div>
72 72
73 73 {% endblock %}
74 74
75 75 {% block extra-js%}
76 76 <script src="{% static 'js/bootstrap-datetimepicker.min.js' %}"></script>
77 77 <script type="text/javascript">
78 78
79 79 $('.input-group.date').datetimepicker({
80 80 format: "YYYY-MM-DD",
81 81 icons: {
82 82 time: 'far fa-clock',
83 83 date: 'far fa-calendar-alt',
84 84 up: 'fas fa-arrow-up',
85 85 down: 'fas fa-arrow-down',
86 86 previous: 'fas fa-chevron-left',
87 87 next: 'fas fa-chevron-right',
88 88 today: 'far fa-calendar-check',
89 89 clear: 'far fa-trash-alt',
90 90 close: 'fas fa-times'
91 91 }
92 92 });
93 93
94 94 $(".clickable-row").click(function() {
95 95 document.location = $(this).data("href");
96 96 });
97 97
98 98 </script>
99 99 {% endblock %}
@@ -1,2111 +1,2109
1 1 import ast
2 2 import json
3 3 import hashlib
4 4 from datetime import datetime, timedelta
5 5
6 6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
7 7 from django.utils.safestring import mark_safe
8 8 from django.http import HttpResponseRedirect
9 9 from django.urls import reverse
10 10 from django.db.models import Q
11 11 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
12 12 from django.contrib import messages
13 13 from django.http.request import QueryDict
14 14 from django.contrib.auth.decorators import login_required, user_passes_test
15 15
16 16 from django.utils.timezone import is_aware
17 17
18 18 try:
19 19 from urllib.parse import urlencode
20 20 except ImportError:
21 21 from urllib import urlencode
22 22
23 23 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
24 24 from .forms import OperationSearchForm, FilterForm, ChangeIpForm
25 25
26 26 from apps.rc.forms import RCConfigurationForm, RCLineCode, RCMixConfigurationForm
27 27 from apps.dds.forms import DDSConfigurationForm
28 28 from apps.jars.forms import JARSConfigurationForm
29 29 from apps.cgs.forms import CGSConfigurationForm
30 30 from apps.abs.forms import ABSConfigurationForm
31 31 from apps.usrp.forms import USRPConfigurationForm
32 32 from apps.dds_rest.forms import DDSRestConfigurationForm
33 33 from apps.atrad.forms import ATRADConfigurationForm
34 34 from .utils import Params
35 35
36 36 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment, DEV_STATES
37 37 from apps.cgs.models import CGSConfiguration
38 38 from apps.jars.models import JARSConfiguration, EXPERIMENT_TYPE
39 39 from apps.usrp.models import USRPConfiguration
40 40 from apps.abs.models import ABSConfiguration, ABSBeam
41 41 from apps.rc.models import RCConfiguration, RCLine, RCLineType, RCClock
42 42 from apps.dds.models import DDSConfiguration
43 43 from apps.dds_rest.models import DDSRestConfiguration
44 44 from apps.atrad.models import ATRADConfiguration
45 45
46 46 #from .tasks import task_start
47 47 from radarsys.celery import app
48 48
49 49
50 50 from .mqtt import client as mqtt_client
51 51 from radarsys.socketconfig import sio as sio
52 52
53 53 #comentario test
54 54 CONF_FORMS = {
55 55 'rc': RCConfigurationForm,
56 56 'dds': DDSConfigurationForm,
57 57 'dds_rest': DDSRestConfigurationForm,
58 58 'jars': JARSConfigurationForm,
59 59 'cgs': CGSConfigurationForm,
60 60 'abs': ABSConfigurationForm,
61 61 'usrp': USRPConfigurationForm,
62 62 'atrad': ATRADConfigurationForm,
63 63 }
64 64
65 65 CONF_MODELS = {
66 66 'rc': RCConfiguration,
67 67 'dds': DDSConfiguration,
68 68 'dds_rest': DDSRestConfiguration,
69 69 'jars': JARSConfiguration,
70 70 'cgs': CGSConfiguration,
71 71 'abs': ABSConfiguration,
72 72 'usrp': USRPConfiguration,
73 73 'atrad': ATRADConfiguration,
74 74 }
75 75
76 76 MIX_MODES = {
77 77 '0': 'P',
78 78 '1': 'S',
79 79 }
80 80
81 81 MIX_OPERATIONS = {
82 82 '0': 'OR',
83 83 '1': 'XOR',
84 84 '2': 'AND',
85 85 '3': 'NAND',
86 86 }
87 87
88 88
89 89 def is_developer(user):
90 90
91 91 groups = [str(g.name) for g in user.groups.all()]
92 92 return 'Developer' in groups or user.is_staff
93 93
94 94
95 95 def is_operator(user):
96 96
97 97 groups = [str(g.name) for g in user.groups.all()]
98 98 return 'Operator' in groups or user.is_staff
99 99
100 100
101 101 def has_been_modified(model):
102 102
103 103 prev_hash = model.hash
104 104 new_hash = hashlib.sha256(str(model.parms_to_dict).encode()).hexdigest()
105 105 if prev_hash != new_hash:
106 106 model.hash = new_hash
107 107 model.save()
108 108 return True
109 109 return False
110 110
111 111
112 112 def index(request):
113 113 kwargs = {'no_sidebar': True}
114 114
115 115 return render(request, 'index.html', kwargs)
116 116
117 117
118 118 def locations(request):
119 119
120 120 page = request.GET.get('page')
121 121 order = ('name',)
122 122
123 123 kwargs = get_paginator(Location, page, order)
124 124
125 125 kwargs['keys'] = ['name', 'description']
126 126 kwargs['title'] = 'Radar System'
127 127 kwargs['suptitle'] = 'List'
128 128 kwargs['no_sidebar'] = True
129 129
130 130 return render(request, 'base_list.html', kwargs)
131 131
132 132
133 133 def location(request, id_loc):
134 134
135 135 location = get_object_or_404(Location, pk=id_loc)
136 136
137 137 kwargs = {}
138 138 kwargs['location'] = location
139 139 kwargs['location_keys'] = ['name', 'description']
140 140
141 141 kwargs['title'] = 'Location'
142 142 kwargs['suptitle'] = 'Details'
143 143
144 144 return render(request, 'location.html', kwargs)
145 145
146 146
147 147 @login_required
148 148 def location_new(request):
149 149
150 150 if request.method == 'GET':
151 151 form = LocationForm()
152 152
153 153 if request.method == 'POST':
154 154 form = LocationForm(request.POST)
155 155
156 156 if form.is_valid():
157 157 form.save()
158 158 return redirect('url_locations')
159 159
160 160 kwargs = {}
161 161 kwargs['form'] = form
162 162 kwargs['title'] = 'Radar System'
163 163 kwargs['suptitle'] = 'New'
164 164 kwargs['button'] = 'Create'
165 165
166 166 return render(request, 'base_edit.html', kwargs)
167 167
168 168
169 169 @login_required
170 170 def location_edit(request, id_loc):
171 171
172 172 location = get_object_or_404(Location, pk=id_loc)
173 173
174 174 if request.method == 'GET':
175 175 form = LocationForm(instance=location)
176 176
177 177 if request.method == 'POST':
178 178 form = LocationForm(request.POST, instance=location)
179 179
180 180 if form.is_valid():
181 181 form.save()
182 182 return redirect('url_locations')
183 183
184 184 kwargs = {}
185 185 kwargs['form'] = form
186 186 kwargs['title'] = 'Location'
187 187 kwargs['suptitle'] = 'Edit'
188 188 kwargs['button'] = 'Update'
189 189
190 190 return render(request, 'base_edit.html', kwargs)
191 191
192 192
193 193 @login_required
194 194 def location_delete(request, id_loc):
195 195
196 196 location = get_object_or_404(Location, pk=id_loc)
197 197
198 198 if request.method == 'POST':
199 199
200 200 if is_developer(request.user):
201 201 location.delete()
202 202 return redirect('url_locations')
203 203
204 204 messages.error(request, 'Not enough permission to delete this object')
205 205 return redirect(location.get_absolute_url())
206 206
207 207 kwargs = {
208 208 'title': 'Delete',
209 209 'suptitle': 'Location',
210 210 'object': location,
211 211 'delete': True
212 212 }
213 213
214 214 return render(request, 'confirm.html', kwargs)
215 215
216 216
217 217 def devices(request):
218 218
219 219 page = request.GET.get('page')
220 220 order = ('location', 'device_type')
221 221
222 222 filters = request.GET.copy()
223 223 kwargs = get_paginator(Device, page, order, filters)
224 224 form = FilterForm(initial=request.GET, extra_fields=['tags'])
225 225
226 226 kwargs['keys'] = ['device_type', 'location',
227 227 'ip_address', 'port_address', 'actions']
228 228 kwargs['title'] = 'Device'
229 229 kwargs['suptitle'] = 'List'
230 230 kwargs['no_sidebar'] = True
231 231 kwargs['form'] = form
232 232 kwargs['add_url'] = reverse('url_add_device')
233 233 filters.pop('page', None)
234 234 kwargs['q'] = urlencode(filters)
235 235 kwargs['menu_devices'] = 'active'
236 236 return render(request, 'base_list.html', kwargs)
237 237
238 238
239 239 def device(request, id_dev):
240 240
241 241 device = get_object_or_404(Device, pk=id_dev)
242 242
243 243 kwargs = {}
244 244 kwargs['device'] = device
245 245 kwargs['device_keys'] = ['device_type',
246 246 'ip_address', 'port_address', 'description']
247 247
248 248 kwargs['title'] = 'Device'
249 249 kwargs['suptitle'] = 'Details'
250 250 kwargs['menu_devices'] = 'active'
251 251
252 252 return render(request, 'device.html', kwargs)
253 253
254 254
255 255 @login_required
256 256 def device_new(request):
257 257
258 258 if request.method == 'GET':
259 259 form = DeviceForm()
260 260
261 261 if request.method == 'POST':
262 262 form = DeviceForm(request.POST)
263 263
264 264 if form.is_valid():
265 265 form.save()
266 266 return redirect('url_devices')
267 267
268 268 kwargs = {}
269 269 kwargs['form'] = form
270 270 kwargs['title'] = 'Device'
271 271 kwargs['suptitle'] = 'New_2'
272 272 kwargs['button'] = 'Create'
273 273 kwargs['menu_devices'] = 'active'
274 274
275 275 return render(request, 'base_edit.html', kwargs)
276 276
277 277
278 278 @login_required
279 279 def device_edit(request, id_dev):
280 280
281 281 device = get_object_or_404(Device, pk=id_dev)
282 282
283 283 if request.method == 'GET':
284 284 form = DeviceForm(instance=device)
285 285
286 286 if request.method == 'POST':
287 287 form = DeviceForm(request.POST, instance=device)
288 288
289 289 if form.is_valid():
290 290 form.save()
291 291 return redirect(device.get_absolute_url())
292 292
293 293 kwargs = {}
294 294 kwargs['form'] = form
295 295 kwargs['title'] = 'Device'
296 296 kwargs['suptitle'] = 'Edit'
297 297 kwargs['button'] = 'Update'
298 298 kwargs['menu_devices'] = 'active'
299 299
300 300 return render(request, 'base_edit.html', kwargs)
301 301
302 302
303 303 @login_required
304 304 def device_delete(request, id_dev):
305 305
306 306 device = get_object_or_404(Device, pk=id_dev)
307 307
308 308 if request.method == 'POST':
309 309
310 310 if is_developer(request.user):
311 311 device.delete()
312 312 return redirect('url_devices')
313 313
314 314 messages.error(request, 'Not enough permission to delete this object')
315 315 return redirect(device.get_absolute_url())
316 316
317 317 kwargs = {
318 318 'title': 'Delete',
319 319 'suptitle': 'Device',
320 320 'object': device,
321 321 'delete': True
322 322 }
323 323 kwargs['menu_devices'] = 'active'
324 324
325 325 return render(request, 'confirm.html', kwargs)
326 326
327 327
328 328 @login_required
329 329 def device_change_ip(request, id_dev):
330 330
331 331 device = get_object_or_404(Device, pk=id_dev)
332 332
333 333 if request.method == 'POST':
334 334
335 335 if is_developer(request.user):
336 336 device.change_ip(**request.POST.dict())
337 337
338 338 print(device.ip_address, device.message)
339 339
340 340 level, message = device.message.split('|')
341 341 messages.add_message(request, level, message)
342 342 else:
343 343 messages.error(
344 344 request, 'Not enough permission to delete this object')
345 345 return redirect(device.get_absolute_url())
346 346
347 347 kwargs = {
348 348 'title': 'Device',
349 349 'suptitle': 'Change IP',
350 350 'object': device,
351 351 'previous': device.get_absolute_url(),
352 352 'form': ChangeIpForm(initial={'ip_address': device.ip_address}),
353 353 'message': ' ',
354 354 }
355 355 kwargs['menu_devices'] = 'active'
356 356
357 357 return render(request, 'confirm.html', kwargs)
358 358
359 359
360 360 def campaigns(request):
361 361
362 362 page = request.GET.get('page')
363 363 order = ('-start_date',)
364 364 filters = request.GET.copy()
365 365
366 366 kwargs = get_paginator(Campaign, page, order, filters)
367 367
368 368 form = FilterForm(initial=request.GET, extra_fields=[
369 369 'range_date', 'tags', 'template'])
370 370 kwargs['keys'] = ['name', 'start_date', 'end_date', 'actions']
371 371 kwargs['title'] = 'Campaign'
372 372 kwargs['suptitle'] = 'List'
373 373 kwargs['no_sidebar'] = True
374 374 kwargs['form'] = form
375 375 kwargs['add_url'] = reverse('url_add_campaign')
376 376 filters.pop('page', None)
377 377 kwargs['q'] = urlencode(filters)
378 378 kwargs['menu_campaigns'] = 'active'
379 379
380 380 return render(request, 'base_list.html', kwargs)
381 381
382 382
383 383 def campaign(request, id_camp):
384 384
385 385 campaign = get_object_or_404(Campaign, pk=id_camp)
386 386 experiments = Experiment.objects.filter(campaign=campaign)
387 387
388 388 form = CampaignForm(instance=campaign)
389 389
390 390 kwargs = {}
391 391 kwargs['campaign'] = campaign
392 392 kwargs['campaign_keys'] = ['template', 'name',
393 393 'start_date', 'end_date', 'tags', 'description']
394 394
395 395 kwargs['experiments'] = experiments
396 396 kwargs['experiment_keys'] = [
397 397 'name', 'radar_system', 'start_time', 'end_time']
398 398
399 399 kwargs['title'] = 'Campaign'
400 400 kwargs['suptitle'] = 'Details'
401 401
402 402 kwargs['form'] = form
403 403 kwargs['button'] = 'Add Experiment'
404 404 kwargs['menu_campaigns'] = 'active'
405 405
406 406 return render(request, 'campaign.html', kwargs)
407 407
408 408
409 409 @login_required
410 410 def campaign_new(request):
411 411
412 412 kwargs = {}
413 413
414 414 if request.method == 'GET':
415 415
416 416 if 'template' in request.GET:
417 417 if request.GET['template'] == '0':
418 418 form = NewForm(initial={'create_from': 2},
419 419 template_choices=Campaign.objects.filter(template=True).values_list('id', 'name'))
420 420 else:
421 421 kwargs['button'] = 'Create'
422 422 kwargs['experiments'] = Configuration.objects.filter(
423 423 experiment=request.GET['template'])
424 424 kwargs['experiment_keys'] = ['name', 'start_time', 'end_time']
425 425 camp = Campaign.objects.get(pk=request.GET['template'])
426 426 form = CampaignForm(instance=camp,
427 427 initial={'name': '{}_{:%Y%m%d%H%M%S}'.format(camp.name, datetime.now()),
428 428 'template': False})
429 429 elif 'blank' in request.GET:
430 430 kwargs['button'] = 'Create'
431 431 form = CampaignForm()
432 432 else:
433 433 form = NewForm()
434 434
435 435 if request.method == 'POST':
436 436 kwargs['button'] = 'Create'
437 437 post = request.POST.copy()
438 438 experiments = []
439 439
440 440 for id_exp in post.getlist('experiments'):
441 441 exp = Experiment.objects.get(pk=id_exp)
442 442 new_exp = exp.clone(template=False)
443 443 experiments.append(new_exp)
444 444
445 445 post.setlist('experiments', [])
446 446
447 447 form = CampaignForm(post)
448 448
449 449 if form.is_valid():
450 450 campaign = form.save(commit=False)
451 451 campaign.author = request.user
452 452 campaign.save()
453 453 for exp in experiments:
454 454 campaign.experiments.add(exp)
455 455
456 456 return redirect('url_campaign', id_camp=campaign.id)
457 457
458 458 kwargs['form'] = form
459 459 kwargs['title'] = 'Campaign'
460 460 kwargs['suptitle'] = 'New'
461 461 kwargs['menu_campaigns'] = 'active'
462 462
463 463 return render(request, 'campaign_edit.html', kwargs)
464 464
465 465
466 466 @login_required
467 467 def campaign_edit(request, id_camp):
468 468
469 469 campaign = get_object_or_404(Campaign, pk=id_camp)
470 470
471 471 if request.method == 'GET':
472 472 form = CampaignForm(instance=campaign)
473 473
474 474 if request.method == 'POST':
475 475 exps = campaign.experiments.all().values_list('pk', flat=True)
476 476 post = request.POST.copy()
477 477 new_exps = post.getlist('experiments')
478 478 post.setlist('experiments', [])
479 479 form = CampaignForm(post, instance=campaign)
480 480
481 481 if form.is_valid():
482 482 camp = form.save()
483 483 for id_exp in new_exps:
484 484 if int(id_exp) in exps:
485 485 exps.pop(id_exp)
486 486 else:
487 487 exp = Experiment.objects.get(pk=id_exp)
488 488 if exp.template:
489 489 camp.experiments.add(exp.clone(template=False))
490 490 else:
491 491 camp.experiments.add(exp)
492 492
493 493 for id_exp in exps:
494 494 camp.experiments.remove(Experiment.objects.get(pk=id_exp))
495 495
496 496 return redirect('url_campaign', id_camp=id_camp)
497 497
498 498 kwargs = {}
499 499 kwargs['form'] = form
500 500 kwargs['title'] = 'Campaign'
501 501 kwargs['suptitle'] = 'Edit'
502 502 kwargs['button'] = 'Update'
503 503 kwargs['menu_campaigns'] = 'active'
504 504
505 505 return render(request, 'campaign_edit.html', kwargs)
506 506
507 507
508 508 @login_required
509 509 def campaign_delete(request, id_camp):
510 510
511 511 campaign = get_object_or_404(Campaign, pk=id_camp)
512 512
513 513 if request.method == 'POST':
514 514 if is_developer(request.user):
515 515
516 516 for exp in campaign.experiments.all():
517 517 for conf in Configuration.objects.filter(experiment=exp):
518 518 conf.delete()
519 519 exp.delete()
520 520 campaign.delete()
521 521
522 522 return redirect('url_campaigns')
523 523
524 524 messages.error(request, 'Not enough permission to delete this object')
525 525 return redirect(campaign.get_absolute_url())
526 526
527 527 kwargs = {
528 528 'title': 'Delete',
529 529 'suptitle': 'Campaign',
530 530 'object': campaign,
531 531 'delete': True
532 532 }
533 533 kwargs['menu_campaigns'] = 'active'
534 534
535 535 return render(request, 'confirm.html', kwargs)
536 536
537 537
538 538 @login_required
539 539 def campaign_export(request, id_camp):
540 540
541 541 campaign = get_object_or_404(Campaign, pk=id_camp)
542 542 content = campaign.parms_to_dict()
543 543 content_type = 'application/json'
544 544 filename = '%s_%s.json' % (campaign.name, campaign.id)
545 545
546 546 response = HttpResponse(content_type=content_type)
547 547 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
548 548 response.write(json.dumps(content, indent=2))
549 549
550 550 return response
551 551
552 552
553 553 @login_required
554 554 def campaign_import(request, id_camp):
555 555
556 556 campaign = get_object_or_404(Campaign, pk=id_camp)
557 557
558 558 if request.method == 'GET':
559 559 file_form = UploadFileForm()
560 560
561 561 if request.method == 'POST':
562 562 file_form = UploadFileForm(request.POST, request.FILES)
563 563
564 564 if file_form.is_valid():
565 565 new_camp = campaign.dict_to_parms(
566 566 json.load(request.FILES['file']), CONF_MODELS)
567 567 messages.success(
568 568 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
569 569 return redirect(new_camp.get_absolute_url_edit())
570 570
571 571 messages.error(request, "Could not import parameters from file")
572 572
573 573 kwargs = {}
574 574 kwargs['title'] = 'Campaign'
575 575 kwargs['form'] = file_form
576 576 kwargs['suptitle'] = 'Importing file'
577 577 kwargs['button'] = 'Import'
578 578 kwargs['menu_campaigns'] = 'active'
579 579
580 580 return render(request, 'campaign_import.html', kwargs)
581 581
582 582
583 583 def experiments(request):
584 584
585 585 page = request.GET.get('page')
586 586 order = ('location',)
587 587 filters = request.GET.copy()
588 588
589 589 if 'my experiments' in filters:
590 590 filters.pop('my experiments', None)
591 591 filters['mine'] = request.user.id
592 592
593 593 kwargs = get_paginator(Experiment, page, order, filters)
594 594
595 595 fields = ['tags', 'template']
596 596 if request.user.is_authenticated:
597 597 fields.append('my experiments')
598 598
599 599 form = FilterForm(initial=request.GET, extra_fields=fields)
600 600
601 601 kwargs['keys'] = ['name', 'radar_system',
602 602 'start_time', 'end_time', 'actions']
603 603 kwargs['title'] = 'Experiment'
604 604 kwargs['suptitle'] = 'List'
605 605 kwargs['no_sidebar'] = True
606 606 kwargs['form'] = form
607 607 kwargs['add_url'] = reverse('url_add_experiment')
608 608 filters = request.GET.copy()
609 609 filters.pop('page', None)
610 610 kwargs['q'] = urlencode(filters)
611 611 kwargs['menu_experiments'] = 'active'
612 612
613 613 return render(request, 'base_list.html', kwargs)
614 614
615 615
616 616 def experiment(request, id_exp):
617 617
618 618 experiment = get_object_or_404(Experiment, pk=id_exp)
619 619
620 620 configurations = Configuration.objects.filter(
621 621 experiment=experiment, type=0)
622 622
623 623 kwargs = {}
624 624
625 625 kwargs['experiment_keys'] = ['template', 'radar_system',
626 626 'name', 'freq', 'start_time', 'end_time']
627 627 kwargs['experiment'] = experiment
628 628 kwargs['configuration_keys'] = ['name', 'device__ip_address',
629 629 'device__port_address', 'device__status']
630 630 kwargs['configurations'] = configurations
631 631 kwargs['title'] = 'Experiment'
632 632 kwargs['suptitle'] = 'Details'
633 633 kwargs['button'] = 'Add Configuration'
634 634 kwargs['menu_experiments'] = 'active'
635 635
636 636 ###### SIDEBAR ######
637 637 kwargs.update(sidebar(experiment=experiment))
638 638
639 639 return render(request, 'experiment.html', kwargs)
640 640
641 641
642 642 @login_required
643 643 def experiment_new(request, id_camp=None):
644 644
645 645 if not is_developer(request.user):
646 646 messages.error(
647 647 request, 'Developer required, to create new Experiments')
648 648 return redirect('index')
649 649 kwargs = {}
650 650
651 651 if request.method == 'GET':
652 652 if 'template' in request.GET:
653 653 if request.GET['template'] == '0':
654 654 form = NewForm(initial={'create_from': 2},
655 655 template_choices=Experiment.objects.filter(template=True).values_list('id', 'name'))
656 656 else:
657 657 kwargs['button'] = 'Create'
658 658 kwargs['configurations'] = Configuration.objects.filter(
659 659 experiment=request.GET['template'])
660 660 kwargs['configuration_keys'] = ['name', 'device__name',
661 661 'device__ip_address', 'device__port_address']
662 662 exp = Experiment.objects.get(pk=request.GET['template'])
663 663 form = ExperimentForm(instance=exp,
664 664 initial={'name': '{}_{:%y%m%d}'.format(exp.name, datetime.now()),
665 665 'template': False})
666 666 elif 'blank' in request.GET:
667 667 kwargs['button'] = 'Create'
668 668 form = ExperimentForm()
669 669 else:
670 670 form = NewForm()
671 671
672 672 if request.method == 'POST':
673 673 form = ExperimentForm(request.POST)
674 674 if form.is_valid():
675 675 experiment = form.save(commit=False)
676 676 experiment.author = request.user
677 677 experiment.save()
678 678
679 679 if 'template' in request.GET:
680 680 configurations = Configuration.objects.filter(
681 681 experiment=request.GET['template'], type=0)
682 682 for conf in configurations:
683 683 conf.clone(experiment=experiment, template=False)
684 684
685 685 return redirect('url_experiment', id_exp=experiment.id)
686 686
687 687 kwargs['form'] = form
688 688 kwargs['title'] = 'Experiment'
689 689 kwargs['suptitle'] = 'New'
690 690 kwargs['menu_experiments'] = 'active'
691 691
692 692 return render(request, 'experiment_edit.html', kwargs)
693 693
694 694
695 695 @login_required
696 696 def experiment_edit(request, id_exp):
697 697
698 698 experiment = get_object_or_404(Experiment, pk=id_exp)
699 699
700 700 if request.method == 'GET':
701 701 form = ExperimentForm(instance=experiment)
702 702
703 703 if request.method == 'POST':
704 704 form = ExperimentForm(request.POST, instance=experiment)
705 705
706 706 if form.is_valid():
707 707 experiment = form.save()
708 708 return redirect('url_experiment', id_exp=experiment.id)
709 709
710 710 kwargs = {}
711 711 kwargs['form'] = form
712 712 kwargs['title'] = 'Experiment'
713 713 kwargs['suptitle'] = 'Edit'
714 714 kwargs['button'] = 'Update'
715 715 kwargs['menu_experiments'] = 'active'
716 716
717 717 return render(request, 'experiment_edit.html', kwargs)
718 718
719 719
720 720 @login_required
721 721 def experiment_delete(request, id_exp):
722 722
723 723 experiment = get_object_or_404(Experiment, pk=id_exp)
724 724
725 725 if request.method == 'POST':
726 726 if is_developer(request.user):
727 727 for conf in Configuration.objects.filter(experiment=experiment):
728 728 conf.delete()
729 729 experiment.delete()
730 730 return redirect('url_experiments')
731 731
732 732 messages.error(request, 'Not enough permission to delete this object')
733 733 return redirect(experiment.get_absolute_url())
734 734
735 735 kwargs = {
736 736 'title': 'Delete',
737 737 'suptitle': 'Experiment',
738 738 'object': experiment,
739 739 'delete': True
740 740 }
741 741
742 742 return render(request, 'confirm.html', kwargs)
743 743
744 744
745 745 @login_required
746 746 def experiment_export(request, id_exp):
747 747
748 748 experiment = get_object_or_404(Experiment, pk=id_exp)
749 749 content = experiment.parms_to_dict()
750 750 content_type = 'application/json'
751 751 filename = '%s_%s.json' % (experiment.name, experiment.id)
752 752
753 753 response = HttpResponse(content_type=content_type)
754 754 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
755 755 response.write(json.dumps(content, indent=2))
756 756
757 757 return response
758 758
759 759
760 760 @login_required
761 761 def experiment_import(request, id_exp):
762 762
763 763 experiment = get_object_or_404(Experiment, pk=id_exp)
764 764 configurations = Configuration.objects.filter(experiment=experiment)
765 765
766 766 if request.method == 'GET':
767 767 file_form = UploadFileForm()
768 768
769 769 if request.method == 'POST':
770 770 file_form = UploadFileForm(request.POST, request.FILES)
771 771
772 772 if file_form.is_valid():
773 773 new_exp = experiment.dict_to_parms(
774 774 json.load(request.FILES['file']), CONF_MODELS)
775 775 messages.success(
776 776 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
777 777 return redirect(new_exp.get_absolute_url_edit())
778 778
779 779 messages.error(request, "Could not import parameters from file")
780 780
781 781 kwargs = {}
782 782 kwargs['title'] = 'Experiment'
783 783 kwargs['form'] = file_form
784 784 kwargs['suptitle'] = 'Importing file'
785 785 kwargs['button'] = 'Import'
786 786 kwargs['menu_experiments'] = 'active'
787 787
788 788 kwargs.update(sidebar(experiment=experiment))
789 789
790 790 return render(request, 'experiment_import.html', kwargs)
791 791
792 792
793 793 @login_required
794 794 def experiment_start(request, id_exp):
795 795
796 796 exp = get_object_or_404(Experiment, pk=id_exp)
797 797
798 798 if exp.status == 2:
799 799 messages.warning(request, 'Experiment {} already runnnig'.format(exp))
800 800 else:
801 801 exp.status = exp.start()
802 802 if exp.status == 0:
803 803 messages.error(request, 'Experiment {} not start'.format(exp))
804 804 if exp.status == 2:
805 805 messages.success(request, 'Experiment {} started'.format(exp))
806 806
807 807 exp.save()
808 808
809 809 return redirect(exp.get_absolute_url())
810 810
811 811
812 812 @login_required
813 813 def experiment_stop(request, id_exp):
814 814
815 815 exp = get_object_or_404(Experiment, pk=id_exp)
816 816
817 817 if exp.status == 2:
818 818 exp.status = exp.stop()
819 819 exp.save()
820 820 messages.success(request, 'Experiment {} stopped'.format(exp))
821 821 else:
822 822 messages.error(request, 'Experiment {} not running'.format(exp))
823 823
824 824 return redirect(exp.get_absolute_url())
825 825
826 826
827 827 def experiment_status(request, id_exp):
828 828
829 829 exp = get_object_or_404(Experiment, pk=id_exp)
830 830
831 831 exp.get_status()
832 832
833 833 return redirect(exp.get_absolute_url())
834 834
835 835
836 836 @login_required
837 837 def experiment_mix(request, id_exp):
838 838
839 839 experiment = get_object_or_404(Experiment, pk=id_exp)
840 840 rc_confs = [conf for conf in RCConfiguration.objects.filter(
841 841 experiment=id_exp,
842 842 type=0,
843 843 mix=False)]
844 844
845 845 if len(rc_confs) < 2:
846 846 messages.warning(
847 847 request, 'You need at least two RC Configurations to make a mix')
848 848 return redirect(experiment.get_absolute_url())
849 849
850 850 mix_confs = RCConfiguration.objects.filter(experiment=id_exp, mix=True, type=0)
851 851
852 852 if mix_confs:
853 853 mix = mix_confs[0]
854 854 else:
855 855 mix = RCConfiguration(experiment=experiment,
856 856 device=rc_confs[0].device,
857 857 ipp=rc_confs[0].ipp,
858 858 clock_in=rc_confs[0].clock_in,
859 859 clock_divider=rc_confs[0].clock_divider,
860 860 mix=True,
861 861 parameters='')
862 862 mix.save()
863 863
864 864 line_type = RCLineType.objects.get(name='mix')
865 865 print("VIew obteniendo len getlines")
866 866 print(len(rc_confs[0].get_lines()))
867 867 for i in range(len(rc_confs[0].get_lines())):
868 868 line = RCLine(rc_configuration=mix, line_type=line_type, channel=i)
869 869 line.save()
870 870
871 871 initial = {'name': mix.name,
872 872 'result': parse_mix_result(mix.parameters),
873 873 'delay': 0,
874 874 'mask': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
875 875 }
876 876
877 877 if request.method == 'GET':
878 878 form = RCMixConfigurationForm(confs=rc_confs, initial=initial)
879 879
880 880 if request.method == 'POST':
881 881 result = mix.parameters
882 882
883 883 if '{}|'.format(request.POST['experiment']) in result:
884 884 messages.error(request, 'Configuration already added')
885 885 else:
886 886 if 'operation' in request.POST:
887 887 operation = MIX_OPERATIONS[request.POST['operation']]
888 888 else:
889 889 operation = ' '
890 890
891 891 mode = MIX_MODES[request.POST['mode']]
892 892
893 893 if result:
894 894 result = '{}-{}|{}|{}|{}|{}'.format(mix.parameters,
895 895 request.POST['experiment'],
896 896 mode,
897 897 operation,
898 898 float(
899 899 request.POST['delay']),
900 900 parse_mask(
901 901 request.POST.getlist('mask'))
902 902 )
903 903 else:
904 904 result = '{}|{}|{}|{}|{}'.format(request.POST['experiment'],
905 905 mode,
906 906 operation,
907 907 float(request.POST['delay']),
908 908 parse_mask(
909 909 request.POST.getlist('mask'))
910 910 )
911 911
912 912 mix.parameters = result
913 913 mix.save()
914 914 mix.update_pulses()
915 915
916 916 initial['result'] = parse_mix_result(result)
917 917 initial['name'] = mix.name
918 918
919 919 form = RCMixConfigurationForm(initial=initial, confs=rc_confs)
920 920
921 921 kwargs = {
922 922 'title': 'Experiment',
923 923 'suptitle': 'Mix Configurations',
924 924 'form': form,
925 925 'extra_button': 'Delete',
926 926 'button': 'Add',
927 927 'cancel': 'Back',
928 928 'previous': experiment.get_absolute_url(),
929 929 'id_exp': id_exp,
930 930
931 931 }
932 932 kwargs['menu_experiments'] = 'active'
933 933
934 934 return render(request, 'experiment_mix.html', kwargs)
935 935
936 936
937 937 @login_required
938 938 def experiment_mix_delete(request, id_exp):
939 939
940 940 conf = RCConfiguration.objects.get(experiment=id_exp, mix=True, type=0)
941 941 values = conf.parameters.split('-')
942 942 conf.parameters = '-'.join(values[:-1])
943 943 conf.save()
944 944
945 945 return redirect('url_mix_experiment', id_exp=id_exp)
946 946
947 947
948 948 def experiment_summary(request, id_exp):
949 949
950 950 experiment = get_object_or_404(Experiment, pk=id_exp)
951 951 configurations = Configuration.objects.filter(
952 952 experiment=experiment, type=0)
953 953
954 954 kwargs = {}
955 955 kwargs['experiment_keys'] = ['radar_system',
956 956 'name', 'freq', 'start_time', 'end_time']
957 957 kwargs['experiment'] = experiment
958 958 kwargs['configurations'] = []
959 959 kwargs['title'] = 'Experiment Summary'
960 960 kwargs['suptitle'] = 'Details'
961 961 kwargs['button'] = 'Verify Parameters'
962 962
963 963 c_vel = 3.0*(10**8) # m/s
964 964 ope_freq = experiment.freq*(10**6) # 1/s
965 965 radar_lambda = c_vel/ope_freq # m
966 966 kwargs['radar_lambda'] = radar_lambda
967 967
968 968 ipp = None
969 969 nsa = 1
970 970 code_id = 0
971 971 tx_line = {}
972 972
973 973 for configuration in configurations.filter(device__device_type__name = 'rc'):
974 974
975 975 if configuration.mix:
976 976 continue
977 977 conf = {'conf': configuration}
978 978 conf['keys'] = []
979 979 conf['NTxs'] = configuration.ntx
980 980 conf['keys'].append('NTxs')
981 981 ipp = configuration.ipp
982 982 conf['IPP'] = ipp
983 983 conf['keys'].append('IPP')
984 984 lines = configuration.get_lines(line_type__name='tx')
985 985
986 986 for tx_line in lines:
987 987 tx_params = json.loads(tx_line.params)
988 988 conf[tx_line.get_name()] = '{} Km'.format(tx_params['pulse_width'])
989 989 conf['keys'].append(tx_line.get_name())
990 990 delays = tx_params['delays']
991 991 if delays not in ('', '0'):
992 992 n = len(delays.split(','))
993 993 taus = '{} Taus: {}'.format(n, delays)
994 994 else:
995 995 taus = '-'
996 996 conf['Taus ({})'.format(tx_line.get_name())] = taus
997 997 conf['keys'].append('Taus ({})'.format(tx_line.get_name()))
998 998 for code_line in configuration.get_lines(line_type__name='codes'):
999 999 code_params = json.loads(code_line.params)
1000 1000 code_id = code_params['code']
1001 1001 if tx_line.pk == int(code_params['TX_ref']):
1002 1002 conf['Code ({})'.format(tx_line.get_name())] = '{}:{}'.format(RCLineCode.objects.get(pk=code_params['code']),
1003 1003 '-'.join(code_params['codes']))
1004 1004 conf['keys'].append('Code ({})'.format(tx_line.get_name()))
1005 1005
1006 1006 for windows_line in configuration.get_lines(line_type__name='windows'):
1007 1007 win_params = json.loads(windows_line.params)
1008 1008 if tx_line.pk == int(win_params['TX_ref']):
1009 1009 windows = ''
1010 1010 nsa = win_params['params'][0]['number_of_samples']
1011 1011 for i, params in enumerate(win_params['params']):
1012 1012 windows += 'W{}: Ho={first_height} km DH={resolution} km NSA={number_of_samples}<br>'.format(
1013 1013 i, **params)
1014 1014 conf['Window'] = mark_safe(windows)
1015 1015 conf['keys'].append('Window')
1016 1016
1017 1017 kwargs['configurations'].append(conf)
1018 1018
1019 1019 for configuration in configurations.filter(device__device_type__name = 'jars'):
1020 1020
1021 1021 conf = {'conf': configuration}
1022 1022 conf['keys'] = []
1023 1023 conf['Type of Data'] = EXPERIMENT_TYPE[configuration.exp_type][1]
1024 1024 conf['keys'].append('Type of Data')
1025 1025 channels_number = configuration.channels_number
1026 1026 exp_type = configuration.exp_type
1027 1027 fftpoints = configuration.fftpoints
1028 1028 filter_parms = json.loads(configuration.filter_parms)
1029 1029 spectral_number = configuration.spectral_number
1030 1030 acq_profiles = configuration.acq_profiles
1031 1031 cohe_integr = configuration.cohe_integr
1032 1032 profiles_block = configuration.profiles_block
1033 1033
1034 1034 conf['Num of Profiles'] = acq_profiles
1035 1035 conf['keys'].append('Num of Profiles')
1036 1036
1037 1037 conf['Prof per Block'] = profiles_block
1038 1038 conf['keys'].append('Prof per Block')
1039 1039
1040 1040 conf['Blocks per File'] = configuration.raw_data_blocks
1041 1041 conf['keys'].append('Blocks per File')
1042 1042
1043 1043 if exp_type == 0: # Short
1044 1044 bytes_ = 2
1045 1045 b = nsa*2*bytes_*channels_number
1046 1046 else: # Float
1047 1047 bytes_ = 4
1048 1048 channels = channels_number + spectral_number
1049 1049 b = nsa*2*bytes_*fftpoints*channels
1050 1050
1051 1051 codes_num = 7
1052 1052 if code_id == 2:
1053 1053 codes_num = 7
1054 1054 elif code_id == 12:
1055 1055 codes_num = 15
1056 1056
1057 1057 #Jars filter values:
1058 1058
1059 1059 clock = float(filter_parms['clock'])
1060 1060 filter_2 = int(filter_parms['cic_2'])
1061 1061 filter_5 = int(filter_parms['cic_5'])
1062 1062 filter_fir = int(filter_parms['fir'])
1063 1063 Fs_MHz = clock/(filter_2*filter_5*filter_fir)
1064 1064
1065 1065 #Jars values:
1066 1066 if ipp is not None:
1067 1067 IPP_units = ipp/0.15*Fs_MHz
1068 1068 IPP_us = IPP_units / Fs_MHz
1069 1069 IPP_s = IPP_units / (Fs_MHz * (10**6))
1070 1070 Ts = 1/(Fs_MHz*(10**6))
1071 1071
1072 1072 Va = radar_lambda/(4*Ts*cohe_integr)
1073 1073 rate_bh = ((nsa-codes_num)*channels_number*2 *
1074 1074 bytes_/IPP_us)*(36*(10**8)/cohe_integr)
1075 1075 rate_gh = rate_bh/(1024*1024*1024)
1076 1076
1077 1077 conf['Time per Block'] = IPP_s * profiles_block * cohe_integr
1078 1078 conf['keys'].append('Time per Block')
1079 1079 conf['Acq time'] = IPP_s * acq_profiles
1080 1080 conf['keys'].append('Acq time')
1081 1081 conf['Data rate'] = str(rate_gh)+" (GB/h)"
1082 1082 conf['keys'].append('Data rate')
1083 1083 conf['Va (m/s)'] = Va
1084 1084 conf['keys'].append('Va (m/s)')
1085 1085 conf['Vrange (m/s)'] = 3/(2*IPP_s*cohe_integr)
1086 1086 conf['keys'].append('Vrange (m/s)')
1087 1087
1088 1088 kwargs['configurations'].append(conf)
1089 1089 kwargs['menu_experiments'] = 'active'
1090 1090
1091 1091 ###### SIDEBAR ######
1092 1092 kwargs.update(sidebar(experiment=experiment))
1093 1093
1094 1094 return render(request, 'experiment_summary.html', kwargs)
1095 1095
1096 1096
1097 1097 @login_required
1098 1098 def experiment_verify(request, id_exp):
1099 1099
1100 1100 experiment = get_object_or_404(Experiment, pk=id_exp)
1101 1101 experiment_data = experiment.parms_to_dict()
1102 1102 configurations = Configuration.objects.filter(
1103 1103 experiment=experiment, type=0)
1104 1104
1105 1105 kwargs = {}
1106 1106
1107 1107 kwargs['experiment_keys'] = ['template',
1108 1108 'radar_system', 'name', 'start_time', 'end_time']
1109 1109 kwargs['experiment'] = experiment
1110 1110
1111 1111 kwargs['configuration_keys'] = ['name', 'device__ip_address',
1112 1112 'device__port_address', 'device__status']
1113 1113 kwargs['configurations'] = configurations
1114 1114 kwargs['experiment_data'] = experiment_data
1115 1115
1116 1116 kwargs['title'] = 'Verify Experiment'
1117 1117 kwargs['suptitle'] = 'Parameters'
1118 1118
1119 1119 kwargs['button'] = 'Update'
1120 1120
1121 1121 jars_conf = False
1122 1122 rc_conf = False
1123 1123 dds_conf = False
1124 1124
1125 1125 for configuration in configurations:
1126 1126 #-------------------- JARS -----------------------:
1127 1127 if configuration.device.device_type.name == 'jars':
1128 1128 jars_conf = True
1129 1129 jars = configuration
1130 1130 kwargs['jars_conf'] = jars_conf
1131 1131 filter_parms = json.loads(jars.filter_parms)
1132 1132 kwargs['filter_parms'] = filter_parms
1133 1133 #--Sampling Frequency
1134 1134 clock = filter_parms['clock']
1135 1135 filter_2 = filter_parms['cic_2']
1136 1136 filter_5 = filter_parms['cic_5']
1137 1137 filter_fir = filter_parms['fir']
1138 1138 samp_freq_jars = clock/filter_2/filter_5/filter_fir
1139 1139
1140 1140 kwargs['samp_freq_jars'] = samp_freq_jars
1141 1141 kwargs['jars'] = configuration
1142 1142
1143 1143 #--------------------- RC ----------------------:
1144 1144 if configuration.device.device_type.name == 'rc' and not configuration.mix:
1145 1145 rc_conf = True
1146 1146 rc = configuration
1147 1147
1148 1148 rc_parms = configuration.parms_to_dict()
1149 1149
1150 1150 win_lines = rc.get_lines(line_type__name='windows')
1151 1151 if win_lines:
1152 1152 dh = json.loads(win_lines[0].params)['params'][0]['resolution']
1153 1153 #--Sampling Frequency
1154 1154 samp_freq_rc = 0.15/dh
1155 1155 kwargs['samp_freq_rc'] = samp_freq_rc
1156 1156
1157 1157 kwargs['rc_conf'] = rc_conf
1158 1158 kwargs['rc'] = configuration
1159 1159
1160 1160 #-------------------- DDS ----------------------:
1161 1161 if configuration.device.device_type.name == 'dds':
1162 1162 dds_conf = True
1163 1163 dds = configuration
1164 1164 dds_parms = configuration.parms_to_dict()
1165 1165
1166 1166 kwargs['dds_conf'] = dds_conf
1167 1167 kwargs['dds'] = configuration
1168 1168
1169 1169 #------------Validation------------:
1170 1170 #Clock
1171 1171 if dds_conf and rc_conf and jars_conf:
1172 1172 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) and float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
1173 1173 messages.warning(request, "Devices don't have the same clock.")
1174 1174 elif rc_conf and jars_conf:
1175 1175 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']):
1176 1176 messages.warning(request, "Devices don't have the same clock.")
1177 1177 elif rc_conf and dds_conf:
1178 1178 if float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
1179 1179 messages.warning(request, "Devices don't have the same clock.")
1180 1180 if float(samp_freq_rc) != float(dds_parms['configurations']['byId'][str(dds.pk)]['frequencyA']):
1181 1181 messages.warning(
1182 1182 request, "Devices don't have the same Frequency A.")
1183 1183
1184 1184 #------------POST METHOD------------:
1185 1185 if request.method == 'POST':
1186 1186 if request.POST['suggest_clock']:
1187 1187 try:
1188 1188 suggest_clock = float(request.POST['suggest_clock'])
1189 1189 except:
1190 1190 messages.warning(request, "Invalid value in CLOCK IN.")
1191 1191 return redirect('url_verify_experiment', id_exp=experiment.id)
1192 1192 else:
1193 1193 suggest_clock = ""
1194 1194 if suggest_clock:
1195 1195 if rc_conf:
1196 1196 rc.clock_in = suggest_clock
1197 1197 rc.save()
1198 1198 if jars_conf:
1199 1199 filter_parms = jars.filter_parms
1200 1200 filter_parms = ast.literal_eval(filter_parms)
1201 1201 filter_parms['clock'] = suggest_clock
1202 1202 jars.filter_parms = json.dumps(filter_parms)
1203 1203 jars.save()
1204 1204 kwargs['filter_parms'] = filter_parms
1205 1205 if dds_conf:
1206 1206 dds.clock = suggest_clock
1207 1207 dds.save()
1208 1208
1209 1209 if request.POST['suggest_frequencyA']:
1210 1210 try:
1211 1211 suggest_frequencyA = float(request.POST['suggest_frequencyA'])
1212 1212 except:
1213 1213 messages.warning(request, "Invalid value in FREQUENCY A.")
1214 1214 return redirect('url_verify_experiment', id_exp=experiment.id)
1215 1215 else:
1216 1216 suggest_frequencyA = ""
1217 1217 if suggest_frequencyA:
1218 1218 if jars_conf:
1219 1219 filter_parms = jars.filter_parms
1220 1220 filter_parms = ast.literal_eval(filter_parms)
1221 1221 filter_parms['fch'] = suggest_frequencyA
1222 1222 jars.filter_parms = json.dumps(filter_parms)
1223 1223 jars.save()
1224 1224 kwargs['filter_parms'] = filter_parms
1225 1225 if dds_conf:
1226 1226 dds.frequencyA_Mhz = request.POST['suggest_frequencyA']
1227 1227 dds.save()
1228 1228
1229 1229 kwargs['menu_experiments'] = 'active'
1230 1230 kwargs.update(sidebar(experiment=experiment))
1231 1231 return render(request, 'experiment_verify.html', kwargs)
1232 1232
1233 1233
1234 1234 def parse_mix_result(s):
1235 1235
1236 1236 values = s.split('-')
1237 1237 html = 'EXP MOD OPE DELAY MASK\r\n'
1238 1238
1239 1239 if not values or values[0] in ('', ' '):
1240 1240 return mark_safe(html)
1241 1241
1242 1242 for i, value in enumerate(values):
1243 1243 if not value:
1244 1244 continue
1245 1245 pk, mode, operation, delay, mask = value.split('|')
1246 1246 conf = RCConfiguration.objects.get(pk=pk)
1247 1247 if i == 0:
1248 1248 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1249 1249 conf.name,
1250 1250 mode,
1251 1251 ' ',
1252 1252 delay,
1253 1253 mask)
1254 1254 else:
1255 1255 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1256 1256 conf.name,
1257 1257 mode,
1258 1258 operation,
1259 1259 delay,
1260 1260 mask)
1261 1261
1262 1262 return mark_safe(html)
1263 1263
1264 1264
1265 1265 def parse_mask(l):
1266 1266
1267 1267 values = []
1268 1268
1269 1269 for x in range(16):
1270 1270 if '{}'.format(x) in l:
1271 1271 values.append(1)
1272 1272 else:
1273 1273 values.append(0)
1274 1274
1275 1275 values.reverse()
1276 1276
1277 1277 return int(''.join([str(x) for x in values]), 2)
1278 1278
1279 1279
1280 1280 def dev_confs(request):
1281 1281
1282 1282 page = request.GET.get('page')
1283 1283 order = ('-programmed_date', )
1284 1284 filters = request.GET.copy()
1285 1285 if 'my configurations' in filters:
1286 1286 filters.pop('my configurations', None)
1287 1287 filters['mine'] = request.user.id
1288 1288 kwargs = get_paginator(Configuration, page, order, filters)
1289 1289 fields = ['tags', 'template', 'historical']
1290 1290 if request.user.is_authenticated:
1291 1291 fields.append('my configurations')
1292 1292 form = FilterForm(initial=request.GET, extra_fields=fields)
1293 1293 kwargs['keys'] = ['name', 'experiment',
1294 1294 'type', 'programmed_date', 'actions']
1295 1295 kwargs['title'] = 'Configuration'
1296 1296 kwargs['suptitle'] = 'List'
1297 1297 kwargs['no_sidebar'] = True
1298 1298 kwargs['form'] = form
1299 1299 kwargs['add_url'] = reverse('url_add_dev_conf', args=[0])
1300 1300 filters = request.GET.copy()
1301 1301 filters.pop('page', None)
1302 1302 kwargs['q'] = urlencode(filters)
1303 1303 kwargs['menu_configurations'] = 'active'
1304 1304
1305 1305 return render(request, 'base_list.html', kwargs)
1306 1306
1307 1307
1308 1308 def dev_conf(request, id_conf):
1309 1309
1310 1310 conf = get_object_or_404(Configuration, pk=id_conf)
1311 1311
1312 1312 return redirect(conf.get_absolute_url())
1313 1313
1314 1314
1315 1315 @login_required
1316 1316 def dev_conf_new(request, id_exp=0, id_dev=0):
1317 1317
1318 1318 if not is_developer(request.user):
1319 1319 messages.error(
1320 1320 request, 'Developer required, to create new configurations')
1321 1321 return redirect('index')
1322 1322
1323 1323 initial = {}
1324 1324 kwargs = {}
1325 1325
1326 1326 if id_exp != 0:
1327 1327 initial['experiment'] = id_exp
1328 1328
1329 1329 if id_dev != 0:
1330 1330 initial['device'] = id_dev
1331 1331
1332 1332 if request.method == 'GET':
1333 1333
1334 1334 if id_dev:
1335 1335 kwargs['button'] = 'Create'
1336 1336 device = Device.objects.get(pk=id_dev)
1337 1337 DevConfForm = CONF_FORMS[device.device_type.name]
1338 1338 initial['name'] = request.GET['name']
1339 1339 form = DevConfForm(initial=initial)
1340 1340 else:
1341 1341 if 'template' in request.GET:
1342 1342 if request.GET['template'] == '0':
1343 1343 choices = [(conf.pk, '{}'.format(conf))
1344 1344 for conf in Configuration.objects.filter(template=True)]
1345 1345 form = NewForm(initial={'create_from': 2},
1346 1346 template_choices=choices)
1347 1347 else:
1348 1348 kwargs['button'] = 'Create'
1349 1349 conf = Configuration.objects.get(
1350 1350 pk=request.GET['template'])
1351 1351 id_dev = conf.device.pk
1352 1352 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1353 1353 form = DevConfForm(instance=conf,
1354 1354 initial={'name': '{}_{:%y%m%d}'.format(conf.name, datetime.now()),
1355 1355 'template': False,
1356 1356 'experiment': id_exp})
1357 1357 elif 'blank' in request.GET:
1358 1358 kwargs['button'] = 'Create'
1359 1359 form = ConfigurationForm(initial=initial)
1360 1360 else:
1361 1361 form = NewForm()
1362 1362
1363 1363 if request.method == 'POST':
1364 1364
1365 1365 device = Device.objects.get(pk=request.POST['device'])
1366 1366 DevConfForm = CONF_FORMS[device.device_type.name]
1367 1367
1368 1368 form = DevConfForm(request.POST)
1369 1369 kwargs['button'] = 'Create'
1370 1370 if form.is_valid():
1371 1371 conf = form.save(commit=False)
1372 1372 conf.author = request.user
1373 1373 conf.save()
1374 1374
1375 1375 if 'template' in request.GET and conf.device.device_type.name == 'rc':
1376 1376 lines = RCLine.objects.filter(
1377 1377 rc_configuration=request.GET['template'])
1378 1378 for line in lines:
1379 1379 line.clone(rc_configuration=conf)
1380 1380
1381 1381 new_lines = conf.get_lines()
1382 1382 for line in new_lines:
1383 1383 line_params = json.loads(line.params)
1384 1384 if 'TX_ref' in line_params:
1385 1385 ref_line = RCLine.objects.get(pk=line_params['TX_ref'])
1386 1386 line_params['TX_ref'] = ['{}'.format(
1387 1387 l.pk) for l in new_lines if l.get_name() == ref_line.get_name()][0]
1388 1388 line.params = json.dumps(line_params)
1389 1389 line.save()
1390 1390 elif conf.device.device_type.name == 'rc':
1391 1391 clk = RCClock(rc_configuration=conf)
1392 1392 clk.save()
1393 1393
1394 1394 return redirect('url_dev_conf', id_conf=conf.pk)
1395 1395
1396 1396 kwargs['id_exp'] = id_exp
1397 1397 kwargs['form'] = form
1398 1398 kwargs['title'] = 'Configuration'
1399 1399 kwargs['suptitle'] = 'New'
1400 1400 kwargs['menu_configurations'] = 'active'
1401 1401
1402 1402 if id_dev != 0:
1403 1403 device = Device.objects.get(pk=id_dev)
1404 1404 kwargs['device'] = device.device_type.name
1405 1405 print(id_exp)
1406 1406 return render(request, 'dev_conf_edit.html', kwargs)
1407 1407
1408 1408
1409 1409 @login_required
1410 1410 def dev_conf_edit(request, id_conf):
1411 1411
1412 1412 conf = get_object_or_404(Configuration, pk=id_conf)
1413 1413
1414 1414 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1415 1415
1416 1416 if request.method == 'GET':
1417 1417 form = DevConfForm(instance=conf)
1418 1418
1419 1419 if request.method == 'POST':
1420 1420 form = DevConfForm(request.POST, instance=conf)
1421 1421
1422 1422 if form.is_valid():
1423 1423 form.save()
1424 1424 return redirect('url_dev_conf', id_conf=id_conf)
1425 1425
1426 1426 kwargs = {}
1427 1427 kwargs['form'] = form
1428 1428 kwargs['title'] = 'Device Configuration'
1429 1429 kwargs['suptitle'] = 'Edit'
1430 1430 kwargs['button'] = 'Update'
1431 1431 kwargs['menu_configurations'] = 'active'
1432 1432
1433 1433 ###### SIDEBAR ######
1434 1434 kwargs.update(sidebar(conf=conf))
1435 1435
1436 1436 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1437 1437
1438 1438
1439 1439 @login_required
1440 1440 def dev_conf_start(request, id_conf):
1441 1441
1442 1442 conf = get_object_or_404(Configuration, pk=id_conf)
1443 1443
1444 1444 if conf.start_device():
1445 1445 messages.success(request, conf.message)
1446 1446 else:
1447 1447 messages.error(request, conf.message)
1448 1448
1449 1449 #conf.status_device()
1450 1450
1451 1451 return redirect(conf.get_absolute_url())
1452 1452
1453 1453
1454 1454 @login_required
1455 1455 def dev_conf_stop(request, id_conf):
1456 1456
1457 1457 conf = get_object_or_404(Configuration, pk=id_conf)
1458 1458
1459 1459 if conf.stop_device():
1460 1460 messages.success(request, conf.message)
1461 1461 else:
1462 1462 messages.error(request, conf.message)
1463 1463
1464 1464 #conf.status_device()
1465 1465
1466 1466 return redirect(conf.get_absolute_url())
1467 1467
1468 1468 @login_required
1469 1469 def dev_conf_stop_mqtt(request, id_conf):
1470 1470
1471 1471 conf = get_object_or_404(Configuration, pk=id_conf)
1472 1472
1473 1473 if conf.stop_device_mqtt():
1474 1474 messages.success(request, conf.message)
1475 1475 else:
1476 1476 messages.error(request, conf.message)
1477 1477
1478 1478 #conf.status_device()
1479 1479
1480 1480 return redirect(conf.get_absolute_url())
1481 1481
1482 1482 @login_required
1483 1483 def dev_conf_status(request, id_conf):
1484 1484
1485 1485 conf = get_object_or_404(Configuration, pk=id_conf)
1486 1486
1487 1487 conf_active = Configuration.objects.filter(pk=conf.device.conf_active).first()
1488 1488 if conf_active!=conf:
1489 1489 url = '#' if conf_active is None else conf_active.get_absolute_url()
1490 1490 label = 'None' if conf_active is None else conf_active.label
1491 1491 messages.warning(
1492 1492 request,
1493 1493 mark_safe('The current configuration has not been written to device, the active configuration is <a href="{}">{}</a>'.format(
1494 1494 url,
1495 1495 label
1496 1496 ))
1497 1497 )
1498 1498
1499 1499 return redirect(conf.get_absolute_url())
1500 1500
1501 1501 if conf.status_device():
1502 1502 messages.success(request, conf.message)
1503 1503 else:
1504 1504 messages.error(request, conf.message)
1505 1505
1506 1506 return redirect(conf.get_absolute_url())
1507 1507
1508 1508
1509 1509 @login_required
1510 1510 def dev_conf_reset(request, id_conf):
1511 1511
1512 1512 conf = get_object_or_404(Configuration, pk=id_conf)
1513 1513
1514 1514 if conf.reset_device():
1515 1515 messages.success(request, conf.message)
1516 1516 else:
1517 1517 messages.error(request, conf.message)
1518 1518
1519 1519 return redirect(conf.get_absolute_url())
1520 1520
1521 1521
1522 1522 @login_required
1523 1523 def dev_conf_write(request, id_conf):
1524 1524
1525 1525 conf = get_object_or_404(Configuration, pk=id_conf)
1526 1526
1527 1527 if request.method == 'POST':
1528 1528 if conf.write_device():
1529 1529 conf.device.conf_active = conf.pk
1530 1530 conf.device.save()
1531 1531 messages.success(request, conf.message)
1532 1532 if has_been_modified(conf):
1533 1533 conf.clone(type=1, template=False)
1534 1534 else:
1535 1535 messages.error(request, conf.message)
1536 1536
1537 1537 return redirect(get_object_or_404(Configuration, pk=id_conf).get_absolute_url())
1538 1538
1539 1539 kwargs = {
1540 1540 'title': 'Write Configuration',
1541 1541 'suptitle': conf.label,
1542 1542 'message': 'Are you sure yo want to write this {} configuration?'.format(conf.device),
1543 1543 'delete': False
1544 1544 }
1545 1545 kwargs['menu_configurations'] = 'active'
1546 1546
1547 1547 return render(request, 'confirm.html', kwargs)
1548 1548
1549 1549
1550 1550 @login_required
1551 1551 def dev_conf_write_mqtt(request,id_conf):
1552 1552
1553 1553 conf = get_object_or_404(Configuration, pk=id_conf)
1554 1554 beams = ABSBeam.objects.filter(abs_conf=conf)
1555 1555
1556 1556 if request.method == 'POST':
1557 1557 if conf.write_device_mqtt():
1558 1558 conf.device.conf_active = conf.pk
1559 1559 conf.device.save()
1560 1560 messages.success(request, conf.message)
1561 1561 if has_been_modified(conf):
1562 1562 conf.clone(type=1, template=False)
1563 1563 else:
1564 1564 messages.error(request, conf.message)
1565 1565 print("return",flush=True)
1566 1566 #return redirect(get_object_or_404(Configuration, pk=id_conf).get_absolute_url())
1567 1567
1568 1568 module_messages = json.loads(conf.module_messages)
1569 1569 kwargs = {}
1570 1570 kwargs['connected_modules'] = str(conf.connected_modules())+'/64'
1571 1571 kwargs['dev_conf'] = conf
1572 1572
1573 1573 if conf.operation_mode == 0:
1574 1574 kwargs['dev_conf_keys'] = ['label', 'operation_mode']
1575 1575 else:
1576 1576 kwargs['dev_conf_keys'] = ['label', 'operation_mode', 'operation_value']
1577 1577
1578 1578 kwargs['title'] = 'ABS Configuration'
1579 1579 kwargs['suptitle'] = 'Details'
1580 1580 kwargs['button'] = 'Edit Configuration'
1581 1581
1582 1582 print("conf.active_beam: {}".format(conf.active_beam))
1583 1583 if conf.active_beam != 0:
1584 1584 kwargs['active_beam'] = int(conf.active_beam)
1585 1585
1586 1586
1587 1587 kwargs['beams'] = beams
1588 1588 # kwargs['modules_status'] = all_status
1589 1589 # kwargs['color_status'] = color_status
1590 1590
1591
1592 1591 kwargs['module_messages'] = module_messages
1593 1592
1594 1593 ###### SIDEBAR ######
1595 1594 kwargs.update(sidebar(conf=conf))
1596 1595
1597
1598 1596 return render(request, 'abs_conf_mqtt.html',kwargs)
1599 1597
1600 1598 kwargs = {
1601 1599 'title': 'MQTT Write Configuration',
1602 1600 'suptitle': conf.label,
1603 1601 'message': 'Are you sure yo want to write through MQTT this {} configuration?'.format(conf.device),
1604 1602 'delete': False
1605 1603 }
1606 1604 kwargs['menu_configurations'] = 'active'
1607 1605 print("Confirm",flush=True)
1608 1606 return render(request, 'confirm.html', kwargs)
1609 1607
1610 1608
1611 1609 @login_required
1612 1610 def dev_conf_read(request, id_conf):
1613 1611
1614 1612 conf = get_object_or_404(Configuration, pk=id_conf)
1615 1613
1616 1614 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1617 1615
1618 1616 if request.method == 'GET':
1619 1617
1620 1618 parms = conf.read_device()
1621 1619 #conf.status_device()
1622 1620
1623 1621 if not parms:
1624 1622 messages.error(request, conf.message)
1625 1623 return redirect(conf.get_absolute_url())
1626 1624
1627 1625 form = DevConfForm(initial=parms, instance=conf)
1628 1626
1629 1627 if request.method == 'POST':
1630 1628 form = DevConfForm(request.POST, instance=conf)
1631 1629
1632 1630 if form.is_valid():
1633 1631 form.save()
1634 1632 return redirect(conf.get_absolute_url())
1635 1633
1636 1634 messages.error(request, "Parameters could not be saved")
1637 1635
1638 1636 kwargs = {}
1639 1637 kwargs['id_dev'] = conf.id
1640 1638 kwargs['form'] = form
1641 1639 kwargs['title'] = 'Device Configuration'
1642 1640 kwargs['suptitle'] = 'Parameters read from device'
1643 1641 kwargs['button'] = 'Save'
1644 1642
1645 1643 ###### SIDEBAR ######
1646 1644 kwargs.update(sidebar(conf=conf))
1647 1645
1648 1646 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1649 1647
1650 1648
1651 1649 @login_required
1652 1650 def dev_conf_import(request, id_conf):
1653 1651
1654 1652 conf = get_object_or_404(Configuration, pk=id_conf)
1655 1653 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1656 1654
1657 1655 if request.method == 'GET':
1658 1656 file_form = UploadFileForm()
1659 1657
1660 1658 if request.method == 'POST':
1661 1659 file_form = UploadFileForm(request.POST, request.FILES)
1662 1660
1663 1661 if file_form.is_valid():
1664 1662
1665 1663 data = conf.import_from_file(request.FILES['file'])
1666 1664 parms = Params(data=data).get_conf(
1667 1665 dtype=conf.device.device_type.name)
1668 1666
1669 1667 if parms:
1670 1668
1671 1669 form = DevConfForm(initial=parms, instance=conf)
1672 1670
1673 1671 kwargs = {}
1674 1672 kwargs['id_dev'] = conf.id
1675 1673 kwargs['form'] = form
1676 1674 kwargs['title'] = 'Device Configuration'
1677 1675 kwargs['suptitle'] = 'Parameters imported'
1678 1676 kwargs['button'] = 'Save'
1679 1677 kwargs['action'] = conf.get_absolute_url_edit()
1680 1678 kwargs['previous'] = conf.get_absolute_url()
1681 1679
1682 1680 ###### SIDEBAR ######
1683 1681 kwargs.update(sidebar(conf=conf))
1684 1682
1685 1683 messages.success(
1686 1684 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
1687 1685
1688 1686 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1689 1687
1690 1688 messages.error(request, "Could not import parameters from file")
1691 1689
1692 1690 kwargs = {}
1693 1691 kwargs['id_dev'] = conf.id
1694 1692 kwargs['title'] = 'Device Configuration'
1695 1693 kwargs['form'] = file_form
1696 1694 kwargs['suptitle'] = 'Importing file'
1697 1695 kwargs['button'] = 'Import'
1698 1696 kwargs['menu_configurations'] = 'active'
1699 1697
1700 1698 kwargs.update(sidebar(conf=conf))
1701 1699
1702 1700 return render(request, 'dev_conf_import.html', kwargs)
1703 1701
1704 1702
1705 1703 @login_required
1706 1704 def dev_conf_export(request, id_conf):
1707 1705
1708 1706 conf = get_object_or_404(Configuration, pk=id_conf)
1709 1707
1710 1708 if request.method == 'GET':
1711 1709 file_form = DownloadFileForm(conf.device.device_type.name)
1712 1710
1713 1711 if request.method == 'POST':
1714 1712 file_form = DownloadFileForm(
1715 1713 conf.device.device_type.name, request.POST)
1716 1714
1717 1715 if file_form.is_valid():
1718 1716 fields = conf.export_to_file(
1719 1717 format=file_form.cleaned_data['format'])
1720 1718 if not fields['content']:
1721 1719 messages.error(request, conf.message)
1722 1720 return redirect(conf.get_absolute_url_export())
1723 1721 response = HttpResponse(content_type=fields['content_type'])
1724 1722 response['Content-Disposition'] = 'attachment; filename="%s"' % fields['filename']
1725 1723 response.write(fields['content'])
1726 1724
1727 1725 return response
1728 1726
1729 1727 messages.error(request, "Could not export parameters")
1730 1728
1731 1729 kwargs = {}
1732 1730 kwargs['id_dev'] = conf.id
1733 1731 kwargs['title'] = 'Device Configuration'
1734 1732 kwargs['form'] = file_form
1735 1733 kwargs['suptitle'] = 'Exporting file'
1736 1734 kwargs['button'] = 'Export'
1737 1735 kwargs['menu_configurations'] = 'active'
1738 1736
1739 1737 return render(request, 'dev_conf_export.html', kwargs)
1740 1738
1741 1739
1742 1740 @login_required
1743 1741 def dev_conf_delete(request, id_conf):
1744 1742
1745 1743 conf = get_object_or_404(Configuration, pk=id_conf)
1746 1744
1747 1745 if request.method == 'POST':
1748 1746 if is_developer(request.user):
1749 1747 conf.delete()
1750 1748 return redirect('url_dev_confs')
1751 1749
1752 1750 messages.error(request, 'Not enough permission to delete this object')
1753 1751 return redirect(conf.get_absolute_url())
1754 1752
1755 1753 kwargs = {
1756 1754 'title': 'Delete',
1757 1755 'suptitle': 'Configuration',
1758 1756 'object': conf,
1759 1757 'delete': True
1760 1758 }
1761 1759 kwargs['menu_configurations'] = 'active'
1762 1760
1763 1761 return render(request, 'confirm.html', kwargs)
1764 1762
1765 1763
1766 1764 def sidebar(**kwargs):
1767 1765
1768 1766 side_data = {}
1769 1767
1770 1768 conf = kwargs.get('conf', None)
1771 1769 experiment = kwargs.get('experiment', None)
1772 1770
1773 1771 if not experiment:
1774 1772 experiment = conf.experiment
1775 1773
1776 1774 if experiment:
1777 1775 side_data['experiment'] = experiment
1778 1776 campaign = experiment.campaign_set.all()
1779 1777 if campaign:
1780 1778 side_data['campaign'] = campaign[0]
1781 1779 experiments = campaign[0].experiments.all().order_by('name')
1782 1780 else:
1783 1781 experiments = [experiment]
1784 1782 configurations = experiment.configuration_set.filter(type=0)
1785 1783 side_data['side_experiments'] = experiments
1786 1784 side_data['side_configurations'] = configurations.order_by(
1787 1785 'device__device_type__name')
1788 1786
1789 1787 return side_data
1790 1788
1791 1789 def get_paginator(model, page, order, filters={}, n=8):
1792 1790 kwargs = {}
1793 1791 query = Q()
1794 1792 if isinstance(filters, QueryDict):
1795 1793 filters = filters.dict()
1796 1794 copy_filters=filters.copy()
1797 1795 [filters.pop(key) for key in copy_filters.keys() if copy_filters[key] in (' ', ' ')]
1798 1796 filters.pop('page', None)
1799 1797
1800 1798 fields = [f.name for f in model._meta.get_fields()]
1801 1799
1802 1800 if 'template' in copy_filters:
1803 1801 filters['template'] = True
1804 1802 if 'historical' in copy_filters:
1805 1803 filters.pop('historical')
1806 1804 filters['type'] = 1
1807 1805 elif 'type' in fields:
1808 1806 filters['type'] = 0
1809 1807 if 'start_date' in copy_filters:
1810 1808 filters['start_date__gte'] =filters.pop('start_date')
1811 1809 if 'end_date' in copy_filters:
1812 1810 filters['start_date__lte'] =filters.pop('end_date')
1813 1811 if 'tags' in copy_filters:
1814 1812 tags =filters.pop('tags')
1815 1813 if 'tags' in fields:
1816 1814 query = query | Q(tags__icontains=tags)
1817 1815 if 'label' in fields:
1818 1816 query = query | Q(label__icontains=tags)
1819 1817 if 'location' in fields:
1820 1818 query = query | Q(location__name__icontains=tags)
1821 1819 if 'device' in fields:
1822 1820 query = query | Q(device__device_type__name__icontains=tags)
1823 1821 query = query | Q(device__location__name__icontains=tags)
1824 1822 if 'device_type' in fields:
1825 1823 query = query | Q(device_type__name__icontains=tags)
1826 1824
1827 1825 if 'mine' in copy_filters:
1828 1826 filters['author_id'] =filters['mine']
1829 1827 filters.pop('mine')
1830 1828 object_list = model.objects.filter(query, **filters).order_by(*order)
1831 1829 paginator = Paginator(object_list, n)
1832 1830
1833 1831 try:
1834 1832 objects = paginator.page(page)
1835 1833 except PageNotAnInteger:
1836 1834 objects = paginator.page(1)
1837 1835 except EmptyPage:
1838 1836 objects = paginator.page(paginator.num_pages)
1839 1837
1840 1838 kwargs['objects'] = objects
1841 1839 kwargs['offset'] = (int(page)-1)*n if page else 0
1842 1840
1843 1841 return kwargs
1844 1842
1845 1843 # def get_paginator(model, page, order, filters={}, n=8):
1846 1844 # kwargs = {}
1847 1845 # query = Q()
1848 1846 # if isinstance(filters, QueryDict):
1849 1847 # filters = filters.dict()
1850 1848 # [filters.pop(key) for key in filters.keys() if filters[key] in ('', ' ')]
1851 1849 # filters.pop('page', None)
1852 1850
1853 1851 # fields = [f.name for f in model._meta.get_fields()]
1854 1852
1855 1853 # if 'template' in filters:
1856 1854 # filters['template'] = True
1857 1855 # if 'historical' in filters:
1858 1856 # filters.pop('historical')
1859 1857 # filters['type'] = 1
1860 1858 # elif 'type' in fields:
1861 1859 # filters['type'] = 0
1862 1860 # if 'start_date' in filters:
1863 1861 # filters['start_date__gte'] = filters.pop('start_date')
1864 1862 # if 'end_date' in filters:
1865 1863 # filters['start_date__lte'] = filters.pop('end_date')
1866 1864 # if 'tags' in filters:
1867 1865 # tags = filters.pop('tags')
1868 1866 # if 'tags' in fields:
1869 1867 # query = query | Q(tags__icontains=tags)
1870 1868 # if 'label' in fields:
1871 1869 # query = query | Q(label__icontains=tags)
1872 1870 # if 'location' in fields:
1873 1871 # query = query | Q(location__name__icontains=tags)
1874 1872 # if 'device' in fields:
1875 1873 # query = query | Q(device__device_type__name__icontains=tags)
1876 1874 # query = query | Q(device__location__name__icontains=tags)
1877 1875 # if 'device_type' in fields:
1878 1876 # query = query | Q(device_type__name__icontains=tags)
1879 1877
1880 1878 # if 'mine' in filters:
1881 1879 # filters['author_id'] = filters['mine']
1882 1880 # filters.pop('mine')
1883 1881 # object_list = model.objects.filter(query, **filters).order_by(*order)
1884 1882 # paginator = Paginator(object_list, n)
1885 1883
1886 1884 # try:
1887 1885 # objects = paginator.page(page)
1888 1886 # except PageNotAnInteger:
1889 1887 # objects = paginator.page(1)
1890 1888 # except EmptyPage:
1891 1889 # objects = paginator.page(paginator.num_pages)
1892 1890
1893 1891 # kwargs['objects'] = objects
1894 1892 # kwargs['offset'] = (int(page)-1)*n if page else 0
1895 1893
1896 1894 # return kwargs
1897 1895
1898 1896
1899 1897 def operation(request, id_camp=None):
1900 1898
1901 1899 kwargs = {}
1902 1900 kwargs['title'] = 'Radars Operation'
1903 1901 kwargs['no_sidebar'] = True
1904 1902 kwargs['menu_operation'] = 'active'
1905 1903 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
1906 1904 end_date__gte=datetime.now()).order_by('-start_date')
1907 1905
1908 1906 if id_camp:
1909 1907 campaign = get_object_or_404(Campaign, pk=id_camp)
1910 1908 form = OperationForm(
1911 1909 initial={'campaign': campaign.id}, campaigns=campaigns)
1912 1910 kwargs['campaign'] = campaign
1913 1911 else:
1914 1912 # form = OperationForm(campaigns=campaigns)
1915 1913 kwargs['campaigns'] = campaigns
1916 1914 return render(request, 'operation.html', kwargs)
1917 1915
1918 1916 #---Experiment
1919 1917 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1920 1918 kwargs['experiment_keys'] = keys[1:]
1921 1919 kwargs['experiments'] = experiments
1922 1920 #---Radar
1923 1921 kwargs['locations'] = campaign.get_experiments_by_radar()
1924 1922 kwargs['form'] = form
1925 1923
1926 1924 return render(request, 'operation.html', kwargs)
1927 1925
1928 1926
1929 1927 @login_required
1930 1928 def radar_start(request, id_camp, id_radar):
1931 1929 print("Boton presionados",flush=True)
1932 1930 campaign = get_object_or_404(Campaign, pk=id_camp)
1933 1931 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1934 1932 now = datetime.now()
1935 1933
1936 1934 for exp in experiments:
1937 1935 #app.control.revoke(exp.task)
1938 1936 print("----------------------")
1939 1937 print("status:->", exp.status,flush=True)
1940 1938 start = datetime.combine(datetime.now().date(), exp.start_time)
1941 1939 end = datetime.combine(datetime.now().date(), exp.end_time)
1942 1940 print("start exp: ",exp.start_time,flush=True)
1943 1941 print("end exp: ",exp.end_time,flush=True)
1944 1942
1945 1943 print("start comb: ",start,flush=True)
1946 1944 print("end comb: ",end,flush=True)
1947 1945 print(is_aware(start),flush=True)
1948 1946 print("start camp",campaign.start_date,flush=True)
1949 1947 print("end camp",campaign.end_date,flush=True)
1950 1948 print(is_aware(campaign.start_date),flush=True)
1951 1949 if end < start:
1952 1950 end += timedelta(1)
1953 1951
1954 1952 if exp.status == 2:
1955 1953 messages.warning(
1956 1954 request, 'Experiment {} already running'.format(exp))
1957 1955 #continue
1958 1956
1959 1957 if exp.status == 3:
1960 1958 messages.warning(
1961 1959 request, 'Experiment {} already programmed'.format(exp))
1962 1960 #continue
1963 1961
1964 1962 if exp.status == 1:
1965 1963 messages.warning(
1966 1964 request, 'Experiment {} stopped'.format(exp))
1967 1965 #continue
1968 1966
1969 1967 if start > campaign.end_date:
1970 1968 messages.warning(
1971 1969 request, 'Experiment {} out of date'.format(exp))
1972 1970
1973 1971 #app.control.revoke(exp.task)
1974 1972 print("Llego luego del revoke",flush=True)
1975 1973 if now >= start and now <= end:
1976 1974
1977 1975 print("Caso now > start and < end -- (1)",flush=True)
1978 1976
1979 1977 # -------------------------------------------
1980 1978
1981 1979 # task = task_start.delay(exp.id)
1982 1980 # exp.task = task.id
1983 1981 # exp.status = task.get()
1984 1982 # -------------------------------------------
1985 1983
1986 1984 #exp.status = task.wait()
1987 1985
1988 1986 if exp.status == 0:
1989 1987 messages.error(request, 'Experiment {} not start'.format(exp))
1990 1988 if exp.status == 2:
1991 1989 messages.success(request, 'Experiment {} started'.format(exp))
1992 1990 elif now < start:
1993 1991 print("Caso now <= start -- (2)",exp.pk)
1994 1992 #task = task_start.apply_async((exp.pk, ), eta=start)#start+timedelta(hours=5))
1995 1993 # task = task_start.apply_async((exp.pk, ), eta=start+timedelta(hours=5))#)
1996 1994 # exp.task = task.id
1997 1995 # exp.status = 3
1998 1996 messages.success(request, 'Experiment {} programmed to start at {}'.format(exp, start))
1999 1997 else:
2000 1998 print("Caso now > end -- (3)")
2001 1999 exp.status = 4
2002 2000 messages.warning(
2003 2001 request, 'Experiment {} out of date'.format(exp))
2004 2002
2005 2003 exp.save()
2006 2004
2007 2005 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
2008 2006
2009 2007
2010 2008 @login_required
2011 2009 def radar_stop(request, id_camp, id_radar):
2012 2010
2013 2011 campaign = get_object_or_404(Campaign, pk=id_camp)
2014 2012 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
2015 2013 print("Ingreso en stop radar_stop")
2016 2014 #for exp in experiments:
2017 2015
2018 2016 # if exp.task:
2019 2017 # print("Ingreso antes de revoke stop")
2020 2018 # app.control.revoke(exp.task)
2021 2019
2022 2020
2023 2021 # if exp.status == 2: #status 2 es started
2024 2022 # print("llama a exp.stop")
2025 2023 # exp.stop()
2026 2024 # messages.warning(request, 'Experiment {} stopped'.format(exp))
2027 2025 # exp.status = 1
2028 2026 # exp.save()
2029 2027
2030 2028 #return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
2031 2029
2032 2030
2033 2031 @login_required
2034 2032 def radar_refresh(request, id_camp, id_radar):
2035 2033
2036 2034 campaign = get_object_or_404(Campaign, pk=id_camp)
2037 2035 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
2038 2036
2039 2037 i = app.control.inspect()
2040 2038 print("inspect",i)
2041 2039 print(i.scheduled())
2042 2040 print(i.scheduled().values())
2043 2041 scheduled = list(i.scheduled().values())[0]
2044 2042 revoked = list(i.revoked().values())[0]
2045 2043
2046 2044 # for exp in experiments:
2047 2045 # if exp.task in revoked:
2048 2046 # exp.status = 1
2049 2047 # elif exp.task in [t['request']['id'] for t in scheduled if 'task_stop' in t['request']['name']]:
2050 2048 # exp.status = 2
2051 2049 # elif exp.task in [t['request']['id'] for t in scheduled if 'task_start' in t['request']['name']]:
2052 2050 # exp.status = 3
2053 2051 # else:
2054 2052 # exp.status = 4
2055 2053 # exp.save()
2056 2054 # return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
2057 2055
2058 2056 #@login_required
2059 2057 # def revoke_tasks(request, id_camp):
2060 2058
2061 2059 # i = app.control.inspect()
2062 2060 # scheduled = list(i.scheduled().values())[0]
2063 2061 # revoked = list(i.revoked().values())[0]
2064 2062
2065 2063 # for t in scheduled:
2066 2064 # if t['request']['id'] in revoked:
2067 2065 # continue
2068 2066 # app.control.revoke(t['request']['id'])
2069 2067 # exp = Experiment.objects.get(pk=eval(str(t['request']['args']))[0])
2070 2068 # eta = t['eta']
2071 2069 # #task = t['request']['name'].split('.')[-1]
2072 2070 # messages.warning(request, 'Scheduled {} at {} for experiment {} revoked'.format(task, eta, exp.name))
2073 2071
2074 2072 # return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
2075 2073
2076 2074 # @login_required
2077 2075 # def show_tasks(request, id_camp):
2078 2076
2079 2077 # i = app.control.inspect()
2080 2078 # scheduled = list(i.scheduled().values())[0]
2081 2079 # revoked = list(i.revoked().values())[0]
2082 2080
2083 2081 # for t in scheduled:
2084 2082 # if t['request']['id'] in revoked:
2085 2083 # continue
2086 2084 # exp = Experiment.objects.get(pk=eval(str(t['request']['args']))[0])
2087 2085 # eta = t['eta']
2088 2086 # #task = t['request']['name'].split('.')[-1]
2089 2087 # #messages.success(request, 'Task {} scheduled at {} for experiment {}'.format(task, eta, exp.name))
2090 2088
2091 2089 # return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
2092 2090
2093 2091 def real_time(request):
2094 2092
2095 2093 graphic_path = "/home/fiorella/Pictures/catwbeanie.jpg"
2096 2094
2097 2095 kwargs = {}
2098 2096 kwargs['title'] = 'CLAIRE'
2099 2097 kwargs['suptitle'] = 'Real Time'
2100 2098 kwargs['no_sidebar'] = True
2101 2099 kwargs['graphic_path'] = graphic_path
2102 2100 kwargs['graphic1_path'] = 'http://www.bluemaize.net/im/girls-accessories/shark-beanie-11.jpg'
2103 2101
2104 2102 return render(request, 'real_time.html', kwargs)
2105 2103
2106 2104 def theme(request, theme):
2107 2105
2108 2106 user = request.user
2109 2107 user.profile.theme = theme
2110 2108 user.save()
2111 2109 return redirect('index')
General Comments 0
You need to be logged in to leave comments. Login now