How to format energy data

I think you need to use the alternative syntax with square brackets to construct an object:

for (let parameter of Parameters) {
    let myobject = {}
    myobject[parameter] = msg.payload
    myValueDeltas.push(myobject)
    msg.ValueDeltas = myValueDeltas
}

EDIT: maybe this answer has been made irrelevant by subsequent events...

The object below Value Deltas is not named "0"!
As I said earlier on, the debug output prints the numerical index of array elements.

Yes, and I am 90 % there.

let Parameters = ["ENERGY.Power", "ENERGY.Today", "ENERGY.Voltage", "ENERGY.Current", "ENERGY.Factor", "ANALOG.Temperature"]
let myValueDeltas = []

for (let parameter of Parameters) {
    myValueDeltas.push({ [parameter.split('.')[0]] : { [parameter.split('.')[1]]: msg.payload} })
    msg.ValueDeltas = myValueDeltas
}    
return msg;

but the first object should not be 0 but already "ENERGY"

image

See the edit in my post immediately above.

image

1 Like

No, the loop is iterated for each element in the array

Oh, I just need to make it an object instead of an array. I did not realize that you had stated it as = {}.

@AleXSR700 do you want msg.ValueDeltas to be an array or an object?

So msg.ValueDeltas is an object in which you want certain properties of ENERGY object and ANALOG object

The result will be:

{
    payload: {...},
    ValueDeltas: {
      ENERGY: {
        Power: [0, 1, 2], 
        Today: [0, 1, 2],
    }
}

It is supposed to be an object, so I successfully modified jbudd's code.

Thank you both for making this first step possible!

On a related problem I would like to iterate through the length of an object but I would like to use the same code block to also process name key pair. I hope I said it right.

So I want to be able to process this input:

{
    "Time": "2023-10-21T18:49:01",
    "ENERGY": {
        "TotalStartTime": "2023-08-31T12:04:17",
        "Power": [
            9,
            10
        ]
    }
}

but also this input

{
    "Time": "2023-10-21T18:49:01",
    "ANALOG": {
        "Temperature": 70
    },
    "ENERGY": {
        "TotalStartTime": "2023-09-01T21:46:07",
        "Power": 5
    }
}

I am able to enter the for loop but I cannot get the value of "Power" for the second case because it is not an object, so it does not have the index 0.

            for (let i = 0; i < (Array.isArray(msg.payload[parameter.split('.')[0]][parameter.split('.')[1]]) ? msg.payload[parameter.split('.')[0]][parameter.split('.')[1]].length : 1); i++) {

                if (!Array.isArray(msg.payload[parameter.split('.')[0]][parameter.split('.')[1]])) {
                    i =""
                }

                flow.set(msg.topic + "/" + parameter.replace(".","") + [i], msg.payload[parameter.split('.')[0]][parameter.split('.')[1]][i])
...
//rest of code

As you can see I tried to initialize "i" as "" but that does not allow me to read msg.payload[parameter.split('.')[0]][parameter.split('.')[1]][i] and returns TypeError: Cannot set properties of undefined (setting '')
It would work if I removed the [i], so the rest seems to be fine. I just need to find a way to make the [i]"disappear" if isArray is false.

I am guessing that there is a really simple solution but I cannot figure it out :frowning:

I don't understand why you don't use my code, it does everything you ask, no need to get into hellish loops

If that is the case, then I apologize because I then I do not understand how your code works :frowning:

The content of msg.ValueDeltas depends on different conditions being met in my code. So I check the input data and depending on what it is and what the parameter is, I process it differently.

From my (possible poor) understanding, your code assumes that I always assing the value of msg.payload.WhatEverParameter and do not perform further processing.
And if I did, I would have to do the processing inside msg.ValueDeltas = {}. And have a separete processing block for TimeDelta and ValueDelta.

If that is the case, then that would also be a complete code re-write as creating those msg properties is only one command in a block of commands.

So you can define your process in the reduce function: actually the function adds the property key (e.g. "Power") to the object and the value as msg.payload.ENERGY[property] (e.g. "msg.payload.ENERGY.Power"). You can change the value to whatever you want.
There are two functions, one for ENERGY and the other for ANALOG, joining them would be difficult to reread and would complicate its role.
You can use Object.entries to convert object to array, if you prefer

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.