Complete Async Component Example

Hi,
I set out to develop an async component, but the documentation is lacking, and I cannot find a complete example of a component that has config loading flows, lights, sensors, and switches. I have looked at the hue component source, but there is a lot more going on there with connecting to the hubs and hues and so so so much boilerplate that I am lost. Is there a better starting point for developing an async component?

Thanks!
DaAwesomeP

Deconz uses it all and is quite streamlined

So I took a look at the deconz component and there a lot of parts that are very different than the hue component, which is just more confusing. Is there an empty async component example that doesn’t include a platform-specific discovery process or other platform-specific methods? I guess what is also confusing is that I’m trying to read through the source files and link where things are called from where, but there have to be a hundred different functions. I know these things take time and effort, and I’m only asking because I think that is what would help most, but are there plans for full async docs in the roadmap?

I guess one thing I have been struggling with is just a list of all of the async methods that I need to assign and what their expected output is. For example, what do I call when my platform has an update for a switch/sensor/etc.?

1 Like

Well all of deconz different platforms keep a common base, so that should really help you identify these kinds of things.

Updating an entity:

This will read state and a lot of other properties of the entity, so make sure to have them updated before calling self.async_schedule_update_ha_state()

Feel free to use this thread to ask dev questions, or pm me on discord :+1:

Thank you for all the help! I really appreciate it!

So I should have the callback from my library call my own internal function to change the entity’s state and then call async_schedule_update_ha_state()?

That works :+1:

In deconz it specifically registers the update callback to be called

It looks like deconz adds sensors, etc. by querying the gateway. How would I do this by simply looking for a config entry where the platform is set to my domain and some other attributes?

The config entry is for credentials, then you set up your communication and create entities.

Or are you meaning you configure it from configuration.yaml?

Maybe Im misunderstanding your question…

yes, from configuration.yaml.

I’m making an async firmata component from scratch using the newer pymata_aio. It makes much more sense to define arduino pins/i2c devices/etc in the config than attempt autodiscover what could be 30 unused pins. The current firmata/arduino component doesn’t support the full capabilities of digital and analog io. Also, each pin has to be put in a mode, so that really wouldn’t work well.

Maybe you shouldn’t bother with config entries yet if you need a lot of advanced configuration then that will not be acceptable for config entries. Unless you more or less load all in a dynamic way.

I think it makes sense for config entries. Basically, it would configure like this:

firmata:
  - name: board1
    serialport: /dev/ttyACM0
  - name: remoteboard
    host: myip
    port: 12345
    handshake: mycoolstring

binary_sensor:
  platform: firmata
  board1:
   - type: pullup
     pin: 3
     name: mycoolbutton

You will probably get resistance with config entries and needing to specify exact pin per sensor.

The broader configuration part would be ok. But there would be too many things to configure a part from the service and it’s credentials.

If the component can be smart and do that automatically that would be a different thing

The way an arduino works—you have to configure each pin. How else would I do that? That is how the current arduino component works. I’m sure the Raspberry Pi GPIO component would work the same way. I could detect how many analog and digital pins a device has, but that is about it. I still have to tell those pins to listen and what mode to listen in. Firmata doesn’t remember states.

Then you will probably not achieve this as a config entry.

Feel free to ping Balloob on discord for a more correct answer though

I’m really confused. This is how the current component is configured (from the component doc):

switch:
  platform: arduino
  pins:
    11:
      name: Fan Office
    12:
      name: Light Desk
      initial: true
      negate: true

This is very similar to what I am trying to do. What is the limitation? Do async components not allow config via configuration.yaml outside the base of the component? Is it assumed that all async components are self-discovering?

Config entry is when you initiate the integration from the front end. If that is what youre meaning then the configuration.yaml is the way and you will be just fine :+1:

Scrolled up… Sorry missread your comment about config entry.

Ah no problem! So do I completely cut out the config flow parts? How do I get attributes from a sensor in configuration.yaml in my sensor.py?

If all you want to do is to create binary sensors, you don’t really need the component.

But if you wish to use component, you can pass configuration to the binary sensor platform that can do what you seek.

Right, but specifically from this example:

binary_sensor:
  platform: firmata
  board1:
   - type: pullup
     pin: 3
     name: mycoolbutton

how do I fetch type and pin from binary_sensor.py (as in what code)? In __init__.py it’s config.get(DOMAIN), so what would it be in an entity file?

They would be a part of the config

Look for how the gpio is read

Time for me to sleep