From 236a8d0dd790fac64ff91fb12afc343e53204aa0 Mon Sep 17 00:00:00 2001 From: clavay Date: Tue, 24 Oct 2023 14:21:44 +0200 Subject: [PATCH 1/5] load hidden config2 after view html load to load the view quickly load the hidden config2 after the loading the view html code --- pyscada/hmi/models.py | 63 ++++++-- .../pyscada/js/pyscada/pyscada_v0-7-0rc14.js | 20 +++ pyscada/hmi/templates/view.html | 2 +- pyscada/hmi/urls.py | 5 + pyscada/hmi/views.py | 150 ++++++++++++++++++ 5 files changed, 224 insertions(+), 16 deletions(-) diff --git a/pyscada/hmi/models.py b/pyscada/hmi/models.py index 5e95f121..49bdfa7e 100644 --- a/pyscada/hmi/models.py +++ b/pyscada/hmi/models.py @@ -94,6 +94,12 @@ def _get_objects_for_html( exclude_model_names=exclude_model_names, ) + def add_custom_fields_list(self, opts): + return opts + + def add_exclude_fields_list(self, opts): + return opts + def create_widget_content_entry(self): def fullname(o): return o.__module__ + "." + o.__class__.__name__ @@ -543,8 +549,8 @@ def gen_html(self, **kwargs): opts["show_daterangepicker"] = True opts["show_timeline"] = True opts["flot"] = True - opts["object_config_list"] = set() - opts["object_config_list"].update(self._get_objects_for_html()) + # opts["object_config_list"] = set() + # opts["object_config_list"].update(self._get_objects_for_html()) return main_content, sidebar_content, opts def _get_objects_for_html( @@ -763,19 +769,24 @@ def gen_html(self, **kwargs): and item.display_value_options.type == 3 ): opts["flot"] = True - opts["object_config_list"] = set() - opts["object_config_list"].update(self._get_objects_for_html()) - opts["custom_fields_list"] = { - "variable": [ + # opts["object_config_list"] = set() + # opts["object_config_list"].update(self._get_objects_for_html()) + # opts = self.add_custom_fields_list(opts) + return main_content, sidebar_content, opts + + def add_custom_fields_list(self, opts): + if type(opts) == dict: + if "custom_fields_list" not in opts: + opts["custom_fields_list"] = dict() + opts["custom_fields_list"]["variable"] = [ {"name": "refresh-requested-timestamp", "value": ""}, {"name": "value-timestamp", "value": ""}, - ], - "variableproperty": [ + ] + opts["custom_fields_list"]["variableproperty"] = [ {"name": "refresh-requested-timestamp", "value": ""}, {"name": "value-timestamp", "value": ""}, - ], - } - return main_content, sidebar_content, opts + ] + return opts class CustomHTMLPanel(WidgetContentModel): @@ -813,8 +824,8 @@ def gen_html(self, **kwargs): ) sidebar_content = None opts = dict() - opts["object_config_list"] = set() - opts["object_config_list"].update(self._get_objects_for_html()) + # opts["object_config_list"] = set() + # opts["object_config_list"].update(self._get_objects_for_html()) return main_content, sidebar_content, opts @@ -906,8 +917,8 @@ def gen_html(self, **kwargs): ) sidebar_content = None opts = dict() - opts["object_config_list"] = set() - opts["object_config_list"].update(self._get_objects_for_html()) + # opts["object_config_list"] = set() + # opts["object_config_list"].update(self._get_objects_for_html()) return main_content, sidebar_content, opts @@ -949,6 +960,28 @@ def create_panel_html(self, **kwargs): # todo del self return "", "", "" + def get_hidden_config2(self, **kwargs): + """ + return main_content, sidebar_content, optional list + """ + content_model = self._import_content_model() + opts = dict() + opts["object_config_list"] = set() + try: + if content_model is not None: + opts["object_config_list"].update(content_model._get_objects_for_html()) + opts = content_model.add_custom_fields_list(opts) + opts = content_model.add_exclude_fields_list(opts) + else: + logger.info( + f"WidgetContent content_model of {self.content_str} is None" + ) + except: + logger.error(f"{content_model} unhandled exception", exc_info=True) + # todo del self + + return opts + def _import_content_model(self): content_class_str = self.content_model class_name = content_class_str.split(".")[-1] diff --git a/pyscada/hmi/static/pyscada/js/pyscada/pyscada_v0-7-0rc14.js b/pyscada/hmi/static/pyscada/js/pyscada/pyscada_v0-7-0rc14.js index db01d820..2719fa83 100644 --- a/pyscada/hmi/static/pyscada/js/pyscada/pyscada_v0-7-0rc14.js +++ b/pyscada/hmi/static/pyscada/js/pyscada/pyscada_v0-7-0rc14.js @@ -3972,6 +3972,26 @@ function fix_page_anchor() { $(".ReadAllTask").parent().parent().show(); $(".AutoUpdateButtonParent").show(); + set_loading_state(1, 20); + + // load hidden config2 + fetch('/getHiddenConfig2/' + document.querySelector("body").dataset["viewTitle"] + "/", { + method: "POST", + headers: { + "X-CSRFToken": CSRFTOKEN, + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", + }, + body: "", + }).then((response) => { + if (!response.ok) { + throw new Error(`HTTP error, status = ${response.status}`); + } + return response.text(); + }).then((text) => { + document.querySelector("body #wrap #content .hidden.globalConfig2").innerHTML = text; + console.log("hidden config2 loaded"); + }).catch((err) => console.log(err)); + // init loading states set_loading_state(1, 40); diff --git a/pyscada/hmi/templates/view.html b/pyscada/hmi/templates/view.html index 047ba308..78aef6c9 100644 --- a/pyscada/hmi/templates/view.html +++ b/pyscada/hmi/templates/view.html @@ -9,7 +9,7 @@ {% endfor %} {% endblock %} -{% block body_confic_data %} data-data-file="json/cache_data/" {% endblock %} +{% block body_confic_data %} data-data-file="json/cache_data/" data-view-title="{{ view_link_title }}" {% endblock %} {% block top_menu_left %} {% for page in page_list %} diff --git a/pyscada/hmi/urls.py b/pyscada/hmi/urls.py index 0e67796d..e1369023 100644 --- a/pyscada/hmi/urls.py +++ b/pyscada/hmi/urls.py @@ -41,4 +41,9 @@ path("form/read_all_task/", views.form_read_all_task), path("form/write_property2/", views.form_write_property2), path("view//", views.view, name="main-view"), + path( + "getHiddenConfig2//", + views.get_hidden_config2, + name="get-hidden-config2", + ), ] diff --git a/pyscada/hmi/views.py b/pyscada/hmi/views.py index 74634b41..09f8d92c 100644 --- a/pyscada/hmi/views.py +++ b/pyscada/hmi/views.py @@ -75,6 +75,155 @@ def index(request): ) # HttpResponse(t.render(c)) +@unauthenticated_redirect +def get_hidden_config2(request, link_title): + try: + v = ( + get_group_display_permission_list(View.objects, request.user.groups.all()) + .filter(link_title=link_title) + .first() + ) + if v is None: + raise View.DoesNotExist + # v = View.objects.get(link_title=link_title) + except View.DoesNotExist as e: + logger.warning(f"{request.user} has no permission for view {link_title}") + raise PermissionDenied("You don't have access to this view.") + except View.MultipleObjectsReturned as e: + logger.error(f"{e} for view link_title", exc_info=True) + raise PermissionDenied(f"Multiples views with this link : {link_title}") + # return HttpResponse(status=404) + + object_config_list = dict() + custom_fields_list = dict() + exclude_fields_list = dict() + visible_objects_lists = dict() + + items = [ + field + for field in GroupDisplayPermission._meta.get_fields() + if issubclass(type(field), OneToOneRel) + ] + if GroupDisplayPermission.objects.count() == 0: + # no groups + for item in items: + item_str = item.related_model.m2m_related_model._meta.object_name.lower() + visible_objects_lists[ + f"visible_{item_str}_list" + ] = item.related_model.m2m_related_model.objects.all().values_list( + "pk", flat=True + ) + visible_objects_lists["visible_page_list"] = v.pages.all().values_list( + "pk", flat=True + ) + visible_objects_lists[ + "visible_slidingpanelmenu_list" + ] = v.sliding_panel_menus.all().values_list("pk", flat=True) + else: + for item in items: + item_str = item.related_model.m2m_related_model._meta.object_name.lower() + visible_objects_lists[ + f"visible_{item_str}_list" + ] = get_group_display_permission_list( + item.related_model.m2m_related_model.objects, request.user.groups.all() + ).values_list( + "pk", flat=True + ) + visible_objects_lists["visible_page_list"] = get_group_display_permission_list( + v.pages, request.user.groups.all() + ).values_list("pk", flat=True) + visible_objects_lists[ + "visible_slidingpanelmenu_list" + ] = get_group_display_permission_list( + v.sliding_panel_menus, request.user.groups.all() + ).values_list( + "pk", flat=True + ) + + panel_list = SlidingPanelMenu.objects.filter( + id__in=visible_objects_lists["visible_slidingpanelmenu_list"] + ).filter( + position__in=( + 1, + 2, + ) + ) + control_list = SlidingPanelMenu.objects.filter( + id__in=visible_objects_lists["visible_slidingpanelmenu_list"] + ).filter(position=0) + + for page_pk in visible_objects_lists["visible_page_list"]: + page = Page.objects.get(id=page_pk) + for widget in page.widget_set.all(): + if widget.pk not in visible_objects_lists["visible_widget_list"]: + continue + if not widget.visible: + continue + if widget.content is None: + continue + widget_extra_css_class = ( + widget.extra_css_class.css_class + if widget.extra_css_class is not None + else "" + ) + opts = widget.content.get_hidden_config2( + visible_objects_lists=visible_objects_lists, + ) + if ( + type(opts) == dict + and "object_config_list" in opts + and type(opts["object_config_list"] == list) + ): + for obj in opts["object_config_list"]: + model_name = str(obj._meta.model_name).lower() + if model_name not in object_config_list: + object_config_list[model_name] = list() + if obj not in object_config_list[model_name]: + object_config_list[model_name].append(obj) + if ( + type(opts) == dict + and "custom_fields_list" in opts + and type(opts["custom_fields_list"] == list) + ): + for model in opts["custom_fields_list"]: + custom_fields_list[str(model).lower()] = opts["custom_fields_list"][ + model + ] + + if ( + type(opts) == dict + and "exclude_fields_list" in opts + and type(opts["exclude_fields_list"] == list) + ): + for model in opts["exclude_fields_list"]: + exclude_fields_list[str(model).lower()] = opts[ + "exclude_fields_list" + ][model] + + # Adding SlidingPanelMenu to hidden config + for s_pk in visible_objects_lists["visible_slidingpanelmenu_list"]: + s = SlidingPanelMenu.objects.get(id=s_pk) + if s.control_panel is not None: + for obj in s.control_panel._get_objects_for_html(obj=s): + if obj._meta.model_name not in object_config_list: + object_config_list[obj._meta.model_name] = list() + if obj not in object_config_list[obj._meta.model_name]: + object_config_list[obj._meta.model_name].append(obj) + # Generate html object hidden config + hidden_globalConfig_html = "" + for model, val in sorted(object_config_list.items(), key=lambda ele: ele[0]): + hidden_globalConfig_html += '" + + return HttpResponse(hidden_globalConfig_html, content_type="text/plain") + + @unauthenticated_redirect @requires_csrf_token def view(request, link_title): @@ -456,6 +605,7 @@ def view(request, link_title): ], "visible_form_list": visible_objects_lists["visible_form_list"], "view_title": v.title, + "view_link_title": link_title, "view_show_timeline": v.show_timeline, "version_string": core_version, "link_target": settings.LINK_TARGET From 6c1f437cbf6c162c95fbe15842599e68523cee69 Mon Sep 17 00:00:00 2001 From: clavay Date: Mon, 6 Nov 2023 12:17:53 +0100 Subject: [PATCH 2/5] JS: load config2 before the pyscada hmi init then send event Load config2 Init the pyscada hmi send PyScadaCoreJSLoaded for plugins --- .../pyscada/js/pyscada/pyscada_v0-7-0rc14.js | 56 +++++++++++-------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/pyscada/hmi/static/pyscada/js/pyscada/pyscada_v0-7-0rc14.js b/pyscada/hmi/static/pyscada/js/pyscada/pyscada_v0-7-0rc14.js index 2719fa83..c3c48965 100644 --- a/pyscada/hmi/static/pyscada/js/pyscada/pyscada_v0-7-0rc14.js +++ b/pyscada/hmi/static/pyscada/js/pyscada/pyscada_v0-7-0rc14.js @@ -3963,35 +3963,35 @@ function fix_page_anchor() { } }); - - // fix drop down problem - $( document ).ready(function() { + set_loading_state(1, 10); + +document.body.onload = () => init_pyscada_content(); + +function init_pyscada_content() { + console.log("PyScada HMI : fetching hidden config2") + fetch('/getHiddenConfig2/' + document.querySelector("body").dataset["viewTitle"] + "/", { + method: "POST", + headers: { + "X-CSRFToken": CSRFTOKEN, + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", + }, + body: "", + }).then((response) => { + if (!response.ok) { + throw new Error(`HTTP error, status = ${response.status}`); + } + set_loading_state(1, 20); + return response.text(); + }).then((text) => { + document.querySelector("body #wrap #content .hidden.globalConfig2").innerHTML = text; + console.log("PyScada HMI : hidden config2 loaded"); + }).then(() => { // show buttons $(".loadingAnimation").parent().show(); $(".AutoUpdateStatus").parent().parent().show(); $(".ReadAllTask").parent().parent().show(); $(".AutoUpdateButtonParent").show(); - set_loading_state(1, 20); - - // load hidden config2 - fetch('/getHiddenConfig2/' + document.querySelector("body").dataset["viewTitle"] + "/", { - method: "POST", - headers: { - "X-CSRFToken": CSRFTOKEN, - "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", - }, - body: "", - }).then((response) => { - if (!response.ok) { - throw new Error(`HTTP error, status = ${response.status}`); - } - return response.text(); - }).then((text) => { - document.querySelector("body #wrap #content .hidden.globalConfig2").innerHTML = text; - console.log("hidden config2 loaded"); - }).catch((err) => console.log(err)); - // init loading states set_loading_state(1, 40); @@ -4289,4 +4289,14 @@ function fix_page_anchor() { // Fill aggregated lists setAggregatedLists(); + }).then(() => { + // PyScada Core JS loaded successfully => send the event for plugins + var event = new CustomEvent("PyScadaCoreJSLoaded"); + document.dispatchEvent(event); + console.log("PyScada HMI : dispatch PyScadaCoreJSLoaded event"); + }).catch((err) => { + console.log("PyScada HMI : ", err); + console.log("Retrying to init PyScada Core JS in 1 sec..."); + setTimeout(init_pyscada_content, 1000); }); +}; From da5fcc703550a1257233a9e73bcbebef8f5aea8e Mon Sep 17 00:00:00 2001 From: clavay Date: Mon, 6 Nov 2023 12:33:16 +0100 Subject: [PATCH 3/5] add loading page with svg icon can be replaced by the loading_page block default icon color (000, black) can be change with svg_loading_color for example: svg_loading_color="00f" --- pyscada/hmi/templates/svg_loading_icon.html | 32 +++++++++++++++++++++ pyscada/hmi/templates/view.html | 6 ++++ 2 files changed, 38 insertions(+) create mode 100644 pyscada/hmi/templates/svg_loading_icon.html diff --git a/pyscada/hmi/templates/svg_loading_icon.html b/pyscada/hmi/templates/svg_loading_icon.html new file mode 100644 index 00000000..fbbc07b4 --- /dev/null +++ b/pyscada/hmi/templates/svg_loading_icon.html @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/pyscada/hmi/templates/view.html b/pyscada/hmi/templates/view.html index 78aef6c9..59d2a9b1 100644 --- a/pyscada/hmi/templates/view.html +++ b/pyscada/hmi/templates/view.html @@ -90,6 +90,12 @@ + {% block loading_page %} + +
+ {% include "svg_loading_icon.html" %} +
+ {% endblock loading_page %} {% for panel in panel_list %}
    From 3be6776051682dd40f505f0b1f54050cc7e025bf Mon Sep 17 00:00:00 2001 From: clavay Date: Mon, 6 Nov 2023 12:35:55 +0100 Subject: [PATCH 4/5] kill setTimeout and xhr request on page unload store all timeouts in the PYSCADA_TIMEOUTS dictionary store the current xhr blocking request in PYSCADA_XHR variable --- .../pyscada/js/pyscada/pyscada_v0-7-0rc14.js | 50 +++++++++++++------ 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/pyscada/hmi/static/pyscada/js/pyscada/pyscada_v0-7-0rc14.js b/pyscada/hmi/static/pyscada/js/pyscada/pyscada_v0-7-0rc14.js index c3c48965..524403bb 100644 --- a/pyscada/hmi/static/pyscada/js/pyscada/pyscada_v0-7-0rc14.js +++ b/pyscada/hmi/static/pyscada/js/pyscada/pyscada_v0-7-0rc14.js @@ -341,6 +341,16 @@ var ONBEFORERELOAD_ASK = true; var store_temp_ajax_data = null; + /** + * store all timeout ids for each functions + */ + var PYSCADA_TIMEOUTS = {}; + + /** + * store current ajax request + */ + var PYSCADA_XHR = null; + //--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -1065,10 +1075,10 @@ function set_config_from_hidden_config(type,filter_data,val,get_data,value){ // initialisation is active //setTimeout(function() {data_handler();}, REFRESH_RATE/2.0); if (STATUS_VARIABLE_KEYS.count() + CHART_VARIABLE_KEYS.count() == 0 && LOADING_PAGE_DONE == 0) {LOADING_PAGE_DONE = 1;show_page();hide_loading_state();} - setTimeout(function() {data_handler();}, 100); + PYSCADA_TIMEOUTS["data_handler"] = setTimeout(function() {data_handler();}, 100); }else{ if (LOADING_PAGE_DONE == 0) {LOADING_PAGE_DONE = 1;show_page();hide_loading_state();loading_states={};} - setTimeout(function() {data_handler();}, REFRESH_RATE); + PYSCADA_TIMEOUTS["data_handler"] = setTimeout(function() {data_handler();}, REFRESH_RATE); } } @@ -1088,7 +1098,7 @@ function set_config_from_hidden_config(type,filter_data,val,get_data,value){ request_data = {timestamp_from:timestamp_from, variables: variable_keys, init: init, variable_properties:variable_property_keys}; if (typeof(timestamp_to !== 'undefined')){request_data['timestamp_to']=timestamp_to}; //if (!init){request_data['timestamp_from'] = request_data['timestamp_from'] - REFRESH_RATE;}; - $.ajax({ + PYSCADA_XHR = $.ajax({ url: ROOT_URL+'json/cache_data/', dataType: "json", timeout: ((init == 1) ? FETCH_DATA_TIMEOUT*5: FETCH_DATA_TIMEOUT), @@ -3544,7 +3554,7 @@ function fix_page_anchor() { show_update_status(); - $.ajax({ + PYSCADA_XHR = $.ajax({ url: ROOT_URL+'json/log_data/', type: 'post', dataType: "json", @@ -3743,7 +3753,7 @@ function fix_page_anchor() { refresh_logo(key, type); data_type = $(this).data('type'); $(this)[0].disabled = true; - $.ajax({ + PYSCADA_XHR = $.ajax({ type: 'post', url: ROOT_URL+'form/read_task/', data: {key:key, type:data_type}, @@ -3787,7 +3797,7 @@ function fix_page_anchor() { $(this).parents(".input-group").removeClass("has-error") if (isNaN(value)) { if (item_type == "variable_property" && value_class == 'STRING'){ - $.ajax({ + PYSCADA_XHR = $.ajax({ type: 'post', url: ROOT_URL+'form/write_property2/', data: {variable_property:key, value:value}, @@ -3803,7 +3813,7 @@ function fix_page_anchor() { $(this).parents(".input-group-btn").after('The value must be a number ! Use dot not coma.'); }; }else { - $.ajax({ + PYSCADA_XHR = $.ajax({ type: 'post', url: ROOT_URL+'form/write_task/', data: {key:key, value:value, item_type:item_type}, @@ -3835,7 +3845,7 @@ function fix_page_anchor() { if ($(tabinputs[i]).hasClass('btn-success')){ id = $(tabinputs[i]).attr('id'); //$('#'+id).removeClass('update-able'); - $.ajax({ + PYSCADA_XHR = $.ajax({ type: 'post', url: ROOT_URL+'form/write_task/', data: {key:key,value:1,item_type:item_type}, @@ -3848,7 +3858,7 @@ function fix_page_anchor() { }else if ($(tabinputs[i]).hasClass('btn-default')){ id = $(tabinputs[i]).attr('id'); //$('#'+id).removeClass('update-able'); - $.ajax({ + PYSCADA_XHR = $.ajax({ type: 'post', url: ROOT_URL+'form/write_task/', data: {key:key,value:0,item_type:item_type}, @@ -3859,7 +3869,7 @@ function fix_page_anchor() { } }); }else{ - $.ajax({ + PYSCADA_XHR = $.ajax({ type: 'post', url: ROOT_URL+'form/write_task/', data: {key:key, value:value, item_type:item_type}, @@ -3880,7 +3890,7 @@ function fix_page_anchor() { item_type = $(tabselects[i]).data('type'); if (isNaN(value)){ if (item_type == "variable_property"){ - $.ajax({ + PYSCADA_XHR = $.ajax({ type: 'post', url: ROOT_URL+'form/write_property2/', data: {variable_property:var_name, value:value}, @@ -3895,7 +3905,7 @@ function fix_page_anchor() { add_notification("select is " + item_type + " and not a number",3); }; }else { - $.ajax({ + PYSCADA_XHR = $.ajax({ type: 'post', url: ROOT_URL+'form/write_task/', data: {key:key, value:value, item_type:item_type}, @@ -3935,7 +3945,7 @@ function fix_page_anchor() { $(".variable-config[data-refresh-requested-timestamp][data-key=" + key + "][data-type=" + item_type + "]").attr('data-refresh-requested-timestamp', SERVER_TIME) $(".variable-config2[data-refresh-requested-timestamp][data-id=" + key + "]").attr('data-refresh-requested-timestamp', SERVER_TIME) if($(this).hasClass('btn-default')){ - $.ajax({ + PYSCADA_XHR = $.ajax({ type: 'post', url: ROOT_URL+'form/write_task/', data: {key:key,value:1,item_type:item_type}, @@ -3948,7 +3958,7 @@ function fix_page_anchor() { } }); }else if ($(this).hasClass('btn-success')){ - $.ajax({ + PYSCADA_XHR = $.ajax({ type: 'post', url: ROOT_URL+'form/write_task/', data: {key:key,value:0,item_type:item_type}, @@ -4050,6 +4060,14 @@ function init_pyscada_content() { return null; }; }; + // stop all setTimeout and Ajax requests when leaving + window.onunload = function() { + for (t in PYSCADA_TIMEOUTS) {clearTimeout(PYSCADA_TIMEOUTS[t]);console.log("PyScada HMI : clearing timeout", t);} + if(PYSCADA_XHR != null && PYSCADA_XHR.readyState != 4){ + PYSCADA_XHR.abort(); + console.log("PyScada HMI : aborting xhr") + } + }; $(window).on('hashchange', function() { // nav menu click event if (window.location.hash.length > 0) { @@ -4181,7 +4199,7 @@ function init_pyscada_content() { set_chart_selection_mode(); }); - setTimeout(function() {data_handler();}, 5000); + PYSCADA_TIMEOUTS["data_handler"] = setTimeout(function() {data_handler();}, 5000); set_chart_selection_mode(); @@ -4207,7 +4225,7 @@ function init_pyscada_content() { // Send request data to all devices $('.ReadAllTask').click(function(e) { - $.ajax({ + PYSCADA_XHR = $.ajax({ url: ROOT_URL+'form/read_all_task/', type: "POST", data:{}, From 47bd4037fbc401a5cf56f27bbce4d7628d9928c5 Mon Sep 17 00:00:00 2001 From: clavay Date: Mon, 6 Nov 2023 12:37:16 +0100 Subject: [PATCH 5/5] JS: add PyScada HMI at the beginning of each console.log --- .../pyscada/js/pyscada/pyscada_v0-7-0rc14.js | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/pyscada/hmi/static/pyscada/js/pyscada/pyscada_v0-7-0rc14.js b/pyscada/hmi/static/pyscada/js/pyscada/pyscada_v0-7-0rc14.js index 524403bb..1ed1ffe3 100644 --- a/pyscada/hmi/static/pyscada/js/pyscada/pyscada_v0-7-0rc14.js +++ b/pyscada/hmi/static/pyscada/js/pyscada/pyscada_v0-7-0rc14.js @@ -418,10 +418,10 @@ var store_temp_ajax_data = null; if (typeof(start_id) === "number" ){ DATA[key] = value.slice(0,start_id).concat(DATA[key]); }else{ - console.log(key + ' : dropped data'); + console.log("PyScada HMI : var" , key, ": dropped data, start_id not found.", value, DATA[key][0][0]); } }else{ - console.log(key + ' : dropped data'); + console.log("PyScada HMI : var" , key, ": dropped data, stop_id not found.", value, DATA[key][DATA[key].length-1][0]); } } @@ -432,7 +432,7 @@ var store_temp_ajax_data = null; if (typeof(stop_id) === "number" ){ DATA[key] = value.slice(0,stop_id).concat(DATA[key]); }else{ - console.log(key + ' : dropped data'); + console.log("PyScada HMI : var" , key, ": dropped data, stop_id not found.", value, DATA[key][0][0]); } } else if (v_t_max > d_t_max && d_t_min < v_t_min){ // data and value overlapping, data has older elements than value, append @@ -440,10 +440,10 @@ var store_temp_ajax_data = null; if (typeof(stop_id) === "number" ){ DATA[key] = DATA[key].concat(value.slice(stop_id)); }else{ - console.log(key + ' : dropped data'); + console.log("PyScada HMI : var" , key, ": dropped data, stop_id not found.", value, DATA[key][DATA[key].length-1][0]); } } else{ - //console.log(key + ' : no new data'); + console.log("PyScada HMI : var" , key, ' : no new data, drop.'); } } @@ -563,7 +563,10 @@ var store_temp_ajax_data = null; } function rgbToHex(rgb) { - if (typeof rgb != "object" || rgb.constructor != Array || rgb.length != 3) {console.log(typeof rgb, rgb.constructor, rgb.length, rgb);return;} + if (typeof rgb != "object" || rgb.constructor != Array || rgb.length != 3) { + console.log("PyScada HMI : cannot update data colors, rgb to hex error :", typeof rgb, rgb.constructor, rgb.length, rgb); + return; + } r = rgb[0] g = rgb[1] b = rgb[2] @@ -932,7 +935,7 @@ function set_config_from_hidden_config(type,filter_data,val,get_data,value){ INIT_CHART_VARIABLES_COUNT++; vars.push(key); dpi = get_config_from_hidden_config('device','id',get_config_from_hidden_config('variable','id',key,'device') ,'polling-interval'); - if (! isNaN(dpi)) {device_pulling_interval_sum += parseFloat(dpi);var_count_poll++;}else {console.log("ConfigV2 not found for var " + key);}; + if (! isNaN(dpi)) {device_pulling_interval_sum += parseFloat(dpi);var_count_poll++;}else {console.log("PyScada HMI : ConfigV2 not found for var", key);}; if (typeof(DATA[key]) == 'object'){ timestamp = Math.max(timestamp,DATA[key][0][0]); }else{ @@ -1465,21 +1468,24 @@ function createOffset(date) { (14, 'distinct count'), */ function get_aggregated_data(key, start, stop, type=6, min_aggregate=3) { - if (!Number.isInteger(key) || Number.isNaN(start) || Number.isNaN(stop) || !Number.isInteger(type) || !Number.isInteger(min_aggregate)) {console.log("get_aggregated_data : a param is not a int, number, number, int : ", key, start, stop, type);return key;}; + if (!Number.isInteger(key) || Number.isNaN(start) || Number.isNaN(stop) || !Number.isInteger(type) || !Number.isInteger(min_aggregate)) { + console.log("PyScada HMI : get_aggregated_data : params types are not int, number, number, int : ", key, start, stop, type); + return key; + }; key = Number(key); start = Number(start); stop = Number(stop); type = Number(type); min_aggregate = parseInt(min_aggregate); - if (min_aggregate <= 0) {console.log("min_aggregate should be > 0, it is ", min_aggregate);return key;}; - if (!key in DATA) {console.log(key, "not in DATA");return key;}; + if (min_aggregate <= 0) {console.log("PyScada HMI : min_aggregate should be > 0, it is ", min_aggregate);return key;}; + if (!key in DATA) {console.log("PyScada HMI :", key, "not in DATA");return key;}; //if (start < 0 || stop < 0) {console.log("start or stop < 0 :", start, stop);}; if (start < 0) {start = DATA_FROM_TIMESTAMP;}; if (stop < 0) {stop = DATA_TO_TIMESTAMP;}; start = start / 1000; stop = stop / 1000; - if (start >= stop) {console.log("start is not < stop :", start, stop);return key;}; - if (type < 0 || type > 14) {console.log("type is not 0 between and 14 included :", type)}; + if (start >= stop) {console.log("PyScada HMI : start is not < stop :", start, stop);return key;}; + if (type < 0 || type > 14) {console.log("PyScada HMI : type is not 0<= and >=14 :", type)}; periodFields = get_period_fields(key); validPeriodFields = filter_period_fields_by_type(periodFields, type);