Dynamically create HA entity

yeah you are right. stuff gets created. but the behaviour from entities other then sensors is not like expected.
i tried to create switches on the fly long time ago, but when trying to use it it got buggy. for example you couldnt change the state from the switch in HA.
but thanks for saying it again, because i just got an idea to try out.

edit:
tried to create a switch. it is created, but as mentioned you cant change the state
tried to change the state by using a service_call but that doesnt work.

At one point, I was able to do this. I created a switch.test using “set_state” from AppDaemon, detected the switch toggle from the UI, and then performed a set_state again to show the change. Basically, I implemented “input_boolean” within AppDaemon that appeared as “switch.test” in HASS. I did it because I wanted to know if I could. The amount of code required was absurd and it was much easier to just make an actual input_boolean and react to it. I don’t remember all of the events I had to detect but, if I get some free time in the near future I’ll try to do it again just in case the code is useful to you.

the problem is that you cant change the state from the created switch in the HA GUI
i used self.set_state(“switch.test”, state = “on”) and the switch is there, but i cant set it to off in any way i try.

so yeah if you found a way i would love to know how.

I don’t have AppDaemon even running any more, but I was able to verify what I thought to be true using the API.

If I do: set_state(‘switch.testme’,‘on’) … then, in the UI, we see the switch. If I then toggle that switch in the UI, the following event it emitted.

{"event_type":"call_service","event":{"domain":"switch","service":"turn_off","service_data":{"entity_id":"switch.testme"}}}

So, based on the AppDaemon docs, I would need something like…

listen_event(my_call_back, event = "call_service")

then, in my_call_back… I would do…

def my_call_back(self,event_name,data, kwargs):
  if(data.domain == "switch" and data.service_data.entity_id == "switch.testme"):
    # yes... this is me... do the things
  else:
    # this was a service_call to something that isn't me... so ignore it.

Also, keep in mind, you’ll need to data.domain == “homeassistant” as well. For UI interaction, it’ll generally be switch.turn_off/turn_on. But, in automations, one might call homeassistant.turn_on/turn_off… so you need to catch them both.

Somewhere in the code of your call back, you need to make sure to self.set_state() back on if they turned the device on or off if they turned it off. If you’re doing something more than an input_boolean type behavior, generally you’d want to run the code to turn the thing on first, and then report back with the state saying that it’s on.

1 Like

the switch doesnt toggle. it stays to on no matter what i try. (or at least it immediatly switches back)
so i am not sure if the event will be triggered at all. (but i could try)
if the event is triggered then i would need to use set_state to set the switch to off after the event is triggered.

it is worth a try, it would only be 1 app for all “on the fly” entities
to make them work.

but i think it will create a circle.

if i try to switch the boolean in the UI, it would generate an event, then i need to use set_state and that would also generate an event.

tried it and it works. set_state doesnt trigger the event (or at least not the same)
so the app looks like:

import appdaemon.plugins.hass.hassapi as hass

class input_boolean(hass.Hass):

    def initialize(self):
        self.input_boolean = self.args["name"]
        if not self.entity_exists(self.input_boolean):
            self.set_state(self.input_boolean, state = "off")
        self.listen_event(self.change_state, event = "call_service")

    def change_state(self,event_name,data, kwargs):
        if(data["service"] == "turn_off" and data["service_data"]["entity_id"] == self.input_boolean):
            self.log(self.input_boolean + "switched off")
            self.set_state(self.input_boolean, state = "off")
        if(data["service"] == "turn_on" and data["service_data"]["entity_id"] == self.input_boolean):
            self.log(self.input_boolean + "switched on")
            self.set_state(self.input_boolean, state = "on")

with this app i can easy add new input booleans by just adding

rene:
  class: input_boolean
  module: input_boolean
  name: switch.rene

to the yaml and from that moment on i can use it in the gui and use listen_state in AD.

Thank you very much for that!!!

3 Likes

Absolutely. Glad to help.

