c-klinger / MMM-JsonValue

Extension module for the Magic Mirror allows you to show information from any JSON on your mirror using an HTTP Request to an REST API
MIT License
11 stars 5 forks source link

Subscript support #8

Closed saundersrg closed 1 year ago

saundersrg commented 2 years ago

I'm looking at using subscript in my jsonPath variable, but it does not seem to work and the module just shows "Loading". Is there perhaps something I'm missing, or is this unsupported? I'm trying to filter the results coming back to only certain results in the JSON. If I validate using the JSONPath online evaluator my query works. An example as follows, to return JSON name for only items where there resultType is "Filter":

results.[?(@.resultType=='Filter')].name

If I don't filter, all the names are returned:

results..name

Happy to provide actual subscript and API privately if it is supposed to be working.

c-klinger commented 2 years ago

Hi, can you provide me an (anonymized) example JSON for ur jsonPath to test and ha a look into this? I think access to your private API is not required than.

late4marshmellow commented 1 year ago

i'm having a similar issue maybe.

this jsonPath: "$[?(@.uriObj.name == 'Eva Meter Reader' && @.title == 'Power')].value" gives me followingerror output

0|mm  | Expecting 'STAR', 'IDENTIFIER', 'SCRIPT_EXPRESSION', 'INTEGER', 'END', got 'DOLLAR'
0|mm  |     at Parser.parseError (/home/pi/MagicMirror/modules/MMM-JsonValue/node_modules/jsonpath/generated/parser.js:166:15)
0|mm  |     at Parser.parser.yy.parseError (/home/pi/MagicMirror/modules/MMM-JsonValue/node_modules/jsonpath/lib/parser.js:13:17)
0|mm  |     at Parser.parse (/home/pi/MagicMirror/modules/MMM-JsonValue/node_modules/jsonpath/generated/parser.js:224:22)
0|mm  |     at JSONPath.nodes (/home/pi/MagicMirror/modules/MMM-JsonValue/node_modules/jsonpath/lib/index.js:118:26)
0|mm  |     at JSONPath.query (/home/pi/MagicMirror/modules/MMM-JsonValue/node_modules/jsonpath/lib/index.js:94:22)
0|mm  |     at Class.parseData (/home/pi/MagicMirror/modules/MMM-JsonValue/node_helper.js:32:13)
0|mm  |     at /home/pi/MagicMirror/modules/MMM-JsonValue/node_helper.js:25:76
0|mm  |     at /home/pi/MagicMirror/modules/MMM-JsonValue/node_helper.js:39:21
0|mm  |     at process.processTicksAndRejections (node:internal/process/task_queues:96:5)
0|mm  | [08.03.2023 20:24.34.742] [LOG]
0|mm  | Error: Parse error on line 1:
0|mm  | $.$[?(@.uriObj.name ==
0|mm  | --^

So it seems the jsonpath cant begin with $

this is a sample of the JSON

[ 
 {
        "uri": "homey:device:123",
        "id": "measure_power",
        "title": "Power",
        "type": "number",
        "value": 33,
        "uriObj": {
            "type": "device",
            "id": "123",
            "name": "Eva Meter Reader",
            "color": "#266DFB",
            "meta": {
                "zoneId": "123",
                "zoneName": "EK13B",
                "driverUri": "homey:app:com.datek.eva"
            },
            "iconObj": {
                "id": "123",
                "url": "/icon/123/icon.svg"
            }
        }
    },
    {
        "uri": "homey:device:123",
        "id": "meter_power",
        "title": "Energy",
        "type": "number",
        "value": 76742.54,
        "uriObj": {
            "type": "device",
            "id": "123",
            "name": "Eva Meter Reader",
            "color": "#266DFB",
            "meta": {
                "zoneId": "123",
                "zoneName": "123",
                "driverUri": "homey:app:com.datek.eva"
            },
            "iconObj": {
                "id": "123",
                "url": "/icon/123/icon.svg"
            }
        }
    },
    {
        "uri": "homey:device:123",
        "id": "measure_temperature",
        "title": "Temperature",
        "type": "number",
        "value": 28.1,
        "uriObj": {
            "type": "device",
            "id": "123",
            "name": "Eva Meter Reader",
            "color": "#266DFB",
            "meta": {
                "zoneId": "123",
                "zoneName": "123",
                "driverUri": "homey:app:com.datek.eva"
            },
            "iconObj": {
                "id": "123",
                "url": "/icon/123/icon.svg"
            }
        }
    }
    ]
late4marshmellow commented 1 year ago

i discovered my issue myself. Problem was that node_helper.js forced $. and a dot between first $ and a filter is not possible

i solved it by adding a rule, made a pull request i hope can be helpful :)

[https://github.com/c-klinger/MMM-JsonValue/pull/9/commits/3b56d6e424aa7ca6bf4840b28b13b4932edb314d]

c-klinger commented 1 year ago

Thanks for the analysis @late4marshmellow. I added the $. in node_helper.js for compability support as the first version of the plugin wasn't using jsonp (or ... only a very limited self-implementation).

I had a look in your pr, which made me think: maybe checking for $ as first character is the better option than the regular expression for this specific use case ... if your path starts with $ just evaluate it, otherwise add $. for backward compability.

late4marshmellow commented 1 year ago

in my case this would work too, as both $.$ and just $ would work. in general that would probably also be a better approach :)

like this?

parseData: function(data, jsonPath) {
  if (!jsonPath.startsWith("$")) {
    jsonPath = "$." + jsonPath;
  }
  return jp.query(data, jsonPath);
}
c-klinger commented 1 year ago

Yeah exactly.

c-klinger commented 1 year ago

Thanks for the updated pull request @late4marshmellow, i merged the changes