Can I use Template Text to change the name of a device?

I have 4 binary sensors to detect if switches are on or off. For now, I’m giving them the names Switch1 through Switch4.

I’d like to make it so I can use the web interface to change their names. (Not worried about the ID, just the name that’ll show up on the web interface and for Home Assistant.) I see how I can use Template Text to change the value of a text field. Is there any way to use that text variable I create with a Template Text as the name of a sensor? And when I change the value of the text variable (in the web interface), is there a way to make sure the name is updated on the web page as well?

You probably can use set_name() to change its name, but I’m not sure that will automatically update on Home Assistant side or the Web interface… You have to test.
And remember to change that on on_boot also, as the name change won’t be permanent.

Aha, just realized you wanna change device name, not an entity name.
I don’t think you can do that dynamically.
The method above shoukd work to change the switch entities names.

Making sure I get the boot issue - so I’d use restore_value: true to make sure the new name was preserved between boots, then update the name on the device when it reboots.

I may have “entity” and “device” confused. I’ll have to check on that.

When I create a binary sensor, does that create an entity or a device?

restore_values will retain the state, not the name. So you will have to call set_names on each boot.

Please share your yaml and I can try to help with the code. :wink:

A binary sensor is an entity.
Your esp32 running ESPHome is a device.

Okay. Got the difference between device and entity and I follow on the part about on_boot and updating the name. (Sometimes if I’m not completely sure I understand something, I just rephrase it to see if I’ve got it clear in my head - so I guess I did, but wanted to be sure. Thanks!)

I’m about to go to bed, so I’ll experiment with the YAML file tomorrow when I get up. Let me test it out and experiment and see if I can get it working on my own first. If not, I’ll post the file. (I figure if I have to poke around a bit, I have a better chance of understanding what happens. I think I’m finally beginning to get the feel of how ESPHome and HA YAML files work.)

1 Like

Ok.
I just woke up, so we are probably at different time zones… :smiley:

But this is kind of what I would try:

esphome:
  name: test1
  friendly_name: test1
  on_boot: 
    then:
      - lambda: |-
          if (!id(switch1_name).state.empty()) {
            id(switch1).set_name(id(switch1_name).state.c_str());
          }

switch:
  - id: switch1
    name: Switch 1
    platform: template
    optimistic: true
    restore_mode: RESTORE_DEFAULT_OFF

text_sensor:
  - id: switch1_name
    name: Switch 1 name
    platform: template
    on_value: 
      then:
        - lambda: |-
            if (!x.empty()) {
              id(switch1).set_name(x.c_str());
            }

Again, I’ve never tried this and I don’t know how the API and the web interface will react to dynamic name changes, but I would give it a try.
Maybe you have to reset your ESP32 to have it taking effect.

I haven’t done anything using on_boot yet - want to deal with one thing at a time.

I’m also having trouble understanding string manipulation and usage in YAML. For instance, when I’ve tried to use logger.log "The new value is...", I’ve had trouble and have tried several different formats to be able to specify the text in a log entry. I found that I’d get gibberish and, no matter what I changed the text to, it was the same gibberish, which makes me think instead of getting the text, I’m getting a pointer to the text. I haven’t done anything in C++ in over a decade, so I’m not sure how to specify that I want what is being pointed to, not the pointer.

Here’s what I was using just to read the variable and have it printed to the log:

on_value:
  - logger.log:
    format: "DEBUG: Name changed to: %s"
      args:
        - MasterSwitchName.c_str()

(That was within the text component - going to paste in the entire text component after I removed that, below.)

So, somehow, with that, I was getting what looks more like a pointer than the text being pointed to. (Unless there’s some conversion issue, like C++ is reading UFT8 and YAML is reading ASCII, which I doubt is the issue.)

So I went on and removed the logging component and added in the lamda you provided. Here’s the full section:

text:
  - platform: template
    id: MasterSwitchName
    name: "Master Switch Name"
    optimistic: true
    min_length: 0
    max_length: 64
    initial_value: "Master Switch"
    restore_value: true
    mode: text
    web_server:
      sorting_group_id: sorting_group_values
      sorting_weight: 2
    on_value:
      then:
        - lambda: |-
            if (!x.empty()) {
              id(MasterSwitch).set_name(x.c_str());
            }

I used a different format than what you had, since I was using what I had been from earlier to display and let me change the value.

I found a few issues with the name of the master switch not showing up sometimes, but I think that’s another issue, so we can set that issue aside for now. I did find when I changed it, I would have to reload the web page to get it to show. (I think I may have had to reboot the chip - not sure at the moment.) But when I did that, here’s what I got:


Which looksl ike another pointer instead of the text. I got other things, too, once I got this:

I need to do more testing, but I have to take care of a few things with the family before I have time to do it. What I get from this:

  1. This is changing the name of the entity. I have not registered this in HA at this point, and don’t want to until I know I’ve got things working. Don’t want to keep adding and removing and dealing with extra things like that. Just want to make it work on the chip first.
  2. Somehow, the lamda, and the function I used to read the string, are not getting the text, but seem to get a pointer, or, from looking at that last screenshot, maybe it’s treating a string as a pointer to some random spot in memory.

Related to this: I mentioned I am having a hard time understanding string handling in YAML, or, at least, in ESPHome. It looks like a lot of it is done with C++ in lambda functions. Is that true? I’ve searched, but can’t find anything about how to work with strings (like compare them, see if they’re empty, or insert them into text, or set something else equal to them) in the YAML file. If anyone can tell me more about that or if there’s a page that covers that, it’d help me understand what’s going on.

The HA backend is written in Python, the front end in JavaScript/TypeScript, end-user .yaml coding with jinja. The default DB is SQLITE (which you can change to MariaDB, PostgreSQL or MySQL), communication with HA is by Websockets for realtime updates, REST API for integration with other services - and you can also use MQTT for communication with IOT devices.

I am also very interested in being able to change the names (or labels shown) for entities displayed on dashboards (or at least be able to show an entity value with no label to programmatically do the same thing visually).

I would also like to see polymorphism across scripts and the ability to create entities at runtime through code, but I think those latter two will never happen!

Did some playing around and testing. I found I can print the new name to the log with:

    on_value:
      then:
       - logger.log:
           format: "DEBUG: Name changed to: %s"
           args: ["x.c_str()"]

I get, now, that x will refer to the value of the text in the Text Template. Wasn’t sure about that earlier, but finally figured it all out. This function will write to the log a message with the text value or state, so x.c_str() is definitely returning the actual value of the text.

But then, when I add the function suggested here:

    on_value:
      then:
       - logger.log:
           format: "DEBUG: Name changed to: %s"
           args: ["x.c_str()"]
       - lambda: |-
           if (!x.empty()) {
             id(PrimarySwitch).set_name(x.c_str());
           }

I find it DOES change the value of the name of the entity, but it changes it to gibberish. (Again, as I mentioned before, I think this is because there’s a pointer involved and I’m either writing over it or something like that.)

I think this narrows down the issue I brought up earlier. Now it’s shown that x.c_str() is returning the value. That leaves the issue of just what id(PrimarySwitch).set_name(x.c_str()) is changing and how to do that by working with the pointer. (Again, I’m guessing it’s a pointer issue. I don’t have the experience in C++ that many hear do have.)

@ImaginaryTango why do you keep saying c++, read my earlier post?

This is about ESPHome, which is yaml based but with c++ in the behind.
Only the codegen is Python, but the change proposed must be c++.

Lambda functions are in C++ and I also see that when I make changes to my YAML file and upload it, it’s compiled and linked and the files it compiles are .cpp files.

I did not realize - nice!

1 Like