I realise my problem is about understanding JS objects and arrays, I thus published this request in stackoverflow, but either I did not explain my problem correctly, or people do not understand why I need to have nested arrays and objects in Node-RED global context. No-one came back to offer real help, accept a person that thinks I should be making all nested arrays objects as well. for searching of the objects, I think they should still be arrays, I still do not have a solution. Here is what I have published in Stackoverflow here
I want to build a nested JS object, with an array, objects, arrays, etc, that will keep homie
variables at different levels, closely resembling an easy storage structure to store and retrieve from the homie v3.0.1 convention. (I include some of my own structures into the JS objects & arrays, to improve readiblity & flexibility of the code, like grouping variables leading with an _ underscore, so its not the same as the homie convention.)
The structure of the nested array / objects to be stored (in Node-RED global context - in JS object format), which I call the homie Shadow
, (roughly deviceID > nodeID > propertyID > propAttribute
, where devices, nodes, properties are all arrays of nested objects), are
:
[
{"deviceID":
{"_nodesArr":
[
{"nodeID":{
"_propArr":
[
{"propertyID":{"_propertyAttributes":
{"$attribute: attributeValue}}}
} } ] } } ]
]
Below is an example dataset, which is stored in Node-RED in a global context variable called homieShw (short for homie Shadow):
[
{"ESP70":
{"_nodesArr":
[
{"Light": {
"_propArr":
[
{"Switch":{
"val":1,
"_propAttributes":{"$settable":true}
} } ] } } ]
]
Now, heading to what I want to do, and my problem: The Javascript code, will receive messages from mqtt
, to setup the above structure, but also update the variables, for instance, when the light of this ESP is switched off, the mqtt message looks as follows:
homie/ESP70/Light/Switch/1
Without needing to quote all the code I do, I have a specific problem - and that is to store into an array further down in the array hierarchy of the homie Shadow
or variable arrHomieShw
(retreived from the global context variable homieShw
).
-
To add an ESP device in the object's first array, the JS code, which tests if the deviceID is in the array already, and if not, adds a new element to the array (this code works perfectly), from the incoming
mqtt message
above:function checkDeviceArrCreated(deviceID, arrHomieShw){ for (i=0; i < arrHomieShw.length; i++) { if(deviceID !== Object.keys(arrHomieShw[i])[0] ) { foundDeviceID = 0 } else { foundDeviceID = 1; break } } if(foundDeviceID === 0){ branch = {[deviceID]:{ "_deviceAttributes": { "$homie": $homie } }}; arrHomieShw.push( branch ); } }
-
The above function checks if the object exits, and if it does not, it pushes the new branch into arrHomieShw, this works perfectly.
-
But now, I want to do same for the array at the next level of the hierarchy of
homieShw
. Thus, I want to write into the node array of objects, by checking if the nodeID exist for the deviceID, and if not, to push a new branch into it. -
The push command does not want to push into a hierarchy as explained above. This is what I have tried, (amongst others). The function
checkNodesArrCreated()
is called, with for instance with this mqtt message :homie/ESP70/Air/Temperature/23
, after the variablearrIdxDevice = getDeviceIdx();
- see this function also below. -
In the function
checkNodesArrCreated()
, the branch variable - which is pushed into the nested arrayarrHomieShw
creates a new object, and does not branch below the same deviceID it found. I also tried to use variations of arrHomieShw.deviceID.push( branch ), but this also does not work.
How should I go about this?
//-----------------------------------------------------------------------
function checkNodesArrCreated(){
if(deviceID == Object.keys(arrHomieShw[arrIdxDevice])[0] ) {
theObj = Object.values(arrHomieShw[arrIdxDevice][deviceID])
if(theObj._nodesArr === undefined){
branch = { _nodesArr:
{[nodeID]:{"_nodeAttributes": { [nodeAttribute]: val } } }
};
arrHomieShw.push( branch );
}
}
}
//-----------------------------------------------------------------------
function getDeviceIdx(){
for (i=0; i < arrHomieShw.length; i++) {
if(deviceID == Object.keys(arrHomieShw[i])[0] ) {
return i;
}
}
return arrIdxDevice;
}
function getNodeIdx(deviceID, nodeID, arrIdxDevice, arrHomieShw){
for (j=0; j < arrHomieShw[arrIdxDevice][deviceID]._nodesArr.length; j++) {
if(nodeID == arrHomieShw[arrIdxDevice][deviceID]._nodesArr[j]){
return j;
}
}
}
Could anybody help me out of the sink-hole I find myself in now?