svghmi/svghmi.js
author Edouard Tisserant
Wed, 01 Dec 2021 09:54:02 +0100
branchRuntimeLists
changeset 3394 9ea29ac18837
parent 3385 18621ce81f5f
child 3413 2e84a2782295
permissions -rw-r--r--
RUNTIME: Variable trace now uses limited list and buffer instead of flags in instance tree that was requiring systematical instance tree traversal, and worst size buffer. Forcing and retain still use tree traversal.
2783
5ee6967f721d SVGHMI: Starting to define JS side more in details.
Edouard Tisserant
parents: 2780
diff changeset
     1
// svghmi.js
5ee6967f721d SVGHMI: Starting to define JS side more in details.
Edouard Tisserant
parents: 2780
diff changeset
     2
3080
e5fa1f49f0b9 SVGHMI: WIP trying to reduce memory usage : use .onclick onstead of SetAttribute, avoid useless closure and object creation when possible, etc.
Edouard Tisserant
parents: 3078
diff changeset
     3
var need_cache_apply = [];
2803
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
     4
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
     5
function dispatch_value(index, value) {
3022
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
     6
    let widgets = subscribers(index);
2800
68cee1366b9c SVGHMI: dispatching data to minimalist "Display" text widget.
Edouard Tisserant
parents: 2799
diff changeset
     7
2805
e521e0d133d5 SVGHMI: fixed HMI->PLC dataflow : not updates as expected, and not initialized properly after subscribe.
Edouard Tisserant
parents: 2803
diff changeset
     8
    let oldval = cache[index];
e521e0d133d5 SVGHMI: fixed HMI->PLC dataflow : not updates as expected, and not initialized properly after subscribe.
Edouard Tisserant
parents: 2803
diff changeset
     9
    cache[index] = value;
e521e0d133d5 SVGHMI: fixed HMI->PLC dataflow : not updates as expected, and not initialized properly after subscribe.
Edouard Tisserant
parents: 2803
diff changeset
    10
2800
68cee1366b9c SVGHMI: dispatching data to minimalist "Display" text widget.
Edouard Tisserant
parents: 2799
diff changeset
    11
    if(widgets.size > 0) {
68cee1366b9c SVGHMI: dispatching data to minimalist "Display" text widget.
Edouard Tisserant
parents: 2799
diff changeset
    12
        for(let widget of widgets){
3006
bbffdefd2eed SVGHMI: JS refactoring continued : "dispatch_value_to_widget" becomes widget class member "new_hmi_value" (was also broken by previous relativeness commit)
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3005
diff changeset
    13
            widget.new_hmi_value(index, value, oldval);
2800
68cee1366b9c SVGHMI: dispatching data to minimalist "Display" text widget.
Edouard Tisserant
parents: 2799
diff changeset
    14
        }
68cee1366b9c SVGHMI: dispatching data to minimalist "Display" text widget.
Edouard Tisserant
parents: 2799
diff changeset
    15
    }
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
    16
};
2783
5ee6967f721d SVGHMI: Starting to define JS side more in details.
Edouard Tisserant
parents: 2780
diff changeset
    17
2801
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    18
function init_widgets() {
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    19
    Object.keys(hmi_widgets).forEach(function(id) {
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    20
        let widget = hmi_widgets[id];
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    21
        let init = widget.init;
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    22
        if(typeof(init) == "function"){
2834
6ac6a9dff594 SVGHMI: be a bit more tolerant with missing HMI paths or missing elements in widgets : continue build (with warning) and fail silently at runtime.
Edouard Tisserant
parents: 2829
diff changeset
    23
            try {
6ac6a9dff594 SVGHMI: be a bit more tolerant with missing HMI paths or missing elements in widgets : continue build (with warning) and fail silently at runtime.
Edouard Tisserant
parents: 2829
diff changeset
    24
                init.call(widget);
6ac6a9dff594 SVGHMI: be a bit more tolerant with missing HMI paths or missing elements in widgets : continue build (with warning) and fail silently at runtime.
Edouard Tisserant
parents: 2829
diff changeset
    25
            } catch(err) {
2836
ce6cecdb7320 SVGHMI : still behave, even if important things are missing in SVG widget definitions (ex: needle missing for Meter widget)
Edouard Tisserant
parents: 2834
diff changeset
    26
                console.log(err);
2834
6ac6a9dff594 SVGHMI: be a bit more tolerant with missing HMI paths or missing elements in widgets : continue build (with warning) and fail silently at runtime.
Edouard Tisserant
parents: 2829
diff changeset
    27
            }
2801
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    28
        }
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    29
    });
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    30
};
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    31
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
    32
// Open WebSocket to relative "/ws" address
3381
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
    33
var has_watchdog = window.location.hash == "#watchdog";
3268
d22782b9591f SVGHMI: Added a way to distinguish watchdog-enabled HMI from multi-client HMI in URL.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3206
diff changeset
    34
d22782b9591f SVGHMI: Added a way to distinguish watchdog-enabled HMI from multi-client HMI in URL.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3206
diff changeset
    35
var ws_url = 
d22782b9591f SVGHMI: Added a way to distinguish watchdog-enabled HMI from multi-client HMI in URL.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3206
diff changeset
    36
    window.location.href.replace(/^http(s?:\/\/[^\/]*)\/.*$/, 'ws$1/ws')
3381
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
    37
    + '?mode=' + (has_watchdog ? "watchdog" : "multiclient");
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
    38
3268
d22782b9591f SVGHMI: Added a way to distinguish watchdog-enabled HMI from multi-client HMI in URL.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3206
diff changeset
    39
var ws = new WebSocket(ws_url);
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
    40
ws.binaryType = 'arraybuffer';
2783
5ee6967f721d SVGHMI: Starting to define JS side more in details.
Edouard Tisserant
parents: 2780
diff changeset
    41
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
    42
