Parsing JSON for Point values
-
I have some JSON data -
{"status": 200, "message": "ok", "data": {"priceIndex": 0.4513350942223604, "action": "charge", "responseGenerated": "2017-08-01T13:30:48.244247+12:00", "dischargeIfPriceAbove": 360.4239999999999, "losseskW": 2.0, "billable": "ICJ-19133", "capacitykWh": 100.0, "chargeRatekW": 90.0, "chargePercent": 50.0, "efficiencyPercent": 82.0, "averagePrice": 300.3533333333333, "chargeIfPriceBelow": 240.28266666666664, "GXP": "HOR0331", "dischargeRatekW": 90.0, "prices": [{"starts": "2017-08-01T13:30:00+12:00", "ends": "2017-08-01T14:00:00+12:00", "spotEnergyPriceDollarsPerMWh": 135.56}, {"starts": "2017-08-01T14:00:00+12:00", "ends": "2017-08-01T14:30:00+12:00", "spotEnergyPriceDollarsPerMWh": 135.56}, .......
We have used the HTTP retriever and regex to get the unique values out (status and capacity etc) but we are having trouble getting the "prices" data out as the constituents of prices are not unique (starts,ends,spotEnergyPriceDollarsPerWh). Looking for advice for the best way to iterate through the "prices" JSON data to create point values. The idea would be to log a point value (Starts1) which takes the time after the first appearance of "starts" in the prices, then iterate through to the next appearance of starts and log the time as Starts2 etc etc.
Any suggestions would be appreciated.
-
Hi MaP,
Is the key "prices" unique in the JSON? If so, you could use a regex like....
"prices": (.*?\}\])
I think, value index 1. That'll capture the list, which can then be parsed in a script...if( scriptRuntime.time < httpPoint.time ) { var pricesList = JSON.parse( httpPoint.value ); for( var k = 0; k < pricesList.length; k+=1 ) { var time = Date.parse( pricesList[k].starts ); if( isNaN(time) ) continue; //Consider error handling? outputPoint.set( priceList[k].spotEnergyPriceDollarsPerMWh, time ); } scriptRuntime.set( scriptRuntime.value + 1 ); }
Where output point is either a numeric scripting point or a settable virtual point, and scriptRuntime is a multistate scripting point I am setting to see if newer data has arrived. You may wish to turn that point to not log. You could also do something in the loop like
if( time <= outputPoint.time ) continue;
to prevent extra work. The script would be on a cron similar to the polling rate of the http data source.Edit: In Mango 3.2 (which should be released next week) we've added the ability for scripting points to trigger the script, which would eliminate the need for the scriptRuntime point. We've also added the ability for meta points or point links to call the set() function.