From 1b34360b0515bb1559224ccbc4122e70506e71a8 Mon Sep 17 00:00:00 2001 From: Sergey Lyubka Date: Sat, 18 Jun 2022 11:30:44 +0100 Subject: [PATCH] Update uart bridge --- examples/uart-bridge/net.c | 61 ++- examples/uart-bridge/packed_fs.c | 747 ++++++++++++++------------ examples/uart-bridge/web_root/main.js | 70 +-- 3 files changed, 480 insertions(+), 398 deletions(-) diff --git a/examples/uart-bridge/net.c b/examples/uart-bridge/net.c index 9ca9b18f..e9b792cb 100644 --- a/examples/uart-bridge/net.c +++ b/examples/uart-bridge/net.c @@ -44,6 +44,14 @@ void uart_write(const void *buf, size_t len) { int uart_read(char *buf, size_t len) { return read(0, buf, len); // Read from stdin } + +char *config_read(void) { + return mg_file_read(&mg_fs_posix, "config.json", NULL); +} + +void config_write(struct mg_str config) { + mg_file_write(&mg_fs_posix, "config.json", config.ptr, config.len); +} #endif // Event handler for a connected Websocket client @@ -77,16 +85,11 @@ static void tcp_fn(struct mg_connection *c, int ev, void *evd, void *fnd) { (void) fnd, (void) evd; } -// Extract RX topic name from the MQTT address -static struct mg_str mqtt_rx_topic(void) { - char *url = s_state.mqtt.url, *p = strrchr(url, ','); - return mg_str(p ? p : "b/rx"); -} - -// Extract TX topic name from the MQTT address -static struct mg_str mqtt_tx_topic(void) { - char *url = s_state.mqtt.url, *p1 = strchr(url, ','), *p2 = strrchr(url, ','); - return mg_str_n(p1 && p2 ? p1 : "b/tx", p1 && p2 ? p2 - p1 + 1 : 4); +// Extract topic name from the MQTT address +static struct mg_str mqtt_topic(const char *name, const char *dflt) { + struct mg_str qs = mg_str(strchr(s_state.mqtt.url, '?')); + struct mg_str v = mg_http_var(qs, mg_str(name)); + return v.ptr == NULL ? mg_str(dflt) : v; } // Event handler for MQTT connection @@ -95,7 +98,7 @@ static void mq_fn(struct mg_connection *c, int ev, void *evd, void *fnd) { // c->is_hexdumping = 1; c->label[0] = 'M'; } else if (ev == MG_EV_MQTT_OPEN) { - mg_mqtt_sub(c, mqtt_rx_topic(), 1); // Subscribe to RX topic + mg_mqtt_sub(c, mqtt_topic("rx", "b/rx"), 1); // Subscribe to RX topic } else if (ev == MG_EV_MQTT_MSG) { struct mg_mqtt_message *mm = evd; // MQTT message uart_write(mm->data.ptr, mm->data.len); // Send to UART @@ -116,7 +119,7 @@ static void timer_fn(void *param) { s_state.websocket.c = mg_http_listen(mgr, s_state.websocket.url, ws_fn, 0); } if (s_state.mqtt.c == NULL && s_state.mqtt.enable) { - struct mg_mqtt_opts opts = {.clean = true, .will_qos = 1}; + struct mg_mqtt_opts opts = {.clean = true}; s_state.mqtt.c = mg_mqtt_connect(mgr, s_state.mqtt.url, &opts, mq_fn, 0); } @@ -129,24 +132,54 @@ static void timer_fn(void *param) { if (c->label[0] == 'W') mg_ws_send(c, buf, len, WEBSOCKET_OP_TEXT); if (c->label[0] == 'T') mg_send(c, buf, len); if (c->label[0] == 'M') - mg_mqtt_pub(c, mqtt_tx_topic(), mg_str_n(buf, len), 1, false); + mg_mqtt_pub(c, mqtt_topic("tx", "b/tx"), mg_str_n(buf, len), 1, false); } } } +static void config_apply(struct mg_str s) { + MG_INFO(("Applying config: %.*s", (int) s.len, s.ptr)); + + mg_json_get_bool(s, "$.tcp.enable", &s_state.tcp.enable); + mg_json_get_bool(s, "$.ws.enable", &s_state.websocket.enable); + mg_json_get_bool(s, "$.mqtt.enable", &s_state.mqtt.enable); + + free(s_state.tcp.url), s_state.tcp.url = mg_json_get_str(s, "$.tcp.url"); + free(s_state.mqtt.url), s_state.mqtt.url = mg_json_get_str(s, "$.mqtt.url"); + free(s_state.websocket.url), + s_state.websocket.url = mg_json_get_str(s, "$.ws.url"); + + double v; + if (mg_json_get_num(s, "$.rx", &v)) s_state.rx = (int) v; + if (mg_json_get_num(s, "$.tx", &v)) s_state.tx = (int) v; + if (mg_json_get_num(s, "$.baud", &v)) s_state.baud = (int) v; + + if (s_state.mqtt.c) s_state.mqtt.c->is_closing = 1; + if (s_state.tcp.c) s_state.tcp.c->is_closing = 1; + if (s_state.websocket.c) s_state.websocket.c->is_closing = 1; +} + // HTTP request handler function void uart_bridge_fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { if (ev == MG_EV_OPEN && c->is_listening) { + char *config = config_read(); + if (config != NULL) config_apply(mg_str(config)); + free(config); s_state.tcp.url = strdup(DEFAULT_TCP); s_state.websocket.url = strdup(DEFAULT_WEBSOCKET); s_state.mqtt.url = strdup(DEFAULT_MQTT); mg_timer_add(c->mgr, 20, MG_TIMER_REPEAT, timer_fn, c->mgr); uart_init(s_state.tx, s_state.rx, s_state.baud); + // mg_log_set("3"); } else if (ev == MG_EV_HTTP_MSG) { struct mg_http_message *hm = (struct mg_http_message *) ev_data; if (mg_http_match_uri(hm, "/api/hi")) { mg_http_reply(c, 200, "", "hi\n"); // Testing endpoint + } else if (mg_http_match_uri(hm, "/api/config/set")) { + config_apply(hm->body); + config_write(hm->body); + mg_http_reply(c, 200, "", "true\n"); } else if (mg_http_match_uri(hm, "/api/config/get")) { mg_http_reply(c, 200, "Content-Type: application/json\r\n", "{%Q:{%Q:%Q,%Q:%s},%Q:{%Q:%Q,%Q:%s},%Q:{%Q:%Q,%Q:%s}," @@ -160,7 +193,7 @@ void uart_bridge_fn(struct mg_connection *c, int ev, void *ev_data, "tx", s_state.tx, "baud", s_state.baud); } else { struct mg_http_serve_opts opts = {0}; -#if 0 +#if 1 opts.root_dir = "/web_root"; opts.fs = &mg_fs_packed; #else diff --git a/examples/uart-bridge/packed_fs.c b/examples/uart-bridge/packed_fs.c index c9663a93..b4a426be 100644 --- a/examples/uart-bridge/packed_fs.c +++ b/examples/uart-bridge/packed_fs.c @@ -78,144 +78,187 @@ static const unsigned char v2[] = { 99, 111, 110, 115, 116, 32, 91, 119, 115, 44, 32, 115, // const [ws, s 101, 116, 87, 115, 93, 32, 61, 32, 117, 115, 101, 83, // etWs] = useS 116, 97, 116, 101, 40, 110, 117, 108, 108, 41, 59, 10, // tate(null);. - 32, 32, 99, 111, 110, 115, 116, 32, 91, 114, 120, 44, // const [rx, - 32, 115, 101, 116, 82, 120, 93, 32, 61, 32, 117, 115, // setRx] = us - 101, 83, 116, 97, 116, 101, 40, 39, 39, 41, 59, 10, // eState('');. - 32, 32, 99, 111, 110, 115, 116, 32, 91, 116, 120, 44, // const [tx, - 32, 115, 101, 116, 84, 120, 93, 32, 61, 32, 117, 115, // setTx] = us - 101, 83, 116, 97, 116, 101, 40, 39, 39, 41, 59, 10, // eState('');. - 32, 32, 99, 111, 110, 115, 116, 32, 91, 98, 97, 117, // const [bau - 100, 44, 32, 115, 101, 116, 66, 97, 117, 100, 93, 32, // d, setBaud] - 61, 32, 117, 115, 101, 83, 116, 97, 116, 101, 40, 39, // = useState(' - 39, 41, 59, 10, 32, 32, 99, 111, 110, 115, 116, 32, // ');. const - 91, 116, 99, 112, 112, 111, 114, 116, 44, 32, 115, 101, // [tcpport, se - 116, 84, 99, 112, 112, 111, 114, 116, 93, 32, 61, 32, // tTcpport] = - 117, 115, 101, 83, 116, 97, 116, 101, 40, 52, 48, 48, // useState(400 - 49, 41, 59, 10, 32, 32, 99, 111, 110, 115, 116, 32, // 1);. const - 91, 119, 115, 112, 111, 114, 116, 44, 32, 115, 101, 116, // [wsport, set - 87, 115, 112, 111, 114, 116, 93, 32, 61, 32, 117, 115, // Wsport] = us - 101, 83, 116, 97, 116, 101, 40, 52, 48, 48, 50, 41, // eState(4002) - 59, 10, 32, 32, 99, 111, 110, 115, 116, 32, 91, 109, // ;. const [m - 113, 116, 116, 44, 32, 115, 101, 116, 77, 113, 116, 116, // qtt, setMqtt - 93, 32, 61, 32, 117, 115, 101, 83, 116, 97, 116, 101, // ] = useState - 40, 39, 39, 41, 59, 10, 10, 32, 32, 47, 47, 32, // ('');.. // - 99, 111, 110, 115, 116, 32, 116, 99, 112, 95, 112, 111, // const tcp_po - 114, 116, 32, 61, 32, 99, 102, 103, 46, 116, 99, 112, // rt = cfg.tcp - 46, 115, 112, 108, 105, 116, 40, 39, 58, 39, 41, 91, // .split(':')[ - 50, 93, 32, 124, 124, 32, 52, 48, 48, 49, 59, 10, // 2] || 4001;. - 32, 32, 47, 47, 32, 99, 111, 110, 115, 116, 32, 119, // // const w - 115, 95, 112, 111, 114, 116, 32, 61, 32, 99, 102, 103, // s_port = cfg - 46, 119, 115, 46, 115, 112, 108, 105, 116, 40, 39, 58, // .ws.split(': - 39, 41, 91, 50, 93, 32, 124, 124, 32, 52, 48, 48, // ')[2] || 400 - 50, 59, 10, 10, 32, 32, 99, 111, 110, 115, 116, 32, // 2;.. const - 114, 101, 102, 114, 101, 115, 104, 32, 61, 32, 40, 41, // refresh = () - 32, 61, 62, 32, 102, 101, 116, 99, 104, 40, 39, 47, // => fetch('/ - 97, 112, 105, 47, 99, 111, 110, 102, 105, 103, 47, 103, // api/config/g - 101, 116, 39, 41, 46, 116, 104, 101, 110, 40, 114, 32, // et').then(r - 61, 62, 32, 114, 46, 106, 115, 111, 110, 40, 41, 41, // => r.json()) - 46, 116, 104, 101, 110, 40, 114, 32, 61, 62, 32, 123, // .then(r => { - 10, 32, 32, 32, 32, 115, 101, 116, 84, 120, 40, 114, // . setTx(r - 46, 116, 120, 41, 44, 32, 115, 101, 116, 82, 120, 40, // .tx), setRx( - 114, 46, 114, 120, 41, 44, 32, 115, 101, 116, 66, 97, // r.rx), setBa - 117, 100, 40, 114, 46, 98, 97, 117, 100, 41, 44, 32, // ud(r.baud), - 115, 101, 116, 67, 102, 103, 40, 114, 41, 59, 10, 32, // setCfg(r);. - 32, 32, 32, 115, 101, 116, 84, 99, 112, 112, 111, 114, // setTcppor - 116, 40, 114, 46, 116, 99, 112, 46, 117, 114, 108, 46, // t(r.tcp.url. - 115, 112, 108, 105, 116, 40, 39, 58, 39, 41, 91, 50, // split(':')[2 - 93, 32, 124, 124, 32, 52, 48, 48, 49, 41, 59, 10, // ] || 4001);. - 32, 32, 32, 32, 115, 101, 116, 87, 115, 112, 111, 114, // setWspor - 116, 40, 114, 46, 119, 115, 46, 117, 114, 108, 46, 115, // t(r.ws.url.s - 112, 108, 105, 116, 40, 39, 58, 39, 41, 91, 50, 93, // plit(':')[2] - 32, 124, 124, 32, 52, 48, 48, 50, 41, 59, 10, 32, // || 4002);. - 32, 32, 32, 115, 101, 116, 77, 113, 116, 116, 40, 114, // setMqtt(r - 46, 109, 113, 116, 116, 46, 117, 114, 108, 41, 59, 10, // .mqtt.url);. - 32, 32, 125, 41, 59, 10, 10, 32, 32, 99, 111, 110, // });.. con - 115, 116, 32, 119, 97, 116, 99, 104, 87, 101, 98, 115, // st watchWebs - 111, 99, 107, 101, 116, 32, 61, 32, 102, 117, 110, 99, // ocket = func - 116, 105, 111, 110, 40, 41, 32, 123, 10, 32, 32, 32, // tion() {. - 32, 47, 47, 32, 67, 111, 110, 110, 101, 99, 116, 32, // // Connect - 116, 111, 32, 119, 101, 98, 115, 111, 99, 107, 101, 114, // to websocker - 32, 112, 111, 114, 116, 44, 32, 116, 111, 32, 105, 109, // port, to im - 112, 108, 101, 109, 101, 110, 116, 32, 87, 83, 32, 99, // plement WS c - 111, 110, 115, 111, 108, 101, 10, 32, 32, 32, 32, 118, // onsole. v - 97, 114, 32, 114, 101, 99, 111, 110, 110, 101, 99, 116, // ar reconnect - 32, 61, 32, 102, 117, 110, 99, 116, 105, 111, 110, 40, // = function( - 41, 32, 123, 10, 32, 32, 32, 32, 32, 32, 118, 97, // ) {. va - 114, 32, 112, 111, 114, 116, 59, 10, 32, 32, 32, 32, // r port;. - 32, 32, 115, 101, 116, 87, 115, 112, 111, 114, 116, 40, // setWsport( - 120, 32, 61, 62, 32, 112, 111, 114, 116, 32, 61, 32, // x => port = - 120, 41, 59, 10, 32, 32, 32, 32, 32, 32, 118, 97, // x);. va - 114, 32, 108, 32, 61, 32, 119, 105, 110, 100, 111, 119, // r l = window - 46, 108, 111, 99, 97, 116, 105, 111, 110, 44, 32, 112, // .location, p - 114, 111, 116, 111, 32, 61, 32, 108, 46, 112, 114, 111, // roto = l.pro - 116, 111, 99, 111, 108, 46, 114, 101, 112, 108, 97, 99, // tocol.replac - 101, 40, 39, 104, 116, 116, 112, 39, 44, 32, 39, 119, // e('http', 'w - 115, 39, 41, 59, 10, 32, 32, 32, 32, 32, 32, 118, // s');. v - 97, 114, 32, 116, 105, 100, 44, 32, 117, 114, 108, 32, // ar tid, url - 61, 32, 96, 36, 123, 112, 114, 111, 116, 111, 125, 47, // = `${proto}/ - 47, 36, 123, 108, 46, 104, 111, 115, 116, 110, 97, 109, // /${l.hostnam - 101, 125, 58, 36, 123, 112, 111, 114, 116, 125, 47, 119, // e}:${port}/w - 115, 96, 59, 10, 32, 32, 32, 32, 32, 32, 47, 47, // s`;. // - 32, 99, 111, 110, 115, 111, 108, 101, 46, 108, 111, 103, // console.log - 40, 117, 114, 108, 41, 59, 10, 32, 32, 32, 32, 32, // (url);. - 32, 118, 97, 114, 32, 119, 115, 32, 61, 32, 110, 101, // var ws = ne - 119, 32, 87, 101, 98, 83, 111, 99, 107, 101, 116, 40, // w WebSocket( - 117, 114, 108, 41, 59, 10, 32, 32, 32, 32, 32, 32, // url);. - 119, 115, 46, 111, 110, 111, 112, 101, 110, 32, 61, 32, // ws.onopen = - 40, 41, 32, 61, 62, 32, 123, 10, 32, 32, 32, 32, // () => {. - 32, 32, 32, 32, 115, 101, 116, 67, 111, 110, 110, 101, // setConne - 99, 116, 101, 100, 40, 116, 114, 117, 101, 41, 59, 10, // cted(true);. - 32, 32, 32, 32, 32, 32, 32, 32, 115, 101, 116, 87, // setW - 115, 40, 119, 115, 41, 59, 10, 32, 32, 32, 32, 32, // s(ws);. - 32, 125, 59, 10, 32, 32, 32, 32, 32, 32, 119, 115, // };. ws - 46, 111, 110, 109, 101, 115, 115, 97, 103, 101, 32, 61, // .onmessage = - 32, 101, 118, 32, 61, 62, 32, 123, 10, 32, 32, 32, // ev => {. - 32, 32, 32, 32, 32, 47, 47, 32, 99, 111, 110, 115, // // cons - 111, 108, 101, 46, 108, 111, 103, 40, 101, 118, 44, 32, // ole.log(ev, - 101, 118, 46, 100, 97, 116, 97, 41, 59, 10, 32, 32, // ev.data);. - 32, 32, 32, 32, 32, 32, 115, 101, 116, 77, 101, 115, // setMes + 10, 32, 32, 99, 111, 110, 115, 116, 32, 114, 101, 102, // . const ref + 114, 101, 115, 104, 32, 61, 32, 40, 41, 32, 61, 62, // resh = () => + 10, 32, 32, 32, 32, 32, 32, 102, 101, 116, 99, 104, // . fetch + 40, 39, 47, 97, 112, 105, 47, 99, 111, 110, 102, 105, // ('/api/confi + 103, 47, 103, 101, 116, 39, 41, 46, 116, 104, 101, 110, // g/get').then + 40, 114, 32, 61, 62, 32, 114, 46, 106, 115, 111, 110, // (r => r.json + 40, 41, 41, 46, 116, 104, 101, 110, 40, 114, 32, 61, // ()).then(r = + 62, 32, 115, 101, 116, 67, 102, 103, 40, 114, 41, 41, // > setCfg(r)) + 59, 10, 10, 32, 32, 99, 111, 110, 115, 116, 32, 103, // ;.. const g + 101, 116, 112, 111, 114, 116, 32, 61, 32, 40, 117, 114, // etport = (ur + 108, 44, 32, 118, 41, 32, 61, 62, 32, 40, 40, 117, // l, v) => ((u + 114, 108, 32, 124, 124, 32, 39, 39, 41, 46, 109, 97, // rl || '').ma + 116, 99, 104, 40, 47, 46, 42, 58, 40, 92, 100, 43, // tch(/.*:(.d+ + 41, 47, 41, 32, 124, 124, 32, 91, 39, 39, 44, 32, // )/) || ['', + 118, 93, 41, 91, 49, 93, 59, 10, 10, 32, 32, 99, // v])[1];.. c + 111, 110, 115, 116, 32, 119, 97, 116, 99, 104, 87, 101, // onst watchWe + 98, 115, 111, 99, 107, 101, 116, 32, 61, 32, 102, 117, // bsocket = fu + 110, 99, 116, 105, 111, 110, 40, 41, 32, 123, 10, 32, // nction() {. + 32, 32, 32, 47, 47, 32, 67, 111, 110, 110, 101, 99, // // Connec + 116, 32, 116, 111, 32, 119, 101, 98, 115, 111, 99, 107, // t to websock + 101, 114, 32, 112, 111, 114, 116, 44, 32, 116, 111, 32, // er port, to + 105, 109, 112, 108, 101, 109, 101, 110, 116, 32, 87, 83, // implement WS + 32, 99, 111, 110, 115, 111, 108, 101, 10, 32, 32, 32, // console. + 32, 118, 97, 114, 32, 114, 101, 99, 111, 110, 110, 101, // var reconne + 99, 116, 32, 61, 32, 102, 117, 110, 99, 116, 105, 111, // ct = functio + 110, 40, 41, 32, 123, 10, 32, 32, 32, 32, 32, 32, // n() {. + 118, 97, 114, 32, 112, 111, 114, 116, 32, 61, 32, 103, // var port = g + 101, 116, 112, 111, 114, 116, 40, 99, 102, 103, 46, 119, // etport(cfg.w + 115, 46, 117, 114, 108, 44, 32, 52, 48, 48, 50, 41, // s.url, 4002) + 59, 10, 32, 32, 32, 32, 32, 32, 118, 97, 114, 32, // ;. var + 108, 32, 61, 32, 119, 105, 110, 100, 111, 119, 46, 108, // l = window.l + 111, 99, 97, 116, 105, 111, 110, 44, 32, 112, 114, 111, // ocation, pro + 116, 111, 32, 61, 32, 108, 46, 112, 114, 111, 116, 111, // to = l.proto + 99, 111, 108, 46, 114, 101, 112, 108, 97, 99, 101, 40, // col.replace( + 39, 104, 116, 116, 112, 39, 44, 32, 39, 119, 115, 39, // 'http', 'ws' + 41, 59, 10, 32, 32, 32, 32, 32, 32, 118, 97, 114, // );. var + 32, 116, 105, 100, 44, 32, 117, 114, 108, 32, 61, 32, // tid, url = + 96, 36, 123, 112, 114, 111, 116, 111, 125, 47, 47, 36, // `${proto}//$ + 123, 108, 46, 104, 111, 115, 116, 110, 97, 109, 101, 125, // {l.hostname} + 58, 36, 123, 112, 111, 114, 116, 125, 47, 119, 115, 96, // :${port}/ws` + 59, 10, 32, 32, 32, 32, 32, 32, 47, 47, 32, 99, // ;. // c + 111, 110, 115, 111, 108, 101, 46, 108, 111, 103, 40, 117, // onsole.log(u + 114, 108, 41, 59, 10, 32, 32, 32, 32, 32, 32, 118, // rl);. v + 97, 114, 32, 119, 115, 32, 61, 32, 110, 101, 119, 32, // ar ws = new + 87, 101, 98, 83, 111, 99, 107, 101, 116, 40, 117, 114, // WebSocket(ur + 108, 41, 59, 10, 32, 32, 32, 32, 32, 32, 119, 115, // l);. ws + 46, 111, 110, 111, 112, 101, 110, 32, 61, 32, 40, 41, // .onopen = () + 32, 61, 62, 32, 123, 10, 32, 32, 32, 32, 32, 32, // => {. + 32, 32, 115, 101, 116, 67, 111, 110, 110, 101, 99, 116, // setConnect + 101, 100, 40, 116, 114, 117, 101, 41, 59, 10, 32, 32, // ed(true);. + 32, 32, 32, 32, 32, 32, 115, 101, 116, 87, 115, 40, // setWs( + 119, 115, 41, 59, 10, 32, 32, 32, 32, 32, 32, 125, // ws);. } + 59, 10, 32, 32, 32, 32, 32, 32, 119, 115, 46, 111, // ;. ws.o + 110, 109, 101, 115, 115, 97, 103, 101, 32, 61, 32, 101, // nmessage = e + 118, 32, 61, 62, 32, 123, 10, 32, 32, 32, 32, 32, // v => {. + 32, 32, 32, 47, 47, 32, 99, 111, 110, 115, 111, 108, // // consol + 101, 46, 108, 111, 103, 40, 101, 118, 44, 32, 101, 118, // e.log(ev, ev + 46, 100, 97, 116, 97, 41, 59, 10, 32, 32, 32, 32, // .data);. + 32, 32, 32, 32, 115, 101, 116, 77, 101, 115, 115, 97, // setMessa + 103, 101, 115, 40, 120, 32, 61, 62, 32, 120, 46, 99, // ges(x => x.c + 111, 110, 99, 97, 116, 40, 91, 123, 100, 97, 116, 97, // oncat([{data + 58, 32, 101, 118, 46, 100, 97, 116, 97, 44, 32, 117, // : ev.data, u + 97, 114, 116, 58, 32, 116, 114, 117, 101, 125, 93, 41, // art: true}]) + 41, 59, 10, 32, 32, 32, 32, 32, 32, 125, 59, 10, // );. };. + 32, 32, 32, 32, 32, 32, 119, 115, 46, 111, 110, 99, // ws.onc + 108, 111, 115, 101, 32, 61, 32, 102, 117, 110, 99, 116, // lose = funct + 105, 111, 110, 40, 41, 32, 123, 10, 32, 32, 32, 32, // ion() {. + 32, 32, 32, 32, 99, 108, 101, 97, 114, 84, 105, 109, // clearTim + 101, 111, 117, 116, 40, 116, 105, 100, 41, 59, 10, 32, // eout(tid);. + 32, 32, 32, 32, 32, 32, 32, 116, 105, 100, 32, 61, // tid = + 32, 115, 101, 116, 84, 105, 109, 101, 111, 117, 116, 40, // setTimeout( + 114, 101, 99, 111, 110, 110, 101, 99, 116, 44, 32, 49, // reconnect, 1 + 48, 48, 48, 41, 59, 10, 32, 32, 32, 32, 32, 32, // 000);. + 32, 32, 115, 101, 116, 67, 111, 110, 110, 101, 99, 116, // setConnect + 101, 100, 40, 102, 97, 108, 115, 101, 41, 59, 10, 32, // ed(false);. + 32, 32, 32, 32, 32, 32, 32, 115, 101, 116, 87, 115, // setWs + 40, 110, 117, 108, 108, 41, 59, 10, 32, 32, 32, 32, // (null);. + 32, 32, 125, 59, 10, 32, 32, 32, 32, 125, 59, 10, // };. };. + 32, 32, 32, 32, 114, 101, 99, 111, 110, 110, 101, 99, // reconnec + 116, 40, 41, 59, 10, 32, 32, 125, 59, 10, 10, 32, // t();. };.. + 32, 117, 115, 101, 69, 102, 102, 101, 99, 116, 40, 40, // useEffect(( + 41, 32, 61, 62, 32, 123, 10, 32, 32, 32, 32, 114, // ) => {. r + 101, 102, 114, 101, 115, 104, 40, 41, 59, 10, 32, 32, // efresh();. + 32, 32, 119, 97, 116, 99, 104, 87, 101, 98, 115, 111, // watchWebso + 99, 107, 101, 116, 40, 41, 59, 10, 32, 32, 125, 44, // cket();. }, + 32, 91, 93, 41, 59, 10, 10, 10, 32, 32, 99, 111, // []);... co + 110, 115, 116, 32, 115, 101, 110, 100, 109, 101, 115, 115, // nst sendmess + 97, 103, 101, 32, 61, 32, 101, 118, 32, 61, 62, 32, // age = ev => + 123, 10, 32, 32, 32, 32, 115, 101, 116, 77, 101, 115, // {. setMes 115, 97, 103, 101, 115, 40, 120, 32, 61, 62, 32, 120, // sages(x => x 46, 99, 111, 110, 99, 97, 116, 40, 91, 123, 100, 97, // .concat([{da - 116, 97, 58, 32, 101, 118, 46, 100, 97, 116, 97, 44, // ta: ev.data, - 32, 117, 97, 114, 116, 58, 32, 116, 114, 117, 101, 125, // uart: true} - 93, 41, 41, 59, 10, 32, 32, 32, 32, 32, 32, 125, // ]));. } - 59, 10, 32, 32, 32, 32, 32, 32, 119, 115, 46, 111, // ;. ws.o - 110, 99, 108, 111, 115, 101, 32, 61, 32, 102, 117, 110, // nclose = fun - 99, 116, 105, 111, 110, 40, 41, 32, 123, 10, 32, 32, // ction() {. - 32, 32, 32, 32, 32, 32, 99, 108, 101, 97, 114, 84, // clearT - 105, 109, 101, 111, 117, 116, 40, 116, 105, 100, 41, 59, // imeout(tid); - 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 105, 100, // . tid - 32, 61, 32, 115, 101, 116, 84, 105, 109, 101, 111, 117, // = setTimeou - 116, 40, 114, 101, 99, 111, 110, 110, 101, 99, 116, 44, // t(reconnect, - 32, 49, 48, 48, 48, 41, 59, 10, 32, 32, 32, 32, // 1000);. - 32, 32, 32, 32, 115, 101, 116, 67, 111, 110, 110, 101, // setConne - 99, 116, 101, 100, 40, 102, 97, 108, 115, 101, 41, 59, // cted(false); - 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 101, 116, // . set - 87, 115, 40, 110, 117, 108, 108, 41, 59, 10, 32, 32, // Ws(null);. - 32, 32, 32, 32, 125, 59, 10, 32, 32, 32, 32, 125, // };. } - 59, 10, 32, 32, 32, 32, 114, 101, 99, 111, 110, 110, // ;. reconn - 101, 99, 116, 40, 41, 59, 10, 32, 32, 125, 59, 10, // ect();. };. - 10, 32, 32, 117, 115, 101, 69, 102, 102, 101, 99, 116, // . useEffect - 40, 40, 41, 32, 61, 62, 32, 123, 10, 32, 32, 32, // (() => {. - 32, 114, 101, 102, 114, 101, 115, 104, 40, 41, 59, 10, // refresh();. - 32, 32, 32, 32, 119, 97, 116, 99, 104, 87, 101, 98, // watchWeb - 115, 111, 99, 107, 101, 116, 40, 41, 59, 10, 32, 32, // socket();. - 125, 44, 32, 91, 93, 41, 59, 10, 10, 10, 32, 32, // }, []);... - 99, 111, 110, 115, 116, 32, 115, 101, 110, 100, 109, 101, // const sendme - 115, 115, 97, 103, 101, 32, 61, 32, 101, 118, 32, 61, // ssage = ev = - 62, 32, 123, 10, 32, 32, 32, 32, 115, 101, 116, 77, // > {. setM - 101, 115, 115, 97, 103, 101, 115, 40, 120, 32, 61, 62, // essages(x => - 32, 120, 46, 99, 111, 110, 99, 97, 116, 40, 91, 123, // x.concat([{ - 100, 97, 116, 97, 58, 32, 116, 120, 116, 32, 43, 32, // data: txt + - 39, 92, 110, 39, 44, 32, 117, 97, 114, 116, 58, 32, // '.n', uart: - 102, 97, 108, 115, 101, 125, 93, 41, 41, 59, 10, 32, // false}]));. - 32, 32, 32, 105, 102, 32, 40, 119, 115, 41, 32, 119, // if (ws) w - 115, 46, 115, 101, 110, 100, 40, 116, 120, 116, 32, 43, // s.send(txt + - 32, 39, 92, 110, 39, 41, 59, 10, 32, 32, 32, 32, // '.n');. - 115, 101, 116, 84, 120, 116, 40, 39, 39, 41, 59, 10, // setTxt('');. - 32, 32, 125, 59, 10, 10, 32, 32, 99, 111, 110, 115, // };.. cons - 116, 32, 111, 110, 99, 104, 97, 110, 103, 101, 32, 61, // t onchange = - 32, 101, 118, 32, 61, 62, 32, 102, 97, 108, 115, 101, // ev => false + 116, 97, 58, 32, 116, 120, 116, 32, 43, 32, 39, 92, // ta: txt + '. + 110, 39, 44, 32, 117, 97, 114, 116, 58, 32, 102, 97, // n', uart: fa + 108, 115, 101, 125, 93, 41, 41, 59, 10, 32, 32, 32, // lse}]));. + 32, 105, 102, 32, 40, 119, 115, 41, 32, 119, 115, 46, // if (ws) ws. + 115, 101, 110, 100, 40, 116, 120, 116, 32, 43, 32, 39, // send(txt + ' + 92, 110, 39, 41, 59, 10, 32, 32, 32, 32, 115, 101, // .n');. se + 116, 84, 120, 116, 40, 39, 39, 41, 59, 10, 32, 32, // tTxt('');. + 125, 59, 10, 10, 32, 32, 99, 111, 110, 115, 116, 32, // };.. const + 111, 110, 99, 104, 97, 110, 103, 101, 32, 61, 32, 101, // onchange = e + 118, 32, 61, 62, 32, 102, 101, 116, 99, 104, 40, 39, // v => fetch(' + 47, 97, 112, 105, 47, 99, 111, 110, 102, 105, 103, 47, // /api/config/ + 115, 101, 116, 39, 44, 32, 123, 10, 32, 32, 32, 32, // set', {. + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 109, // m + 101, 116, 104, 111, 100, 58, 32, 39, 80, 79, 83, 84, // ethod: 'POST + 39, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, // ',. + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // + 32, 32, 32, 32, 32, 32, 104, 101, 97, 100, 101, 114, // header + 115, 58, 32, 123, 39, 67, 111, 110, 116, 101, 110, 116, // s: {'Content + 45, 84, 121, 112, 101, 39, 58, 32, 39, 97, 112, 112, // -Type': 'app + 108, 105, 99, 97, 116, 105, 111, 110, 47, 106, 115, 111, // lication/jso + 110, 39, 125, 44, 10, 32, 32, 32, 32, 32, 32, 32, // n'},. + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // + 32, 32, 32, 32, 32, 32, 32, 32, 98, 111, 100, 121, // body + 58, 32, 74, 83, 79, 78, 46, 115, 116, 114, 105, 110, // : JSON.strin + 103, 105, 102, 121, 40, 99, 102, 103, 41, 44, 10, 32, // gify(cfg),. + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // + 125, 41, 46, 116, 104, 101, 110, 40, 114, 32, 61, 62, // }).then(r => + 32, 119, 115, 32, 38, 38, 32, 119, 115, 46, 99, 108, // ws && ws.cl + 111, 115, 101, 40, 41, 41, 59, 10, 10, 32, 32, 99, // ose());.. c + 111, 110, 115, 116, 32, 115, 101, 116, 32, 61, 32, 111, // onst set = o + 98, 106, 32, 61, 62, 32, 115, 101, 116, 67, 102, 103, // bj => setCfg + 40, 120, 32, 61, 62, 32, 79, 98, 106, 101, 99, 116, // (x => Object + 46, 97, 115, 115, 105, 103, 110, 40, 120, 44, 32, 111, // .assign(x, o + 98, 106, 41, 41, 59, 10, 32, 32, 99, 111, 110, 115, // bj));. cons + 116, 32, 115, 101, 116, 84, 120, 32, 61, 32, 101, 118, // t setTx = ev + 32, 61, 62, 32, 115, 101, 116, 40, 123, 116, 120, 58, // => set({tx: + 32, 112, 97, 114, 115, 101, 73, 110, 116, 40, 101, 118, // parseInt(ev + 46, 116, 97, 114, 103, 101, 116, 46, 118, 97, 108, 117, // .target.valu + 101, 41, 125, 41, 59, 10, 32, 32, 99, 111, 110, 115, // e)});. cons + 116, 32, 115, 101, 116, 82, 120, 32, 61, 32, 101, 118, // t setRx = ev + 32, 61, 62, 32, 115, 101, 116, 40, 123, 114, 120, 58, // => set({rx: + 32, 112, 97, 114, 115, 101, 73, 110, 116, 40, 101, 118, // parseInt(ev + 46, 116, 97, 114, 103, 101, 116, 46, 118, 97, 108, 117, // .target.valu + 101, 41, 125, 41, 59, 10, 32, 32, 99, 111, 110, 115, // e)});. cons + 116, 32, 115, 101, 116, 66, 97, 117, 100, 32, 61, 32, // t setBaud = + 101, 118, 32, 61, 62, 32, 115, 101, 116, 40, 123, 98, // ev => set({b + 97, 117, 100, 58, 32, 112, 97, 114, 115, 101, 73, 110, // aud: parseIn + 116, 40, 101, 118, 46, 116, 97, 114, 103, 101, 116, 46, // t(ev.target. + 118, 97, 108, 117, 101, 41, 125, 41, 59, 10, 32, 32, // value)});. + 99, 111, 110, 115, 116, 32, 115, 101, 116, 84, 99, 112, // const setTcp + 85, 114, 108, 32, 61, 32, 101, 118, 32, 61, 62, 32, // Url = ev => + 115, 101, 116, 40, 123, 116, 99, 112, 58, 32, 123, 117, // set({tcp: {u + 114, 108, 58, 32, 96, 116, 99, 112, 58, 47, 47, 48, // rl: `tcp://0 + 46, 48, 46, 48, 46, 48, 58, 36, 123, 101, 118, 46, // .0.0.0:${ev. + 116, 97, 114, 103, 101, 116, 46, 118, 97, 108, 117, 101, // target.value + 125, 96, 125, 125, 41, 59, 10, 32, 32, 99, 111, 110, // }`}});. con + 115, 116, 32, 115, 101, 116, 87, 115, 85, 114, 108, 32, // st setWsUrl + 61, 32, 101, 118, 32, 61, 62, 32, 115, 101, 116, 40, // = ev => set( + 123, 119, 115, 58, 32, 123, 117, 114, 108, 58, 32, 96, // {ws: {url: ` + 119, 115, 58, 47, 47, 48, 46, 48, 46, 48, 46, 48, // ws://0.0.0.0 + 58, 36, 123, 101, 118, 46, 116, 97, 114, 103, 101, 116, // :${ev.target + 46, 118, 97, 108, 117, 101, 125, 96, 125, 125, 41, 59, // .value}`}}); + 10, 32, 32, 99, 111, 110, 115, 116, 32, 115, 101, 116, // . const set + 77, 113, 116, 116, 85, 114, 108, 32, 61, 32, 101, 118, // MqttUrl = ev + 32, 61, 62, 32, 115, 101, 116, 40, 123, 109, 113, 116, // => set({mqt + 116, 58, 32, 123, 117, 114, 108, 58, 32, 101, 118, 46, // t: {url: ev. + 116, 97, 114, 103, 101, 116, 46, 118, 97, 108, 117, 101, // target.value + 125, 125, 41, 59, 10, 32, 32, 99, 111, 110, 115, 116, // }});. const + 32, 115, 101, 116, 84, 99, 112, 69, 110, 97, 32, 61, // setTcpEna = + 32, 101, 118, 32, 61, 62, 32, 40, 115, 101, 116, 40, // ev => (set( + 123, 116, 99, 112, 58, 32, 123, 101, 110, 97, 98, 108, // {tcp: {enabl + 101, 58, 32, 101, 118, 46, 116, 97, 114, 103, 101, 116, // e: ev.target + 46, 99, 104, 101, 99, 107, 101, 100, 125, 125, 41, 44, // .checked}}), + 32, 111, 110, 99, 104, 97, 110, 103, 101, 40, 41, 41, // onchange()) + 59, 10, 32, 32, 99, 111, 110, 115, 116, 32, 115, 101, // ;. const se + 116, 87, 115, 69, 110, 97, 32, 61, 32, 101, 118, 32, // tWsEna = ev + 61, 62, 32, 40, 115, 101, 116, 40, 123, 119, 115, 58, // => (set({ws: + 32, 123, 101, 110, 97, 98, 108, 101, 58, 32, 101, 118, // {enable: ev + 46, 116, 97, 114, 103, 101, 116, 46, 99, 104, 101, 99, // .target.chec + 107, 101, 100, 125, 125, 41, 44, 32, 111, 110, 99, 104, // ked}}), onch + 97, 110, 103, 101, 40, 41, 41, 59, 10, 32, 32, 99, // ange());. c + 111, 110, 115, 116, 32, 115, 101, 116, 77, 113, 116, 116, // onst setMqtt + 69, 110, 97, 32, 61, 32, 101, 118, 32, 61, 62, 10, // Ena = ev =>. + 32, 32, 32, 32, 32, 32, 40, 115, 101, 116, 40, 123, // (set({ + 109, 113, 116, 116, 58, 32, 123, 101, 110, 97, 98, 108, // mqtt: {enabl + 101, 58, 32, 101, 118, 46, 116, 97, 114, 103, 101, 116, // e: ev.target + 46, 99, 104, 101, 99, 107, 101, 100, 125, 125, 41, 44, // .checked}}), + 32, 111, 110, 99, 104, 97, 110, 103, 101, 40, 41, 41, // onchange()) 59, 10, 10, 32, 32, 114, 101, 116, 117, 114, 110, 32, // ;.. return 104, 116, 109, 108, 96, 10, 60, 100, 105, 118, 32, 99, // html`.
set - 84, 120, 40, 101, 118, 46, 116, 97, 114, 103, 101, 116, // Tx(ev.target - 46, 118, 97, 108, 117, 101, 41, 125, 32, 47, 62, 10, // .value)} />. - 32, 32, 32, 32, 32, 32, 60, 47, 100, 105, 118, 62, //
- 60, 100, 105, 118, 32, 99, 108, 97, 115, 115, 61, 34, //
. - 32, 32, 32, 60, 108, 97, 98, 101, 108, 32, 99, 108, //
. + 32, 32, 32, 60, 100, 105, 118, 32, 99, 108, 97, 115, //
.

Network con + 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 60, 47, // figuration. . + 32, 32, 32, 32, 32, 32, 32, 32, 60, 108, 97, 98, // Local T + 67, 80, 32, 112, 111, 114, 116, 60, 47, 108, 97, 98, // CP port. + 60, 105, 110, 112, 117, 116, 32, 115, 116, 121, 108, 101, // setRx( - 101, 118, 46, 116, 97, 114, 103, 101, 116, 46, 118, 97, // ev.target.va - 108, 117, 101, 41, 125, 32, 47, 62, 10, 32, 32, 32, // lue)} />. - 32, 32, 32, 60, 47, 100, 105, 118, 62, 60, 100, 105, //

. - 60, 108, 97, 98, 101, 108, 32, 99, 108, 97, 115, 115, // . + 32, 32, 32, 32, 60, 47, 100, 105, 118, 62, 60, 100, // . + 32, 32, 32, 32, 32, 32, 32, 32, 60, 108, 97, 98, // Local W + 83, 32, 112, 111, 114, 116, 60, 47, 108, 97, 98, 101, // S port. < 105, 110, 112, 117, 116, 32, 115, 116, 121, 108, 101, 61, // input style= - 34, 119, 105, 100, 116, 104, 58, 32, 53, 101, 109, 59, // "width: 5em; - 34, 32, 118, 97, 108, 117, 101, 61, 36, 123, 98, 97, // " value=${ba - 117, 100, 125, 32, 111, 110, 99, 104, 97, 110, 103, 101, // ud} onchange - 61, 36, 123, 111, 110, 99, 104, 97, 110, 103, 101, 125, // =${onchange} - 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 111, // . o - 110, 105, 110, 112, 117, 116, 61, 36, 123, 101, 118, 32, // ninput=${ev - 61, 62, 32, 115, 101, 116, 66, 97, 117, 100, 40, 101, // => setBaud(e - 118, 46, 116, 97, 114, 103, 101, 116, 46, 118, 97, 108, // v.target.val - 117, 101, 41, 125, 32, 47, 62, 10, 32, 32, 32, 32, // ue)} />. - 32, 32, 60, 47, 100, 105, 118, 62, 10, 32, 32, 32, // . - 32, 60, 47, 100, 105, 118, 62, 10, 32, 32, 32, 32, // . - 60, 100, 105, 118, 32, 99, 108, 97, 115, 115, 61, 34, //
. - 32, 32, 32, 32, 32, 32, 60, 104, 51, 62, 78, 101, //

Ne - 116, 119, 111, 114, 107, 32, 99, 111, 110, 102, 105, 103, // twork config - 117, 114, 97, 116, 105, 111, 110, 60, 47, 104, 51, 62, // uration

- 10, 32, 32, 32, 32, 32, 32, 60, 100, 105, 118, 32, // .
. - 32, 32, 32, 32, 32, 60, 108, 97, 98, 101, 108, 32, // - 10, 32, 32, 32, 32, 32, 32, 32, 32, 60, 105, 110, // . setT - 99, 112, 112, 111, 114, 116, 40, 101, 118, 46, 116, 97, // cpport(ev.ta - 114, 103, 101, 116, 46, 118, 97, 108, 117, 101, 41, 125, // rget.value)} - 32, 47, 62, 10, 32, 32, 32, 32, 32, 32, 32, 32, // />. - 60, 108, 97, 98, 101, 108, 32, 99, 108, 97, 115, 115, // .
. - 60, 108, 97, 98, 101, 108, 32, 99, 108, 97, 115, 115, //
setMqtt( - 101, 118, 46, 116, 97, 114, 103, 101, 116, 46, 118, 97, // ev.target.va - 108, 117, 101, 41, 125, 32, 47, 62, 10, 32, 32, 32, // lue)} />. - 32, 32, 32, 32, 32, 60, 108, 97, 98, 101, 108, 32, //
. - 32, 60, 47, 100, 105, 118, 62, 10, 32, 32, 60, 47, //
. ..
. Note: - 116, 111, 32, 99, 111, 110, 110, 101, 99, 116, 32, 111, // to connect o - 118, 101, 114, 32, 77, 81, 84, 84, 44, 32, 10, 32, // ver MQTT, . - 32, 32, 32, 32, 32, 103, 111, 32, 116, 111, 32, 60, // go to < - 97, 32, 104, 114, 101, 102, 61, 34, 104, 116, 116, 112, // a href="http - 58, 47, 47, 119, 119, 119, 46, 104, 105, 118, 101, 109, // ://www.hivem - 113, 46, 99, 111, 109, 47, 100, 101, 109, 111, 115, 47, // q.com/demos/ - 119, 101, 98, 115, 111, 99, 107, 101, 116, 45, 99, 108, // websocket-cl - 105, 101, 110, 116, 47, 34, 62, 10, 32, 32, 32, 32, // ient/">. - 32, 32, 32, 32, 99, 111, 110, 115, 111, 108, 101, 60, // console< - 47, 97, 62, 44, 32, 115, 117, 98, 115, 99, 114, 105, // /a>, subscri - 98, 101, 32, 116, 111, 32, 98, 47, 116, 120, 32, 97, // be to b/tx a - 110, 100, 32, 112, 117, 98, 108, 105, 115, 104, 32, 116, // nd publish t - 111, 32, 98, 47, 114, 120, 60, 98, 114, 47, 62, 10, // o b/rx
. - 32, 32, 32, 32, 78, 111, 116, 101, 58, 32, 116, 111, // Note: to - 32, 99, 111, 110, 110, 101, 99, 116, 32, 111, 118, 101, // connect ove - 114, 32, 84, 67, 80, 44, 32, 117, 115, 101, 32, 110, // r TCP, use n - 101, 116, 99, 97, 116, 32, 117, 116, 105, 108, 105, 116, // etcat utilit - 121, 58, 60, 98, 114, 47, 62, 10, 32, 32, 32, 32, // y:
. - 36, 32, 110, 99, 32, 36, 123, 108, 111, 99, 97, 116, // $ nc ${locat - 105, 111, 110, 46, 104, 111, 115, 116, 110, 97, 109, 101, // ion.hostname - 125, 32, 36, 123, 116, 99, 112, 112, 111, 114, 116, 125, // } ${tcpport} - 10, 32, 32, 60, 47, 100, 105, 118, 62, 10, 10, 32, // .
.. - 32, 60, 100, 105, 118, 32, 115, 116, 121, 108, 101, 61, //
. - 60, 98, 62, 85, 65, 82, 84, 32, 99, 111, 110, 115, // UART cons - 111, 108, 101, 60, 47, 98, 62, 60, 115, 112, 97, 110, // oleworks . - 32, 32, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, // over the - 108, 111, 99, 97, 108, 32, 87, 83, 32, 112, 111, 114, // local WS por - 116, 46, 32, 87, 101, 98, 83, 111, 99, 107, 101, 116, // t. WebSocket - 32, 115, 116, 97, 116, 117, 115, 58, 32, 60, 47, 115, // status: . .u2 - 53, 99, 102, 32, 36, 123, 99, 111, 110, 110, 101, 99, // 5cf ${connec - 116, 101, 100, 32, 63, 32, 39, 99, 111, 110, 110, 101, // ted ? 'conne - 99, 116, 101, 100, 39, 32, 58, 32, 39, 100, 105, 115, // cted' : 'dis - 99, 111, 110, 110, 101, 99, 116, 101, 100, 39, 125, 32, // connected'} - 60, 47, 115, 112, 97, 110, 62, 10, 32, 32, 60, 47, // . .
. se - 116, 84, 120, 116, 40, 101, 118, 46, 116, 97, 114, 103, // tTxt(ev.targ - 101, 116, 46, 118, 97, 108, 117, 101, 41, 125, 32, 47, // et.value)} / - 62, 10, 32, 32, 32, 32, 60, 98, 117, 116, 116, 111, // >. + 115, 101, 116, 77, 113, 116, 116, 40, 101, 118, 46, 116, // setMqtt(ev.t + 97, 114, 103, 101, 116, 46, 118, 97, 108, 117, 101, 41, // arget.value) + 125, 32, 47, 62, 10, 32, 32, 32, 32, 32, 32, 32, // } />. + 32, 60, 108, 97, 98, 101, 108, 32, 99, 108, 97, 115, //
. + 10, 32, 32, 60, 100, 105, 118, 32, 99, 108, 97, 115, // .
. + 32, 78, 111, 116, 101, 58, 32, 116, 111, 32, 99, 111, // Note: to co + 110, 110, 101, 99, 116, 32, 111, 118, 101, 114, 32, 77, // nnect over M + 81, 84, 84, 44, 32, 10, 32, 32, 32, 32, 32, 32, // QTT, . + 111, 112, 101, 110, 32, 60, 97, 32, 104, 114, 101, 102, // open . co + 110, 115, 111, 108, 101, 60, 47, 97, 62, 44, 32, 115, // nsole, s + 117, 98, 115, 99, 114, 105, 98, 101, 32, 116, 111, 32, // ubscribe to + 98, 47, 116, 120, 32, 97, 110, 100, 32, 112, 117, 98, // b/tx and pub + 108, 105, 115, 104, 32, 116, 111, 32, 98, 47, 114, 120, // lish to b/rx + 60, 98, 114, 47, 62, 10, 32, 32, 32, 32, 78, 111, //
. No + 116, 101, 58, 32, 116, 111, 32, 99, 111, 110, 110, 101, // te: to conne + 99, 116, 32, 111, 118, 101, 114, 32, 84, 67, 80, 44, // ct over TCP, + 32, 117, 115, 101, 32, 110, 101, 116, 99, 97, 116, 32, // use netcat + 117, 116, 105, 108, 105, 116, 121, 58, 60, 98, 114, 47, // utility:
. $ nc $ + 123, 108, 111, 99, 97, 116, 105, 111, 110, 46, 104, 111, // {location.ho + 115, 116, 110, 97, 109, 101, 125, 32, 36, 123, 103, 101, // stname} ${ge + 116, 112, 111, 114, 116, 40, 99, 102, 103, 46, 116, 99, // tport(cfg.tc + 112, 46, 117, 114, 108, 44, 32, 52, 48, 48, 49, 41, // p.url, 4001) + 125, 10, 32, 32, 60, 47, 100, 105, 118, 62, 10, 10, // }.
.. + 32, 32, 60, 100, 105, 118, 32, 115, 116, 121, 108, 101, //
. + 32, 60, 98, 62, 85, 65, 82, 84, 32, 99, 111, 110, // UART con + 115, 111, 108, 101, 60, 47, 98, 62, 60, 115, 112, 97, // sole setMessage - 115, 40, 91, 93, 41, 125, 62, 99, 108, 101, 97, 114, // s([])}>clear - 60, 47, 98, 117, 116, 116, 111, 110, 62, 10, 32, 32, // . - 60, 47, 100, 105, 118, 62, 10, 32, 32, 60, 112, 114, //
. . ${m - 101, 115, 115, 97, 103, 101, 115, 46, 109, 97, 112, 40, // essages.map( - 109, 101, 115, 115, 97, 103, 101, 32, 61, 62, 32, 104, // message => h - 40, 77, 101, 115, 115, 97, 103, 101, 44, 32, 123, 109, // (Message, {m - 101, 115, 115, 97, 103, 101, 125, 41, 41, 125, 10, 32, // essage}))}. - 32, 60, 47, 112, 114, 101, 62, 10, 10, 60, 47, 100, // ..`;.};..wi - 110, 100, 111, 119, 46, 111, 110, 108, 111, 97, 100, 32, // ndow.onload - 61, 32, 40, 41, 32, 61, 62, 32, 114, 101, 110, 100, // = () => rend - 101, 114, 40, 104, 40, 65, 112, 112, 41, 44, 32, 100, // er(h(App), d - 111, 99, 117, 109, 101, 110, 116, 46, 98, 111, 100, 121, // ocument.body - 41, 59, 10, 0 // );. + 109, 59, 32, 99, 111, 108, 111, 114, 58, 32, 35, 55, // m; color: #7 + 55, 55, 59, 34, 62, 119, 111, 114, 107, 115, 32, 10, // 77;">works . + 32, 32, 32, 32, 111, 118, 101, 114, 32, 116, 104, 101, // over the + 32, 108, 111, 99, 97, 108, 32, 87, 83, 32, 112, 111, // local WS po + 114, 116, 46, 32, 87, 101, 98, 83, 111, 99, 107, 101, // rt. WebSocke + 116, 32, 115, 116, 97, 116, 117, 115, 58, 32, 60, 47, // t status: . .u + 50, 53, 99, 102, 32, 36, 123, 99, 111, 110, 110, 101, // 25cf ${conne + 99, 116, 101, 100, 32, 63, 32, 39, 99, 111, 110, 110, // cted ? 'conn + 101, 99, 116, 101, 100, 39, 32, 58, 32, 39, 100, 105, // ected' : 'di + 115, 99, 111, 110, 110, 101, 99, 116, 101, 100, 39, 125, // sconnected'} + 32, 60, 47, 115, 112, 97, 110, 62, 10, 32, 32, 60, // . < + 47, 100, 105, 118, 62, 10, 32, 32, 60, 100, 105, 118, // /div>.
. s + 101, 116, 84, 120, 116, 40, 101, 118, 46, 116, 97, 114, // etTxt(ev.tar + 103, 101, 116, 46, 118, 97, 108, 117, 101, 41, 125, 32, // get.value)} + 47, 62, 10, 32, 32, 32, 32, 60, 98, 117, 116, 116, // />. setMessag + 101, 115, 40, 91, 93, 41, 125, 62, 99, 108, 101, 97, // es([])}>clea + 114, 60, 47, 98, 117, 116, 116, 111, 110, 62, 10, 32, // r. + 32, 60, 47, 100, 105, 118, 62, 10, 32, 32, 60, 112, //
.

. ${ + 109, 101, 115, 115, 97, 103, 101, 115, 46, 109, 97, 112, // messages.map + 40, 109, 101, 115, 115, 97, 103, 101, 32, 61, 62, 32, // (message => + 104, 40, 77, 101, 115, 115, 97, 103, 101, 44, 32, 123, // h(Message, { + 109, 101, 115, 115, 97, 103, 101, 125, 41, 41, 125, 10, // message}))}. + 32, 32, 60, 47, 112, 114, 101, 62, 10, 10, 60, 47, // ..`;.};..w + 105, 110, 100, 111, 119, 46, 111, 110, 108, 111, 97, 100, // indow.onload + 32, 61, 32, 40, 41, 32, 61, 62, 32, 114, 101, 110, // = () => ren + 100, 101, 114, 40, 104, 40, 65, 112, 112, 41, 44, 32, // der(h(App), + 100, 111, 99, 117, 109, 101, 110, 116, 46, 98, 111, 100, // document.bod + 121, 41, 59, 10, 0 // y);. }; static const unsigned char v3[] = { 118, 97, 114, 32, 101, 44, 110, 44, 95, 44, 116, 44, // var e,n,_,t, @@ -1763,9 +1808,9 @@ static const struct packed_file { time_t mtime; } packed_files[] = { {"/web_root/index.html", v1, sizeof(v1), 1654623573}, - {"/web_root/main.js", v2, sizeof(v2), 1655500873}, + {"/web_root/main.js", v2, sizeof(v2), 1655545304}, {"/web_root/preact.min.js", v3, sizeof(v3), 1654623573}, - {"/web_root/style.css", v4, sizeof(v4), 1655197477}, + {"/web_root/style.css", v4, sizeof(v4), 1655522711}, {NULL, NULL, 0, 0} }; diff --git a/examples/uart-bridge/web_root/main.js b/examples/uart-bridge/web_root/main.js index f72020e8..445cb65d 100644 --- a/examples/uart-bridge/web_root/main.js +++ b/examples/uart-bridge/web_root/main.js @@ -12,28 +12,16 @@ const App = function(props) { const [connected, setConnected] = useState(false); const [txt, setTxt] = useState(''); const [ws, setWs] = useState(null); - const [rx, setRx] = useState(''); - const [tx, setTx] = useState(''); - const [baud, setBaud] = useState(''); - const [tcpport, setTcpport] = useState(4001); - const [wsport, setWsport] = useState(4002); - const [mqtt, setMqtt] = useState(''); - // const tcp_port = cfg.tcp.split(':')[2] || 4001; - // const ws_port = cfg.ws.split(':')[2] || 4002; + const refresh = () => + fetch('/api/config/get').then(r => r.json()).then(r => setCfg(r)); - const refresh = () => fetch('/api/config/get').then(r => r.json()).then(r => { - setTx(r.tx), setRx(r.rx), setBaud(r.baud), setCfg(r); - setTcpport(r.tcp.url.split(':')[2] || 4001); - setWsport(r.ws.url.split(':')[2] || 4002); - setMqtt(r.mqtt.url); - }); + const getport = (url, v) => ((url || '').match(/.*:(\d+)/) || ['', v])[1]; const watchWebsocket = function() { // Connect to websocker port, to implement WS console var reconnect = function() { - var port; - setWsport(x => port = x); + var port = getport(cfg.ws.url, 4002); var l = window.location, proto = l.protocol.replace('http', 'ws'); var tid, url = `${proto}//${l.hostname}:${port}/ws`; // console.log(url); @@ -68,7 +56,23 @@ const App = function(props) { setTxt(''); }; - const onchange = ev => false; + const onchange = ev => fetch('/api/config/set', { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify(cfg), + }).then(r => ws && ws.close()); + + const set = obj => setCfg(x => Object.assign(x, obj)); + const setTx = ev => set({tx: parseInt(ev.target.value)}); + const setRx = ev => set({rx: parseInt(ev.target.value)}); + const setBaud = ev => set({baud: parseInt(ev.target.value)}); + const setTcpUrl = ev => set({tcp: {url: `tcp://0.0.0.0:${ev.target.value}`}}); + const setWsUrl = ev => set({ws: {url: `ws://0.0.0.0:${ev.target.value}`}}); + const setMqttUrl = ev => set({mqtt: {url: ev.target.value}}); + const setTcpEna = ev => (set({tcp: {enable: ev.target.checked}}), onchange()); + const setWsEna = ev => (set({ws: {enable: ev.target.checked}}), onchange()); + const setMqttEna = ev => + (set({mqtt: {enable: ev.target.checked}}), onchange()); return html`

@@ -79,16 +83,16 @@ const App = function(props) {

UART configuration

- setTx(ev.target.value)} /> +
- setRx(ev.target.value)} /> +
- setBaud(ev.target.value)} /> +
@@ -96,34 +100,34 @@ const App = function(props) {
setTcpport(ev.target.value)} /> + value=${getport(cfg.tcp.url, 4001)} onchange=${onchange} + oninput=${setTcpUrl} /> + checked=${cfg.tcp.enable} onchange=${setTcpEna} /> enable
setWsport(ev.target.value)} /> + value=${getport(cfg.ws.url, 4002)} onchange=${onchange} + oninput=${setWsUrl} /> + checked=${cfg.ws.enable} onchange=${setWsEna} /> enable
setMqtt(ev.target.value)} /> + checked=${cfg.mqtt.enable} onchange=${setMqttEna} /> enable
Note: to connect over MQTT, - go to + open console, subscribe to b/tx and publish to b/rx
Note: to connect over TCP, use netcat utility:
- $ nc ${location.hostname} ${tcpport} + $ nc ${location.hostname} ${getport(cfg.tcp.url, 4001)}