diff --git a/data/js/menu_toggles.js b/data/js/menu_toggles.js index 66f2165..0d1b3b7 100644 --- a/data/js/menu_toggles.js +++ b/data/js/menu_toggles.js @@ -4,13 +4,13 @@ function set_menu_toggle_state(toggle_name, toggle_state){ document.getElementById(toggle_name).classList.remove("menu_item_toggle_off"); document.getElementById(toggle_name).classList.add("menu_item_toggle_on"); document.getElementById(toggle_name).innerHTML = "ON"; - transmit(`set|${toggle_name}|1`); + wstx(`set|${toggle_name}|1`); } else{ document.getElementById(toggle_name).classList.remove("menu_item_toggle_on"); document.getElementById(toggle_name).classList.add("menu_item_toggle_off"); document.getElementById(toggle_name).innerHTML = "OFF"; - transmit(`set|${toggle_name}|0`); + wstx(`set|${toggle_name}|0`); } configuration[toggle_name] = !configuration[toggle_name]; diff --git a/data/js/render_controls.js b/data/js/render_controls.js index 3958bd9..a84ecef 100644 --- a/data/js/render_controls.js +++ b/data/js/render_controls.js @@ -310,10 +310,10 @@ function check_and_attach_buzz_listeners() { }); document.addEventListener('touchstart', function(){ - transmit("touch_start"); + wstx("touch_start"); }, { passive: true }); document.addEventListener('touchend', function(){ - transmit("touch_end"); + wstx("touch_end"); }, { passive: true }); window.addEventListener('contextmenu', function(e) { diff --git a/data/js/sliders.js b/data/js/sliders.js index a43d2ab..a3a1ec1 100644 --- a/data/js/sliders.js +++ b/data/js/sliders.js @@ -49,7 +49,7 @@ function track_sliders() { eventPoints.forEach(point => { let id = point.target.closest('.slider_track').getAttribute('id'); - transmit(`slider_touch_start|${id}`); + wstx(`slider_touch_start|${id}`); // Store initial touch positions touch_start_data.set(isMouseEvent ? 'mouse' : point.identifier, { @@ -106,7 +106,7 @@ function track_sliders() { if(configuration[id] != resulting_value){ configuration[id] = resulting_value; - transmit(`set|${id}|${truncate_float(resulting_value, 3)}`); + wstx(`set|${id}|${truncate_float(resulting_value, 3)}`); } let percentage = ((resulting_value-slider_min) / (slider_max-slider_min)) * 100.0; @@ -129,7 +129,7 @@ function track_sliders() { if (data && data.target_div.classList.contains("slider_track")) { let id = data.target_div.getAttribute('id'); - transmit(`slider_touch_end|${id}`); + wstx(`slider_touch_end|${id}`); } touch_start_data.delete(isMouseEvent ? 'mouse' : point.identifier); diff --git a/data/js/toggles.js b/data/js/toggles.js index a2a34e3..9c1551f 100644 --- a/data/js/toggles.js +++ b/data/js/toggles.js @@ -20,7 +20,7 @@ function toggle_toggle(toggle_name){ trigger_vibration(20); let resulting_value = configuration[id] ? 1 : 0; - transmit(`set|${toggle_name}|${resulting_value}`); + wstx(`set|${toggle_name}|${resulting_value}`); } } } @@ -116,7 +116,7 @@ function track_toggles() { if(configuration[id] != resulting_value){ configuration[id] = resulting_value; trigger_vibration(20); - transmit(`set|${id}|${resulting_value}`); + wstx(`set|${id}|${resulting_value}`); } //let percentage = ((resulting_value-slider_min) / (slider_max-slider_min)) * 100.0; diff --git a/data/js/websockets_connection.js b/data/js/websockets_connection.js index 5519d41..dd5d810 100644 --- a/data/js/websockets_connection.js +++ b/data/js/websockets_connection.js @@ -1,335 +1,7 @@ -const MAX_PING_PONG_REPLY_TIME_MS = 4000; -const MAX_CONNECTION_TIME_MS = 10000; -const AUTO_RECONNECT = true; - -let ws; -let device_ip; -let connection_start_time; -let connection_pending = false; -let last_ping_time; -let pong_pending = false; -let reconnecting = false; -let standby_mode = false; -let pongs_halted = false; - -let touch_vals = [ - 0, - 0, - 0 -]; - -let touch_low = [ - 0, - 0, - 0 -]; - -let touch_high = [ - 0, - 0, - 0 -]; - -got_touch_vals = true; - -let auto_response_table = { - "welcome" :"get|config", - "config_ready" :"get|modes", - "modes_ready" :"get|sliders", - "sliders_ready":"get|toggles", - "toggles_ready":"get|menu_toggles", - "reload_config":"get|config", -}; - -function check_connection_timeout(){ - if(connection_pending == true){ - if(performance.now() - connection_start_time >= MAX_CONNECTION_TIME_MS){ - console.log("COULDN'T CONNECT TO DEVICE WITHIN TIMEOUT"); - reconnect_websockets(); - } - } -} - -function ping_server(){ - ws.send("ping"); - last_ping_time = performance.now(); - pong_pending = true; -} - -function check_pong_timeout(){ - if(pongs_halted == false){ - if(pong_pending == true){ - if(performance.now() - last_ping_time >= MAX_PING_PONG_REPLY_TIME_MS){ - console.log("NO PONG WITHIN TIMEOUT!"); - reconnect_websockets(); - } - } - } -} - -function set_ui_locked_state(locked_state){ - let dimmer = document.getElementById("dimmer"); - if(locked_state == true){ - dimmer.style.opacity = 1.0; - dimmer.style.pointerEvents = "all"; - //document.getElementById("device_preview").innerHTML = "LOCK"; - } - else{ - dimmer.style.opacity = 0.0; - dimmer.style.pointerEvents = "none"; - //document.getElementById("device_preview").innerHTML = "UNLOCK"; - } -} - -function attempt_auto_response(message){ - let success = false; - try{ - let reply = auto_response_table[message]; - if(reply != undefined){ - console.log(`Auto-reply for message ${message} is: ${reply}`); - transmit( reply ); - success = true; - } - } - catch(e){ - console.log(e); - } - - return success; -} - -function start_noise_calibration(){ - set_ui_locked_state(true); - transmit('noise_cal'); -} - -function start_debug_recording(){ - set_ui_locked_state(true); - transmit('start_debug_recording'); -} - -function sync_data_from_device(){ - transmit("get|config"); // Triggers chain of data sync commands -} - -function parse_message(message){ - if( attempt_auto_response(message) == false){ - // parse reply contents - let command_data = message.split("|"); - let command_type = command_data[0]; - - if(command_type == "clear_config"){ - // Clear client-side config JSON - configuration = {}; - - set_ui_locked_state(true); - } - else if(command_type == "new_config"){ - // Append new config key to client-side config JSON - let config_key_name = command_data[1]; - let config_data_type = command_data[2]; - let config_value_raw = command_data[3]; - let config_value; - - if(config_data_type == "string"){ - config_value = config_value_raw; - } - else if(config_data_type == "float"){ - config_value = parseFloat(config_value_raw); - } - else if(config_data_type == "int"){ - config_value = parseInt(config_value_raw); - } - else{ - console.log(`UNRECOGNIZED CONFIG DATA TYPE: ${config_data_type}`); - } - - configuration[config_key_name] = config_value; - } - else if(command_type == "clear_modes"){ - modes = []; - } - else if(command_type == "new_mode"){ - let mode_index = parseInt(command_data[1]); - let mode_type = parseInt(command_data[2]); - let mode_name = command_data[3]; - - modes.push({ - "mode_index":mode_index, - "mode_type":mode_type, - "mode_name":mode_name - }); - } - else if(command_type == "clear_sliders"){ - // Force close UI if it's open - transmit(`touch_end`); - transmit(`slider_touch_end`); - - sliders = []; - } - else if(command_type == "new_slider"){ - let slider_name = command_data[1]; - let slider_min = parseFloat(command_data[2]); - let slider_max = parseFloat(command_data[3]); - let slider_step = parseFloat(command_data[4]); - - sliders.push({ - "name":slider_name, - "min":slider_min, - "max":slider_max, - "step":slider_step - }); - } - else if(command_type == "clear_toggles"){ - toggles = []; - } - else if(command_type == "new_toggle"){ - let toggle_name = command_data[1]; - - toggles.push({ - "name":toggle_name - }); - } - else if(command_type == "clear_menu_toggles"){ - menu_toggles = []; - } - else if(command_type == "new_menu_toggle"){ - let toggle_name = command_data[1]; - - menu_toggles.push({ - "name":toggle_name - }); - } - else if(command_type == "menu_toggles_ready"){ - //console.log("DATA SYNC COMPLETE!"); - ping_server(); - setInterval(check_pong_timeout, 100); - render_controls(); - //tint_svg_images(); - set_ui_locked_state(false); - } - else if(command_type == "noise_cal_ready"){ - //console.log("NOISE CAL COMPLETE!"); - hide_page('page_calibration'); - set_ui_locked_state(false); - } - else if(command_type == "debug_recording_ready"){ - //console.log("DEBUG RECORDING COMPLETE!"); - hide_page('page_calibration'); - set_ui_locked_state(false); - } - else if(command_type == "fps_cpu"){ - let FPS = command_data[1]; - document.getElementById("CPU_FPS").innerHTML = `CPU FPS: ${FPS}`; - } - else if(command_type == "fps_gpu"){ - let FPS = command_data[1]; - document.getElementById("GPU_FPS").innerHTML = `GPU FPS: ${FPS}`; - } - else if(command_type == "heap"){ - let heap = command_data[1]; - document.getElementById("HEAP").innerHTML = `HEAP: ${heap}`; - } - else if(command_type == "pong"){ - pong_pending = false; - setTimeout(function(){ - ping_server(); - }, MAX_PING_PONG_REPLY_TIME_MS / 2); - } - else if(command_type == "touch_vals"){ - touch_vals[0] = parseInt(command_data[1]); - touch_vals[1] = parseInt(command_data[2]); - touch_vals[2] = parseInt(command_data[3]); - - //console.log(`TOUCH VALS: ${touch_vals}`); - - got_touch_vals = true; - } - else if(command_type == "update_available"){ - pongs_halted = true; - show_alert( - "UPDATE AVAILABLE", - "An update is available for your Emotiscope!

Click below to download the latest firmware.", - "UPDATE NOW", - function(){ - hide_alert(); - transmit("perform_update"); - } - ); - } - else if(command_type == "no_updates"){ - show_alert( - "ALREADY UP-TO-DATE", - "Your Emotiscope is already running the latest firmware!

(But follow @lixielabs on social media to keep yourself up-to-date on new features and improvements that are coming!)", - "DAMN, OK", - function(){ - hide_alert(); - } - ); - } - else if(command_type == "ota_firmware_progress"){ - let progress = parseInt(command_data[1]); - show_alert( - "UPDATE IN PROGRESS", - "Updating firmware: "+progress+"% done.

Do not disconnect your Emotiscope from power or the internet until the update is complete.", - "PLEASE WAIT", - function(){ - // nothing - } - ); - } - else if(command_type == "ota_filesystem_progress"){ - let progress = parseInt(command_data[1]); - if(progress == 100){ - window.location.reload(); - } - show_alert( - "UPDATE IN PROGRESS", - "Updating filesystem: "+progress+"% done.

Do not disconnect your Emotiscope from power or the internet until the update is complete.", - "PLEASE WAIT", - function(){ - // nothing - } - ); - } - else if(command_type == "version"){ - let version = command_data[1]; - document.getElementById("version_number").innerHTML = "Version: "+version; - } - else{ - console.log(`Unrecognized command type: ${command_type}`); - } - } -} - -function set_mode(mode_name){ - transmit(`set|mode|${mode_name}`); -} - -function increment_mode(){ - transmit(`increment_mode`); -} - -function send_slider_change(slider_name){ - let new_value = document.getElementById(slider_name).value; - transmit(`set|${slider_name}|${new_value}`); -} - -function send_toggle_change(toggle_name){ - let new_state = +(document.getElementById(toggle_name).checked); - transmit(`set|${toggle_name}|${new_state}`); -} - -function send_menu_toggle_change(toggle_name){ - let new_state = +(document.getElementById(toggle_name).checked); - transmit(`set|${toggle_name}|${new_state}`); -} - -function transmit(message){ - console.log(`TX: ${message}`); - //document.getElementById("device_preview").innerHTML = message; - ws.send(message); -} +var emotiscope_connected = false; +var ws = null; +var attempt_to_reach_emotiscope_interval = null; +var device_ip = null; // Function to handle touch events on the device icon function setup_top_touch_listener(div_id) { @@ -341,7 +13,7 @@ function setup_top_touch_listener(div_id) { if (touch_active) return; // Ignore if another touch is already active touch_active = true; touch_timer = setTimeout(function() { - transmit('button_hold'); + wstx('button_hold'); trigger_vibration(100); if(standby_mode == false){ @@ -362,7 +34,7 @@ function setup_top_touch_listener(div_id) { device_icon.addEventListener('touchend', function(e) { if (touch_timer) { clearTimeout(touch_timer); // Clear the timer if the touch ends before 500ms - transmit('button_tap'); + wstx('button_tap'); if(standby_mode == true){ standby_mode = false; @@ -373,67 +45,261 @@ function setup_top_touch_listener(div_id) { }); } -function reconnect_websockets(){ - if(reconnecting == false){ - reconnecting = true; - if(AUTO_RECONNECT == true){ - try{ - ws.close(); +function set_ui_locked_state(locked_state){ + let dimmer = document.getElementById("dimmer"); + if(locked_state == true){ + dimmer.style.opacity = 1.0; + dimmer.style.pointerEvents = "all"; + //document.getElementById("device_preview").innerHTML = "LOCK"; + } + else{ + dimmer.style.opacity = 0.0; + dimmer.style.pointerEvents = "none"; + //document.getElementById("device_preview").innerHTML = "UNLOCK"; + } +} + +function set_mode(mode_name){ + wstx(`set|mode|${mode_name}`); +} + +function increment_mode(){ + wstx(`increment_mode`); +} + +function wstx(message){ + ws.send(message); + console.log("TX: " + message); + //add_to_log("TX: " + message); +} + +function wsrx(message){ + console.log("RX: " + message); + //add_to_log("RX: " + message); + + var message_items = message.split("|"); + var message_type = message_items[0]; + + if( message_type == "emotiscope" ){ + emotiscope_connected = true; + clearInterval(attempt_to_reach_emotiscope_interval); + + console.log("EMOTISCOPE CONNECTED"); + document.getElementById("device_nickname").innerHTML = device_ip; + + wstx("get|version"); + wstx("get|config"); + } + else if(message_type == "clear_config"){ + // Clear client-side config JSON + configuration = {}; + + set_ui_locked_state(true); + } + else if(message_type == "new_config"){ + // Append new config key to client-side config JSON + let config_key_name = message_items[1]; + let config_data_type = message_items[2]; + let config_value_raw = message_items[3]; + let config_value; + + if(config_data_type == "string"){ + config_value = config_value_raw; + } + else if(config_data_type == "float"){ + config_value = parseFloat(config_value_raw); + } + else if(config_data_type == "int"){ + config_value = parseInt(config_value_raw); + } + else{ + console.log(`UNRECOGNIZED CONFIG DATA TYPE: ${config_data_type}`); + } + + configuration[config_key_name] = config_value; + } + else if(message_type == "config_ready"){ + wstx("get|modes"); + } + else if(message_type == "clear_modes"){ + modes = []; + } + else if(message_type == "new_mode"){ + let mode_index = parseInt(message_items[1]); + let mode_type = parseInt(message_items[2]); + let mode_name = message_items[3]; + + modes.push({ + "mode_index":mode_index, + "mode_type":mode_type, + "mode_name":mode_name + }); + } + else if(message_type == "modes_ready"){ + wstx("get|sliders"); + } + else if(message_type == "clear_sliders"){ + // Force close UI if it's open + wstx(`touch_end`); + wstx(`slider_touch_end`); + + sliders = []; + } + else if(message_type == "new_slider"){ + let slider_name = message_items[1]; + let slider_min = parseFloat(message_items[2]); + let slider_max = parseFloat(message_items[3]); + let slider_step = parseFloat(message_items[4]); + + sliders.push({ + "name":slider_name, + "min":slider_min, + "max":slider_max, + "step":slider_step + }); + } + else if(message_type == "sliders_ready"){ + wstx("get|toggles"); + } + else if(message_type == "clear_toggles"){ + toggles = []; + } + else if(message_type == "new_toggle"){ + let toggle_name = message_items[1]; + + toggles.push({ + "name":toggle_name + }); + } + else if(message_type == "toggles_ready"){ + wstx("get|menu_toggles"); + } + else if(message_type == "clear_menu_toggles"){ + menu_toggles = []; + } + else if(message_type == "new_menu_toggle"){ + let toggle_name = message_items[1]; + + menu_toggles.push({ + "name":toggle_name + }); + } + else if(message_type == "menu_toggles_ready"){ + //console.log("DATA SYNC COMPLETE!"); + //ping_server(); + //setInterval(check_pong_timeout, 100); + + render_controls(); + set_ui_locked_state(false); + } + else if(message_type == "reload_config"){ + wstx("get|config"); + } + else if(message_type == "fps_cpu"){ + let FPS = message_items[1]; + document.getElementById("CPU_FPS").innerHTML = `CPU FPS: ${FPS}`; + } + else if(message_type == "fps_gpu"){ + let FPS = message_items[1]; + document.getElementById("GPU_FPS").innerHTML = `GPU FPS: ${FPS}`; + } + else if(message_type == "heap"){ + let heap = message_items[1]; + document.getElementById("HEAP").innerHTML = `HEAP: ${heap}`; + } + else if(message_type == "update_available"){ + pongs_halted = true; + show_alert( + "UPDATE AVAILABLE", + "An update is available for your Emotiscope!

Click below to download the latest firmware.", + "UPDATE NOW", + function(){ + hide_alert(); + wstx("perform_update"); + } + ); + } + else if(message_type == "no_updates"){ + show_alert( + "ALREADY UP-TO-DATE", + "Your Emotiscope is already running the latest firmware!

(But follow @lixielabs on social media to keep yourself up-to-date on new features and improvements that are coming!)", + "DAMN, OK", + function(){ + hide_alert(); } - catch(e){ - console.log("ERROR: "+e); + ); + } + else if(message_type == "ota_firmware_progress"){ + let progress = parseInt(message_items[1]); + show_alert( + "UPDATE IN PROGRESS", + "Updating firmware: "+progress+"% done.

Do not disconnect your Emotiscope from power or the internet until the update is complete.", + "PLEASE WAIT", + function(){ + // nothing } - - set_ui_locked_state(true); - setTimeout(function(){ - window.location.reload(); - }, 500); + ); + } + else if(message_type == "ota_filesystem_progress"){ + let progress = parseInt(message_items[1]); + if(progress == 100){ + window.location.reload(); } + show_alert( + "UPDATE IN PROGRESS", + "Updating filesystem: "+progress+"% done.

Do not disconnect your Emotiscope from power or the internet until the update is complete.", + "PLEASE WAIT", + function(){ + // nothing + } + ); + } + else if(message_type == "version"){ + let version = message_items[1]; + document.getElementById("version_number").innerHTML = "Version: "+version; + } + + else{ + console.log("UNRECOGNIZED MESSAGE TYPE: " + message_type); } } -function open_websockets_connection_to_device(){ - device_ip = window.location.hostname; - connection_start_time = performance.now(); - connection_pending = true; - setInterval(check_connection_timeout, 100); +function attempt_to_reach_emotiscope() { + console.log("attempt_to_reach_emotiscope()"); + if(emotiscope_connected == false){ + // Send a message to the server + wstx("emotiscope?"); + } +} - websockets_server = "ws://"+device_ip+":80/ws"; +function connect_to_emotiscope() { + var websockets_server = "ws://"+device_ip+":80/ws"; + console.log("connecting to emotiscope at " + websockets_server); - console.log("CONNECTING TO WS SERVER: "+websockets_server); ws = new WebSocket(websockets_server); - document.getElementById("device_nickname").innerHTML = device_ip; + ws.onopen = function() { + console.log("Websockets connection established"); + emotiscope_connected = false; - ws.onopen = function(e) { - console.log("[open] Connection established"); - connection_pending = false; + attempt_to_reach_emotiscope(); + attempt_to_reach_emotiscope_interval = setInterval(attempt_to_reach_emotiscope, 250); - transmit("get|version"); + setInterval(function(){ + wstx("EMO~stats|CPU-FPS|249.12|GPU-FPS|471.37~config|brightness|float|0.991|slider|softness|float|1.000|slider~modes|0Analog|0Spectrum"); + }, 500); }; ws.onmessage = function(event) { - if(event.data != "pong"){ - //console.log(`RX: ${event.data}`); - } - //document.getElementById("device_preview").innerHTML = event.data; - parse_message(event.data); + wsrx(event.data); }; - ws.onclose = function(event) { - if (event.wasClean) { - console.log(`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`); - } else { - // e.g. server process killed or network down - // event.code is usually 1006 in this case - console.log('[close] Connection died'); - reconnect_websockets(); - } + ws.onclose = function() { + console.log("Websockets connection closed"); }; - ws.onerror = function(error) { - console.log(`[error]`); - reconnect_websockets(); + ws.onerror = function(event) { + console.log("Websockets error: " + event); }; } @@ -445,10 +311,13 @@ function open_websockets_connection_to_device(){ if(first_load == true){ first_load = false; console.log("APP_LOADED websockets_connection.js"); + + device_ip = window.location.hostname; + setup_top_touch_listener("header_logo"); setup_top_touch_listener("device_icon"); - open_websockets_connection_to_device(); + connect_to_emotiscope(); } }); })(); \ No newline at end of file diff --git a/data/remote.html b/data/remote.html index 27644b7..29647a2 100644 --- a/data/remote.html +++ b/data/remote.html @@ -15,7 +15,6 @@ var scripts = [ "js/discovery.js", "js/fetch_mac.js", - "js/touch_calibration.js", "js/info.js", "js/alerts.js", "js/utilities.js", @@ -25,7 +24,6 @@ "js/render_controls.js", "js/websockets_connection.js", "js/pages.js", - "js/spin_ui.js" ]; var loaded_scripts = 0; @@ -128,19 +126,19 @@