thomasnordquist / MQTT-Explorer

An all-round MQTT client that provides a structured topic overview
https://mqtt-explorer.com
Other
2.96k stars 286 forks source link

Add window for creating custom JS-based parser #631

Open RuStrannik opened 2 years ago

RuStrannik commented 2 years ago

It would be very handy to pass original input from mqtt topic to mqtt explorer through a JS syntax based parser function

Sample prototype:

function (value) { return JSON.parse(value); };

This is how I see it working internally:

const default_parser = function (value) { return JSON.parse(value); }; // should be similar to the way it works right now
let parser = default_parser;
let user_parser = "function (value) { return JSON.parse(value.trim().replace('gg','lol')); };" // say, this is entered via interface
if (user_parser.length > 0) { // probably, require some more checks
    try {
        "use strict";
        eval("parser = "+ user_parser);
        if (!last_val || (last_val.length === 0)) { last_val = "test sample input"; };
        let test_run_result = parser(last_val); // test-run(s), to make sure user's parser is somewhat functional
        console.log("test_run_result:", test_run_result);
    } catch (err) { consoe.error(err); parser = default_parser; };
}

This way, users would be able to transform whatever they have into already well enough handled Javascript object.

Example

Say, I have tabulated input, as follows:

1177    6229    1204    6326    0000    0000    0000    0000    0000    0000    1302    6121    1151    9674    1289    7136

Then I could specify how to handle this by filling Custom Parser window with this text:

function(value) { let id=0; const ret=[]; value.split('\t').forEach((val,i) => { if ((i%2) == 0) { ret[id]={}; }; ret[id][((i%2)?("hum"):("temp"))] = Number(val)/100; if (i%2) {++id;}; }); return ret; }

and strange text string will turn into quite meaningful object:

[
  { temp: 11.77, hum: 62.29 },
  { temp: 12.04, hum: 63.26 },
  { temp:     0, hum:     0 },
  { temp:     0, hum:     0 },
  { temp:     0, hum:     0 },
  { temp: 13.02, hum: 61.21 },
  { temp: 11.51, hum: 96.74 },
  { temp: 12.89, hum: 71.36 }
]

And now I can conveniently view history, add certain values to chart panel, etc.

NOTE

This requires calling eval(), which some might consider unsafe, so a warning might be shown before enabling this feature.

RuStrannik commented 2 years ago

There might also be few standard parsers in a drop-down auto-fill menu, like:

  <select>
    <option value="">Select from some standard parsers</option>
    <option value="function(value) { return value.split(/\\s+/); }">Tabulated input parser</option>
    <option value="function(value) { return value.split(','); }">CSV parser</option>
  </select>