Update uart bridge

This commit is contained in:
Sergey Lyubka 2022-06-18 11:30:44 +01:00
parent c84dab21e4
commit 1b34360b05
3 changed files with 480 additions and 398 deletions

View File

@ -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

View File

@ -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`.<div c
108, 97, 115, 115, 61, 34, 99, 111, 110, 116, 97, 105, // lass="contai
@ -247,114 +290,112 @@ static const unsigned char v2[] = {
32, 32, 32, 32, 32, 32, 32, 60, 105, 110, 112, 117, // <inpu
116, 32, 115, 116, 121, 108, 101, 61, 34, 119, 105, 100, // t style="wid
116, 104, 58, 32, 53, 101, 109, 59, 34, 32, 118, 97, // th: 5em;" va
108, 117, 101, 61, 36, 123, 116, 120, 125, 32, 111, 110, // lue=${tx} on
99, 104, 97, 110, 103, 101, 61, 36, 123, 111, 110, 99, // change=${onc
104, 97, 110, 103, 101, 125, 10, 32, 32, 32, 32, 32, // hange}.
32, 32, 32, 32, 32, 111, 110, 105, 110, 112, 117, 116, // oninput
61, 36, 123, 101, 118, 32, 61, 62, 32, 115, 101, 116, // =${ev => 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, // </div>
60, 100, 105, 118, 32, 99, 108, 97, 115, 115, 61, 34, // <div class="
100, 45, 102, 108, 101, 120, 32, 112, 114, 45, 49, 32, // d-flex pr-1
109, 121, 45, 49, 34, 62, 10, 32, 32, 32, 32, 32, // my-1">.
32, 32, 32, 60, 108, 97, 98, 101, 108, 32, 99, 108, // <label cl
97, 115, 115, 61, 34, 97, 100, 100, 111, 110, 34, 62, // ass="addon">
85, 65, 82, 84, 32, 82, 88, 32, 112, 105, 110, 60, // UART RX pin<
47, 108, 97, 98, 101, 108, 62, 10, 32, 32, 32, 32, // /label>.
32, 32, 32, 32, 60, 105, 110, 112, 117, 116, 32, 115, // <input s
116, 121, 108, 101, 61, 34, 119, 105, 100, 116, 104, 58, // tyle="width:
32, 53, 101, 109, 59, 34, 32, 118, 97, 108, 117, 101, // 5em;" value
61, 36, 123, 114, 120, 125, 32, 111, 110, 99, 104, 97, // =${rx} oncha
108, 117, 101, 61, 36, 123, 99, 102, 103, 46, 116, 120, // lue=${cfg.tx
125, 32, 111, 110, 99, 104, 97, 110, 103, 101, 61, 36, // } onchange=$
123, 111, 110, 99, 104, 97, 110, 103, 101, 125, 10, 32, // {onchange}.
32, 32, 32, 32, 32, 32, 32, 32, 32, 111, 110, 105, // oni
110, 112, 117, 116, 61, 36, 123, 115, 101, 116, 84, 120, // nput=${setTx
125, 32, 47, 62, 10, 32, 32, 32, 32, 32, 32, 60, // } />. <
47, 100, 105, 118, 62, 60, 100, 105, 118, 32, 99, 108, // /div><div cl
97, 115, 115, 61, 34, 100, 45, 102, 108, 101, 120, 32, // ass="d-flex
112, 114, 45, 49, 32, 109, 121, 45, 49, 34, 62, 10, // pr-1 my-1">.
32, 32, 32, 32, 32, 32, 32, 32, 60, 108, 97, 98, // <lab
101, 108, 32, 99, 108, 97, 115, 115, 61, 34, 97, 100, // el class="ad
100, 111, 110, 34, 62, 85, 65, 82, 84, 32, 82, 88, // don">UART RX
32, 112, 105, 110, 60, 47, 108, 97, 98, 101, 108, 62, // pin</label>
10, 32, 32, 32, 32, 32, 32, 32, 32, 60, 105, 110, // . <in
112, 117, 116, 32, 115, 116, 121, 108, 101, 61, 34, 119, // put style="w
105, 100, 116, 104, 58, 32, 53, 101, 109, 59, 34, 32, // idth: 5em;"
118, 97, 108, 117, 101, 61, 36, 123, 99, 102, 103, 46, // value=${cfg.
114, 120, 125, 32, 111, 110, 99, 104, 97, 110, 103, 101, // rx} 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, 115, 101, 116, // ninput=${set
82, 120, 125, 32, 47, 62, 10, 32, 32, 32, 32, 32, // Rx} />.
32, 60, 47, 100, 105, 118, 62, 60, 100, 105, 118, 32, // </div><div
99, 108, 97, 115, 115, 61, 34, 100, 45, 102, 108, 101, // class="d-fle
120, 32, 112, 114, 45, 49, 32, 109, 121, 45, 121, 34, // x pr-1 my-y"
62, 10, 32, 32, 32, 32, 32, 32, 32, 32, 60, 108, // >. <l
97, 98, 101, 108, 32, 99, 108, 97, 115, 115, 61, 34, // abel class="
97, 100, 100, 111, 110, 34, 62, 85, 65, 82, 84, 32, // addon">UART
66, 97, 117, 100, 60, 47, 108, 97, 98, 101, 108, 62, // Baud</label>
10, 32, 32, 32, 32, 32, 32, 32, 32, 60, 105, 110, // . <in
112, 117, 116, 32, 115, 116, 121, 108, 101, 61, 34, 119, // put style="w
105, 100, 116, 104, 58, 32, 53, 101, 109, 59, 34, 32, // idth: 5em;"
118, 97, 108, 117, 101, 61, 36, 123, 99, 102, 103, 46, // value=${cfg.
98, 97, 117, 100, 125, 32, 111, 110, 99, 104, 97, 110, // baud} onchan
103, 101, 61, 36, 123, 111, 110, 99, 104, 97, 110, 103, // ge=${onchang
101, 125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, // e}.
32, 111, 110, 105, 110, 112, 117, 116, 61, 36, 123, 115, // oninput=${s
101, 116, 66, 97, 117, 100, 125, 32, 47, 62, 10, 32, // etBaud} />.
32, 32, 32, 32, 32, 60, 47, 100, 105, 118, 62, 10, // </div>.
32, 32, 32, 32, 60, 47, 100, 105, 118, 62, 10, 32, // </div>.
32, 32, 32, 60, 100, 105, 118, 32, 99, 108, 97, 115, // <div clas
115, 61, 34, 99, 111, 108, 32, 99, 111, 108, 45, 56, // s="col col-8
34, 62, 10, 32, 32, 32, 32, 32, 32, 60, 104, 51, // ">. <h3
62, 78, 101, 116, 119, 111, 114, 107, 32, 99, 111, 110, // >Network con
102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 60, 47, // figuration</
104, 51, 62, 10, 32, 32, 32, 32, 32, 32, 60, 100, // h3>. <d
105, 118, 32, 99, 108, 97, 115, 115, 61, 34, 100, 45, // iv class="d-
102, 108, 101, 120, 32, 109, 121, 45, 49, 34, 62, 10, // flex my-1">.
32, 32, 32, 32, 32, 32, 32, 32, 60, 108, 97, 98, // <lab
101, 108, 32, 99, 108, 97, 115, 115, 61, 34, 97, 100, // el class="ad
100, 111, 110, 34, 62, 76, 111, 99, 97, 108, 32, 84, // don">Local T
67, 80, 32, 112, 111, 114, 116, 60, 47, 108, 97, 98, // CP port</lab
101, 108, 62, 10, 32, 32, 32, 32, 32, 32, 32, 32, // el>.
60, 105, 110, 112, 117, 116, 32, 115, 116, 121, 108, 101, // <input style
61, 34, 109, 105, 110, 45, 119, 105, 100, 116, 104, 58, // ="min-width:
32, 52, 101, 109, 59, 32, 102, 108, 101, 120, 58, 32, // 4em; flex:
49, 32, 49, 48, 48, 37, 59, 34, 10, 32, 32, 32, // 1 100%;".
32, 32, 32, 32, 32, 32, 32, 118, 97, 108, 117, 101, // value
61, 36, 123, 103, 101, 116, 112, 111, 114, 116, 40, 99, // =${getport(c
102, 103, 46, 116, 99, 112, 46, 117, 114, 108, 44, 32, // fg.tcp.url,
52, 48, 48, 49, 41, 125, 32, 111, 110, 99, 104, 97, // 4001)} oncha
110, 103, 101, 61, 36, 123, 111, 110, 99, 104, 97, 110, // nge=${onchan
103, 101, 125, 10, 32, 32, 32, 32, 32, 32, 32, 32, // ge}.
32, 32, 111, 110, 105, 110, 112, 117, 116, 61, 36, 123, // oninput=${
101, 118, 32, 61, 62, 32, 115, 101, 116, 82, 120, 40, // ev => 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, // </div><di
118, 32, 99, 108, 97, 115, 115, 61, 34, 100, 45, 102, // v class="d-f
108, 101, 120, 32, 112, 114, 45, 49, 32, 109, 121, 45, // lex pr-1 my-
121, 34, 62, 10, 32, 32, 32, 32, 32, 32, 32, 32, // y">.
60, 108, 97, 98, 101, 108, 32, 99, 108, 97, 115, 115, // <label class
61, 34, 97, 100, 100, 111, 110, 34, 62, 85, 65, 82, // ="addon">UAR
84, 32, 66, 97, 117, 100, 60, 47, 108, 97, 98, 101, // T Baud</labe
115, 101, 116, 84, 99, 112, 85, 114, 108, 125, 32, 47, // setTcpUrl} /
62, 10, 32, 32, 32, 32, 32, 32, 32, 32, 60, 108, // >. <l
97, 98, 101, 108, 32, 99, 108, 97, 115, 115, 61, 34, // abel class="
109, 108, 45, 49, 32, 100, 45, 102, 108, 101, 120, 32, // ml-1 d-flex
108, 97, 98, 101, 108, 34, 62, 60, 105, 110, 112, 117, // label"><inpu
116, 32, 116, 121, 112, 101, 61, 34, 99, 104, 101, 99, // t type="chec
107, 98, 111, 120, 34, 10, 32, 32, 32, 32, 32, 32, // kbox".
32, 32, 32, 32, 99, 104, 101, 99, 107, 101, 100, 61, // checked=
36, 123, 99, 102, 103, 46, 116, 99, 112, 46, 101, 110, // ${cfg.tcp.en
97, 98, 108, 101, 125, 32, 111, 110, 99, 104, 97, 110, // able} onchan
103, 101, 61, 36, 123, 115, 101, 116, 84, 99, 112, 69, // ge=${setTcpE
110, 97, 125, 32, 47, 62, 32, 101, 110, 97, 98, 108, // na} /> enabl
101, 60, 47, 108, 97, 98, 101, 108, 62, 10, 32, 32, // e</label>.
32, 32, 32, 32, 60, 47, 100, 105, 118, 62, 60, 100, // </div><d
105, 118, 32, 99, 108, 97, 115, 115, 61, 34, 100, 45, // iv class="d-
102, 108, 101, 120, 32, 109, 121, 45, 49, 34, 62, 10, // flex my-1">.
32, 32, 32, 32, 32, 32, 32, 32, 60, 108, 97, 98, // <lab
101, 108, 32, 99, 108, 97, 115, 115, 61, 34, 97, 100, // el class="ad
100, 111, 110, 34, 62, 76, 111, 99, 97, 108, 32, 87, // don">Local W
83, 32, 112, 111, 114, 116, 60, 47, 108, 97, 98, 101, // S port</labe
108, 62, 10, 32, 32, 32, 32, 32, 32, 32, 32, 60, // l>. <
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, // </div>.
32, 60, 47, 100, 105, 118, 62, 10, 32, 32, 32, 32, // </div>.
60, 100, 105, 118, 32, 99, 108, 97, 115, 115, 61, 34, // <div class="
99, 111, 108, 32, 99, 111, 108, 45, 56, 34, 62, 10, // col col-8">.
32, 32, 32, 32, 32, 32, 60, 104, 51, 62, 78, 101, // <h3>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</h3>
10, 32, 32, 32, 32, 32, 32, 60, 100, 105, 118, 32, // . <div
99, 108, 97, 115, 115, 61, 34, 100, 45, 102, 108, 101, // class="d-fle
120, 32, 109, 121, 45, 49, 34, 62, 10, 32, 32, 32, // x my-1">.
32, 32, 32, 32, 32, 60, 108, 97, 98, 101, 108, 32, // <label
99, 108, 97, 115, 115, 61, 34, 97, 100, 100, 111, 110, // class="addon
34, 62, 76, 111, 99, 97, 108, 32, 84, 67, 80, 32, // ">Local TCP
112, 111, 114, 116, 60, 47, 108, 97, 98, 101, 108, 62, // port</label>
10, 32, 32, 32, 32, 32, 32, 32, 32, 60, 105, 110, // . <in
112, 117, 116, 32, 115, 116, 121, 108, 101, 61, 34, 109, // put style="m
105, 110, 45, 119, 105, 100, 116, 104, 58, 32, 52, 101, // in-width: 4e
109, 59, 32, 102, 108, 101, 120, 58, 32, 49, 32, 49, // m; flex: 1 1
48, 48, 37, 59, 34, 10, 32, 32, 32, 32, 32, 32, // 00%;".
32, 32, 32, 32, 118, 97, 108, 117, 101, 61, 36, 123, // value=${
116, 99, 112, 112, 111, 114, 116, 125, 32, 111, 110, 99, // tcpport} onc
104, 97, 110, 103, 101, 61, 36, 123, 111, 110, 99, 104, // hange=${onch
97, 110, 103, 101, 125, 10, 32, 32, 32, 32, 32, 32, // ange}.
32, 32, 32, 32, 111, 110, 105, 110, 112, 117, 116, 61, // oninput=
36, 123, 101, 118, 32, 61, 62, 32, 115, 101, 116, 84, // ${ev => 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, // <label class
61, 34, 109, 108, 45, 49, 32, 100, 45, 102, 108, 101, // ="ml-1 d-fle
120, 32, 108, 97, 98, 101, 108, 34, 62, 60, 105, 110, // x label"><in
112, 117, 116, 32, 116, 121, 112, 101, 61, 34, 99, 104, // put type="ch
101, 99, 107, 98, 111, 120, 34, 10, 32, 32, 32, 32, // eckbox".
32, 32, 32, 32, 32, 32, 99, 104, 101, 99, 107, 101, // checke
100, 61, 36, 123, 99, 102, 103, 46, 116, 99, 112, 46, // d=${cfg.tcp.
101, 110, 97, 98, 108, 101, 125, 32, 47, 62, 32, 101, // enable} /> e
110, 97, 98, 108, 101, 60, 47, 108, 97, 98, 101, 108, // nable</label
62, 10, 32, 32, 32, 32, 32, 32, 60, 47, 100, 105, // >. </di
118, 62, 60, 100, 105, 118, 32, 99, 108, 97, 115, 115, // v><div class
61, 34, 100, 45, 102, 108, 101, 120, 32, 109, 121, 45, // ="d-flex my-
49, 34, 62, 10, 32, 32, 32, 32, 32, 32, 32, 32, // 1">.
60, 108, 97, 98, 101, 108, 32, 99, 108, 97, 115, 115, // <label class
61, 34, 97, 100, 100, 111, 110, 34, 62, 76, 111, 99, // ="addon">Loc
97, 108, 32, 87, 83, 32, 112, 111, 114, 116, 60, 47, // al WS port</
108, 97, 98, 101, 108, 62, 10, 32, 32, 32, 32, 32, // label>.
32, 32, 32, 60, 105, 110, 112, 117, 116, 32, 115, 116, // <input st
121, 108, 101, 61, 34, 102, 108, 101, 120, 58, 32, 49, // yle="flex: 1
32, 49, 48, 48, 37, 59, 34, 10, 32, 32, 32, 32, // 100%;".
32, 32, 32, 32, 32, 32, 118, 97, 108, 117, 101, 61, // value=
36, 123, 119, 115, 112, 111, 114, 116, 125, 32, 111, 110, // ${wsport} on
99, 104, 97, 110, 103, 101, 61, 36, 123, 111, 110, 99, // change=${onc
104, 97, 110, 103, 101, 125, 10, 32, 32, 32, 32, 32, // hange}.
32, 32, 32, 32, 32, 111, 110, 105, 110, 112, 117, 116, // oninput
61, 36, 123, 101, 118, 32, 61, 62, 32, 115, 101, 116, // =${ev => set
87, 115, 112, 111, 114, 116, 40, 101, 118, 46, 116, 97, // Wsport(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, // <label class
61, 34, 109, 108, 45, 49, 32, 100, 45, 102, 108, 101, // ="ml-1 d-fle
120, 32, 108, 97, 98, 101, 108, 34, 62, 60, 105, 110, // x label"><in
112, 117, 116, 32, 116, 121, 112, 101, 61, 34, 99, 104, // put type="ch
101, 99, 107, 98, 111, 120, 34, 10, 32, 32, 32, 32, // eckbox".
32, 32, 32, 32, 32, 32, 99, 104, 101, 99, 107, 101, // checke
100, 61, 36, 123, 99, 102, 103, 46, 119, 115, 46, 101, // d=${cfg.ws.e
110, 97, 98, 108, 101, 125, 32, 47, 62, 32, 101, 110, // nable} /> en
34, 102, 108, 101, 120, 58, 32, 49, 32, 49, 48, 48, // "flex: 1 100
37, 59, 34, 10, 32, 32, 32, 32, 32, 32, 32, 32, // %;".
32, 32, 118, 97, 108, 117, 101, 61, 36, 123, 103, 101, // value=${ge
116, 112, 111, 114, 116, 40, 99, 102, 103, 46, 119, 115, // tport(cfg.ws
46, 117, 114, 108, 44, 32, 52, 48, 48, 50, 41, 125, // .url, 4002)}
32, 111, 110, 99, 104, 97, 110, 103, 101, 61, 36, 123, // onchange=${
111, 110, 99, 104, 97, 110, 103, 101, 125, 10, 32, 32, // onchange}.
32, 32, 32, 32, 32, 32, 32, 32, 111, 110, 105, 110, // onin
112, 117, 116, 61, 36, 123, 115, 101, 116, 87, 115, 85, // put=${setWsU
114, 108, 125, 32, 47, 62, 10, 32, 32, 32, 32, 32, // rl} />.
32, 32, 32, 60, 108, 97, 98, 101, 108, 32, 99, 108, // <label cl
97, 115, 115, 61, 34, 109, 108, 45, 49, 32, 100, 45, // ass="ml-1 d-
102, 108, 101, 120, 32, 108, 97, 98, 101, 108, 34, 62, // flex label">
60, 105, 110, 112, 117, 116, 32, 116, 121, 112, 101, 61, // <input type=
34, 99, 104, 101, 99, 107, 98, 111, 120, 34, 10, 32, // "checkbox".
32, 32, 32, 32, 32, 32, 32, 32, 32, 99, 104, 101, // che
99, 107, 101, 100, 61, 36, 123, 99, 102, 103, 46, 119, // cked=${cfg.w
115, 46, 101, 110, 97, 98, 108, 101, 125, 32, 111, 110, // s.enable} on
99, 104, 97, 110, 103, 101, 61, 36, 123, 115, 101, 116, // change=${set
87, 115, 69, 110, 97, 125, 32, 47, 62, 32, 101, 110, // WsEna} /> en
97, 98, 108, 101, 60, 47, 108, 97, 98, 101, 108, 62, // able</label>
10, 32, 32, 32, 32, 32, 32, 60, 47, 100, 105, 118, // . </div
62, 60, 100, 105, 118, 32, 99, 108, 97, 115, 115, 61, // ><div class=
@ -367,118 +408,122 @@ static const unsigned char v2[] = {
60, 105, 110, 112, 117, 116, 32, 115, 116, 121, 108, 101, // <input style
61, 34, 102, 108, 101, 120, 58, 32, 49, 32, 49, 48, // ="flex: 1 10
48, 37, 59, 34, 10, 32, 32, 32, 32, 32, 32, 32, // 0%;".
32, 32, 32, 118, 97, 108, 117, 101, 61, 36, 123, 109, // value=${m
113, 116, 116, 125, 32, 111, 110, 99, 104, 97, 110, 103, // qtt} onchang
101, 61, 36, 123, 111, 110, 99, 104, 97, 110, 103, 101, // e=${onchange
125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // }.
111, 110, 105, 110, 112, 117, 116, 61, 36, 123, 101, 118, // oninput=${ev
32, 61, 62, 32, 115, 101, 116, 77, 113, 116, 116, 40, // => 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, // <label
99, 108, 97, 115, 115, 61, 34, 109, 108, 45, 49, 32, // class="ml-1
100, 45, 102, 108, 101, 120, 32, 108, 97, 98, 101, 108, // d-flex label
34, 62, 60, 105, 110, 112, 117, 116, 32, 116, 121, 112, // "><input typ
101, 61, 34, 99, 104, 101, 99, 107, 98, 111, 120, 34, // e="checkbox"
10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 99, // . c
104, 101, 99, 107, 101, 100, 61, 36, 123, 99, 102, 103, // hecked=${cfg
46, 109, 113, 116, 116, 46, 101, 110, 97, 98, 108, 101, // .mqtt.enable
125, 32, 47, 62, 32, 101, 110, 97, 98, 108, 101, 60, // } /> enable<
47, 108, 97, 98, 101, 108, 62, 10, 32, 32, 32, 32, // /label>.
32, 32, 60, 47, 100, 105, 118, 62, 10, 32, 32, 32, // </div>.
32, 60, 47, 100, 105, 118, 62, 10, 32, 32, 60, 47, // </div>. </
100, 105, 118, 62, 10, 10, 32, 32, 60, 100, 105, 118, // div>.. <div
32, 99, 108, 97, 115, 115, 61, 34, 109, 115, 103, 34, // class="msg"
62, 10, 32, 32, 32, 32, 78, 111, 116, 101, 58, 32, // >. 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<br/>.
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:<br/>.
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, // . </div>..
32, 60, 100, 105, 118, 32, 115, 116, 121, 108, 101, 61, // <div style=
34, 109, 97, 114, 103, 105, 110, 45, 116, 111, 112, 58, // "margin-top:
32, 50, 101, 109, 59, 34, 62, 10, 32, 32, 32, 32, // 2em;">.
60, 98, 62, 85, 65, 82, 84, 32, 99, 111, 110, 115, // <b>UART cons
111, 108, 101, 60, 47, 98, 62, 60, 115, 112, 97, 110, // ole</b><span
32, 115, 116, 121, 108, 101, 61, 34, 109, 97, 114, 103, // style="marg
105, 110, 45, 108, 101, 102, 116, 58, 32, 49, 101, 109, // in-left: 1em
59, 32, 99, 111, 108, 111, 114, 58, 32, 35, 55, 55, // ; color: #77
55, 59, 34, 62, 119, 111, 114, 107, 115, 32, 10, 32, // 7;">works .
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: </s
112, 97, 110, 62, 60, 115, 112, 97, 110, 10, 32, 32, // pan><span.
32, 32, 32, 32, 115, 116, 121, 108, 101, 61, 34, 99, // style="c
111, 108, 111, 114, 58, 32, 36, 123, 99, 111, 110, 110, // olor: ${conn
101, 99, 116, 101, 100, 32, 63, 32, 39, 116, 101, 97, // ected ? 'tea
108, 39, 32, 58, 32, 39, 114, 101, 100, 39, 125, 59, // l' : 'red'};
34, 62, 10, 32, 32, 32, 32, 32, 32, 92, 117, 50, // ">. .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, // </span>. </
100, 105, 118, 62, 10, 32, 32, 60, 100, 105, 118, 32, // div>. <div
115, 116, 121, 108, 101, 61, 34, 109, 97, 114, 103, 105, // style="margi
110, 58, 32, 48, 46, 53, 101, 109, 32, 48, 59, 32, // n: 0.5em 0;
100, 105, 115, 112, 108, 97, 121, 58, 32, 102, 108, 101, // display: fle
120, 34, 62, 10, 32, 32, 32, 32, 60, 105, 110, 112, // x">. <inp
117, 116, 32, 112, 108, 97, 99, 101, 104, 111, 108, 100, // ut placehold
101, 114, 61, 34, 116, 111, 32, 115, 101, 110, 100, 32, // er="to send
100, 97, 116, 97, 44, 32, 116, 121, 112, 101, 32, 97, // data, type a
110, 100, 32, 112, 114, 101, 115, 115, 32, 101, 110, 116, // nd press ent
101, 114, 46, 46, 46, 34, 32, 115, 116, 121, 108, 101, // er..." style
61, 34, 102, 108, 101, 120, 58, 32, 49, 32, 49, 48, // ="flex: 1 10
48, 37, 59, 34, 10, 32, 32, 32, 32, 32, 32, 118, // 0%;". v
97, 108, 117, 101, 61, 36, 123, 116, 120, 116, 125, 32, // alue=${txt}
111, 110, 99, 104, 97, 110, 103, 101, 61, 36, 123, 115, // onchange=${s
101, 110, 100, 109, 101, 115, 115, 97, 103, 101, 125, 10, // endmessage}.
32, 32, 32, 32, 32, 32, 111, 110, 105, 110, 112, 117, // oninpu
116, 61, 36, 123, 101, 118, 32, 61, 62, 32, 115, 101, // t=${ev => 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, // >. <butto
32, 32, 32, 118, 97, 108, 117, 101, 61, 36, 123, 99, // value=${c
102, 103, 46, 109, 113, 116, 116, 46, 117, 114, 108, 125, // fg.mqtt.url}
32, 111, 110, 99, 104, 97, 110, 103, 101, 61, 36, 123, // onchange=${
111, 110, 99, 104, 97, 110, 103, 101, 125, 10, 32, 32, // onchange}.
32, 32, 32, 32, 32, 32, 32, 32, 111, 110, 105, 110, // onin
112, 117, 116, 61, 36, 123, 101, 118, 32, 61, 62, 32, // put=${ev =>
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, // <label clas
115, 61, 34, 109, 108, 45, 49, 32, 100, 45, 102, 108, // s="ml-1 d-fl
101, 120, 32, 108, 97, 98, 101, 108, 34, 62, 60, 105, // ex label"><i
110, 112, 117, 116, 32, 116, 121, 112, 101, 61, 34, 99, // nput type="c
104, 101, 99, 107, 98, 111, 120, 34, 10, 32, 32, 32, // heckbox".
32, 32, 32, 32, 32, 32, 32, 99, 104, 101, 99, 107, // check
101, 100, 61, 36, 123, 99, 102, 103, 46, 109, 113, 116, // ed=${cfg.mqt
116, 46, 101, 110, 97, 98, 108, 101, 125, 32, 111, 110, // t.enable} on
99, 104, 97, 110, 103, 101, 61, 36, 123, 115, 101, 116, // change=${set
77, 113, 116, 116, 69, 110, 97, 125, 32, 47, 62, 32, // MqttEna} />
101, 110, 97, 98, 108, 101, 60, 47, 108, 97, 98, 101, // enable</labe
108, 62, 10, 32, 32, 32, 32, 32, 32, 60, 47, 100, // l>. </d
105, 118, 62, 10, 32, 32, 32, 32, 60, 47, 100, 105, // iv>. </di
118, 62, 10, 32, 32, 60, 47, 100, 105, 118, 62, 10, // v>. </div>.
10, 32, 32, 60, 100, 105, 118, 32, 99, 108, 97, 115, // . <div clas
115, 61, 34, 109, 115, 103, 34, 62, 10, 32, 32, 32, // s="msg">.
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 <a href
61, 34, 104, 116, 116, 112, 58, 47, 47, 119, 119, 119, // ="http://www
46, 104, 105, 118, 101, 109, 113, 46, 99, 111, 109, 47, // .hivemq.com/
100, 101, 109, 111, 115, 47, 119, 101, 98, 115, 111, 99, // demos/websoc
107, 101, 116, 45, 99, 108, 105, 101, 110, 116, 47, 34, // ket-client/"
62, 10, 32, 32, 32, 32, 32, 32, 32, 32, 99, 111, // >. co
110, 115, 111, 108, 101, 60, 47, 97, 62, 44, 32, 115, // nsole</a>, 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, // <br/>. 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:<br/
62, 10, 32, 32, 32, 32, 36, 32, 110, 99, 32, 36, // >. $ 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, // }. </div>..
32, 32, 60, 100, 105, 118, 32, 115, 116, 121, 108, 101, // <div style
61, 34, 109, 97, 114, 103, 105, 110, 45, 116, 111, 112, // ="margin-top
58, 32, 50, 101, 109, 59, 34, 62, 10, 32, 32, 32, // : 2em;">.
32, 60, 98, 62, 85, 65, 82, 84, 32, 99, 111, 110, // <b>UART con
115, 111, 108, 101, 60, 47, 98, 62, 60, 115, 112, 97, // sole</b><spa
110, 32, 115, 116, 121, 108, 101, 61, 34, 109, 97, 114, // n style="mar
103, 105, 110, 45, 108, 101, 102, 116, 58, 32, 49, 101, // gin-left: 1e
109, 59, 34, 10, 32, 32, 32, 32, 32, 32, 111, 110, // m;". on
99, 108, 105, 99, 107, 61, 36, 123, 101, 118, 32, 61, // click=${ev =
62, 32, 115, 101, 116, 77, 101, 115, 115, 97, 103, 101, // > 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, // </button>.
60, 47, 100, 105, 118, 62, 10, 32, 32, 60, 112, 114, // </div>. <pr
101, 32, 115, 116, 121, 108, 101, 61, 34, 104, 101, 105, // e style="hei
103, 104, 116, 58, 32, 49, 53, 101, 109, 59, 32, 111, // ght: 15em; o
118, 101, 114, 102, 108, 111, 119, 58, 32, 97, 117, 116, // verflow: aut
111, 59, 34, 62, 10, 32, 32, 32, 32, 36, 123, 109, // o;">. ${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, // </pre>..</d
105, 118, 62, 96, 59, 10, 125, 59, 10, 10, 119, 105, // iv>`;.};..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: </
115, 112, 97, 110, 62, 60, 115, 112, 97, 110, 10, 32, // span><span.
32, 32, 32, 32, 32, 115, 116, 121, 108, 101, 61, 34, // style="
99, 111, 108, 111, 114, 58, 32, 36, 123, 99, 111, 110, // color: ${con
110, 101, 99, 116, 101, 100, 32, 63, 32, 39, 116, 101, // nected ? 'te
97, 108, 39, 32, 58, 32, 39, 114, 101, 100, 39, 125, // al' : 'red'}
59, 34, 62, 10, 32, 32, 32, 32, 32, 32, 92, 117, // ;">. .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, // </span>. <
47, 100, 105, 118, 62, 10, 32, 32, 60, 100, 105, 118, // /div>. <div
32, 115, 116, 121, 108, 101, 61, 34, 109, 97, 114, 103, // style="marg
105, 110, 58, 32, 48, 46, 53, 101, 109, 32, 48, 59, // in: 0.5em 0;
32, 100, 105, 115, 112, 108, 97, 121, 58, 32, 102, 108, // display: fl
101, 120, 34, 62, 10, 32, 32, 32, 32, 60, 105, 110, // ex">. <in
112, 117, 116, 32, 112, 108, 97, 99, 101, 104, 111, 108, // put placehol
100, 101, 114, 61, 34, 116, 111, 32, 115, 101, 110, 100, // der="to send
32, 100, 97, 116, 97, 44, 32, 116, 121, 112, 101, 32, // data, type
97, 110, 100, 32, 112, 114, 101, 115, 115, 32, 101, 110, // and press en
116, 101, 114, 46, 46, 46, 34, 32, 115, 116, 121, 108, // ter..." styl
101, 61, 34, 102, 108, 101, 120, 58, 32, 49, 32, 49, // e="flex: 1 1
48, 48, 37, 59, 34, 10, 32, 32, 32, 32, 32, 32, // 00%;".
118, 97, 108, 117, 101, 61, 36, 123, 116, 120, 116, 125, // value=${txt}
32, 111, 110, 99, 104, 97, 110, 103, 101, 61, 36, 123, // onchange=${
115, 101, 110, 100, 109, 101, 115, 115, 97, 103, 101, 125, // sendmessage}
10, 32, 32, 32, 32, 32, 32, 111, 110, 105, 110, 112, // . oninp
117, 116, 61, 36, 123, 101, 118, 32, 61, 62, 32, 115, // ut=${ev => 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, // />. <butt
111, 110, 32, 115, 116, 121, 108, 101, 61, 34, 109, 97, // on style="ma
114, 103, 105, 110, 45, 108, 101, 102, 116, 58, 32, 49, // rgin-left: 1
101, 109, 59, 34, 10, 32, 32, 32, 32, 32, 32, 111, // em;". o
110, 99, 108, 105, 99, 107, 61, 36, 123, 101, 118, 32, // nclick=${ev
61, 62, 32, 115, 101, 116, 77, 101, 115, 115, 97, 103, // => 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</button>.
32, 60, 47, 100, 105, 118, 62, 10, 32, 32, 60, 112, // </div>. <p
114, 101, 32, 115, 116, 121, 108, 101, 61, 34, 104, 101, // re style="he
105, 103, 104, 116, 58, 32, 49, 53, 101, 109, 59, 32, // ight: 15em;
111, 118, 101, 114, 102, 108, 111, 119, 58, 32, 97, 117, // overflow: au
116, 111, 59, 34, 62, 10, 32, 32, 32, 32, 36, 123, // to;">. ${
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, // </pre>..</
100, 105, 118, 62, 96, 59, 10, 125, 59, 10, 10, 119, // div>`;.};..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}
};

