# How to format energy data

**URL:** <https://discourse.nodered.org/t/how-to-format-energy-data/82237>\
**Category:** General\
**Created:** [21 October 2023 09:12 UTC](https://discourse.nodered.org/t/how-to-format-energy-data/82237 "2023-10-21T09:12:43Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [21 October 2023 09:12 UTC](https://discourse.nodered.org/t/how-to-format-energy-data/82237/1 "2023-10-21T09:12:43Z")

</div>

I have run into a small issue during my attempt to optimize even more the data that is published.

I would like to create a msg property "TimeDelta" with the object parameter (e.g. "ENERGY.Power") and the values of the different iterations.

I was trying to get it done with

```auto
let Parameters = ["ENERGY.Power", "ENERGY.Today", "ENERGY.Voltage", "ENERGY.Current", "ENERGY.Factor", "ANALOG.Temperature"]
msg.TimeDeltas = []
msg.TimeDeltas.push({ name: parameter[i], value: 1 })

```

but the result is

```auto
{"TimeDeltas":[{"name":"E","value":0}]}

```

It should be

```auto
[ {
    TimeDelta: {
      ENERGY: {
        Power: {
          "0": 1,
          "1": 2,
          "2": 3,
        }, }, }, },];
```

---

<div class="post-metadata">

**Author:** ![GogoVega](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gogovega/32/71313_2.png) [@GogoVega](https://discourse.nodered.org/u/GogoVega)\
**Post date:** [21 October 2023 12:02 UTC](https://discourse.nodered.org/t/how-to-format-energy-data/82237/2 "2023-10-21T12:02:33Z")

</div>

What are you trying to do? You talk about two nodes but we see a function which sends a warning.

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [21 October 2023 12:04 UTC](https://discourse.nodered.org/t/how-to-format-energy-data/82237/3 "2023-10-21T12:04:42Z")

</div>

Sorry, I had fixed that issue and was editing to show my current problem while you responded.

---

<div class="post-metadata">

**Author:** ![GogoVega](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gogovega/32/71313_2.png) [@GogoVega](https://discourse.nodered.org/u/GogoVega)\
**Post date:** [21 October 2023 12:11 UTC](https://discourse.nodered.org/t/how-to-format-energy-data/82237/4 "2023-10-21T12:11:00Z")

</div>

What does the `msg.ENERGY.Power` contain? the desired result (TimeDelta.ENERGY.Power ?) ?  
Or do you just want to add each parameter value into the same array?

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [21 October 2023 12:17 UTC](https://discourse.nodered.org/t/how-to-format-energy-data/82237/5 "2023-10-21T12:17:37Z")

</div>

There is no msg.ENERGY.Power.

I am trying to create new msg properties.

I will try an easier to explain example:

```auto
let Parameters = ["ENERGY.Power", "ENERGY.Today", "ENERGY.Voltage", "ENERGY.Current", "ENERGY.Factor", "ANALOG.Temperature"]
msg.ValueDeltas = []

    for (let parameter of Parameters) {
       msg.ValueDeltas.push({name: parameter[i], value: msg.payload[parameter.split('.')[0]][parameter.split('.')[1]][i]})

```

So, each incoming Parameter has a value. So e.g. msg.payload.ENERGY.Power[0] would have the value 1.  
I then want to create a new msg property that looks like

```auto
[ {
    ValueDeltas: {
      ENERGY: {
        Power: {
          "0": 1,
          "1": 2,
          "2": 3,
        }, 
        Today: {
          "0": 1,
          "1": 2,
          "2": 3,
        }, 
}, }, },];

```

and so on. (I hope my syntax for the array is correct, but I think you know what I am aiming for)

EDIT: Updated code example to not perform math operation in the example code.

---

<div class="post-metadata">

**Author:** ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)\
**Post date:** [21 October 2023 12:37 UTC](https://discourse.nodered.org/t/how-to-format-energy-data/82237/6 "2023-10-21T12:37:54Z")

</div>

> [@AleXSR700](#):
>
> I hope my syntax for the array is correct

Power and Today are not arrays but objects.

> [@AleXSR700](#):
>
> ```auto
> Today: {
> "0": 1,
> "1": 2,
> "2": 3,
> },
> 
> ```

An array is contained within square brackets not squiggley ones.  
An array does not have key: value pairs.  
Not sure but I think a trailing comma is illegal in an array.  
NB Some other languages do support arrays indexed with a string ("Associative arrays"). Not, I think, javascript.

This is an array:

```auto
[1, 2, 3]

```

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [21 October 2023 12:39 UTC](https://discourse.nodered.org/t/how-to-format-energy-data/82237/7 "2023-10-21T12:39:57Z")

</div>

Sorry, msg is an array and I am trying to create a new msg property inside that array with nested objects. I think that would be the correct statement ^^

I shortened and modified an existing msg, so I may well have made a syntax mistake or two ☹

---

<div class="post-metadata">

**Author:** ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)\
**Post date:** [21 October 2023 12:41 UTC](https://discourse.nodered.org/t/how-to-format-energy-data/82237/8 "2023-10-21T12:41:31Z")

</div>

> [@AleXSR700](#):
>
> Sorry, msg is an array

I should think msg too is an object.

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [21 October 2023 12:44 UTC](https://discourse.nodered.org/t/how-to-format-energy-data/82237/9 "2023-10-21T12:44:38Z")

</div>

You are correct. msg is an object.  
The array is then the lowest level which contains name and value

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/3/d/3d4c36ef8d7793c45f6471cffc4778f95940845a.png)

Bascially I want to create an object like "payload" in the picture which is not named "payload" but ValueDeltas.

---

<div class="post-metadata">

**Author:** ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)\
**Post date:** [21 October 2023 12:47 UTC](https://discourse.nodered.org/t/how-to-format-energy-data/82237/10 "2023-10-21T12:47:38Z")

</div>

Ah yes, in the debug output array elements are printed alongside their (numerical) index.

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [21 October 2023 12:48 UTC](https://discourse.nodered.org/t/how-to-format-energy-data/82237/11 "2023-10-21T12:48:16Z")

</div>

Normally I would do something like `msg.ValueDeltas.ENERGY.Power[i] = "1"` but since I am getting the parameters from the array, that does not work so easily.  
I tried `msg.ValueDeltas[parameter][i] = "1"` and some variations of that, but it never worked. I think because I am mixing types.

I think I have to use `push` but I cannot get the syntax right.

---

<div class="post-metadata">

**Author:** ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)\
**Post date:** [21 October 2023 12:55 UTC](https://discourse.nodered.org/t/how-to-format-energy-data/82237/12 "2023-10-21T12:55:40Z")

</div>

A simple use of push(), to append array elements to an array

```auto
let myarray = [] // have to declare myarray as an empty array
myarray.push(msg.payload) // make array element 0 = payload
myarray.push({ "foo": 1, "bar": 2 }) // array element 1 is an object
myarray[5] = "egg" // This seems to be legal but inadvisable
msg.payload = myarray
return msg;

```

Note that the array element can be a simple datatype (string, number etc), an object, another array or probably something else.

---

<div class="post-metadata">

**Author:** ![GogoVega](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gogovega/32/71313_2.png) [@GogoVega](https://discourse.nodered.org/u/GogoVega)\
**Post date:** [21 October 2023 13:04 UTC](https://discourse.nodered.org/t/how-to-format-energy-data/82237/13 "2023-10-21T13:04:43Z")

</div>

Ok, i see:

```js
const energy = ["Power", "Today", "Voltage", "Current", "Factor"].reduce((acc, property) => {
  acc[property] = msg.payload.ENERGY[property];
  return acc;
}, {});

const analog = ["Temperature"].reduce((acc, property) => {
  acc[property] = msg.payload.ANALOG[property];
  return acc;
}, {});

msg.ValueDeltas = {
  ENERGY: energy,
  ANALOG: analog,
};

return msg;

```

Maybe not the best solution...

---

<div class="post-metadata">

**Author:** ![GogoVega](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gogovega/32/71313_2.png) [@GogoVega](https://discourse.nodered.org/u/GogoVega)\
**Post date:** [21 October 2023 13:13 UTC](https://discourse.nodered.org/t/how-to-format-energy-data/82237/14 "2023-10-21T13:13:14Z")

</div>

`msg` is an object but it can be sent as an array (`[msg]`), this allows you to define several msgs therefore several outputs (`[msg1, msg2]`)

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [21 October 2023 13:13 UTC](https://discourse.nodered.org/t/how-to-format-energy-data/82237/15 "2023-10-21T13:13:21Z")

</div>

This is what I basically can do without any push() because there is no array being used as part of the naming.

When I want to work with the parameters, I need to get the parameter included.

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

for (let parameter of Parameters) {
    myValueDeltas.push({ parameter : msg.payload }) // this uses "parameter" as name but should use the value of parameter
    msg.ValueDeltas = myValueDeltas
}    
return msg;

```

```auto
[{"id":"f6bbb2255bea8924","type":"function","z":"807907a1ba82ffea","name":"function 22","func":"let Parameters = [\"ENERGY.Power\", \"ENERGY.Today\", \"ENERGY.Voltage\", \"ENERGY.Current\", \"ENERGY.Factor\", \"ANALOG.Temperature\"]\nlet myValueDeltas = []\n\nfor (let parameter of Parameters) {\n myValueDeltas.push({ parameter : msg.payload }) // this uses \"parameter\" as name but should use the value of parameter\n msg.ValueDeltas = myValueDeltas\n} \nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":670,"y":2620,"wires":[["ecea2f597a5493e3"]]},{"id":"92646279f23dd4f1","type":"inject","z":"807907a1ba82ffea","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"25","payloadType":"str","x":420,"y":2630,"wires":[["f6bbb2255bea8924"]]},{"id":"ecea2f597a5493e3","type":"debug","z":"807907a1ba82ffea","name":"debug 332","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":900,"y":2610,"wires":[]}]

```

---

<div class="post-metadata">

**Author:** ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)\
**Post date:** [21 October 2023 13:14 UTC](https://discourse.nodered.org/t/how-to-format-energy-data/82237/16 "2023-10-21T13:14:41Z")

</div>

@AleXSR700 please continue with this topic as it's a different issue.

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [21 October 2023 13:15 UTC](https://discourse.nodered.org/t/how-to-format-energy-data/82237/17 "2023-10-21T13:15:34Z")

</div>

This looks interesting also. Need to read through it and understand it all first.

But I was trying to not create more constants than I have to. That's why I used ENERGY.Power and ANALAOG.Temperature directly. That way 6 lines turn into 1 line of code.

---

<div class="post-metadata">

**Author:** ![GogoVega](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gogovega/32/71313_2.png) [@GogoVega](https://discourse.nodered.org/u/GogoVega)\
**Post date:** [21 October 2023 13:20 UTC](https://discourse.nodered.org/t/how-to-format-energy-data/82237/18 "2023-10-21T13:20:54Z")

</div>

You can do this too 🙃 :

```js
msg.ValueDeltas = {
  // You create a new object with only the desired properties
  ENERGY:["Power", "Today", "Voltage", "Current", "Factor"].reduce((acc, property) => {
  acc[property] = msg.payload.ENERGY[property];
  return acc;
}, {}),
  ANALOG: ["Temperature"].reduce((acc, property) => {
  acc[property] = msg.payload.ANALOG[property];
  return acc;
}, {}),
};

return msg;

```

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [21 October 2023 13:26 UTC](https://discourse.nodered.org/t/how-to-format-energy-data/82237/19 "2023-10-21T13:26:56Z")

</div>

Ah, I think I understand the code now.

I did not specify this earlier because I would never have thought of your solution and what that would mean, but I am creating multiple new properties in my code, so with your approach I would have to execute all of the code once per msg property.... I think.

HEre is a small snippet of a block where I am creating three of these new msg properties

```auto
                        if (
                            (msg.payload[parameter.split('.')[0]][parameter.split('.')[1]][i] >= flow.get("PowerThresholdHigh") && Math.abs(msg.payload[parameter.split('.')[0]][parameter.split('.')[1]][i] - flow.get(msg.topic + parameter + [i])) >= flow.get("PowerDeltaHigh"))
                            || (msg.payload[parameter.split('.')[0]][parameter.split('.')[1]][i] <= flow.get("PowerThresholdHigh") && msg.payload[parameter.split('.')[0]][parameter.split('.')[1]][i] >= flow.get("PowerThreshold" + flow.get("tasmotaEnd")) && Math.abs(msg.payload[parameter.split('.')[0]][parameter.split('.')[1]][i] - flow.get(msg.topic + parameter + [i])) >= flow.get("PowerDelta" + flow.get("tasmotaEnd")))
                            || (context.get("betweenConditions" + [i]) == "True")
                            || (msg.payload[parameter.split('.')[0]][parameter.split('.')[1]][i] < flow.get("PowerThreshold1") && Math.abs(msg.payload[parameter.split('.')[0]][parameter.split('.')[1]][i] - flow.get(msg.topic + parameter + [i])) >= flow.get("PowerDeltaLow"))
                        ) {
                            msg.ValueDeltas.push({name: parameter[i], value: Math.abs(msg.payload[parameter.split('.')[0]][parameter.split('.')[1]][i] - flow.get(msg.topic + parameter + [i]))})
                            msg.TimeDeltas.push({name: parameter[i], value: ((new Date(msg.payload.Time).getTime()) - (new Date(flow.get(msg.topic + parameter + "_Time" + [i])).getTime())) / 1000})
                            msg.UpdateCause.push({name: parameter[i], value: "True"})
                            context.set("betweenConditions" + [i], "False")
                            flow.set(msg.topic + parameter + [i], msg.payload[parameter.split('.')[0]][parameter.split('.')[1]][i])
                            flow.set(msg.topic + parameter + "_Time" + [i], msg.payload.Time)
                            context.set(msg.topic + parameter + "_UpdateValue" + [i], msg.payload[parameter.split('.')[0]][parameter.split('.')[1]][i])
                            node.warn("PowerIf" + [i])
                        }

```

The syntax for the three `push()` commands is still incorrect as that is what I am trying to fix.

---

<div class="post-metadata">

**Author:** ![AleXSR700](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alexsr700/32/41161_2.png) [@AleXSR700](https://discourse.nodered.org/u/AleXSR700)\
**Post date:** [21 October 2023 13:31 UTC](https://discourse.nodered.org/t/how-to-format-energy-data/82237/20 "2023-10-21T13:31:31Z")

</div>

Getting closer. but still not the wanted output

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

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

```

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/d/7/d73dbec7445f148de935a0e01b47bbb02dbd7658.png)  
The object below ValueDeltas should not be named "0" but "ENERGY.Power". And then the indexes below with the value.

[Next page](https://discourse.nodered.org/t/how-to-format-energy-data/82237.md?page=2)