const dvgetters = {
2826
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    43
    INT: (dv,offset) => [dv.getInt16(offset, true), 2],
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    44
    BOOL: (dv,offset) => [dv.getInt8(offset, true), 1],
2890
ae8063127e95 SVGHMI: make root HMI tree node a HMI_NODE, droped HMI_ROOT node type
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2889
diff changeset
    45
    NODE: (dv,offset) => [dv.getInt8(offset, true), 1],
3068
81758c94f3df SVGHMI: Fix HMI_REAL support, and add a HMI_REAL use case in tests/svghmi.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3035
diff changeset
    46
    REAL: (dv,offset) => [dv.getFloat32(offset, true), 4],
2826
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    47
    STRING: (dv, offset) => {
3080
e5fa1f49f0b9 SVGHMI: WIP trying to reduce memory usage : use .onclick onstead of SetAttribute, avoid useless closure and object creation when possible, etc.
Edouard Tisserant
parents: 3078
diff changeset
    48
        const size = dv.getInt8(offset);
2826
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    49
        return [
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    50
            String.fromCharCode.apply(null, new Uint8Array(
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    51
                dv.buffer, /* original buffer */
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    52
                offset + 1, /* string starts after size*/
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    53
                size /* size of string */
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    54
            )), size + 1]; /* total increment */
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    55
    }
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
    56
};
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
    57
2859
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
    58
// Apply updates recieved through ws.onmessage to subscribed widgets
2865
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    59
function apply_updates() {
3152
c80a5a7198ea SVGHMI: Switch from {object} to Map for "updates" global, for performance but also preventing wierd behaviour when iterating
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3148
diff changeset
    60
    updates.forEach((value, index) => {
c80a5a7198ea SVGHMI: Switch from {object} to Map for "updates" global, for performance but also preventing wierd behaviour when iterating
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3148
diff changeset
    61
        dispatch_value(index, value);
c80a5a7198ea SVGHMI: Switch from {object} to Map for "updates" global, for performance but also preventing wierd behaviour when iterating
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3148
diff changeset
    62
    });
c80a5a7198ea SVGHMI: Switch from {object} to Map for "updates" global, for performance but also preventing wierd behaviour when iterating
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3148
diff changeset
    63
    updates.clear();
2865
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    64
}
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    65
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    66
// Called on requestAnimationFrame, modifies DOM
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    67
var requestAnimationFrameID = null;
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    68
function animate() {
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    69
    // Do the page swith if any one pending
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    70
    if(current_subscribed_page != current_visible_page){
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    71
        switch_visible_page(current_subscribed_page);
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    72
    }
2895
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
    73
2897
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
    74
    while(widget = need_cache_apply.pop()){
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
    75
        widget.apply_cache();
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
    76
    }
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
    77
2903
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
    78
    if(jumps_need_update) update_jumps();
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
    79
2865
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    80
    apply_updates();
3019
497aac6522a3 SVGHMI: provide request_animate() to Widget authors so that they can register redraw code when events lead to redraw. Widget member animate() is called when it is time to update DOM.
Edouard Tisserant
parents: 3018
diff changeset
    81
497aac6522a3 SVGHMI: provide request_animate() to Widget authors so that they can register redraw code when events lead to redraw. Widget member animate() is called when it is time to update DOM.
Edouard Tisserant
parents: 3018
diff changeset
    82
    pending_widget_animates.forEach(widget => widget._animate());
497aac6522a3 SVGHMI: provide request_animate() to Widget authors so that they can register redraw code when events lead to redraw. Widget member animate() is called when it is time to update DOM.
Edouard Tisserant
parents: 3018
diff changeset
    83
    pending_widget_animates = [];
497aac6522a3 SVGHMI: provide request_animate() to Widget authors so that they can register redraw code when events lead to redraw. Widget member animate() is called when it is time to update DOM.
Edouard Tisserant
parents: 3018
diff changeset
    84
2864
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
    85
    requestAnimationFrameID = null;
2859
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
    86
}
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
    87
2860
b7650c6abeda SVGHMI: more decoupling in between UI related and the rest of JS code, still in the aim of enhancing robustness under heavy load.
Edouard Tisserant
parents: 2859
diff changeset
    88
function requestHMIAnimation() {
2864
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
    89
    if(requestAnimationFrameID == null){
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
    90
        requestAnimationFrameID = window.requestAnimationFrame(animate);
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
    91
    }
2860
b7650c6abeda SVGHMI: more decoupling in between UI related and the rest of JS code, still in the aim of enhancing robustness under heavy load.
Edouard Tisserant
parents: 2859
diff changeset
    92
}
b7650c6abeda SVGHMI: more decoupling in between UI related and the rest of JS code, still in the aim of enhancing robustness under heavy load.
Edouard Tisserant
parents: 2859
diff changeset
    93
2859
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
    94
// Message reception handler
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
    95
// Hash is verified and HMI values updates resulting from binary parsing
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
    96
// are stored until browser can compute next frame, DOM is left untouched
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
    97
ws.onmessage = function (evt) {
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
    98
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
    99
    let data = evt.data;
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   100
    let dv = new DataView(data);
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   101
    let i = 0;
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   102
    try {
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   103
        for(let hash_int of hmi_hash) {
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   104
            if(hash_int != dv.getUint8(i)){
2800
68cee1366b9c SVGHMI: dispatching data to minimalist "Display" text widget.
Edouard Tisserant
parents: 2799
diff changeset
   105
                throw new Error("Hash doesn't match");
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   106
            };
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   107
            i++;
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   108
        };
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   109
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   110
        while(i < data.byteLength){
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   111
            let index = dv.getUint32(i, true);
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   112
            i += 4;
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   113
            let iectype = hmitree_types[index];
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   114
            if(iectype != undefined){
2826
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
   115
                let dvgetter = dvgetters[iectype];
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
   116
                let [value, bytesize] = dvgetter(dv,i);
3152
c80a5a7198ea SVGHMI: Switch from {object} to Map for "updates" global, for performance but also preventing wierd behaviour when iterating
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3148
diff changeset
   117
                updates.set(index, value);
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   118
                i += bytesize;
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   119
            } else {
2859
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
   120
                throw new Error("Unknown index "+index);
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   121
            }
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   122
        };
2859
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
   123
        // register for rendering on next frame, since there are updates
2864
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   124
        requestHMIAnimation();
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   125
    } catch(err) {
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   126
        // 1003 is for "Unsupported Data"
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   127
        // ws.close(1003, err.message);
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   128
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   129
        // TODO : remove debug alert ?
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   130
        alert("Error : "+err.message+"\\\\nHMI will be reloaded.");
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   131
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   132
        // force reload ignoring cache
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   133
        location.reload(true);
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   134
    }
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   135
};
2783
5ee6967f721d SVGHMI: Starting to define JS side more in details.
Edouard Tisserant
parents: 2780
diff changeset
   136
