Can't work out how to pull array from attrib's

Hi all,

So I am stuck and can't seem to work out where to start on something, I have Octopus Agile, and I have the rates available to me in 30 minute blocks, I can get the data which are recorded as attributes as seen here:

These are stored in msg.data.attributes, it looks like each price segment is it's own data entry, my goal is to parse them all and find the 3 lowest value entries and pass them on down the line, the issue I've got at the moment is parsing the dataset, I can't see to figure out a way to parse the entire attribute object in to an array to work it out, but I fear doing that it will have the date/time stamp there which will confuse the calculations in working out what is the cheapest time.

Anyone got any idea's please?

N/B the timestamps change so aren't constant so can't write a huge expression to calculate it them all.

There are a number of ways to approach this is one way: Object.entries() - JavaScript | MDN

Pass the msg.whatever.attributes object into Object.entries and you'll get an array of arrays ([key, value])

Cheers, I've read though that and I've managed to get it in to an array and find the lowest price, but it seems to kill the key so I can't see what time the price came from...

image

[{"id":"f3dc28c4406d5034","type":"inject","z":"4fbb0f02.0e5f6","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":1420,"wires":[["a0ab059cf17c3de7"]]},{"id":"a0ab059cf17c3de7","type":"api-current-state","z":"4fbb0f02.0e5f6","name":"","server":"b3a3253e.d12568","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"octopusagile.all_rates","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":370,"y":1420,"wires":[["81c05b0bba92579c","ca97de9e3d173bb1"]]},{"id":"81c05b0bba92579c","type":"debug","z":"4fbb0f02.0e5f6","name":"debug 11","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"data.attributes","targetType":"msg","statusVal":"","statusType":"auto","x":640,"y":1420,"wires":[]},{"id":"ca97de9e3d173bb1","type":"function","z":"4fbb0f02.0e5f6","name":"function 8","func":"\nconst obj = msg.data.attributes;\n//let arr = Object.values(obj);\nvar arr = Object.keys( obj ).map(function ( key ) { return obj[key]; });\nlet min = Math.min(...arr);\n//const map = new Map(Object.entries(obj));\n//console.log(map); // Map(2) {\"foo\" => \"bar\", \"baz\" => 42}\n\n\nmsg.prices=arr\nmsg.lowestprice=min\nreturn msg;\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":640,"y":1460,"wires":[["77085d7a9acce152"]]},{"id":"77085d7a9acce152","type":"debug","z":"4fbb0f02.0e5f6","name":"debug Function out","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":830,"y":1460,"wires":[]},{"id":"b3a3253e.d12568","type":"server","name":"Home Assistant","version":5,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30,"areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true}]

Hi, Steve mentioned Object.entries(), so you have an array of arrays containing timestamp and price, you can then just sort() it. The first three indexes will be the lowest
With msg.payload[0][0] holding timestamp of lowest price and msg.payload[0][1] holding the lowest price.
e.g.

msg.data = {
    attributes: {
        one:3,
        two:4,
        three:1
    }
}
msg.payload = Object.entries(msg.data.attributes).sort((a,b) => a[1] -b[1]);

return msg;

Output

[
    [
        "three",
        1
    ],
    [
        "one",
        3
    ],
    [
        "two",
        4
    ]
]
1 Like