Fire Danger Rating

i did that a week ago but didn’t create the init.py - is that a problem?

This is the first I’ve seen to add __init__.py. Everything else is working fine that I’ve moved.

same. moved all my components and not one of those in sight and everything seems to be working

Putting an __init__.py file into a folder makes Python treat that folder as a package.

As of now custom components seem to work even without that __init__.py file, but there may be a time where either a future Python version or the Home Assistant code ignores folders without that file.

From The Great Migration blog post:

  • Components are created in <config>/custom_components/<integration name>/. Always make sure you create at least an empty __init__.py file in that folder.

Yeah I saw that… guess I need to do that for all custom components too

Yep, me too. Damn this “The Great Migration”…

I’m having troubles getting this started - I have a sneaking suspicion it has something to do with the third-party library and my installing it incorrectly. I’m running the latest version of Hassbian. Here’s what I do.

Upon logging in via Putty:

sudo -u homeassistant -H -s
pip install xmltodict
Collecting xmltodict
Downloading https://files.pythonhosted.org/packages/28/fd/30d5c1d3ac29ce229f6bdc40bbc20b28f716e8b363140c26eff19122d8a5/xmltodict-0.12.0-py2.py3-none-any.whl
Installing collected packages: xmltodict
Successfully installed xmltodict-0.12.0

I then proceed to follow the rest of your instructions - creating a folder in custom_components called nsw_rural_fire_service_fire_danger and then placing sensory.py and __init__.py into that folder.

Then, in configuration.yaml, place the following lines:

sensor:
  #RFS
  - platform: nsw_rural_fire_service_fire_danger
    district_name: Greater Sydney Region

This is the resulting error in the logs:

Error handling request
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.5/site-packages/aiohttp/web_protocol.py", line 418, in start
    resp = await task
  File "/usr/lib/python3.5/asyncio/futures.py", line 380, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.5/asyncio/tasks.py", line 304, in _wakeup
    future.result()
  File "/usr/lib/python3.5/asyncio/futures.py", line 293, in result
    raise self._exception
  File "/usr/lib/python3.5/asyncio/tasks.py", line 241, in _step
    result = coro.throw(exc)
  File "/srv/homeassistant/lib/python3.5/site-packages/aiohttp/web_app.py", line 458, in _handle
    resp = await handler(request)
  File "/srv/homeassistant/lib/python3.5/site-packages/aiohttp/web_middlewares.py", line 119, in impl
    return await handler(request)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/http/real_ip.py", line 33, in real_ip_middleware
    return await handler(request)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/http/ban.py", line 68, in ban_middleware
    return await handler(request)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/http/auth.py", line 98, in auth_middleware
    return await handler(request)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/http/view.py", line 112, in handle
    result = await result
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/config/core.py", line 21, in post
    errors = await async_check_ha_config_file(request.app['hass'])
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/config.py", line 779, in async_check_ha_config_file
    check_ha_config_file, hass)
  File "/usr/lib/python3.5/asyncio/futures.py", line 380, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.5/asyncio/tasks.py", line 304, in _wakeup
    future.result()
  File "/usr/lib/python3.5/asyncio/futures.py", line 293, in result
    raise self._exception
  File "/usr/lib/python3.5/concurrent/futures/thread.py", line 55, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/scripts/check_config.py", line 371, in check_ha_config_file
    platform = loader.get_platform(hass, domain, p_name)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/loader.py", line 86, in get_platform
    component = _load_file(hass, platform_name, LOOKUP_PATHS)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/loader.py", line 166, in _load_file
    module = importlib.import_module(path)
  File "/usr/lib/python3.5/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 986, in _gcd_import
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 669, in exec_module
  File "<frozen importlib._bootstrap_external>", line 775, in get_code
  File "<frozen importlib._bootstrap_external>", line 735, in source_to_code
  File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
  File "/home/homeassistant/.homeassistant/custom_components/nsw_rural_fire_service_fire_danger/__init__.py", line 7
    <!DOCTYPE html>
    ^
SyntaxError: invalid syntax

It seems that you have copied the wrong source - there is no DOCTYPE in the __init__.py file. When you manually copy files from GitHub, please make sure that you copy the raw file, not the HTML source of the file representation (i.e. don’t right-click on a filename and then “Save file as”). There is a “Raw” button in the UI that gives you the actual Python source code:

That did it, new it was something stupid. Thanks very much.

Yes I use vertical stacks… Didn’t I post that already above?

You can check out my lovelace file here… https://github.com/DavidFW1960/home-assistant/blob/master/ui-lovelace.yaml

You did, just my terrible indenting on my part. All working on my end, thank you very much everyone.

2 Likes

Please note that Home Assistant 0.91 will contain some more code structure changes, and hence this custom component will require a small code fix. The latest version on GitHub already contains this fix.

Without the fix you will get the following error message from 0.91 onwards:

Unable to find platform nsw_rural_fire_service_fire_danger. Search path was limited to path of component: custom_components

To fix this manually, please change line 14 in the custom component code to:

from homeassistant.components.rest.sensor import RestData

Thanks, @DavidFW1960 for making me aware of this upcoming issue.

1 Like

Is this only from 0.91 or will the fix work in 0.90.x?

Yes, this fix will only work from 0.91 onwards, but not with any previous version.

The corresponding PR which caused the need for this fix is the following. This code change is included in the current 0.91 beta releases.

Unfortunately this means that the fix must be deployed as part of the upgrade to version 0.91.

All good. Thought I better ask before I break something. I’ll just make a note to update when 0.91 comes out.

Thanks.

1 Like

What is the process for getting a custom component put into the core of Home Assistant?

I’m wanting to switch from Hassbian to Hass.io, but this currently wouldn’t be supported in Hass.io (I’m assuming) due to needing xmltodict installed.

In the meantime I have updated some files in my github repository to align with the new structure of custom components, in particular there is now a manifest.json that defines the xmldict requirement instead of doing that in the code. A quick test on my local dev instance (v0.93.0.dev0) shows that HA indeed successfully installs xmldict on startup with the latest code from my repository.
I don’t use hass.io myself, but maybe someone could give this custom component a try?

To your original question of how to get a custom component into the core:

In addition to the existing code, someone would need to write some unit tests and user documentation on how to use it. All that goes into a pull request, is reviewed, and then integrated into a next release.
However, I believe in its current state the custom component code is probably rejected in reviews, and would require some refactoring. Instead of retrieving the data as a sensor and then let users create template sensors to display the details from the feed, I think a proper component should retrieve the data in the background and then generate sensors for display automatically.
If there is a lot of interest, I could look into making all these changes to possibly get this component into the core.

I think it’s a great component, but that’s easily said when I’m not the one having to spend hours working on it. I’m useless when it comes to coding but I’d be happy to help write the documentation when the time comes.

It works fine with hass.io

1 Like

Error in 0.117…

2020-10-23 09:44:55 ERROR (MainThread) [homeassistant.components.sensor] Error while setting up nsw_rural_fire_service_fire_danger platform for sensor
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 193, in _async_setup_platform
    await asyncio.shield(task)
  File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/nsw_rural_fire_service_fire_danger/sensor.py", line 65, in setup_platform
    rest.update()
AttributeError: 'RestData' object has no attribute 'update'