3080
e5fa1f49f0b9 SVGHMI: WIP trying to reduce memory usage : use .onclick onstead of SetAttribute, avoid useless closure and object creation when possible, etc.
Edouard Tisserant
parents: 3078
diff changeset
   137
hmi_hash_u8 = new Uint8Array(hmi_hash);
2788
2ed9ff826d03 SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents: 2783
diff changeset
   138
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   139
function send_blob(data) {
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   140
    if(data.length > 0) {
3080
e5fa1f49f0b9 SVGHMI: WIP trying to reduce memory usage : use .onclick onstead of SetAttribute, avoid useless closure and object creation when possible, etc.
Edouard Tisserant
parents: 3078
diff changeset
   141
        ws.send(new Blob([hmi_hash_u8].concat(data)));
2780
e468f18df200 SVGHMI: moved static JS code to a separate file included at xhtml generation time
Edouard Tisserant
parents:
diff changeset
   142
    };
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   143
};
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   144
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   145
const typedarray_types = {
2829
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   146
    INT: (number) => new Int16Array([number]),
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   147
    BOOL: (truth) => new Int16Array([truth]),
2890
ae8063127e95 SVGHMI: make root HMI tree node a HMI_NODE, droped HMI_ROOT node type
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2889
diff changeset
   148
    NODE: (truth) => new Int16Array([truth]),
3145
80ebb88cf7b7 SVGHMI: Fixed sending HMI_REAL to PLC. Added a svghmi_real test that illustrates using printf style formating in HMI:Display to control precision of Float number display.
Edouard Tisserant
parents: 3142
diff changeset
   149
    REAL: (number) => new Float32Array([number]),
2829
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   150
    STRING: (str) => {
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   151
        // beremiz default string max size is 128
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   152
        str = str.slice(0,128);
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   153
        binary = new Uint8Array(str.length + 1);
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   154
        binary[0] = str.length;
3080
e5fa1f49f0b9 SVGHMI: WIP trying to reduce memory usage : use .onclick onstead of SetAttribute, avoid useless closure and object creation when possible, etc.
Edouard Tisserant
parents: 3078
diff changeset
   155
        for(let i = 0; i < str.length; i++){
2829
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   156
            binary[i+1] = str.charCodeAt(i);
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   157
        }
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   158
        return binary;
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   159
    }
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   160
    /* TODO */
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   161
};
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   162
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   163
function send_reset() {
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   164
    send_blob(new Uint8Array([1])); /* reset = 1 */
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   165
};
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   166
3022
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   167
var subscriptions = [];
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   168
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   169
function subscribers(index) {
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   170
    let entry = subscriptions[index];
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   171
    let res;
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   172
    if(entry == undefined){
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   173
        res = new Set();
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   174
        subscriptions[index] = [res,0];
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   175
    }else{
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   176
        [res, _ign] = entry;
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   177
    }
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   178
    return res
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   179
}
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   180
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   181
function get_subscription_period(index) {
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   182
    let entry = subscriptions[index];
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   183
    if(entry == undefined)
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   184
        return 0;
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   185
    let [_ign, period] = entry;
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   186
    return period;
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   187
}
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   188
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   189
function set_subscription_period(index, period) {
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   190
    let entry = subscriptions[index];
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   191
    if(entry == undefined){
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   192
        subscriptions[index] = [new Set(), period];
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   193
    } else {
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   194
        entry[1] = period;
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   195
    }
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   196
}
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   197
3381
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   198
if(has_watchdog){
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   199
    // artificially subscribe the watchdog widget to "/heartbeat" hmi variable
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   200
    // Since dispatch directly calls change_hmi_value,
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   201
    // PLC will periodically send variable at given frequency
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   202
    subscribers(heartbeat_index).add({
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   203
        /* type: "Watchdog", */
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   204
        frequency: 1,
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   205
        indexes: [heartbeat_index],
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   206
        new_hmi_value: function(index, value, oldval) {
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   207
            apply_hmi_value(heartbeat_index, value+1);
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   208
        }
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   209
    });
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   210
}
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   211
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   212
// subscribe to per instance current page hmi variable
3385
18621ce81f5f SVGHMI: Changes /CURRENT_PAGE_* behaviour to prevent problem whith multiclient : all clients were switching page when one was jumping.
Edouard Tisserant
parents: 3381
diff changeset
   213
// PLC must prefix page name with "!" for page switch to happen
3381
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   214
subscribers(current_page_var_index).add({
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2811
diff changeset
   215
    frequency: 1,
3381
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   216
    indexes: [current_page_var_index],
3006
bbffdefd2eed SVGHMI: JS refactoring continued : "dispatch_value_to_widget" becomes widget class member "new_hmi_value" (was also broken by previous relativeness commit)
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3005
diff changeset
   217
    new_hmi_value: function(index, value, oldval) {
3385
18621ce81f5f SVGHMI: Changes /CURRENT_PAGE_* behaviour to prevent problem whith multiclient : all clients were switching page when one was jumping.
Edouard Tisserant
parents: 3381
diff changeset
   218
        if(value.startsWith("!"))
18621ce81f5f SVGHMI: Changes /CURRENT_PAGE_* behaviour to prevent problem whith multiclient : all clients were switching page when one was jumping.
Edouard Tisserant
parents: 3381
diff changeset
   219
            switch_page(value.slice(1));
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2811
diff changeset
   220
    }
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2811
diff changeset
   221
});
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2811
diff changeset
   222
