Namespace ... undefined

Hi,

Still trying to understand templating …

I’ve read the Jinja docs but … I misunderstand how the use of namespace(var=val), or may be it’s the scope.

The assignment ’ set ns = namespace(…’ is OK, no error
But when trying to use in -service:rest_command, the error ‘ns undefined’ raise !

What I want to do is :
set/define a variable and be able to use it later, in another service (same trigger …)
How to do that ?

I guess I also misunderstand the ‘embebdment’ and interactions of/between differents items like service: , action: …
Any ‘for the noob’ docs on this subject ? Thanks for a link I would be able to understand …

alias: 'rhasspy SetLight'
  trigger:
    platform: event
    event_type: rhasspy_SetLight
    #event_data: 
    #   piece2: piece
  action: 
    - service_template: >
        {% set action = trigger.event.data.action %} 
        {% set niveau = trigger.event.data.niveau %}
        {% set ns=namespace(test="test") %}
        {% if action == 'allume' %}
        light.turn_on
        {% elif action == 'éteint' %}
        light.turn_off
        {% else %}
        chabada
        {% endif %}
      data_template: 
        entity_id: light.bureau
    - service: rest_command.tts
      data_template: 
        payload: >
          {% set piece = trigger.event.data.piece %} 
          {% set action = trigger.event.data.action %}
          j'{{action}} la lumière de {{piece}} et {{ns.test}}

Thanks for help !
p

As far as I know you can’t use a variable from one template in another template even if it is in the same automation, you can only use it in the same template. I think the namespaces are for inside the same template.

2 Likes

@Burningstone is correct. There is zero way for a variable to leave a template without a custom integration, or writing it to something else (i.e. an input_number). The namespace is if you want the variable to leave the current scope. i.e. inside of an if block or for loop.

If what you posted is something you want to do, you could achieve it with a script. Those parameters passed in are available for the whole script.

script:
  rhasspy_setlight_script:
    # my_input is a 2 part variable separated by comma.
    # Part 1 is the service
    # part 2 is the other data...
    sequence:
      - service_template: {{ my_input.split(',')[0] }}
        data_template:
          entity_id: {{ entity_id }}
      - service_template: rest_command.tts
        data_template:
          payload: "The variable was {{ my_input.split(',')[1] }}"

Then just call your script in the automation.

alias: 'rhasspy SetLight'
  trigger:
    platform: event
    event_type: rhasspy_SetLight
    #event_data: 
    #   piece2: piece
  action:
    - service: script.rhasspy_setlight_script
      data_template:
        # Create a value with "service_name, value"
        my_input: > 
          {% set action = trigger.event.data.action %} 
          {% set niveau = trigger.event.data.niveau %}
          {% set ns=namespace(action="action", test="test") %}
          {% if action == 'allume' %}
            {% set ns.action="light.turn_on" %}
          {% elif action == 'éteint' %}
            {% set ns.action="light.turn_off" %}
          {% else %}
            {% set ns.action="chabada" %}
          {% endif %}
          {{ ns.action ~ "," ~ ns.test }}
        entity_id: light.bureau

It’s a little hacky…but it should work. It seems better than creating an input_text to store values for us.

2 Likes

Why is namespace used in your action?

Whereas a variable used within a for-loop has its scope limited to the for-loop (and represents a use-case for namespace), there’s no such constraint for if-else.


Ok, I now see you just copy-pasted the original code. FWIW, the use of namespace is unnecessary in this situation.

You might want to take a look at Variables in HACS. That lets you store variables that are persistent.

Thanks to everyone !
i’ll read all your comments, suggestions and explanations.

‘script’ was my next subject…i guess it’s time now
:grin:

i’ll let you now here if something is still difficult for me.

thanks again
p

Yeah, my example, there is zero reason to use namespace. Though I guess I didn’t realize variable scope would persist outside of the if statement. Too used to c/c++. So I learned something there!

The only reason you would maybe do something like I did is if you’ve set up an elaborate template with macros and what not to parse something and you want to preserve multiple outputs of that template for other tasks. Otherwise, just create a new script data variable for each thing.

But I feel like if this is your design, there’s probably a different approach you can use to do what you’re trying to do :stuck_out_tongue:

Hi everyone,

The idea behind a namespace/global variable was to be able use it in differents services/actions …
(in my example, I used 1°) service_template and then 2°) service:rest_command.
I wanted to ‘share’ variables between these 2 services.)

But I guess they are other way to achieve this, that I still have to discover.

Seems script is one of them …

Keep learnin’
:slight_smile:

Can you recall what you read that led you to believe namespace could do that?

The documentation for Jinja2 is quite clear about the use-case for namespace:

The main purpose of this is to allow carrying a value from within a loop body to an outer scope.

1 Like