Believe it or not, I made a climate entity with appdaemon way back in the day using this method. :slight_smile:

This is very interesting stuff. Thanks for sharing guys

did the climate entity also show like a climate entity in the gui from HA?
i tried to create a light, but it shows like a switch.
is it just a matter of adding attributes?

Yup!

Home Assistant is strange that way. The “domain” part of an entity ID (climate.myclimate or switch.myswitch) ONLY matters to the UI. Switches could be named somecrazything.mycrazything and as long as they trap the “switch.turn_on” service calls (and friends) then they’ll still WORK like a switch. But they won’t display like a switch in the UI.

At least this is how it SEEMED back when I was messing with it (I didn’t dig into HASS internals to confirm this, it just seemed to work that way when I tried it). Perhaps Home Assistant has been changed since then.

For lights, the UI responds to the “supported_features” attribute. I’m sure, in the code, it’s some kind of bitmask that ends up resulting in an integer. I’m not sure what all the values are, but, if you want a light with a brightness slider… try this… which works just fine for me and presents as a light with a brightness slider…

{
    "state": "on",
    "attributes": {
        "brightness": 255,
        "supported_features": 41
    }
}

If you want to do it “right”, you should dig into the code, find out what the bitmasks are for everything and set them accordingly. If you want to do it quickly, just find an existing light that has the features you want (RGB color, brightness, etc, etc) and copy the number from the existing entity.

and how do i find that number?

digging in the code and looking for bitmasks is hard, because i dont even know what bitmasks are :wink:

at this moment the switch on the fly is the thing i will use the most, but i might want to try other stuff too. (i know i will even just to be able to :wink: )

The easiest way to find the number is to find someone with a working, REAL, light device, have them look in dev-states and give you the number.

A quick look at source code shows this:

SUPPORT_BRIGHTNESS = 1
SUPPORT_COLOR_TEMP = 2
SUPPORT_EFFECT = 4
SUPPORT_FLASH = 8
SUPPORT_COLOR = 16
SUPPORT_TRANSITION = 32
SUPPORT_WHITE_VALUE = 128

Which would mean the light I used as an example (supported_features = 41) supports:
TRANSITION
FLASH
BRIGHTNESS

Basically… just add the numbers together for the things your device supports. For RGB and BRIGHTNESS, as example, then COLOR = 16, BRIGHTNESS = 1… so 17. For just brightness… then 1.

You’ll have to play with the numbers to see exactly which effects that enables in the UI. But that’s the gist of it.

1 Like

thanks. found where i need to look for the bitmasks.
i guess all i need to do is play around :wink:

you have played around with it.
so maybe you know if that is possible too:

is it possible to connect the created entity to a certain component from the outside?

I’m not sure what you mean by “connected component from the outside”. AppDaemon is not special in the way that it can set states and listen for events. Any application that connects to Hass’s websocket can do that. So, a NodeJS app, for instance, could do the same thing.

If you mean getting a switch that you made in AppDaemon to be handled automatically by HASS… no… that can’t be done. By setting the state of a non-existent entity, you circumvent anything automated that HASS would do for you. You can use MQTT Discovery and announce the new entity via MQTT and then home assistant will treat it like a more native switch/light/climate device.

i meant a component like limitlessled when its configured in HA.

would it be possible to connect the new entity to the already running limitlessled component?
i suspect not, but untill now i didnt think it was possible to create other working entities.

ahhh. no. not that I’m aware of. Internally, each “sensor” or “switch” is from a specific component is regarded as a type of that component. But, that can only be done from inside of HA.

1 Like

I know it’s been a while since this thread was alive. But I built an AD app to dynamically change entity attributes, or even create totally new ones, that PERSIST through updates from their components or even a full restart of Home Assistant, check out: Entity Augmentation

That post also links to a github repo containing a lot of other automation services in addition to the entity augmentation.

there is a difference between creating a new entity, or changing an entity that is created by HA.
your app creates an enormous amount of overhead, because it listens to every state change.

a better way would be just to listen to entities that you want to change/control