3142
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   223
function svg_text_to_multiline(elt) {
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   224
    return(Array.prototype.map.call(elt.children, x=>x.textContent).join("\\\\n")); 
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   225
}
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   226
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   227
function multiline_to_svg_text(elt, str) {
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   228
    str.split('\\\\n').map((line,i) => {elt.children[i].textContent = line;});
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   229
}
3129
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   230
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   231
function switch_langnum(langnum) {
3144
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   232
    langnum = Math.max(0, Math.min(langs.length - 1, langnum));
3129
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   233
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   234
    for (let translation of translations) {
3144
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   235
        let [objs, msgs] = translation;
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   236
        let msg = msgs[langnum];
3129
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   237
        for (let obj of objs) {
3142
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   238
            multiline_to_svg_text(obj, msg);
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   239
            obj.setAttribute("lang",langnum);
3129
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   240
        }
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   241
    }
3144
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   242
    return langnum;
3129
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   243
}
3142
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   244
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   245
// backup original texts
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   246
for (let translation of translations) {
3144
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   247
    let [objs, msgs] = translation;
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   248
    msgs.unshift(svg_text_to_multiline(objs[0])); 
3142
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   249
}
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   250
3129
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   251
var lang_local_index = hmi_local_index("lang");
3144
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   252
var langcode_local_index = hmi_local_index("lang_code");
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   253
var langname_local_index = hmi_local_index("lang_name");
3129
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   254
subscribers(lang_local_index).add({
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   255
    indexes: [lang_local_index],
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   256
    new_hmi_value: function(index, value, oldval) {
3144
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   257
        let current_lang =  switch_langnum(value);
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   258
        let [langname,langcode] = langs[current_lang];
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   259
        apply_hmi_value(langcode_local_index, langcode);
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   260
        apply_hmi_value(langname_local_index, langname);
3142
2637bb6a6bb0 SVGHMI: allow i18n of formated strings of HMI:Messages. This was by construction impossible since formating was given as an argument. Now added optional "format" labelled element in HMI:Display, so that it can be translated, when labelled "_format".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   261
        switch_page();
3129
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   262
    }
f2709923c82c SVGHMI: Add "lang" permament persistent HMI_LOCAL variable to reflect selected language, apply stored language choice at startup and make it always subscribed to a pseudo widget (as for hearbeat) that apply language choice when it changes.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3128
diff changeset
   263
});
3144
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   264
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   265
function setup_lang(){
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   266
    let current_lang = cache[lang_local_index];
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   267
    let new_lang = switch_langnum(current_lang);
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   268
    if(current_lang != new_lang){
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   269
        apply_hmi_value(lang_local_index, new_lang);
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   270
    }
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   271
}
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   272
2af6afaccaf2 SVGHMI: i18n: ensure langs always appea in same order, and add two variables that are updated automatically when selecting a new language : lang_name and lang_code. Also fixed i18n startup, prevent wrong lang numer to crash loading.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3142
diff changeset
   273
setup_lang();
3022
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   274
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   275
function update_subscriptions() {
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   276
    let delta = [];
3022
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   277
    for(let index in subscriptions){
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   278
        let widgets = subscribers(index);
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   279
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   280
        // periods are in ms
3022
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   281
        let previous_period = get_subscription_period(index);
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   282
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2811
diff changeset
   283
        // subscribing with a zero period is unsubscribing
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   284
        let new_period = 0;
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   285
        if(widgets.size > 0) {
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   286
            let maxfreq = 0;
2960
5ad82541b46e SVGHMI: explicit handling of undefined maximum widget update frequency
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2951
diff changeset
   287
            for(let widget of widgets){
5ad82541b46e SVGHMI: explicit handling of undefined maximum widget update frequency
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2951
diff changeset
   288
                let wf = widget.frequency;
5ad82541b46e SVGHMI: explicit handling of undefined maximum widget update frequency
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2951
diff changeset
   289
                if(wf != undefined && maxfreq < wf)
5ad82541b46e SVGHMI: explicit handling of undefined maximum widget update frequency
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2951
diff changeset
   290
                    maxfreq = wf;
5ad82541b46e SVGHMI: explicit handling of undefined maximum widget update frequency
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2951
diff changeset
   291
            }
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   292
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   293
            if(maxfreq != 0)
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   294
                new_period = 1000/maxfreq;
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   295
        }
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   296
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   297
        if(previous_period != new_period) {
3022
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   298
            set_subscription_period(index, new_period);
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   299
            if(index <= last_remote_index){
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   300
                delta.push(
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   301
                    new Uint8Array([2]), /* subscribe = 2 */
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   302
                    new Uint32Array([index]),
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   303
                    new Uint16Array([new_period]));
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   304
            }
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   305
        }
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   306
    }
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   307
    send_blob(delta);
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   308
};
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   309
2801
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
   310
