How to send data from function node to ha service node

How to send data from function node to ha service node?

16.06.2021_18.33.03_REC

I need to fill this information to ha service node:

Please post what’s in the function node.

Here function node code:

var service1 = ("service1", "set_speed");
var domain = ("domain", "fan");
var entity1 = ("entity1", "fan.balcony_light_n_fan");
var topic1 = ("home/rooms/balcony/switch-01/button-02/state");
var topic2 = ("home/rooms/balcony/switch-01/button-03/state");
var topic3 = ("home/rooms/balcony/switch-01/button-04/state");
    
 if (msg.payload === "pressed" && msg.topic === topic1){
    msg.payload = {
    domain: domain,
    service: service1,
    data: { entity_id: entity1},
    };
    node.send(msg);
    node.log("on fan-speed-1");
}


 if (msg.payload === "pressed" && msg.topic === topic2){
    msg.payload = {
    domain: domain,
    service: service1,
    data: { entity_id: entity1 },
    };
    node.send(msg);
    node.log("toggle fan-speed-2");
}

 if (msg.payload === "pressed" && msg.topic === topic3){
    msg.payload = {
    domain: domain,
    service: service1,
    data: { entity_id: entity1 },
    };
    node.send(msg);
    node.log("toggle fan-speed-3");
}

I don’t know where to put:

{"speed":"low"}
{"speed":"medium"}
{"speed":"high"}

I try like this, but I get API error on ha service node:

API error:
Call-service API error. Error Message: required key not provided @ data['speed']

var service1 = ("service1", "set_speed");
var domain = ("domain", "fan");
var entity1 = ("entity1", "fan.balcony_light_n_fan");
var topic1 = ("home/rooms/balcony/switch-01/button-02/state");
var topic2 = ("home/rooms/balcony/switch-01/button-03/state");
var topic3 = ("home/rooms/balcony/switch-01/button-04/state");
var low = [low];
var medium = [medium];
var high = [high];
    
 if (msg.payload === "pressed" && msg.topic === topic1){
    msg.payload = {
    domain: domain,
    service: service1,
    data: { entity_id: entity1, speed: low },
    };
    node.send(msg);
    node.log("on fan-speed-1");
}


 if (msg.payload === "pressed" && msg.topic === topic2){
    msg.payload = {
    domain: domain,
    service: service1,
    data: { entity_id: entity1, speed: medium },
    };
    node.send(msg);
    node.log("toggle fan-speed-2");
}

 if (msg.payload === "pressed" && msg.topic === topic3){
    msg.payload = {
    domain: domain,
    service: service1,
    data: { entity_id: entity1, speed: high },
    };
    node.send(msg);
    node.log("toggle fan-speed-3");
}

I’m not sure if there was some other purpose for this but we could make it a little simpler.

var topic1 = ("home/rooms/balcony/switch-01/button-02/state");
var topic2 = ("home/rooms/balcony/switch-01/button-03/state");
var topic3 = ("home/rooms/balcony/switch-01/button-04/state");
    
 if (msg.payload === "pressed" && msg.topic === topic1){
    msg.payload = { 
    "low"
    };
    node.send(msg);
    node.log("on fan-speed-1");
}


 if (msg.payload === "pressed" && msg.topic === topic2){
    msg.payload = {
    "medium"
    };
    node.send(msg);
    node.log("toggle fan-speed-2");
}

 if (msg.payload === "pressed" && msg.topic === topic3){
    msg.payload = {
    "high"
    };
    node.send(msg);
    node.log("toggle fan-speed-3");
}

Then use

{"speed":"{{ payload }}"}

in the data field.

That’s not actually valid JS. I think you meant this:

var topic1 = ("home/rooms/balcony/switch-01/button-02/state");
var topic2 = ("home/rooms/balcony/switch-01/button-03/state");
var topic3 = ("home/rooms/balcony/switch-01/button-04/state");
    
 if (msg.payload === "pressed" && msg.topic === topic1){
    msg.payload = "low";
    node.send(msg);
    node.log("on fan-speed-1");
}


 if (msg.payload === "pressed" && msg.topic === topic2){
    msg.payload = "medium";
    node.send(msg);
    node.log("toggle fan-speed-2");
}

 if (msg.payload === "pressed" && msg.topic === topic3){
    msg.payload = "high";
    node.send(msg);
    node.log("toggle fan-speed-3");
}

Although @lpt2007 if its important to you to have the function node set everything and have the service node be blank then you can tweak your original code. The problem was that you were declaring low, medium and high like this:

var low = [low];
var medium = [medium];
var high = [high];

This isn’t valid. First the speed should be a string not an array. Second you’re using the variables before they are declared. Tweak your code like this and it will work fine, you’re passing it to the call service node correctly you’re just setting speed wrong:

