Multiple Arrays with function node

Hi!

With help from this forum, I was able to create the following:

const msg2 = { payload: { prod_price_forecast: [], "solcast_rooftop_id": "MYID", "solcast_api_key": "MYKEY" }}
msg.payload.data.forEach(entry => {
    msg2.payload.prod_price_forecast.push((entry.marketprice / 1000 - 0.0048) * 1.2)
    msg2.payload.prod_price_forecast.push((entry.marketprice / 1000 - 0.0048) * 1.2)
})

//const msg3 = JSON.stringify(msg2);

//return msg3;

return msg2;

This takes the values from a payload and adds them as an array.

I now need to add another array which replaces the solcast parts of the above call.
It has to be taken from two home assistant sensors: sensor.solcast_forecast_today and sensor.solcast_forecast_tomorrow.

The values from this sensor which look like this:
image
need to be concatenated so we have the same amount of values in the array as the existing script puts out for prod_price_forecast.

So basically my questions are:
How can I count the number of values in the array at prod_price_forecast?
How can I concat the two solar sensor values to have the same number of values as prod_price_forecast?
How would I write the number of arrays into the curl command?

The final result should pretty much like this:
curl -i -H "Content-Type: application/json" -X POST -d '{"prod_price_forecast":[0.26373599999999997,0.26373599999999997,0.29424,0.29424,0.29424,0.29424,0.271596,0.271596,0.251064,0.251064,0.219312,0.219312,0.203724,0.203724,0.189456,0.189456,0.17473199999999997,0.17473199999999997,0.17360399999999998,0.17360399999999998,0.172032,0.172032,0.16756799999999997,0.16756799999999997,0.16716,0.16716,0.17495999999999998,0.17495999999999998,0.20070000000000002,0.20070000000000002,0.23531999999999997,0.23531999999999997,0.26428799999999997,0.26428799999999997,0.26424,0.26424,0.24914399999999998,0.24914399999999998,0.235416,0.235416,0.22607999999999998,0.22607999999999998,0.21647999999999998,0.21647999999999998,0.22452000000000003,0.22452000000000003,0.23099999999999998,0.23099999999999998],"prediction_horizon":48,"solar_forecast":[allsolardata_array]}' http://192.168.0.45:5000/action/dayahead-optim

I'd really appreciate your support.
Thanks!

This is basic JavaScript so you might want to go do a quick refresher course.

myarray.length gives you the number of entries in an array.

Well it probably would be a lot easier if your price forecast had the same keys as your sensor. Otherwise, you are hoping that the price forecast array has the same time-slots as the solar data.

We can't quite see the actual structure of your solar data so we have to assume it is an array of objects. In that case, the easiest thing would be to forEach the outer array and push the estimate values (I assume that's what you want?) to a new array.

Urm, why would you want to do that? Use an http-request node and it will be a lot easier.

Hi!

Thanks for your reply and sorry for my late one.

Regarding myarray.length: Thanks, I will check that.

Concatination: I think I did not specify enough what I want to do and actually appending might be a better term. I have two sensors for pv forecast: sensor.solcast_forecast_today and sensor.solcast_forecast_tomorrow.
If it is for example 20:15 in the evening, I'd need both. So data between 20:00 till 23:00(59) (prices are always for one hour) from sensor.solcast_forecast_today and from 00:00 to 19:59 from sensor.solcast_forecast_tomorrow while the actual kwh are stored in the attribute "pv_estimate".

I would need the same number of values as I have in the array of prices.

Curl: I need to create this curl command with function and/or template node. The curl command needs to hold the information about the prediction horizon, which would be the number of values in the arrays.

Thanks!

Why Curl though? Sure, if you want to use it, that's fine, you can trigger it via an exec node. But Node-RED has the native http-request node which will do most if not everything that curl can do.

Well I would also use the http node, doesn't really matter for me as long as I can build something as the curl in my initial post.

Would this be easier with the http node?

Probably. More efficient too.

Hi!

I THINK I was able to achieve some of the required functionality:

