svghmi/svghmi.js
branchsvghmi
changeset 2798 ddb2c4668a6b
parent 2788 2ed9ff826d03
child 2799 f5da343b9b63
equal deleted inserted replaced
2797:c5ba1e77f054 2798:ddb2c4668a6b
     1 // svghmi.js
     1 // svghmi.js
     2 
     2 
     3 (function(){
     3 function dispatch_value(index, value) {
     4     // Open WebSocket to relative "/ws" address
     4     console.log("dispatch_value("+index+value+")");
     5     var ws = new WebSocket(window.location.href.replace(/^http(s?:\/\/[^\/]*)\/.*$/, 'ws$1/ws'));
     5 };
     6 
     6 
     7     // Register message reception handler 
     7 // Open WebSocket to relative "/ws" address
     8     ws.onmessage = function (evt) {
     8 var ws = new WebSocket(window.location.href.replace(/^http(s?:\/\/[^\/]*)\/.*$/, 'ws$1/ws'));
     9         // TODO : dispatch and cache hmi tree updates
     9 ws.binaryType = 'arraybuffer';
    10 
    10 
    11         var received_msg = evt.data;
    11 const dvgetters = {
    12         // TODO : check for hmitree hash header
    12     INT: [DataView.prototype.getInt16, 2],
    13         //        if not matching, reload page
    13     BOOL: [DataView.prototype.getInt8, 1]
    14         alert("Message is received..."+received_msg); 
    14     /* TODO */
       
    15 };
       
    16 
       
    17 // Register message reception handler 
       
    18 ws.onmessage = function (evt) {
       
    19 
       
    20     let data = evt.data;
       
    21     let dv = new DataView(data);
       
    22     let i = 0;
       
    23     for(let hash_int of hmi_hash) {
       
    24         if(hash_int != dv.getUint8(i)){
       
    25             console.log("Recv non maching hash. Reload.");
       
    26 
       
    27             // 1003 is for "Unsupported Data"
       
    28             ws.close(1003,"Hash doesn't match");
       
    29 
       
    30             // TODO : remove debug alert ?
       
    31             alert("HMI will be reloaded.");
       
    32 
       
    33             // force reload ignoring cache
       
    34             location.reload(true);
       
    35         };
       
    36         i++;
    15     };
    37     };
    16 
    38 
    17     // Once connection established
    39     while(i < data.length){
    18     ws.onopen = function (evt) {
    40         let index = dv.getUint32(i);
    19         // TODO : enable the HMI (was previously offline, or just starts)
    41         i += 4;
    20         //        show main page
    42         let iectype = hmitree_types[index];
       
    43         let [dvgetter, bytesize] = dvgetters[iectypes];
       
    44         value = dvgetter.call(dv,i);
       
    45         dispatch_value(index, value);
       
    46         i += bytesize;
       
    47     };
       
    48 };
    21 
    49 
    22 
    50 
    23         // TODO : prefix with hmitree hash header
    51 function send_blob(data) {
    24         ws.send("test");
    52     if(data.length > 0) {
       
    53         ws.send(new Blob([
       
    54             new Uint8Array(hmi_hash), 
       
    55             data]));
    25     };
    56     };
    26 })();
    57 };
       
    58 
       
    59 const typedarray_types = {
       
    60     INT: Int16Array,
       
    61     BOOL: Uint8Array
       
    62     /* TODO */
       
    63 };
       
    64 
       
    65 function send_reset() {
       
    66     send_blob(new Uint8Array([1])); /* reset = 1 */
       
    67 };
       
    68 
       
    69 // subscription state, as it should be in hmi server
       
    70 // hmitree indexed array of integers
       
    71 var subscriptions =  hmitree_types.map(_ignored => 0);
       
    72 
       
    73 // subscription state as needed by widget now
       
    74 // hmitree indexed array of Sets of widgets objects
       
    75 var subscribers = hmitree_types.map(_ignored => new Set());
       
    76 
       
    77 function update_subscriptions() {
       
    78     let delta = [];
       
    79     for(let index = 0; index < subscribers.length; index++){
       
    80         let widgets = subscribers[index];
       
    81 
       
    82         // periods are in ms
       
    83         let previous_period = subscriptions[index];
       
    84 
       
    85         let new_period;
       
    86         if(widgets.size > 0) {
       
    87             let maxfreq = 0;
       
    88             for(let widget of widgets)
       
    89                 if(maxfreq < widgets.frequency)
       
    90                     maxfreq = widgets.frequency;
       
    91 
       
    92             new_period = 1000/maxfreq;
       
    93         } else {
       
    94             new_period = 0;
       
    95         }
       
    96 
       
    97         if(previous_period != new_period) {
       
    98             subscriptions[index] = new_period;
       
    99             delta.push([
       
   100                 new Uint8Array([2]), /* subscribe = 2 */
       
   101                 new Uint32Array([index]), 
       
   102                 new Uint16Array([new_period])]);
       
   103         }
       
   104         
       
   105     }
       
   106     send_blob(delta);
       
   107 };
       
   108 
       
   109 function update_value(index, value) {
       
   110     iectype = hmitree_types[index];
       
   111     jstype = typedarray_types[iectypes];
       
   112     send_blob([
       
   113         new Uint8Array([0]),  /* setval = 0 */
       
   114         new jstype([value])
       
   115         ]);
       
   116 
       
   117 };
       
   118 
       
   119 var current_page;
       
   120 
       
   121 function switch_page(page_name) {
       
   122     let old_desc = page_desc[current_page];
       
   123     let new_desc = page_desc[page_name];
       
   124     /* TODO hide / show widgets */
       
   125     /* TODO move viewport */
       
   126 
       
   127     /* remove subsribers of previous page if any */
       
   128     if(old_desc) for(let widget of old_desc.widgets){
       
   129         for(let index of widget.indexes){
       
   130             subscribers[index].delete(widget);
       
   131         }
       
   132     }
       
   133     /* add new subsribers if any */
       
   134     if(new_desc) for(let widget of new_desc.widgets){
       
   135         for(let index of widget.indexes){
       
   136             subscribers[index].add(widget);
       
   137         }
       
   138     }
       
   139 
       
   140     current_page = page_name;
       
   141 
       
   142     update_subscriptions();
       
   143 };
       
   144 
       
   145 
       
   146 // Once connection established
       
   147 ws.onopen = function (evt) {
       
   148     send_reset();
       
   149     // show main page
       
   150     switch_page(default_page);
       
   151 
       
   152 };
       
   153