View File

@ -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`
<div class="container">
@ -79,16 +83,16 @@ const App = function(props) {
<h3>UART configuration</h3>
<div class="d-flex pr-1 my-1">
<label class="addon">UART TX pin</label>
<input style="width: 5em;" value=${tx} onchange=${onchange}
oninput=${ev => setTx(ev.target.value)} />
<input style="width: 5em;" value=${cfg.tx} onchange=${onchange}
oninput=${setTx} />
</div><div class="d-flex pr-1 my-1">
<label class="addon">UART RX pin</label>
<input style="width: 5em;" value=${rx} onchange=${onchange}
oninput=${ev => setRx(ev.target.value)} />
<input style="width: 5em;" value=${cfg.rx} onchange=${onchange}
oninput=${setRx} />
</div><div class="d-flex pr-1 my-y">
<label class="addon">UART Baud</label>
<input style="width: 5em;" value=${baud} onchange=${onchange}
oninput=${ev => setBaud(ev.target.value)} />
<input style="width: 5em;" value=${cfg.baud} onchange=${onchange}
oninput=${setBaud} />
</div>
</div>
<div class="col col-8">
@ -96,34 +100,34 @@ const App = function(props) {
<div class="d-flex my-1">
<label class="addon">Local TCP port</label>
<input style="min-width: 4em; flex: 1 100%;"
value=${tcpport} onchange=${onchange}
oninput=${ev => setTcpport(ev.target.value)} />
value=${getport(cfg.tcp.url, 4001)} onchange=${onchange}
oninput=${setTcpUrl} />
<label class="ml-1 d-flex label"><input type="checkbox"
checked=${cfg.tcp.enable} /> enable</label>
checked=${cfg.tcp.enable} onchange=${setTcpEna} /> enable</label>
</div><div class="d-flex my-1">
<label class="addon">Local WS port</label>
<input style="flex: 1 100%;"
value=${wsport} onchange=${onchange}
oninput=${ev => setWsport(ev.target.value)} />
value=${getport(cfg.ws.url, 4002)} onchange=${onchange}
oninput=${setWsUrl} />
<label class="ml-1 d-flex label"><input type="checkbox"
checked=${cfg.ws.enable} /> enable</label>
checked=${cfg.ws.enable} onchange=${setWsEna} /> enable</label>
</div><div class="d-flex my-1">
<label class="addon">Remote MQTT</label>
<input style="flex: 1 100%;"
value=${mqtt} onchange=${onchange}
value=${cfg.mqtt.url} onchange=${onchange}
oninput=${ev => setMqtt(ev.target.value)} />
<label class="ml-1 d-flex label"><input type="checkbox"
checked=${cfg.mqtt.enable} /> enable</label>
checked=${cfg.mqtt.enable} onchange=${setMqttEna} /> enable</label>
</div>
</div>
</div>
<div class="msg">
Note: to connect over MQTT,
go to <a href="http://www.hivemq.com/demos/websocket-client/">
open <a href="http://www.hivemq.com/demos/websocket-client/">
console</a>, subscribe to b/tx and publish to b/rx<br/>
Note: to connect over TCP, use netcat utility:<br/>
$ nc ${location.hostname} ${tcpport}
$ nc ${location.hostname} ${getport(cfg.tcp.url, 4001)}
</div>
<div style="margin-top: 2em;">