zachowj / node-red-contrib-home-assistant-websocket

Node-RED integration with Home Assistant
https://zachowj.github.io/node-red-contrib-home-assistant-websocket/
MIT License
494 stars 91 forks source link

Subflow Variables not working with 0.66 #1628

Open karamfil opened 5 days ago

karamfil commented 5 days ago

Describe the bug

Hi

with 0.66.0 subflow variables throwing errors

I have a subflow that uses variables as domain/entity/action and it broke

this broke all subflows that I use as templates for most of my automation.

To Reproduce

Here is an simplified example flow. very simple just inject, subflow and debug (complete msg) nodes

image

The subflow has 2 parameters switch2 and switch2_domain. and 3 nodes input, output and action or api-call-service

image

I am testing by clicking the inject. and I receive the correct message with 0.65.1

{ _msgid: "79c03bd910f2bb29", payload: 1728167133573, topic: "" }

However when I upgrade to 0.66.0 I get an error message.

HomeAssistantError: Service ${switch2_domain}.turn_off not found.

Expected behavior

to correctly evaluate subflow template variables

Screenshots

No response

Example Flow

No response

Environment Information

Version: 0.66.0

Home Assistant version: 2024.10.1 Companion version: 4.1.1

Node-RED version: 4.0.3 Docker: yes Add-on: no

Node.js version: v18.20.4 x64 linux OS: Linux 5.10.0-15-amd64 x64

Additional context

No response

zachowj commented 5 days ago

In version 0.66.0, there was a breaking change that combined the domain and service fields into a single action field. To adapt, you'll need to modify your environment to include both values in the action field, as environment variables can only be applied to the entire field and cannot concatenate values.

karamfil commented 4 days ago

Hey, thanks for the quick reply.

I am not too clear on what exactly I need to change, would you be able to help me? Are you saying that I need to have more variables? like:${switch2_domain_and_action_off} that is switch.turn_off - this will not be too desirable as it will exponentially add more variables.

Is there a way to interpolate values using env vars?

~if 0.66 combined both values in a single action wouldn't it be better to evaluate a variable before combining this. Or is this a new UI change removing domain and service and adding a single action field?~

zachowj commented 4 days ago

The action node allows config overrides via input. To resolve this, use a change node to build the action by combining the environment variable with "turn_off". Ensure that the "Block input overrides" option is unchecked in the action node. Add the change node before the action node and use JSONata to set msg.payload to { "action": $env("switch2_domain") & ".turn_off" }. This will concatenate the environment variable and "turn_off" into a single string, passing it to the action node to correctly override the node's local configuration.

image

karamfil commented 3 days ago

I see, thanks for this solution, I will try this!

Is this a limitation of node-red-contrib-home-assistant-websocket, node-red itself, or something else? (is it worth investing time in a more general solution to allow env var interpolation and which project would be most appropriate?)

Based on this, i suppose this is a node-red limitation? unfortunate... https://nodered.org/docs/user-guide/environment-variables

Looking at the code on the main branch in node-red I feel like having multiple env variables interpolated should be supported to some extent (for env type properties) https://github.com/node-red/node-red/blob/master/packages/node_modules/%40node-red/util/lib/util.js#L584 https://github.com/node-red/node-red/blob/master/packages/node_modules/%40node-red/util/lib/util.js#L686

Ah this is also in the doc above i just missed it:

Within the editor, the TypedInput widget can offer ‘environment variable’ 
....
- if ${} is present, it will substitute the corresponding environment variable into the result: For example, given the value "Hello ${FOO}" and the env var FOO is set to World, this results in the value "Hello World"

From what I understand so far, an idea could be to have this go through TypedInput widget with only string and environment and it would allow us to achieve this flexibility.

what are your thoughts?

zachowj commented 3 days ago

If you're asking about a global solution to insert environment variables into fields with other text, one idea is to add an "env." prefix to the Mustache template context. This way, you could do something like {{env.switch2_domain}}.turn_off. Mustache templates are already accepted in most major fields, so this approach would utilize the existing system without the need to build a completely new one.