28 } |
28 } |
29 }); |
29 }); |
30 }; |
30 }; |
31 |
31 |
32 // Open WebSocket to relative "/ws" address |
32 // Open WebSocket to relative "/ws" address |
|
33 var has_watchdog = window.location.hash == "#watchdog"; |
33 |
34 |
34 var ws_url = |
35 var ws_url = |
35 window.location.href.replace(/^http(s?:\/\/[^\/]*)\/.*$/, 'ws$1/ws') |
36 window.location.href.replace(/^http(s?:\/\/[^\/]*)\/.*$/, 'ws$1/ws') |
36 + '?mode=' + (window.location.hash == "#watchdog" |
37 + '?mode=' + (has_watchdog ? "watchdog" : "multiclient"); |
37 ? "watchdog" |
38 |
38 : "multiclient"); |
|
39 var ws = new WebSocket(ws_url); |
39 var ws = new WebSocket(ws_url); |
40 ws.binaryType = 'arraybuffer'; |
40 ws.binaryType = 'arraybuffer'; |
41 |
41 |
42 const dvgetters = { |
42 const dvgetters = { |
43 INT: (dv,offset) => [dv.getInt16(offset, true), 2], |
43 INT: (dv,offset) => [dv.getInt16(offset, true), 2], |
193 } else { |
193 } else { |
194 entry[1] = period; |
194 entry[1] = period; |
195 } |
195 } |
196 } |
196 } |
197 |
197 |
198 // artificially subscribe the watchdog widget to "/heartbeat" hmi variable |
198 if(has_watchdog){ |
199 // Since dispatch directly calls change_hmi_value, |
199 // artificially subscribe the watchdog widget to "/heartbeat" hmi variable |
200 // PLC will periodically send variable at given frequency |
200 // Since dispatch directly calls change_hmi_value, |
201 subscribers(heartbeat_index).add({ |
201 // PLC will periodically send variable at given frequency |
202 /* type: "Watchdog", */ |
202 subscribers(heartbeat_index).add({ |
|
203 /* type: "Watchdog", */ |
|
204 frequency: 1, |
|
205 indexes: [heartbeat_index], |
|
206 new_hmi_value: function(index, value, oldval) { |
|
207 apply_hmi_value(heartbeat_index, value+1); |
|
208 } |
|
209 }); |
|
210 } |
|
211 |
|
212 // subscribe to per instance current page hmi variable |
|
213 subscribers(current_page_var_index).add({ |
203 frequency: 1, |
214 frequency: 1, |
204 indexes: [heartbeat_index], |
215 indexes: [current_page_var_index], |
205 new_hmi_value: function(index, value, oldval) { |
216 new_hmi_value: function(index, value, oldval) { |
206 apply_hmi_value(heartbeat_index, value+1); |
217 switch_page(value); |
207 } |
218 } |
208 }); |
219 }); |
209 |
220 |
210 function svg_text_to_multiline(elt) { |
221 function svg_text_to_multiline(elt) { |
211 return(Array.prototype.map.call(elt.children, x=>x.textContent).join("\\\\n")); |
222 return(Array.prototype.map.call(elt.children, x=>x.textContent).join("\\\\n")); |
399 return false; |
410 return false; |
400 } |
411 } |
401 |
412 |
402 if(page_name == undefined) |
413 if(page_name == undefined) |
403 page_name = current_subscribed_page; |
414 page_name = current_subscribed_page; |
404 |
415 else if(page_index == undefined){ |
|
416 [page_name, page_index] = page_name.split('@') |
|
417 } |
405 |
418 |
406 let old_desc = page_desc[current_subscribed_page]; |
419 let old_desc = page_desc[current_subscribed_page]; |
407 let new_desc = page_desc[page_name]; |
420 let new_desc = page_desc[page_name]; |
408 |
421 |
409 if(new_desc == undefined){ |
422 if(new_desc == undefined){ |
410 /* TODO LOG ERROR */ |
423 /* TODO LOG ERROR */ |
411 return false; |
424 return false; |
412 } |
425 } |
413 |
426 |
414 if(page_index == undefined){ |
427 if(page_index == undefined) |
415 page_index = new_desc.page_index; |
428 page_index = new_desc.page_index; |
|
429 else if(typeof(page_index) == "string") { |
|
430 let hmitree_node = hmitree_nodes[page_index]; |
|
431 if(hmitree_node !== undefined){ |
|
432 let [int_index, hmiclass] = hmitree_node; |
|
433 if(hmiclass == new_desc.page_class) |
|
434 page_index = int_index; |
|
435 else |
|
436 page_index = new_desc.page_index; |
|
437 } else { |
|
438 page_index = new_desc.page_index; |
|
439 } |
416 } |
440 } |
417 |
441 |
418 if(old_desc){ |
442 if(old_desc){ |
419 old_desc.widgets.map(([widget,relativeness])=>widget.unsub()); |
443 old_desc.widgets.map(([widget,relativeness])=>widget.unsub()); |
420 } |
444 } |
441 requestHMIAnimation(); |
465 requestHMIAnimation(); |
442 jump_history.push([page_name, page_index]); |
466 jump_history.push([page_name, page_index]); |
443 if(jump_history.length > 42) |
467 if(jump_history.length > 42) |
444 jump_history.shift(); |
468 jump_history.shift(); |
445 |
469 |
|
470 apply_hmi_value(current_page_var_index, |
|
471 page_index == undefined |
|
472 ? page_name |
|
473 : page_name + "@" + hmitree_paths[page_index]); |
|
474 |
446 return true; |
475 return true; |
447 }; |
476 }; |
448 |
477 |
449 function switch_visible_page(page_name) { |
478 function switch_visible_page(page_name) { |
450 |
479 |