Pass All Payload Info Into 'Data' Field From Function

Hello,

I am trying to create a function that sets all of the different field values (service, domain, entity_id, data) and then push that into the “Data” field of a call service node. The idea is that none of the other fields are set in the call service node, allowing me to use one function node to, for example, turn on a light at a certain brightness or toggle an input_boolean.

This is what i have in the function node:

var msgA = {};

let control = msg.payload.event.device_id
let rocker = msg.payload.event.property_key
let click = msg.payload.event.value


if (control == 'light.bedroom_ceiling_light' && rocker == '001' && click == 'KeyPressed2x' ) {
    msgA = { "payload": { "domain": "input_boolean", "service": "turn_on", "entity_id": "input_boolean.sleep_mode" } }
    return [msgA];
}

else if (control == 'light.bedroom_ceiling_light' && rocker == '002' && click == 'KeyPressed2x') {
    msgA = { "payload": { "domain": "light", "service": "turn_on", "entity_id": control, "brightness_pct": 15 } }
    return [msgA];
}

return [null];
// return msg;

This call service node works:

However, what I want to do, does not, and I believe it is because of the formatting of the data field:

You’re using the data field as if it’s like an HA field that supports templates, but it does not. Instead you would have to change the selector from JSON ("{}") to JSONata (“J”) and then enter it in the following format:

{ "data": payload }

However, this likely will still not work because it may complain about extra unwanted fields since you’re putting all of payload in there. You might find it easier to just define “msg.data” in your inbound message, or put all the data-related fields in “msg.payload.data” and then use that in the JSONata.

I got it figured out. msg.domain and msg.service cannot be in the payload.

var msgA = {};

let dimmer = msg.payload.event.device_id
let rocker = msg.payload.event.property_key
let click = msg.payload.event.value

if (rocker == '001' && click == 'KeyPressed2x') {
    if (dimmer == 'light.bedroom_ceiling_light') {
        let payload = { "entity_id": "input_boolean.sleep_mode" };
        msgA.payload = payload;
        msgA.domain = "input_boolean";
        msgA.service = "turn_on";
        return [msgA];
    }
}

else if (rocker == '002' && click == 'KeyPressed2x') {
    if (dimmer == 'light.master_bathroom_lights') {
        let payload = { "entity_id": dimmer, "brightness_pct": 50 };
        msgA.payload = payload;
        msgA.domain = "light";
        msgA.service = "turn_on";
        return [msgA];
    } 
    else {
        let payload = { "entity_id": dimmer, "brightness_pct": 15 } ;
        msgA.payload = payload;
        msgA.domain = "light";
        msgA.service = "turn_on";
        return [msgA];
    }
}

return [null];

The call-service accepts config values via the input. https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/call-service.html#input show how to write msg.payload to configure the node. Doing it this way you don’t have to use any mustache templates inside the call-service node.