function send_hmi_value(index, value) {
3017
15e2df3e5610 SVGHMI: Intermediate state while implementing local HMI variables. Now write to cache only (no send), still need to implement dispatch on change.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3006
diff changeset
   311
    if(index > last_remote_index){
3152
c80a5a7198ea SVGHMI: Switch from {object} to Map for "updates" global, for performance but also preventing wierd behaviour when iterating
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3148
diff changeset
   312
        updates.set(index, value);
3128
32a4675af377 SVGHMI: Added HMI:VarInitPersistent to initialize persistent HMI_LOCAL and PAGE_LOCAL variables, stored as cookies in browser.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3126
diff changeset
   313
32a4675af377 SVGHMI: Added HMI:VarInitPersistent to initialize persistent HMI_LOCAL and PAGE_LOCAL variables, stored as cookies in browser.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3126
diff changeset
   314
        if(persistent_indexes.has(index)){
32a4675af377 SVGHMI: Added HMI:VarInitPersistent to initialize persistent HMI_LOCAL and PAGE_LOCAL variables, stored as cookies in browser.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3126
diff changeset
   315
            let varname = persistent_indexes.get(index);
32a4675af377 SVGHMI: Added HMI:VarInitPersistent to initialize persistent HMI_LOCAL and PAGE_LOCAL variables, stored as cookies in browser.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3126
diff changeset
   316
            document.cookie = varname+"="+value+"; max-age=3153600000";
32a4675af377 SVGHMI: Added HMI:VarInitPersistent to initialize persistent HMI_LOCAL and PAGE_LOCAL variables, stored as cookies in browser.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3126
diff changeset
   317
        }
32a4675af377 SVGHMI: Added HMI:VarInitPersistent to initialize persistent HMI_LOCAL and PAGE_LOCAL variables, stored as cookies in browser.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3126
diff changeset
   318
3022
f6fe42b7ce60 SVGHMI: finished initial implementation of PAGE_LOCAL and HMI_LOCAL variables.
Edouard Tisserant
parents: 3017
diff changeset
   319
        requestHMIAnimation();
3017
15e2df3e5610 SVGHMI: Intermediate state while implementing local HMI variables. Now write to cache only (no send), still need to implement dispatch on change.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3006
diff changeset
   320
        return;
15e2df3e5610 SVGHMI: Intermediate state while implementing local HMI variables. Now write to cache only (no send), still need to implement dispatch on change.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3006
diff changeset
   321
    }
15e2df3e5610 SVGHMI: Intermediate state while implementing local HMI variables. Now write to cache only (no send), still need to implement dispatch on change.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3006
diff changeset
   322
2802
64e6f73b9859 SVGHMI - Fixed svghmi.{c,js} about HMI -> PLC data unpack.
Edouard Tisserant
parents: 2801
diff changeset
   323
    let iectype = hmitree_types[index];
2829
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   324
    let tobinary = typedarray_types[iectype];
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   325
    send_blob([
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   326
        new Uint8Array([0]),  /* setval = 0 */
2829
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   327
        new Uint32Array([index]),
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   328
        tobinary(value)]);
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   329
2921
2670f5c53caf SVGHMI: HMI is not speculating on PLC variable update anymore when sending new variable value.
Edouard Tisserant
parents: 2920
diff changeset
   330
    // DON'T DO THAT unless read_iterator in svghmi.c modifies wbuf as well, not only rbuf
2670f5c53caf SVGHMI: HMI is not speculating on PLC variable update anymore when sending new variable value.
Edouard Tisserant
parents: 2920
diff changeset
   331
    // cache[index] = value;
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   332
};
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   333
2911
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   334
function apply_hmi_value(index, new_val) {
3190
80dd371e15bb SVGHMI: cosmetic change, missing semicolon
Edouard Tisserant
parents: 3152
diff changeset
   335
    let old_val = cache[index];
2911
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   336
    if(new_val != undefined && old_val != new_val)
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   337
        send_hmi_value(index, new_val);
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   338
    return new_val;
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   339
}
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   340
3078
d345673610b0 SVGHMI: use const when applicable
Edouard Tisserant
parents: 3075
diff changeset
   341
const quotes = {"'":null, '"':null};
2970
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   342
3098
5823b73b132f SVGHMI: decoupled operation string evaluation from HMI variable uptdate in change_hmi_variable(), paving the way for min/max boundaries enforcement
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3082
diff changeset
   343
function eval_operation_string(old_val, opstr) {
2801
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
   344
    let op = opstr[0];
2970
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   345
    let given_val;
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   346
    if(opstr.length < 2) 
3098
5823b73b132f SVGHMI: decoupled operation string evaluation from HMI variable uptdate in change_hmi_variable(), paving the way for min/max boundaries enforcement
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3082
diff changeset
   347
        return undefined;
2970
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   348
    if(opstr[1] in quotes){
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   349
        if(opstr.length < 3) 
3098
5823b73b132f SVGHMI: decoupled operation string evaluation from HMI variable uptdate in change_hmi_variable(), paving the way for min/max boundaries enforcement
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3082
diff changeset
   350
            return undefined;
2970
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   351
        if(opstr[opstr.length-1] == opstr[1]){
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   352
            given_val = opstr.slice(2,opstr.length-1);
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   353
        }
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   354
    } else {
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   355
        given_val = Number(opstr.slice(1));
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   356
    }
2803
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   357
    let new_val;
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   358
    switch(op){
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   359
      case "=":
2970
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   360
        new_val = given_val;
2803
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   361
        break;
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   362
      case "+":
2970
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   363
        new_val = old_val + given_val;
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   364
        break;
2803
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   365
      case "-":
2970
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   366
        new_val = old_val - given_val;
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   367
        break;
2803
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   368
      case "*":
2970
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   369
        new_val = old_val * given_val;
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   370
        break;
2803
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   371
      case "/":
2970
4a9b0df0602a SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2960
diff changeset
   372
        new_val = old_val / given_val;
2803
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   373
        break;
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   374
    }
3098
5823b73b132f SVGHMI: decoupled operation string evaluation from HMI variable uptdate in change_hmi_variable(), paving the way for min/max boundaries enforcement
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3082
diff changeset
   375
    return new_val;
5823b73b132f SVGHMI: decoupled operation string evaluation from HMI variable uptdate in change_hmi_variable(), paving the way for min/max boundaries enforcement
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3082
diff changeset
   376
}
5823b73b132f SVGHMI: decoupled operation string evaluation from HMI variable uptdate in change_hmi_variable(), paving the way for min/max boundaries enforcement
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3082
diff changeset
   377
2864
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   378
var current_visible_page;
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   379
var current_subscribed_page;
2903
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   380
var current_page_index;
3206
4fd7bd10e606 SVGHMI: added "page_node" variable that reflects the HMI tree path of current relative page
Edouard Tisserant
parents: 3190
diff changeset
   381
