Commit 800f4279a1300456162ad3f8db703bc69292ff7f
1 parent
e5f122b6
Exists in
dev
Updating WeatherWatchHistory models attributes, adding view for WeatherWatchHist…
…ory, improving plotting UI
Showing
9 changed files
with
190 additions
and
7 deletions
Show diff stats
CHANGELOG
1 | +28-04-2022 (AKo): v0.4.6.0 | |
2 | + - Adding weather history view | |
3 | + - time every new entry of weather history is added and last x minutes to plot are set up from config_pyros | |
4 | + - adding env monitoring to config_pyros, update schema accordingly | |
5 | + - update WeatherWatchHistory models attributes to match those with WeatherWatch | |
6 | + - WeatherWatchHistory entry makes a copy of WeatherWatch data | |
7 | + | |
1 | 8 | 27-04-2022 (AKo): v0.4.5.0 |
2 | 9 | - Adding unsubmit button for sequences |
3 | 10 | - Re-enabling cancel button for sequence (cancel = delete) |
4 | 11 | - Fixing bug where "show more informations" button on plan view page was submitting form |
12 | + - Fixing issue with saveWeather for agentM | |
5 | 13 | |
6 | 14 | 26-04-2022 (AKo): v0.4.4.1 |
7 | 15 | - Adding 3 full sequences to debris scientific program in initial fixture | ... | ... |
VERSION
src/core/pyros_django/common/models.py
... | ... | @@ -2179,6 +2179,12 @@ class WeatherWatchHistory(models.Model): |
2179 | 2179 | rain = models.CharField(max_length=45, blank=True, null=True) |
2180 | 2180 | dwn = models.CharField(max_length=45, blank=True, null=True) |
2181 | 2181 | |
2182 | + humidity = models.FloatField(blank=True, null=True) | |
2183 | + wind = models.FloatField(blank=True, null=True) | |
2184 | + wind_dir = models.CharField(max_length=45, blank=True, null=True) | |
2185 | + temperature = models.FloatField(blank=True, null=True) | |
2186 | + cloud = models.FloatField(blank=True, null=True) | |
2187 | + | |
2182 | 2188 | class Meta: |
2183 | 2189 | managed = True |
2184 | 2190 | db_table = 'weatherwatchhistory' | ... | ... |
src/core/pyros_django/misc/static/js/plotter.js
... | ... | @@ -48,7 +48,7 @@ function PlotterClas(hkname, plotdiv, HKRange) { |
48 | 48 | width: 400, |
49 | 49 | height: 200, |
50 | 50 | margin: { |
51 | - l: 20, | |
51 | + l: 50, | |
52 | 52 | r: 10, |
53 | 53 | b: 50, |
54 | 54 | t: 50, |
... | ... | @@ -81,7 +81,11 @@ PlotterClas.prototype = { |
81 | 81 | methode: function() { |
82 | 82 | alert("Attributs: " + this.hkname + ", " + this.plotdiv); |
83 | 83 | }, |
84 | - | |
84 | + clear: function(){ | |
85 | + this.HKQueue.x = []; | |
86 | + this.HKQueue.y = []; | |
87 | + | |
88 | + }, | |
85 | 89 | refresh_list: function(data) { |
86 | 90 | |
87 | 91 | var x = this.HKQueue.x.push(data[0]); |
... | ... | @@ -101,7 +105,7 @@ PlotterClas.prototype = { |
101 | 105 | // this.maxQueue.y.shift(); |
102 | 106 | // } |
103 | 107 | var config = {responsive: true}; |
104 | - Plotly.newPlot(this.plotdiv, this.dataPlot, this.layout, this.config); | |
108 | + Plotly.newPlot(this.plotdiv, this.dataPlot, this.layout, config); | |
105 | 109 | |
106 | 110 | } |
107 | 111 | ... | ... |
src/core/pyros_django/monitoring/templates/monitoring/monitoring_index.html
... | ... | @@ -90,6 +90,15 @@ |
90 | 90 | </div></a> |
91 | 91 | </div> |
92 | 92 | </li> |
93 | + <li> | |
94 | + <div class="all-box all-img-weather"> | |
95 | + <a href="{% url "weather_history" %}"> | |
96 | + <div class="all-info"> | |
97 | + <h3>Weather history</h3> | |
98 | + <img id="weather_big_img" src="{% static "media/weather.png" %}" alt="html5" /> | |
99 | + </div></a> | |
100 | + </div> | |
101 | + </li> | |
93 | 102 | {# TBD #} |
94 | 103 | {% if USER_LEVEL|ifinlist:"Admin,Operator,Unit-PI,Management board member,Observer,TAC" %} |
95 | 104 | <li> | ... | ... |
src/core/pyros_django/monitoring/templates/monitoring/weather_history.html
0 → 100644
... | ... | @@ -0,0 +1,123 @@ |
1 | +{% extends 'base.html' %} | |
2 | +{% load static %} | |
3 | +{% block head %} | |
4 | +<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> | |
5 | +<script src="{% static "js/plotly-2.11.1.min.js" %}"></script> | |
6 | +<script src="{% static "js/plotter.js" %}"></script> | |
7 | +<script src="{% static "js/weather.js" %}"></script> | |
8 | +<script src="{% static "js/vue.min.js" %}"></script> | |
9 | +<script> | |
10 | +var myHeaders = new Headers(); | |
11 | + | |
12 | +var myInit = { method: 'GET', | |
13 | + headers: myHeaders, | |
14 | + mode: 'cors', | |
15 | + cache: 'default' }; | |
16 | + | |
17 | +$(document).ready(function () { | |
18 | + $("#loader").hide(); | |
19 | + $("#div_plots").hide(); | |
20 | + var weather_plots = { | |
21 | + humidity_plot : new PlotterClas("humidity", "humidity_plot", [0,80]), | |
22 | + pressure_plot : new PlotterClas("pressure", "pressure_plot", []), | |
23 | + rain_plot : new PlotterClas("rain", "rain_plot", []), | |
24 | + temperature_plot : new PlotterClas("temperature", "temperature_plot", []), | |
25 | + wind_plot : new PlotterClas("wind", "wind_plot", [0,80]), | |
26 | + wind_dir_plot : new PlotterClas("wind_dir", "wind_dir_plot", []), | |
27 | + } | |
28 | + $("#weather_history_form").submit(function(event){ | |
29 | + event.preventDefault(); | |
30 | + var start_datetime = $("#start_datetime").val() | |
31 | + var end_datetime = $("#end_datetime").val() | |
32 | + $("#loader").show(); | |
33 | + // Clear plots, can't iterate on weather_plots | |
34 | + weather_plots.humidity_plot.clear(); | |
35 | + weather_plots.pressure_plot.clear(); | |
36 | + weather_plots.rain_plot.clear(); | |
37 | + weather_plots.temperature_plot.clear(); | |
38 | + weather_plots.wind_plot.clear(); | |
39 | + weather_plots.wind_dir_plot.clear(); | |
40 | + $.get("weather_history",{start_datetime: start_datetime,end_datetime:end_datetime},function(data){ | |
41 | + | |
42 | + for(var entry of data){ | |
43 | + weather_plots.humidity_plot.refresh_list([entry.fields.datetime , entry.fields.humidity]); | |
44 | + weather_plots.pressure_plot.refresh_list([entry.fields.datetime , entry.fields.pressure]); | |
45 | + weather_plots.rain_plot.refresh_list([entry.fields.datetime , entry.fields.rain]); | |
46 | + weather_plots.temperature_plot.refresh_list([entry.fields.datetime , entry.fields.temperature]); | |
47 | + weather_plots.wind_plot.refresh_list([entry.fields.datetime , entry.fields.wind]); | |
48 | + weather_plots.wind_dir_plot.refresh_list([entry.fields.datetime , entry.fields.wind_dir]); | |
49 | + | |
50 | + } | |
51 | + $("#loader").hide(); | |
52 | + $("#div_plots").show(); | |
53 | + }); | |
54 | + }); | |
55 | +}); | |
56 | +</script> | |
57 | + <style> | |
58 | + div.hbox { | |
59 | + float:left; | |
60 | + display:inline; | |
61 | + font-size: 11pt; | |
62 | + /*background:#e7e4e4;*/ | |
63 | + border: 1px solid rgba(0, 0, 0, 0.125); | |
64 | + border-color: #2FA4E7; | |
65 | + border-radius: 0.25rem; | |
66 | + padding: 3px 5px 3px 3px; | |
67 | + margin: 1px 2px 1px 1px; | |
68 | + } | |
69 | + div.box { | |
70 | + /*float:left;*/ | |
71 | + /*display:inline;*/ | |
72 | + font-size: 11pt; | |
73 | + /*background:#e7e4e4;*/ | |
74 | + border: 1px solid rgba(0, 0, 0, 0.125); | |
75 | + border-color: #2FA4E7; | |
76 | + border-radius: 0.25rem; | |
77 | + padding: 3px 5px 3px 3px; | |
78 | + margin: 1px 2px 1px 1px; | |
79 | + } | |
80 | + | |
81 | + | |
82 | + .loader { | |
83 | + border: 16px solid #f3f3f3; /* Light grey */ | |
84 | + border-top: 16px solid #3498db; /* Blue */ | |
85 | + border-radius: 50%; | |
86 | + width: 120px; | |
87 | + height: 120px; | |
88 | + animation: spin 2s linear infinite; | |
89 | + position: fixed; | |
90 | + left: 45%; | |
91 | + z-index: 1; | |
92 | + top: 45%; | |
93 | + } | |
94 | + | |
95 | + @keyframes spin { | |
96 | + 0% { transform: rotate(0deg); } | |
97 | + 100% { transform: rotate(360deg); } | |
98 | + } | |
99 | + </style> | |
100 | + | |
101 | +{% endblock %} | |
102 | + | |
103 | +{% block content %} | |
104 | +<div id="loader" class="loader" style="display: none;"></div> | |
105 | + <div class="row"> | |
106 | + <div class="col-md-auto"> | |
107 | + <form id="weather_history_form" action=""> | |
108 | + <p>Start datetime (UTC): <input type="datetime" placeholder="dd/mm/yyyy H:m:s" id="start_datetime"></input></p> | |
109 | + <p>End datetime (UTC): <input type="datetime" id="end_datetime" value="{{ default_end_datetime }}"></input></p> | |
110 | + <button class="btn btn-success" type="submit"> Get data</button> | |
111 | + </form> | |
112 | + </div> | |
113 | + <h3>Weather history </h3> | |
114 | + <div class="col" id="div_plots"> | |
115 | + <div id="humidity_plot" class="row hbox"></div> | |
116 | + <div id="pressure_plot" class="row hbox"></div> | |
117 | + <div id="rain_plot" class="row hbox"></div> | |
118 | + <div id="temperature_plot" class="row hbox"></div> | |
119 | + <div id="wind_plot" class="row hbox"></div> | |
120 | + <div id="wind_dir_plot" class="row hbox"></div> | |
121 | + </div> | |
122 | + </div> | |
123 | +{% endblock %} | |
0 | 124 | \ No newline at end of file | ... | ... |
src/core/pyros_django/monitoring/urls.py
... | ... | @@ -6,4 +6,5 @@ urlpatterns = [ |
6 | 6 | path('index', views.index, name="monitoring_index"), |
7 | 7 | path('weather/config', views.weather_config, name="weather_config"), |
8 | 8 | path('weather/config/update', views.weather_config_update, name="weather_config_update"), |
9 | - ] | |
9 | + path('weather_history', views.weather_history, name="weather_history"), | |
10 | +] | ... | ... |
src/core/pyros_django/monitoring/views.py
1 | +from datetime import datetime | |
1 | 2 | from django.http import HttpResponse |
2 | 3 | from django.shortcuts import render |
3 | -from common.models import AgentCmd | |
4 | +from common.models import AgentCmd, WeatherWatchHistory | |
5 | +from django.http import Http404 | |
6 | +import json | |
7 | +from django.db.models import Q | |
8 | + | |
9 | +from django.core import serializers | |
4 | 10 | |
5 | 11 | # Create your views here. |
6 | 12 | |
... | ... | @@ -13,6 +19,32 @@ def index(request): |
13 | 19 | |
14 | 20 | |
15 | 21 | |
22 | +def get_weather_history_from_date(start_datetime:datetime, end_datetime:datetime): | |
23 | + if WeatherWatchHistory.objects.all().exists(): | |
24 | + weather_history_queryset = WeatherWatchHistory.objects.filter(Q(datetime__gte=start_datetime) & Q(datetime__lte=end_datetime)).order_by("datetime") | |
25 | + weather = serializers.serialize('json', weather_history_queryset) | |
26 | + return weather | |
27 | + | |
28 | +def weather_history(request): | |
29 | + if request.GET: | |
30 | + start_datetime = request.GET.get("start_datetime") | |
31 | + end_datetime = request.GET.get("end_datetime") | |
32 | + if start_datetime and end_datetime: | |
33 | + start_datetime = datetime.strptime(start_datetime, "%d/%m/%Y %H:%M:%S") | |
34 | + end_datetime = datetime.strptime(end_datetime, "%d/%m/%Y %H:%M:%S") | |
35 | + try: | |
36 | + weather_history = get_weather_history_from_date(start_datetime, end_datetime) | |
37 | + #return HttpResponse(json.dumps(weather), content_type="application/json") | |
38 | + return HttpResponse(weather_history, content_type="application/json") | |
39 | + except WeatherWatchHistory.DoesNotExist: | |
40 | + raise Http404("No WeatherWatchHistory matches the given query.") | |
41 | + else: | |
42 | + return HttpResponse(json.dumps({"result":"No required start and end datetime found in query"}), content_type="application/json") | |
43 | + end_datetime =datetime.utcnow().strftime("%d/%m/%Y %H:%M:%S") | |
44 | + return render(request,"monitoring/weather_history.html",{ | |
45 | + "default_end_datetime" : end_datetime | |
46 | + }) | |
47 | + | |
16 | 48 | def weather_config(request): |
17 | 49 | """ PM 20180926 prototype without database |
18 | 50 | http://127.0.0.1:8000/dashboard/weather/config | ... | ... |
src/core/pyros_django/pyros/settings.py
... | ... | @@ -439,7 +439,7 @@ EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' |
439 | 439 | |
440 | 440 | python_version = subprocess.run( "python --version | cut -d ' ' -f 2 | cut -d '.' -f 1,2",shell=True,stdout=subprocess.PIPE,universal_newlines=True) |
441 | 441 | python_version = python_version.stdout |
442 | -day = "2022-04-27" | |
442 | +day = "2022-04-28" | |
443 | 443 | django_version_major,django_version_minor = django.VERSION[:2][0],django.VERSION[:2][1] |
444 | 444 | pyros_version = read_version_number_from_file(f"{BASE_DIR}/../../../VERSION") |
445 | 445 | ... | ... |