var service1 = ("service1", "set_speed");
var domain = ("domain", "fan");
var entity1 = ("entity1", "fan.balcony_light_n_fan");
var topic1 = ("home/rooms/balcony/switch-01/button-02/state");
var topic2 = ("home/rooms/balcony/switch-01/button-03/state");
var topic3 = ("home/rooms/balcony/switch-01/button-04/state");
var low = "low";
var medium = "medium";
var high = "high";
    
 if (msg.payload === "pressed" && msg.topic === topic1){
    msg.payload = {
    domain: domain,
    service: service1,
    entity_id: entity1,
    data: { speed: low }
    };
    node.send(msg);
    node.log("on fan-speed-1");
}


 if (msg.payload === "pressed" && msg.topic === topic2){
    msg.payload = {
    domain: domain,
    service: service1,
    entity_id: entity1,
    data: { speed: medium }
    };
    node.send(msg);
    node.log("toggle fan-speed-2");
}

 if (msg.payload === "pressed" && msg.topic === topic3){
    msg.payload = {
    domain: domain,
    service: service1,
    entity_id: entity1,
    data: { speed: high }
    };
    node.send(msg);
    node.log("toggle fan-speed-3");
}

Although just an FYI, as the docs note fan.set_speed is deprecated. So consider switching this to either fan.set_preset_mode or fan.set_percentage before HA breaks it for you in a couple releases.

EDIT: Sorry, small change to above. Speed has to be inside data to be properly passed along as service data. Changed the code to reflect that.

EDIT 2: Ack. Ok I see what happened. Node RED wants entity ID next to domain and service not inside data. data is just for the stuff besides entity_id.

1 Like

Since you have domain service entity and data in the message could you leave most of the call service node blank?

edit: answer is yes, it’s posted above.

1 Like

Yea you totally could. You weren’t wrong at all, yours is simpler by moving the redundant stuff to the call service node. I am just guessing the author wanted everything in the function node and blank out the other but I would just do what you showed personally.

Thanks All for suggestions. :slight_smile:

My final working function node is:

var service1 = ("service1", "set_speed");
var service2 = ("service2", "turn_off");
var domain = ("domain", "fan");
var entity1 = ("entity1", "fan.balcony_light_n_fan");
var topic1 = ("home/rooms/balcony/switch-01/button-02/state");
var topic2 = ("home/rooms/balcony/switch-01/button-03/state");
var topic3 = ("home/rooms/balcony/switch-01/button-04/state");
var low = ("low");
var medium = ("medium");
var high = ("high");
var speed = ("speed");
    
 if (msg.payload === "pressed" && msg.topic === topic1){
    msg.payload = {
    domain: domain,
    service: service1,
    data: { entity_id: entity1, speed: low },
    };
    node.send(msg);
    node.log("fan-speed-1");
}

 if (msg.payload === "depressed" && msg.topic === topic1){
    msg.payload = {
    domain: domain,
    service: service2,
    data: { entity_id: entity1 },
    };
    node.send(msg);
    node.log("off");
}


 if (msg.payload === "pressed" && msg.topic === topic2){
    msg.payload = {
    domain: domain,
    service: service1,
    data: { entity_id: entity1, speed: medium },
    };
    node.send(msg);
    node.log("fan-speed-2");
}

 if (msg.payload === "depressed" && msg.topic === topic2){
    msg.payload = {
    domain: domain,
    service: service2,
    data: { entity_id: entity1 },
    };
    node.send(msg);
    node.log("off");
}

 if (msg.payload === "pressed" && msg.topic === topic3){
    msg.payload = {
    domain: domain,
    service: service1,
    data: { entity_id: entity1, speed: high },
    };
    node.send(msg);
    node.log("fan-speed-3");
}

 if (msg.payload === "depressed" && msg.topic === topic3){
    msg.payload = {
    domain: domain,
    service: service2,
    data: { entity_id: entity1 },
    };
    node.send(msg);
    node.log("off");
}

Hey>

Can you share all the automation of the fan :slight_smile:

And will it work on IFAN that works through MQTT

I try with increase and decrease, but when I increase to 100% decrease stop working.

Here is code:

var service1 = ("service1", "increase_speed");
var service2 = ("service2", "decrease_speed");
var service3 = ("service3", "turn_off");
var domain = ("domain", "fan");
var entity1 = ("entity1", "fan.balcony_light_n_fan");
var topic1 = ("home/rooms/balcony/switch-01/button-02/state");
var topic2 = ("home/rooms/balcony/switch-01/button-03/state");
var topic3 = ("home/rooms/balcony/switch-01/button-04/state");
var step = (33.333333333333336);
var percentage_step = ("percentage_step");
    
 if (msg.payload === "pressed" && msg.topic === topic1){
    msg.payload = {
    domain: domain,
    service: service2,
    data: { entity_id: entity1, percentage_step: step },
    };
    node.send(msg);
    node.log("decrease_speed");
}

 if (msg.payload === "pressed" && msg.topic === topic2){
    msg.payload = {
    domain: domain,
    service: service1,
    data: { entity_id: entity1, percentage_step: step },
    };
    node.send(msg);
    node.log("increase_speed");
}

 if (msg.payload === "pressed" && msg.topic === topic3){
    msg.payload = {
    domain: domain,
    service: service3,
    data: { entity_id: entity1 },
    };
    node.send(msg);
    node.log("off");
}

Any idea what is wrong with code?

Shure what do you need?

If you only want to control iFAN from HA, you must flash iFAN with tasmota, than add tasmota integration under configuration/integrations. And use this card you can install it trough HACS

1 Like