var page_node_local_index = hmi_local_index("page_node");
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   382
3299
8b45d8494fae SVGHMI: Allow toggling fulscreen mode my right click or long press.
Edouard Tisserant
parents: 3268
diff changeset
   383
function toggleFullscreen() {
8b45d8494fae SVGHMI: Allow toggling fulscreen mode my right click or long press.
Edouard Tisserant
parents: 3268
diff changeset
   384
  let elem = document.documentElement;
8b45d8494fae SVGHMI: Allow toggling fulscreen mode my right click or long press.
Edouard Tisserant
parents: 3268
diff changeset
   385
8b45d8494fae SVGHMI: Allow toggling fulscreen mode my right click or long press.
Edouard Tisserant
parents: 3268
diff changeset
   386
  if (!document.fullscreenElement) {
8b45d8494fae SVGHMI: Allow toggling fulscreen mode my right click or long press.
Edouard Tisserant
parents: 3268
diff changeset
   387
    elem.requestFullscreen().catch(err => {
8b45d8494fae SVGHMI: Allow toggling fulscreen mode my right click or long press.
Edouard Tisserant
parents: 3268
diff changeset
   388
      console.log("Error attempting to enable full-screen mode: "+err.message+" ("+err.name+")");
8b45d8494fae SVGHMI: Allow toggling fulscreen mode my right click or long press.
Edouard Tisserant
parents: 3268
diff changeset
   389
    });
8b45d8494fae SVGHMI: Allow toggling fulscreen mode my right click or long press.
Edouard Tisserant
parents: 3268
diff changeset
   390
  } else {
8b45d8494fae SVGHMI: Allow toggling fulscreen mode my right click or long press.
Edouard Tisserant
parents: 3268
diff changeset
   391
    document.exitFullscreen();
8b45d8494fae SVGHMI: Allow toggling fulscreen mode my right click or long press.
Edouard Tisserant
parents: 3268
diff changeset
   392
  }
8b45d8494fae SVGHMI: Allow toggling fulscreen mode my right click or long press.
Edouard Tisserant
parents: 3268
diff changeset
   393
}
8b45d8494fae SVGHMI: Allow toggling fulscreen mode my right click or long press.
Edouard Tisserant
parents: 3268
diff changeset
   394
2843
94696b3f69fb SVGHMI : still trying to optimize. Added xslt code to identitfy minimum set of elements needed by a particular page. Plan is to remove unseen/unused elements from the DOM, and re-appending them later when used, on page switch. Disabled previous optimization.
Edouard Tisserant
parents: 2841
diff changeset
   395
function prepare_svg() {
3082
20a5eb6a02e6 SVGHMI: prevent unwnted context menu and pinch zoom
Edouard Tisserant
parents: 3080
diff changeset
   396
    // prevents context menu from appearing on right click and long touch
20a5eb6a02e6 SVGHMI: prevent unwnted context menu and pinch zoom
Edouard Tisserant
parents: 3080
diff changeset
   397
    document.body.addEventListener('contextmenu', e => {
3299
8b45d8494fae SVGHMI: Allow toggling fulscreen mode my right click or long press.
Edouard Tisserant
parents: 3268
diff changeset
   398
        toggleFullscreen();
3082
20a5eb6a02e6 SVGHMI: prevent unwnted context menu and pinch zoom
Edouard Tisserant
parents: 3080
diff changeset
   399
        e.preventDefault();
20a5eb6a02e6 SVGHMI: prevent unwnted context menu and pinch zoom
Edouard Tisserant
parents: 3080
diff changeset
   400
    });
20a5eb6a02e6 SVGHMI: prevent unwnted context menu and pinch zoom
Edouard Tisserant
parents: 3080
diff changeset
   401
2850
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   402
    for(let eltid in detachable_elements){
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   403
        let [element,parent] = detachable_elements[eltid];
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   404
        parent.removeChild(element);
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   405
    }
2843
94696b3f69fb SVGHMI : still trying to optimize. Added xslt code to identitfy minimum set of elements needed by a particular page. Plan is to remove unseen/unused elements from the DOM, and re-appending them later when used, on page switch. Disabled previous optimization.
Edouard Tisserant
parents: 2841
diff changeset
   406
};
94696b3f69fb SVGHMI : still trying to optimize. Added xslt code to identitfy minimum set of elements needed by a particular page. Plan is to remove unseen/unused elements from the DOM, and re-appending them later when used, on page switch. Disabled previous optimization.
Edouard Tisserant
parents: 2841
diff changeset
   407
2870
634b43d69897 SVGHMI: relative pages and page jumps
Edouard Tisserant
parents: 2869
diff changeset
   408
