Need some suggestions or ideas for a custom component

Hi guys,

As I’m totally new to HA and building component for it I need some suggestions from experienced people.

I’m trying to build my first custom component - I need a few sensors(or maybe devices? I don’t know) with a few attributes each that will show to some astronomical values on a daily basis. Like built-in moon and sun sensors, but for different celestial bodies and different data.

I want to see something like:

  • astro_calcs.body1 (with a state and attribute1, attribute2)
  • astro_calcs.body2 (with a state and attribute3, attribute4, attribute5, attribute6)
  • astro_calcs.body3 (with a state and attribute7, attribute8, attribute9)

Basically I want:

  1. Multiple items (sensors or devices or I don’t know what else it could be).
  2. Combine all of them under one name (e.g. astro_calcs) for simplicity.
  3. Each item will have different number of different attributes.
  4. Attributes will be different for different items.

So my questions are:

  1. Should I use sensors or devices or platform? Sorry for incorrectly used terminology - still learning all that.
  2. Should I use async or sync setup/update? (async_setup, async_setup_platform or setup_platform). Tried to look into a few moon/sun integrations and they are all different. Not sure why.
  3. Are you able to point to any existing component similar to what I explained above so I can study to create my own one? What to see how to create multiple sensors under one name.

Yes, I did check that: https://developers.home-assistant.io/docs/creating_component_index but still cannot get my head around. Really want to see anything similar - not in terms of astronomical calculation (I can do that by myself), but rather than multiple items. Like what HA does for person.user1, person.user2 etc.

Also I need to install Skyfield module for calculations. How I can do that with Home Assistant? On my local non-HA system I’m just doing: pip install skyfield for that and that’s it - I can use it in my Python scripts. But how I can do that in Home Assistant (dev environment) and in “production”?

Hope you can help me, folks!

Ideally, from a user perspective (I’m interested in this) you would have one integration that generated multiple sensors each with a state (e.g. above/below horizon) and as many attributes each as you want (e.g. next rise, next set, azimuth, altitude, max altitude, etc). You could also generate events (e.g. on rise, set and at zenith).

I can’t help with development other than to recommend looking at the code for the sun and moon integrations to get a grip on how they do it.

Thanks, @tom_l Getting better. :slight_smile:

So it should be an integration and it should be async_setup like in Sun integration and not a platform with async_setup_platform.

Yes, sun and moon integrations are my “go to” study files, but they both produce only one sensor. Now need to find how to create multiple ones. I know I’ll do it. :slight_smile:

I’m not qualified to comment on that. :slight_smile:

The other approach is to group all the sensors under one device in the integration. But as you will only ever have one device I don’t see this as bringing any advantage.

Entities are first class citizens, they are what matters in home assistant. You can group entities (sensors, binary sensors, etc) into a device, not mandatory. In the documentation you linked, there is an explanation when to use device, in your case, i don’t see anything to make device.

Ok, guys, I’ve done some study after your clarifications and yes, be an integration and it should be async_setup and not a platform or device etc.

Now I’m trying to implement all required classes and create sensors, but looks like I’m missing some important part and I cannot figure it out yet.

  1. What classes I need to implement for proper functions? Here is what I’ve got.
SCAN_INTERVAL = timedelta(minutes=1)
DOMAIN = "astro_calcs"

async def async_setup(hass, config):
    AstroCalcs(hass)
    return True

class AstroCalcs(Entity):
    def __init__(self, hass):
        self.hass = hass
        self._state = "some initial state"

    @property
    def name(self):
        return "My super cool astronomical calculations"

    @property
    def state(self):
        """Do some calculations."""
        return "some calculated state"

I guess I need some @callback ... update to update status on each scan interval. Anything else from HA point of view needs to be done for a simple calculation?

  1. Still not sure how the actual entity will be updated. How I can specify which one should be created and updated? I can easily do that with self.hass.states.async_set("astro_calcs.item1", "blah-blah-blah") and it works, but is that the right way to do that? I feel like I need to create integration services as well like described here: https://developers.home-assistant.io/docs/dev_101_services and also use async def async_setup_entry for each of my sensors like here: https://developers.home-assistant.io/docs/integration_fetching_data Am I right?

I have two basic custom integration, following two different approaches;

I would go with first one which works save couple of functions and it manages some internal exceptions. To give more information here;

  • config_flow is responsible for initial entry registration, if you need user credentials or some other input, you receive it here and write it into config entries database
  • init.py is responsible of receiving config entry which is either created in previous step or presented from a file in case of restart/reload. Using this config entry, you setup api and keep a reference of data coordinator or api client in memory as hass.data[INTEGRATION_NAME] = coordinater and all downstream sensors can access hass.data to read latest data.
    Your coordinator will fetch data from a remote api, update itself and your sensors will be aromatically informed that they need to refresh as data bad been updated. If you go with second approach, you are setting up a topic name between your coordinator and sensors and throwing a message over this topic when data is updated so all sensors should react on this event.
1 Like

I have only developed one custom integration, but I will give you some pointers.

To create sensors / entities you need to add a platform to your integration.
For your integration this would be a sensor.py which calls a method async_add_entities

async def async_setup_platform(hass: HomeAssistantType, config, async_add_entities, discovery_info=None):
    async_add_entities([
        CelestialBodySensor("body1")
    ])

class CelestialBodySensor(Entity):
    def __init__(
        self,
        name: str
    ):
        """Initialize the sensor."""
        self._name = name

    @property
    def name(self):
        """Return the name of the sensor."""
        return self._name

    @property
    def state(self):
        """Return the state of the sensor."""
        return 20 #Get state from data coordinator

When you are defining a config_flow (allowing configuration with UI) you need to setup the platform in async_setup_entry and not async_setup_platform, but everything else will be the same.

1 Like

@anon63427907 @bramski Thanks a lot guys! That really helped in understanding the way HA works. I’m still in a process of making it working, but at least I’m getting close.