Writing global context by using the content of a variable instead of a property in quotation marks

Hi everybody,

I am trying to write to a global context using a variable as first parameter instead of a hard-coded string but am strugling about what the syntax for that is.

If I am running the following code within a function node, it works flawlessly:

global.set("NewEnvironment.Abstellkammer.Climate.temperature", msg.payload.temperature, "file");
global.set("NewEnvironment.Abstellkammer.Climate.humidity", msg.payload.humidity, "file");

return msg;

(Abstellkammer = lumber room)

However, if I want to dynamically set the global context (don't know the exact name for this, I'm talking about the first parameter of global.set(...)) I am struggling to find the right syntax.

var myEnvironment = "NewEnvironment.";

myEnvironment = myEnvironment + msg.payload.RoomName + ".";
myEnvironment = myEnvironment + msg.payload.SensorType + ".";

global.set(myEnvironment, msg.payload.temperature, "file");
global.set(myEnvironment, msg.payload.humidity, "file");

return msg;

throws an error message:

"Error: Invalid property expression: unterminated expression"

I tried to find out about properties and tried different syntax to use my variable instead of a hard-coded first parameter, but have not been successful.

What I would like to achive, is that I am using the variable myEnvironment within the global.set function.

At the moment I'm helping myself out with using a gigantic switch node which takes care about the room name at first and duplicate versions of my function where the RoomName and SensorTypes are hard-coded.

Unfortunately I'm struggling on this tiny syntax thing here - as I think it should be possible to pass a variable there.

Any help is much appreciated.

Best
Sascha

Try adding node.warn to see what is happening...

let myEnvironment = "NewEnvironment.";

myEnvironment = myEnvironment + msg.payload.RoomName + ".";
myEnvironment = myEnvironment + msg.payload.SensorType + ".";

node.warn( { 
  "myEnvironment": myEnvironment,
  "msg.payload.temperature": msg.payload.temperature,
  "msg.payload.humidity": msg.payload.humidity
})

global.set(myEnvironment, msg.payload.temperature, "file");
global.set(myEnvironment, msg.payload.humidity, "file");

return msg;

NOTE:

this part...

global.set(myEnvironment, msg.payload.temperature, "file");
global.set(myEnvironment, msg.payload.humidity, "file");

essentially sets global[myEnvironment] to msg.payload.temperature then immediately overwirtes it with msg.payload.humidity

What are you really trying to achieve?

Hi @Steve-Mcl
thank you very much for your fast reply.

[...]
essentially sets global[myEnvironment] to msg.payload.temperature then immediately overwirtes it with msg.payload.humidity
What are you really trying to achieve?

I don't know why I didn't see this when I tried what felt like 100 alternatives, but reading "immediately overwrites..." helped me to find the error instantaneously. :person_facepalming:

I changed the code to the following, which is leading to the desired result:

var myEnvironment = "NewEnvironment.";

myEnvironment = myEnvironment + msg.payload.RoomName + ".";
myEnvironment = myEnvironment + msg.payload.SensorType + ".";

var myEnvTemp = myEnvironment + "temperature";
var myEnvHum  = myEnvironment + "humidity";


global.set(myEnvTemp, msg.payload.temperature, "file");
global.set(myEnvHum, msg.payload.humidity, "file");

return msg;

The resulting structure then is:

{"Abstellkammer":{"Climate":{"temperature":24.58,"humidity":63.88}}}

which is, what my intention was. :slight_smile:

And after I check-read this posting, further sensor data arrived into the structure, proving the correctness:

{"Abstellkammer":{"Climate":{"temperature":24.43,"humidity":58.72}},
"Wohnzimmer":{"Climate":{"temperature":22.23,"humidity":65.25}},
"Terrasse":{"Climate":{"temperature":20.88,"humidity":85.18}},
"Bad":{"Climate":{"temperature":23.53,"humidity":88.97}}} 

:slight_smile:

Thank you very much for your help @Steve-Mcl

Glad it's sorted & you understand what/why etc :slight_smile:

Here are some other approached...

const room = msg.payload.RoomName
const sensorType = msg.payload.SensorType
const data = {temperature: msg.payload.temperature, humidity: msg.payload.humidity}
global.set(`${room}.${sensorType}`, data, "file");
const room = global.get(msg.payload.RoomName, "file") || {}
const sensor = room[msg.payload.SensorType] || {}
sensor.temperature = msg.payload.temperature
sensor.humidity = msg.payload.humidity
room[msg.payload.SensorType] = thisSensor
global.set(msg.payload.RoomName, room, "file");

maybe they will help you get a deeper understanding?

1 Like

Indeed that helps a lot in understanding - and saving many, many try & errors on my side :sweat_smile:

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