function switch_page(page_name, page_index) {
2864
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   409
    if(current_subscribed_page != current_visible_page){
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   410
        /* page switch already going */
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   411
        /* TODO LOG ERROR */
2902
1fcb50af0335 SVGHMI: added Back widget.
Edouard Tisserant
parents: 2899
diff changeset
   412
        return false;
2895
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   413
    }
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   414
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   415
    if(page_name == undefined)
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   416
        page_name = current_subscribed_page;
3381
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   417
    else if(page_index == undefined){
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   418
        [page_name, page_index] = page_name.split('@')
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   419
    }
2903
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   420
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   421
    let old_desc = page_desc[current_subscribed_page];
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   422
    let new_desc = page_desc[page_name];
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   423
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   424
    if(new_desc == undefined){
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   425
        /* TODO LOG ERROR */
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   426
        return false;
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   427
    }
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   428
3381
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   429
    if(page_index == undefined)
2903
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   430
        page_index = new_desc.page_index;
3381
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   431
    else if(typeof(page_index) == "string") {
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   432
        let hmitree_node = hmitree_nodes[page_index];
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   433
        if(hmitree_node !== undefined){
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   434
            let [int_index, hmiclass] = hmitree_node;
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   435
            if(hmiclass == new_desc.page_class)
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   436
                page_index = int_index;
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   437
            else
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   438
                page_index = new_desc.page_index;
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   439
        } else {
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   440
            page_index = new_desc.page_index;
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   441
        }
2903
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   442
    }
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   443
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   444
    if(old_desc){
3005
ff9ae4f4e3be SVGHMI: widgets are not anymore binary relative or absolute, but have a "relativeness".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3000
diff changeset
   445
        old_desc.widgets.map(([widget,relativeness])=>widget.unsub());
ff9ae4f4e3be SVGHMI: widgets are not anymore binary relative or absolute, but have a "relativeness".
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3000
diff changeset
   446
    }
3080
e5fa1f49f0b9 SVGHMI: WIP trying to reduce memory usage : use .onclick onstead of SetAttribute, avoid useless closure and object creation when possible, etc.
Edouard Tisserant
parents: 3078
diff changeset
   447
    const new_offset = page_index == undefined ? 0 : page_index - new_desc.page_index;
e5fa1f49f0b9 SVGHMI: WIP trying to reduce memory usage : use .onclick onstead of SetAttribute, avoid useless closure and object creation when possible, etc.
Edouard Tisserant
parents: 3078
diff changeset
   448
e5fa1f49f0b9 SVGHMI: WIP trying to reduce memory usage : use .onclick onstead of SetAttribute, avoid useless closure and object creation when possible, etc.
Edouard Tisserant
parents: 3078
diff changeset
   449
    const container_id = page_name + (page_index != undefined ? page_index : "");
3017
15e2df3e5610 SVGHMI: Intermediate state while implementing local HMI variables. Now write to cache only (no send), still need to implement dispatch on change.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3006
diff changeset
   450
15e2df3e5610 SVGHMI: Intermediate state while implementing local HMI variables. Now write to cache only (no send), still need to implement dispatch on change.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3006
diff changeset
   451
    new_desc.widgets.map(([widget,relativeness])=>widget.sub(new_offset,relativeness,container_id));
2903
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   452
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   453
    update_subscriptions();
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   454
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   455
    current_subscribed_page = page_name;
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   456
    current_page_index = page_index;
3206
4fd7bd10e606 SVGHMI: added "page_node" variable that reflects the HMI tree path of current relative page
Edouard Tisserant
parents: 3190
diff changeset
   457
    let page_node;
4fd7bd10e606 SVGHMI: added "page_node" variable that reflects the HMI tree path of current relative page
Edouard Tisserant
parents: 3190
diff changeset
   458
    if(page_index != undefined){
4fd7bd10e606 SVGHMI: added "page_node" variable that reflects the HMI tree path of current relative page
Edouard Tisserant
parents: 3190
diff changeset
   459
        page_node = hmitree_paths[page_index];
4fd7bd10e606 SVGHMI: added "page_node" variable that reflects the HMI tree path of current relative page
Edouard Tisserant
parents: 3190
diff changeset
   460
    }else{
4fd7bd10e606 SVGHMI: added "page_node" variable that reflects the HMI tree path of current relative page
Edouard Tisserant
parents: 3190
diff changeset
   461
        page_node = "";
4fd7bd10e606 SVGHMI: added "page_node" variable that reflects the HMI tree path of current relative page
Edouard Tisserant
parents: 3190
diff changeset
   462
    }
4fd7bd10e606 SVGHMI: added "page_node" variable that reflects the HMI tree path of current relative page
Edouard Tisserant
parents: 3190
diff changeset
   463
    apply_hmi_value(page_node_local_index, page_node);
2903
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   464
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   465
    jumps_need_update = true;
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   466
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   467
    requestHMIAnimation();
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   468
    jump_history.push([page_name, page_index]);
2905
3d7e3866cc51 SVGHMI: prevent man-made memory leak by limiting back button history items count to 42
Edouard Tisserant
parents: 2903
diff changeset
   469
    if(jump_history.length > 42)
3d7e3866cc51 SVGHMI: prevent man-made memory leak by limiting back button history items count to 42
Edouard Tisserant
parents: 2903
diff changeset
   470
        jump_history.shift();
2903
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   471
3385
18621ce81f5f SVGHMI: Changes /CURRENT_PAGE_* behaviour to prevent problem whith multiclient : all clients were switching page when one was jumping.
Edouard Tisserant
parents: 3381
diff changeset
   472
    apply_hmi_value(current_page_var_index, page_index == undefined
18621ce81f5f SVGHMI: Changes /CURRENT_PAGE_* behaviour to prevent problem whith multiclient : all clients were switching page when one was jumping.
Edouard Tisserant
parents: 3381
diff changeset
   473
        ? page_name
18621ce81f5f SVGHMI: Changes /CURRENT_PAGE_* behaviour to prevent problem whith multiclient : all clients were switching page when one was jumping.
Edouard Tisserant
parents: 3381
diff changeset
   474
        : page_name + "@" + hmitree_paths[page_index]);
3381
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3299
diff changeset
   475
2903
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   476
    return true;
2864
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   477
};
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   478
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   479
function switch_visible_page(page_name) {
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   480
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   481
    let old_desc = page_desc[current_visible_page];
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   482
    let new_desc = page_desc[page_name];
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   483
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   484
    if(old_desc){
2850
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   485
        for(let eltid in old_desc.required_detachables){
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   486
            if(!(eltid in new_desc.required_detachables)){
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   487
                let [element, parent] = old_desc.required_detachables[eltid];
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   488
                parent.removeChild(element);
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   489
            }
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   490
        }
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   491
        for(let eltid in new_desc.required_detachables){
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   492
            if(!(eltid in old_desc.required_detachables)){
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   493
                let [element, parent] = new_desc.required_detachables[eltid];
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   494
                parent.appendChild(element);
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   495
            }
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   496
        }
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   497
    }else{
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   498
        for(let eltid in new_desc.required_detachables){
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   499
            let [element, parent] = new_desc.required_detachables[eltid];
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   500
            parent.appendChild(element);
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   501
        }
2843
94696b3f69fb SVGHMI : still trying to optimize. Added xslt code to identitfy minimum set of elements needed by a particular page. Plan is to remove unseen/unused elements from the DOM, and re-appending them later when used, on page switch. Disabled previous optimization.
Edouard Tisserant
parents: 2841
diff changeset
   502
    }
94696b3f69fb SVGHMI : still trying to optimize. Added xslt code to identitfy minimum set of elements needed by a particular page. Plan is to remove unseen/unused elements from the DOM, and re-appending them later when used, on page switch. Disabled previous optimization.
Edouard Tisserant
parents: 2841
diff changeset
   503
2895
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   504
    svg_root.setAttribute('viewBox',new_desc.bbox.join(" "));
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   505
    current_visible_page = page_name;
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   506
};
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   507
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   508
// Once connection established
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   509
ws.onopen = function (evt) {
2801
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
   510
    init_widgets();
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   511
    send_reset();
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   512
    // show main page
2843
94696b3f69fb SVGHMI : still trying to optimize. Added xslt code to identitfy minimum set of elements needed by a particular page. Plan is to remove unseen/unused elements from the DOM, and re-appending them later when used, on page switch. Disabled previous optimization.
Edouard Tisserant
parents: 2841
diff changeset
   513
    prepare_svg();
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   514
    switch_page(default_page);
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   515
};
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   516
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   517
ws.onclose = function (evt) {
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   518
    // TODO : add visible notification while waiting for reload
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   519
    console.log("Connection closed. code:"+evt.code+" reason:"+evt.reason+" wasClean:"+evt.wasClean+" Reload in 10s.");
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   520
    // TODO : re-enable auto reload when not in debug
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   521
    //window.setTimeout(() => location.reload(true), 10000);
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   522
    alert("Connection closed. code:"+evt.code+" reason:"+evt.reason+" wasClean:"+evt.wasClean+".");
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   523
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   524
};
2911
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   525
3080
e5fa1f49f0b9 SVGHMI: WIP trying to reduce memory usage : use .onclick onstead of SetAttribute, avoid useless closure and object creation when possible, etc.
Edouard Tisserant
parents: 3078
diff changeset
   526
