I started a tutorial series on creating custom components: https://aarongodfrey.dev/home%20automation/building_a_home_assistant_custom_component_part_1/
Would love to get feedback if any of the content is useful or if I missed anything obvious.
I started a tutorial series on creating custom components: https://aarongodfrey.dev/home%20automation/building_a_home_assistant_custom_component_part_1/
Would love to get feedback if any of the content is useful or if I missed anything obvious.
Hi Aaron
This is extremely usefully and I look forward to part 2.
/B
Here’s the 2nd part of the tutorial, covering unit testing, continuous integration and pre-commit: https://aarongodfrey.dev/home%20automation/building_a_home_assistant_custom_component_part_2/
Hi,
I tried to implement the pre-commit but keep getting the below error on many of the imports. I do the development in a Dev Container, so I don’t know if that has any influence:
custom_components/meteobridge/__init__.py:6: error: Cannot find implementation
or library stub for module named 'homeassistant.helpers.device_registry'
[import]
import homeassistant.helpers.device_registry as dr
I get several of these message, both for Home Assistant imports and for Local imports from const.py
file.
I must surely do something wrong, but I am not sure what is it. I have a .pre-commit-config.yaml
file in my root directory that looks like this:
repos:
- repo: https://github.com/asottile/pyupgrade
rev: v2.3.0
hooks:
- id: pyupgrade
args: [--py37-plus]
- repo: https://github.com/psf/black
rev: 19.10b0
hooks:
- id: black
args:
- --safe
- --quiet
files: ^((homeassistant|script|tests)/.+)?[^/]+\.py$
- repo: https://github.com/codespell-project/codespell
rev: v1.16.0
hooks:
- id: codespell
args:
- --ignore-words-list=hass,alot,datas,dof,dur,farenheit,hist,iff,ines,ist,lightsensor,mut,nd,pres,referer,ser,serie,te,technik,ue,uint,visability,wan,wanna,withing
- --skip="./.*,*.csv,*.json"
- --quiet-level=2
exclude_types: [csv, json]
- repo: https://gitlab.com/pycqa/flake8
rev: 3.8.1
hooks:
- id: flake8
additional_dependencies:
- flake8-docstrings==1.5.0
- pydocstyle==5.0.2
files: ^(homeassistant|script|tests)/.+\.py$
- repo: https://github.com/PyCQA/bandit
rev: 1.6.2
hooks:
- id: bandit
args:
- --quiet
- --format=custom
- --configfile=tests/bandit.yaml
files: ^(homeassistant|script|tests)/.+\.py$
- repo: https://github.com/pre-commit/mirrors-isort
rev: v4.3.21
hooks:
- id: isort
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.4.0
hooks:
- id: check-executables-have-shebangs
stages: [manual]
- id: check-json
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.770
hooks:
- id: mypy
args:
- --pretty
- --show-error-codes
- --show-error-context
And I installed pre-commit as per instructions.
What I would suggest to do in this instance is add an additional argument to the mypy pre-commit check to ignore missing imports.
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 9931e3a..5f58332 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -56,3 +56,4 @@ repos:
- --pretty
- --show-error-codes
- --show-error-context
+ - --ignore-missing-imports
See Running mypy and managing imports - mypy 1.9.0 documentation for more information on the cause of that error.
Thanks, that worked. Now on to reading why it shows up, and see if I can fix it
It’s been quite some time, but I finally got around to adding the 3rd part of the tutorial series. This post documents adding a config flow to the custom component. https://aarongodfrey.dev/home%20automation/building_a_home_assistant_custom_component_part_3/
Finally wrapped up this series of posts (only took nearly a year ):
Hi. Thanks for this. How up to date is this tutorial? I just upgraded HA by pulling latest and a custom_component broke because HA seems now to want to look for setup.py and not init.py?
Still working on the latest, 2021.11.5
, on my install. Could you provide some more information about what you are seeing in regards to setup.py
? As far as I know that isn’t something used in custom components.
All good, on traceback the problem was the custom component updates required a “version” parameter and the component I was using was behind in that requirement. I added the “version” parameter to the config and everything sorted itself out. The setup.py function just failed with an uninformative error report, the setup.py function likely was baulking at the missing “version” parameter.
Thank you so much for this wonderful tutorial. It fills quite a few gaps from the official documentation and adds some context where I was lost as a beginner.
Looking at the code of quite a few integrations, I noticed many integrations using a coordinator
but I have to admit that I don’t fully understand how that works. Could you maybe point me in the direction of some explanation or - even better - add another chapter to your wonderful tutorial?
All the best and happy new year!
I think the official developer documentation has a pretty good description and example: Fetching Data | Home Assistant Developer Docs
Here’s a snippet from a somewhat related blog post that describes when you would use it (Use CoordinatorEntity when using the DataUpdateCoordinator - Automate The Things) :
Home Assistant’s DataUpdateCoordinator which drastically reduces network calls by fetching all of the data needed by the entities just once. The entities then use the data stored by the coordinator to update their state. The other way to do this is to have each entity (think 10 games on your wish list) and each one individually hits the api to see if it’s on sale. Since all the data comes from the same endpoint we only need to make that call once and the
DataUpdateCoordinator
helps us manage that.
Thanks for the suggestion, I think it would be a good idea to write up a little post about it since it’s a little bit buried in the documentation.
Thanks for considering. I had found your blog post and that helped me quite a bit. However, while the documentation is great for looking up stuff, your tutorials take this to another level for a beginner like me.
There are also other things that at least to me weren’t obvious, like how to list several entities as part of one device. In the documentation, the terms of devices and entities seem to be mixed at teams - or I just didn’t get it.
I guess a lot of stuff is obvious for the seasoned Python dev and wide-spread convention, but not so obvious if you move over from another language and try to get your head around HA.
Devices vs entities can be confusing at first, but is an HA concept and not anything related to python. Consider a device to be a physical thing (like a sonos speaker) or an api. Each device can have entities, so the Sonos speaker has a media_player entity and a few switches. In order to let HA know each device you must define a unique_id when setting it up in your component. This will ensure all entities related to that device are grouped together.
It gets a little tricky when there is no physical device, like the github tutorial example component. I don’t actually define a device and I’m not entirely sure what should be considered a device (each repository added?). One day I wouldn’t mind revisiting this to see if I can make improvements there for this tutorial.
It’s helpful to browse the core code and checkout how core platinum integrations handle this for one that uses an API and not a physical device. I learned most of what I know by browsing existing code, but I still don’t consider myself to be an expert.
Thank you so much. I browsed your code and quite some other integrations and just finished my first custom integration. It still lacks good tests and probably is not very robust if something goes wrong on the way, but it works and even uses devices.
Your tutorials definitely helped a lot.
Awesome, glad to hear it!
Thanks for the tutorial. I started with your tutorial before I even found the official documentation - I probably would have been pretty confused without it! And I’m so glad to see the devcontainer thing, I was dying before I read that, as every time I made a little change I would copy it to Home Assistant and wait 1-2 mins for it to restart!
Anyway, I may be totally missing it in the documentation, but I can’t find anything that talks about how to create a device. Can you give an example of this?
You can find the documentation for devices here:
Essentially, you define a device by setting a number of properties in entities. All entities with the same properties will be bundled as a device. There is no separate class for devices.
Thanks, I guess I had trouble navigating the docs! Looks like it’s much easier than I thought!