/* * Copyright (c) 2019 Clementine Computing LLC. * * This file is part of PopuFare. * * PopuFare is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * PopuFare is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with PopuFare. If not, see . * */ var _ADDRESS = "localhost"; var _URL = "http://" + _ADDRESS; var _PORT = 60535; var _fqADDRESS = _ADDRESS + ":" + _PORT; var BG_COLOR = "#f7f7f7"; var TEXT_COLOR = "#444444"; var DIU_UI_VERSION = "0.1.5"; var DIU_UI_VERSION_DATE = "2019-11-27 13:09:00"; var g_snd = { "reject_fare" : "", "accept_fare" : "", "rule_error" : "", "button_press" : "" }; function _beep_error() { g_snd.rule_error.currentTime=0; g_snd.rule_error.play(); } function _beep_reject() { g_snd.reject_fare.currentTime=0; g_snd.reject_fare.play(); } function _beep_accept() { g_snd.accept_fare.currentTime=0; g_snd.accept_fare.play(); } function _beep() { g_snd.button_press.currentTime=0; g_snd.button_press.play(); } var g_ctx = { "driver_login_state" : "driver", "driver" : "", "pin" : "", "paddle" : "", "current_ui" : "ui_login", "ui_change_timeoutid": -1, "bulkfare" : "", "bulkfare_count" : "", "status_text": "", "status_text_w": 32, "status_text_h": 11, "status_html_text":"", "diu_status" : {}, "x": "" }; function _api_fail() { console.log(">>api fail"); return true; } function _api_tick() { } function _api_request(action, param, cb_ok, cb_fail, cb_neterr) { var idx = 0; var param_name = [], param_val = []; var req = new XMLHttpRequest(); // Firefox gets testy about parsing assumed XML // req.overrideMimeType("text/plain"); var url = "/req"; var varstr = "action=" + action; for (var x in param) { param_name.push(x); param_val.push(param[x]); } for (var ii=0; ii=2) && (resp[0] == "ok")) { if (typeof cb_ok !== "undefined") { cb_ok(fulltxt); } return; } if (typeof cb_fail !== "undefined") { cb_fail(fulltxt); } } else if (typeof cb_fail !== "undefined") { cb_fail(); } } }; req.addEventListener("error", _api_fail); req.addEventListener("abort", _api_fail); //req.addEventListener("load", _api_tick); //req.addEventListener("progress", _api_tick); req.onerror = function() { console.log("network error"); }; try { //DEBUG console.log("req, varstr:", varstr); req.open("POST", url, true); req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); req.send(varstr); } catch (er) { console.log(">>>>>>ERROR", er); } } function _block_status_window(ui_id) { var ele = document.getElementById(ui_id + "_status"); ele.ondragstart = function() { return false; } ele.onselectstart = function() { return false; } ele.onmousedown = function() { return false; } ele.ondragstart = function() { return false; } var rect = ele.getBoundingClientRect(); var block_ele = document.getElementById(ui_id + "_blockwindow"); block_ele.style.width = rect.width; block_ele.style.height = rect.height; block_ele.style.bottom = rect.bottom; block_ele.style.left = rect.left; block_ele.style.top = rect.top; block_ele.style.right = rect.right; block_ele.style.x = rect.x; block_ele.style.y = rect.y; } function _switch_ui(to) { var ele; console.log(">>>to", to); if (g_ctx.ui_change_timeoutid > 0) { window.clearTimeout(g_ctx.ui_change_timeoutid); g_ctx.ui_change_timeoutid = -1; } var from = g_ctx.current_ui; ele = document.getElementById(from); ele.style.display = "none"; ele = document.getElementById(to); ele.style.display = "block"; g_ctx.current_ui = to; if ((to == "ui_main") || (to == "ui_login")) { _block_status_window(to); } } function _hide_ui(from) { var ele = document.getElementById(from); ele.style.display = "none"; } function _hide_ui_element(from) { var ele = document.getElementById(from); ele.style.display = "none"; } function _show_ui(to) { var ele = document.getElementById(to); ele.style.display = "block"; g_ctx.current_ui = to; // put pane over status window to prevent highlights, // copy/pasting, etc. // if ((to == "ui_main") || (to == "ui_login")) { _block_status_window(to); } } function _show_ui_element(to) { var ele = document.getElementById(to); ele.style.display = "block"; } //------------ // volume is from [0,1] // function _process_volume(vol) { var ele = document.getElementById("ui_configuration_displayvolume"); ivol = Math.floor(vol*100.0); ele.innerHTML = "" + ivol + "%"; } function _slider_change(name) { if (name == "configuration.volume") { var val = document.getElementById("ui_configuration_volume").value; _process_volume(val); } } //------------ function _clear_ui_driver() { var ele; var u = ["driver", "pin"]; for (var i=0; i0) && (lon.length>0)) ? (" (" + lat + "/" + lon + ")") : "" ); var ele = document.getElementById("ui_login_status"); var html_a = []; html_a.push("Tunnel: " + has_tunn + " GPRS: " + has_gprs + " Eq#: " + m["equipno"] + " #Msg: " + m["nmsg"]); html_a.push("Last Token Read (" + m["last_token"] + ")"); html_a.push("GPS: " + has_gps + gps_str + ""); html_a.push(" "); html_a.push("Package Version Installed"); html_a.push(_sp("ui") + _sp(DIU_UI_VERSION) + _sp(DIU_UI_VERSION_DATE) + ""); html_a.push(" "); if ("IMEI" in m) { html_a.push("IMEI = " + m["IMEI"] + ""); } if ("IMSI" in m) { html_a.push("IMSI = " + m["IMSI"] + ""); } if ("ETH0" in m) { html_a.push("ETH0 = " + m["ETH0"] + ""); } html_a.push(" "); for (var ii=0; ii
" + div_hdr ) + ""; ele.innerHTML = str; } else if (g_ctx.current_ui === "ui_main") { var ele = document.getElementById("mainstatus"); var str = ""; str += "Rt " + m["route"] + " "; str += "Trip " + m["trip"] + " "; str += "Stop " + m["stop"] + " "; str += "GPS " + m["gps"] + " "; str += "Tun " + m["tunnel"] + ", "; str += m["date"]; str += " " + moment().format("HH:mm"); ele.innerHTML = str; } } function _cb_status_err(e) { console.log("ERROR: _cb_status_err:", e); } //------------- function _main_message_clear() { g_ctx.status_text = ""; } function _main_message_replace(msg, bg_color, text_color) { var ele = document.getElementById("ui_main_status"); bg_color = ((typeof bg_color === "undefined") ? BG_COLOR : bg_color); text_color = ((typeof text_color === "undefined") ? TEXT_COLOR : text_color); var lines = g_ctx.status_text.split("\n"); if (lines.length > g_ctx.status_text_h) { var n = lines.length; lines = lines.slice(n - g_ctx.status_text_h); } for (var i=0; i"; } else if (html_lines[i].match(/REJECT/)) { html_lines[i] = "
" + html_lines[i] + "
"; } else if (html_lines[i].match(/[Uu]nknown/)) { html_lines[i] = "
" + html_lines[i] + "
"; } else if (html_lines[i].match(/[Pp]assback/)) { html_lines[i] = "
" + html_lines[i] + "
"; } else if (html_lines[i].match(/Rule execution error/)) { html_lines[i] = "
" + html_lines[i] + "
"; } else { html_lines[i] = "
" + html_lines[i] + "
"; } } g_ctx.status_text = lines.join("\n"); g_ctx.status_text = lines.join("\n"); g_ctx.status_html_text = html_lines.join("
"); ele.innerHTML = g_ctx.status_html_text; // sounds // if (msg.match(/ACCEPT/)) { _beep_accept(); } else if (msg.match(/REJECT/)) { _beep_reject(); } else if (msg.match(/[Uu]nknown/)) { _beep_reject(); } else if (msg.match(/[Pp]assback/)) { _beep_reject(); } else if (msg.match(/Rule execution error/)) { _beep_error(); } } function _main_message_add(msg, bg_color, text_color) { var ele = document.getElementById("ui_main_status"); bg_color = ((typeof bg_color === "undefined") ? BG_COLOR : bg_color); text_color = ((typeof text_color === "undefined") ? TEXT_COLOR : text_color); var txt = g_ctx.status_text + "\n" + msg; var html_lines = []; var lines = txt.split("\n"); if (lines.length > g_ctx.status_text_h) { var n = lines.length; lines = lines.slice(n - g_ctx.status_text_h); } for (var i=0; i"; } else if (html_lines[i].match(/REJECT/)) { html_lines[i] = "
" + html_lines[i] + "
"; } else if (html_lines[i].match(/[Uu]nknown/)) { html_lines[i] = "
" + html_lines[i] + "
"; } else if (html_lines[i].match(/[Pp]assback/)) { html_lines[i] = "
" + html_lines[i] + "
"; } else if (html_lines[i].match(/Rule execution error/)) { html_lines[i] = "
" + html_lines[i] + "
"; } else { html_lines[i] = "
" + html_lines[i] + "
"; } } g_ctx.status_text = lines.join("\n"); g_ctx.status_html_text = html_lines.join("
"); ele.innerHTML = g_ctx.status_html_text; // sounds // if (msg.match(/ACCEPT/)) { _beep_accept(); } else if (msg.match(/REJECT/)) { _beep_reject(); } else if (msg.match(/[Uu]nknown/)) { _beep_reject(); } else if (msg.match(/[Pp]assback/)) { _beep_reject(); } else if (msg.match(/Rule execution error/)) { _beep_error(); } } //------------- //------------- //------------- function _ws_process(dat) { var tok = dat.split(" "); if (tok.length < 2) { return; } if (tok[0] == "paddle") { if (tok[1] == "ok") { _verify_paddle_ok(); } else if (tok[1] == "fail") { _verify_paddle_fail(); } else { _verify_paddle_fail(); } } else if (tok[0] == "driver_notify") { if (tok.length < 5) { console.log("malformed message: ", dat); } else if (tok[1] == "replace") { _main_message_replace(tok.slice(4).join(" ")); } else if (tok[1] == "ok") { _main_message_add(tok.slice(4).join(" ")); } else { console.log("unknown message: ", dat); } } } function _init_websocket() { var sock = new WebSocket("ws://" + _fqADDRESS); sock.onopen = function(e) { console.log("open", e); } sock.onmessage = function(e) { _ws_process(e.data); } sock.onclose = function(e) { console.log("close", e); } sock.onerror = function(e) { console.log("error", e); } } //------------- var ui_pattern = { "state" : "idle", "lastX" : 0, "lastY" : 0, "curX" : 0, "curY" : 0 }; function ui_pattern_mousedown(ev) { var ele = document.getElementById("body"); var rect = ele.getBoundingClientRect(); var x = ev["x"]; var y = ev["y"]; var width = rect.width; var height = rect.height; if (ui_pattern.state == "idle") { if (y < (height/4)) { ui_pattern.state = "square_0"; } else { ui_pattern.state = "idle" } } else if (ui_pattern.state == "square_0") { if (x > (3*width/4)) { ui_pattern.state = "square_1"; } else { ui_pattern.state = "idle" } } else if (ui_pattern.state == "square_1") { if (y > (3*height/4)) { ui_pattern.state = "square_2"; } else { ui_pattern.state = "idle" } } else if (ui_pattern.state == "square_2") { if (x < (width/4)) { ui_pattern.state = "square_3"; } else { ui_pattern.state = "idle" } } else if (ui_pattern.state == "square_3") { if (y < (height/4)) { ui_pattern.state = "square_4"; } else { ui_pattern.state = "idle" } } else if (ui_pattern.state == "square_4") { if (x > (3*width/4)) { ui_pattern.state = "square_5"; } else { ui_pattern.state = "idle" } } else if (ui_pattern.state == "square_5") { if (y > (3*height/4)) { ui_pattern.state = "square_6"; } else { ui_pattern.state = "idle" } } else if (ui_pattern.state == "square_6") { if (x < (width/4)) { _switch_ui("ui_diagnostic"); } ui_pattern.state = "idle" } return false; } function ui_pattern_mouseup(ev) { return false; } //------------ function _mainscreen() { _switch_ui('ui_login'); g_ctx.driver_login_state = "driver"; _clear_ui_driver(); _clear_ui_paddle(); } function _configuration() { _switch_ui('ui_configuration'); g_ctx.driver_login_state = "driver"; _clear_ui_driver(); _clear_ui_paddle(); } function _reset() { _switch_ui('ui_login'); g_ctx.driver_login_state = "driver"; _clear_ui_driver(); _clear_ui_paddle(); location.reload(true); } function _reboot() { _switch_ui('ui_login'); g_ctx.driver_login_state = "driver"; _clear_ui_driver(); _clear_ui_paddle(); } function _custom0() { _switch_ui('ui_login'); g_ctx.driver_login_state = "driver"; _clear_ui_driver(); _clear_ui_paddle(); } function _custom1() { _switch_ui('ui_login'); g_ctx.driver_login_state = "driver"; _clear_ui_driver(); _clear_ui_paddle(); } function _custom2() { _switch_ui('ui_login'); g_ctx.driver_login_state = "driver"; _clear_ui_driver(); _clear_ui_paddle(); } //------------ //------------- function init() { _init_websocket(); // diagnostics // document.getElementById('ui_diagnostic_mainscreen').onclick = _mainscreen; document.getElementById('ui_diagnostic_reset').onclick = _reset; document.getElementById('ui_diagnostic_reboot').onclick = _reboot; document.getElementById('ui_diagnostic_custom0').onclick = _custom0; document.getElementById('ui_diagnostic_custom1').onclick = _custom1; document.getElementById('ui_diagnostic_custom2').onclick = _custom2; // configuration // document.getElementById('ui_configuration_back').onclick = _mainscreen; // login // document.getElementById('ui_login_login').onclick = _login; document.getElementById('ui_login_configuration').onclick = _configuration; document.getElementById('ui_driverincorrect_btn').onclick = _driver_incorrect; document.getElementById('ui_paddleunknown_btn').onclick = _paddle_unknown;; // main menu buttons // document.getElementById('ui_main_prv').onclick = _main_prv; document.getElementById('ui_main_nxt').onclick = _main_nxt; document.getElementById('ui_main_bulk').onclick = _main_bulk; document.getElementById('ui_main_menu').onclick = _main_menu; document.getElementById('ui_main_dim').onclick = _main_dim; // dim // document.getElementById('ui_dim_btn').onclick = _dim_wakeup; var simple_fares = [ "adult", "youth", "half", "bike", "wheelchair", "transfer"]; var simple_fares_f = [ _fare_adult, _fare_youth, _fare_half, _fare_bike, _fare_wheelchair, _fare_transfer]; for (var ii=0; ii 0)) { bulk_pass = BULK_PASS; } if ((typeof BULK_RULE !== "undefined") && (BULK_RULE.length > 0)) { bulk_rule= BULK_RULE; } if ((typeof BULK_PASS_NAME !== "undefined") && (BULK_PASS_NAME.length > 0)) { bulk_pass_name = BULK_PASS_NAME; } for (var i=0; i 0)) { override_pass = OVERRIDE_PASS; } if ((typeof OVERRIDE_RULE !== "undefined") && (OVERRIDE_RULE.length > 0)) { override_rule= OVERRIDE_RULE; } for (var i=0; i