const xmlns = "http://www.w3.org/2000/svg";
2911
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   527
var edit_callback;
3075
2f9dbd3ee445 SVGHMI: Fix: on screen keyboard wasn't showing up when editing local variables through Input widget.
Edouard Tisserant
parents: 3068
diff changeset
   528
const localtypes = {"PAGE_LOCAL":null, "HMI_LOCAL":null}
3118
e704b0487515 SVGHMI : removed support for changing keyboard position and showing at user defined location. Feature was problematic in many respect.
Edouard Tisserant
parents: 3098
diff changeset
   529
function edit_value(path, valuetype, callback, initial) {
3075
2f9dbd3ee445 SVGHMI: Fix: on screen keyboard wasn't showing up when editing local variables through Input widget.
Edouard Tisserant
parents: 3068
diff changeset
   530
    if(valuetype in localtypes){
2f9dbd3ee445 SVGHMI: Fix: on screen keyboard wasn't showing up when editing local variables through Input widget.
Edouard Tisserant
parents: 3068
diff changeset
   531
        valuetype = (typeof initial) == "number" ? "HMI_REAL" : "HMI_STRING";
2f9dbd3ee445 SVGHMI: Fix: on screen keyboard wasn't showing up when editing local variables through Input widget.
Edouard Tisserant
parents: 3068
diff changeset
   532
    }
2913
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   533
    let [keypadid, xcoord, ycoord] = keypads[valuetype];
2911
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   534
    edit_callback = callback;
2917
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   535
    let widget = hmi_widgets[keypadid];
3118
e704b0487515 SVGHMI : removed support for changing keyboard position and showing at user defined location. Feature was problematic in many respect.
Edouard Tisserant
parents: 3098
diff changeset
   536
    widget.start_edit(path, valuetype, callback, initial);
2917
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   537
};
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   538
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   539
var current_modal; /* TODO stack ?*/
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   540
3118
e704b0487515 SVGHMI : removed support for changing keyboard position and showing at user defined location. Feature was problematic in many respect.
Edouard Tisserant
parents: 3098
diff changeset
   541
function show_modal() {
2917
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   542
    let [element, parent] = detachable_elements[this.element.id];
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   543
2916
4f3b130fd197 SVGHMI: fix keyboard not showing
Edouard Tisserant
parents: 2913
diff changeset
   544
    tmpgrp = document.createElementNS(xmlns,"g");
2913
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   545
    tmpgrpattr = document.createAttribute("transform");
2917
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   546
    let [xcoord,ycoord] = this.coordinates;
2913
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   547
    let [xdest,ydest] = page_desc[current_visible_page].bbox;
3118
e704b0487515 SVGHMI : removed support for changing keyboard position and showing at user defined location. Feature was problematic in many respect.
Edouard Tisserant
parents: 3098
diff changeset
   548
    tmpgrpattr.value = "translate("+String(xdest-xcoord)+","+String(ydest-ycoord)+")";
3010
893cc309f5e2 Changed keyboard to show on defined position.
usveticic
parents: 3000
diff changeset
   549
2913
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   550
    tmpgrp.setAttributeNode(tmpgrpattr);
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   551
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   552
    tmpgrp.appendChild(element);
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   553
    parent.appendChild(tmpgrp);
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   554
2917
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   555
    current_modal = [this.element.id, tmpgrp];
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   556
};
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   557
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   558
function end_modal() {
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   559
    let [eltid, tmpgrp] = current_modal;
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   560
    let [element, parent] = detachable_elements[this.element.id];
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   561
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   562
    parent.removeChild(tmpgrp);
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   563
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   564
    current_modal = undefined;
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   565
};
2920
3ee337c8c769 SVGHMI: finished shift and capslock support n keypad widget. Added a helper in widgets_common to collect subelements likle active/inactive/disabled...
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2917
diff changeset
   566