[
    {
        "id": "e796441096cb2290",
        "type": "http request",
        "z": "962f7cc1f3b91a29",
        "name": "",
        "method": "POST",
        "ret": "txt",
        "paytoqs": "ignore",
        "url": "http://192.168.0.45:5000/action/dayahead-optim",
        "tls": "",
        "persist": false,
        "proxy": "",
        "insecureHTTPParser": false,
        "authType": "",
        "senderr": false,
        "headers": [
            {
                "keyType": "other",
                "keyValue": "prod_price_forecast",
                "valueType": "msg",
                "valueValue": "prod_price_forecast"
            },
            {
                "keyType": "other",
                "keyValue": "pv_power_forecast",
                "valueType": "msg",
                "valueValue": "pv_power_forecast"
            },
            {
                "keyType": "other",
                "keyValue": "prediction_horizon",
                "valueType": "msg",
                "valueValue": "msg.payload.prod_price_forecast.length"
            },
            {
                "keyType": "other",
                "keyValue": "debug",
                "valueType": "other",
                "valueValue": "true"
            }
        ],
        "x": 1330,
        "y": 1320,
        "wires": [
            [
                "66da5f2244cadff9"
            ]
        ]
    },
    {
        "id": "82dd6511ebfe4faf",
        "type": "http request",
        "z": "962f7cc1f3b91a29",
        "name": "EPEX Spot Preise von aWATTar abfragen",
        "method": "GET",
        "ret": "obj",
        "paytoqs": "ignore",
        "url": "https://api.awattar.at/v1/marketdata",
        "tls": "",
        "persist": false,
        "proxy": "",
        "insecureHTTPParser": false,
        "authType": "",
        "senderr": false,
        "headers": [],
        "x": 620,
        "y": 1220,
        "wires": [
            [
                "9ffb9ea738887dfc"
            ]
        ]
    },
    {
        "id": "f486e90555a65b5f",
        "type": "inject",
        "z": "962f7cc1f3b91a29",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 340,
        "y": 1220,
        "wires": [
            [
                "82dd6511ebfe4faf"
            ]
        ]
    },
    {
        "id": "66da5f2244cadff9",
        "type": "debug",
        "z": "962f7cc1f3b91a29",
        "name": "debug 11",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1360,
        "y": 1440,
        "wires": []
    },
    {
        "id": "13dde51211cac169",
        "type": "change",
        "z": "962f7cc1f3b91a29",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "prod_price_forecast",
                "pt": "msg",
                "to": "payload.prod_price_forecast",
                "tot": "msg",
                "dc": true
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 940,
        "y": 1280,
        "wires": [
            [
                "d4b03fa3f6121306"
            ]
        ]
    },
    {
        "id": "9ffb9ea738887dfc",
        "type": "function",
        "z": "962f7cc1f3b91a29",
        "name": "generate pord_price_forecast array",
        "func": "const msg2 = { payload: { prod_price_forecast: [] }}\nmsg.payload.data.forEach(entry => {\n    msg2.payload.prod_price_forecast.push((entry.marketprice / 1000 - 0.0048) * 1.2)\n    msg2.payload.prod_price_forecast.push((entry.marketprice / 1000 - 0.0048) * 1.2)\n})\n//const msg3 = JSON.stringify(msg2);\n\n//return msg3;\nreturn msg2;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 380,
        "y": 1280,
        "wires": [
            [
                "45cf8107bdf0ed6d"
            ]
        ]
    },
    {
        "id": "d4b03fa3f6121306",
        "type": "api-current-state",
        "z": "962f7cc1f3b91a29",
        "name": "",
        "server": "aadbde09.d5ab3",
        "version": 3,
        "outputs": 1,
        "halt_if": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "entity_id": "sensor.pv_forecast_upcoming",
        "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": 710,
        "y": 1360,
        "wires": [
            [
                "a80e9426f9163929"
            ]
        ]
    },
    {
        "id": "da0435c4b3165ef8",
        "type": "inject",
        "z": "962f7cc1f3b91a29",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "array_length",
                "v": "10",
                "vt": "num"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 440,
        "y": 1360,
        "wires": [
            [
                "d4b03fa3f6121306"
            ]
        ]
    },
    {
        "id": "a80e9426f9163929",
        "type": "change",
        "z": "962f7cc1f3b91a29",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "data.attributes.kwh",
                "tot": "msg",
                "dc": true
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1020,
        "y": 1360,
        "wires": [
            [
                "a50b41b17e5d7477"
            ]
        ]
    },
    {
        "id": "a50b41b17e5d7477",
        "type": "function",
        "z": "962f7cc1f3b91a29",
        "name": "function 2",
        "func": "const array = msg.payload;\nconst array_length = msg.array_length\nvar array_part = array.slice(0, array_length);\nvar array_part_multiplied = array_part.map(function(element) {\n    return element * 1000;\n});\n\nmsg.array_part_multiplied = array_part_multiplied.flatMap(i => [i, i]);\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 820,
        "y": 1440,
        "wires": [
            [
                "df527422f28f7622"
            ]
        ]
    },
    {
        "id": "45cf8107bdf0ed6d",
        "type": "function",
        "z": "962f7cc1f3b91a29",
        "name": "get prediction horizon",
        "func": "const array_length = msg.payload.prod_price_forecast.length / 2;\n\nmsg.array_length = array_length;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 680,
        "y": 1280,
        "wires": [
            [
                "13dde51211cac169"
            ]
        ]
    },
    {
        "id": "df527422f28f7622",
        "type": "change",
        "z": "962f7cc1f3b91a29",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "pv_power_forecast",
                "pt": "msg",
                "to": "array_part_multiplied",
                "tot": "msg",
                "dc": true
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1040,
        "y": 1440,
        "wires": [
            [
                "e796441096cb2290"
            ]
        ]
    },
    {
        "id": "aadbde09.d5ab3",
        "type": "server",
        "name": "Home Assistant",
        "version": 5,
        "addon": false,
        "rejectUnauthorizedCerts": false,
        "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
    }
]

But unfortunately I can not see/debug the request from the http node at the end.
HTTP logger node also does not show anything here.

Do you have an idea how I could do so?

Thanks

I think you have the request set to return an object - in other words to auto-parse the "HTML"? But the return isn't HTML, it is JSON. Try outputting as a string then convert to JSON.

I get a 500 error so I can don't receive a json.

I need to debug the request itself, like showing me the complete request the http node is making.

I manually accessed https://api.awattar.at/v1/marketdata and it worked fine - so is that not the one that is giving an error?

You could try increasing the node-red logging level to see if that helps.

Otherwise, you need a proxy of some kind. or a wire-level protocol analyser. You could probably also do it by running node-red in a debugger.

I need to replace the very last Post http request node which should replace the function node and pushes all the arrays to 192.168.0.45:5000

I'd like to see the actual request that is made to this address to see what the problem is with it.