Reviewers needed: Environment Canada component with weather, sensor, and camera (radar) platforms

Put three backticks (```) on their own line before and after the code to be formatted.

That works for me (proof is the formatted code in my previous post). It’s just one of the many ways to use markdown to format text.

@123 Thanks, I’ve fixed my post

I offer a small refinement to the bad_weather template binary sensor.

In this example, value_template is substantially streamlined because it operates on the assumption that the EnviroCan-related sensors (warnings, statements, advisories, watches) are the only sensors to have an attribute called hidden (which is generally true; hidden is a custom attribute).

#binary_sensor:
  - platform: template
    sensors:
      bad_weather:
        entity_id:
          - sensor.warnings
          - sensor.statements
          - sensor.advisories
          - sensor.watches
        value_template: >-
          {{ true if states.sensor | selectattr('attributes.hidden', 'eq', false) | list | count > 0 else false }}

The template works like this:

  • It gets all sensors and selects the ones with hidden=false.
  • It transforms the result into a list then counts the numbers of items in the list.
  • If the count is greater than zero then the result is true, otherwise it’s false.

FWIW, this same technique is often used to determine the number of lights currently on (it checks the entity’s state as opposed to an attribute).

If you have other sensors with the hidden attribute then this template requires a small revision (and requires you create a group containing the EnviroCan sensors). Let me know if this happens to be the case for you and I’ll provide you with an enhanced template.

In lieu of a template binary sensor you can easily trim the value_template to create a template sensor that reports the number of concurrent alerts (numeric value from 0 to 4). Once again, this template assumes you have no other sensors with an attribute called hidden.

#sensor:
  - platform: template
    sensors:
      bad_weather:
        entity_id:
          - sensor.warnings
          - sensor.statements
          - sensor.advisories
          - sensor.watches
        value_template: >-
          {{ states.sensor | selectattr('attributes.hidden', 'eq', false) | list | count }}
1 Like

Thanks, this is great! I should point out though that I use the hidden attribute for all of the Environment Canada sensors, and it gets flipped to true whenever there isn’t a value present in the data, e.g. for windchill or humidex.

@123 the problem with both of your alternatives is that they grab hidden attributes for all sensors in your HA installation, not just the ones exposed for the custom component. As @michaeldavie says, there are more sensors in the custom component that use those attributes so users could run into issues if they copy and paste your config into theirs.

FWIW HA does not throw warnings for me when I don’t explicitly list the entity ids. This is because in my original bad_weather binary sensor the relevant sensors are listed in the template. Keeps my configuration.yaml a bit tidier. Your suggested improvements definitely need explicit declaration of entity ids.

My post explained it works that way and that it’s a potential limitation if other sensors use the hidden attribute. Michael then confirmed other sensors do use hidden so the solution won’t work as desired (i.e. it won’t limit itself to just the advisories, warnings, statements, and watches sensors).

What I originally offered hinged on this statement:

Should there be a warning message, the solution is to list the entities to be monitored:

You’ve confirmed there is no warning message (thank you) so, as you’ve stated, there’s no need to explicitly identify the entities to be monitored. In this case, Home Assistant is able to identify them automatically within the template (but there are situations when it cannot).

The following version of the bad_weather template binary sensor restricts itself to the four sensors and is compact.

  - platform: template
    sensors:
      bad_weather:
        value_template: >-
          {% set alerts = [state_attr('sensor.advisories', 'hidden'), 
                           state_attr('sensor.statements', 'hidden'),
                           state_attr('sensor.watches', 'hidden'),
                           state_attr('sensor.warnings', 'hidden')] %}
          {{ alerts | select('==', false) | list | count > 0 }}

Should one wish to convert it into a sensor, that reports a value from 0 to 4, the template is easily modified (as explained in my previous post).


Question for all, after you restart Home Assistant do the sensor’s maintain their attribute values?

For example, if hidden=false for sensor.warnings, does it maintain that after a restart?

In my experience with MQTT sensors, custom attributes are lost after a restart.

Yes and no. The sensors don’t save their state or attributes, but they’re refreshed whenever a sensor is updated, including on startup. Specifically, the hidden attribute is set to True if there isn’t any data for that particular sensor after an update. If you’re curious, I’ve linked to the code below.

https://github.com/michaeldavie/home-assistant/blob/df5565cf94a8b57038219b40ee25a5715298c7d4/homeassistant/components/environment_canada/sensor.py#L161

Good evening,

I’ve been following this thread sporadically for some time. Amazing progress!

May I ask if you have any info on when your component will be released “officially” or do you believe it is better to do a custom install?

Thank you.

Thanks, but unfortunately the PR hasn’t made any progress. I suggest that you do a custom install for now, as things have been fairly stable for a few weeks. Let me know if you have any trouble.

1 Like

Here’s a quick Python script I threw together to retrieve the details of weather alerts/statements/watches from Environment Canada.

The script outputs json that can be used in conjunction with a command_line sensor. You can then display the alert details in the frontend. You’ll need to pick your location from this page, and update the URL variable in the script. My sensor is configured as follows:

sensor:
 - platform: command_line
   command: "/path/to/env_canada_alerts.py"
   json_attributes:
    - date
    - title
    - details
   value_template: '{{ value_json.title }}'
   scan_interval: 3600

And here is what is looks like:
52
Suggestions or comments welcome

1 Like

Nice! I’ll try to work that into the sensor. I’d love to be able to set the location automatically as well, but the warning areas are weird. If the publish the GIS data, maybe as SHP files, I might be able to work it out…

That would be great! I agree that it would be better to get the location pulled automatically. By the way I went the scraping/BeautifulSoup route because I couldn’t find a plain XML API to get the actual text descriptions of the alerts.

Yes, that’s a disappointing aspect of EnviroCan’s ATOM feed. It’s missing the actual details of the alert.

FWIW, it’s been that way since I can remember now (at least 8 years) and, for the EnviroCan driver I created, I was obliged to use web-scraping as well to extract the alert’s details. Over the last 8 years I think I had to change my web-scraping algorithm twice because EnviroCan changed the names of the CSS tags.

PS
I’m also waiting for the big deluge to hit later today. One of those times I’m glad I don’t own a home in a low-lying, or waterfront, area.

Okay, based on @davidbb’s work I’ve added alert details to the sensor. Here’s how it looks:

To update:

  • Install the updated env_canada library:
    • For Docker: docker exec [container name] pip install env_canada==0.0.9 --target /config/deps/lib/python3.6/site-packages --upgrade
    • Otherwise: pip install env_canada==0.0.9 --target [config folder]/deps/lib/python3.6/site-packages --upgrade
  • Place the files from Dropbox in a folder at [config folder]/custom_components/environment_canada/
  • Restart your Home Assistant installation

Let me know what you think, or if you have any trouble.

This looks great! Just wanted to confirm: this feature is available in your Dropbox but hasn’t been put into your fork of HA right? I’m looking here.

Yeah, they’re starting to diverge a bit because of changes to how the requirements are being loaded, I think starting in 0.92. I’ll add it into the fork as well shortly.

@michaeldavie I pulled down the latest version of all the files in your github repo and upgraded to 0.92.1. Also installed env_canada==0.0.9 Everything is working well except sensor.warnings. There is currently a rainfall warning in my area and I’m getting this error on start:

Traceback (most recent call last):
File “/usr/local/lib/python3.5/site-packages/homeassistant/helpers/entity_platform.py”, line 261, in _async_add_entity
await entity.async_device_update(warning=False)
File “/usr/local/lib/python3.5/site-packages/homeassistant/helpers/entity.py”, line 377, in async_device_update
await self.hass.async_add_executor_job(self.update)
File “/usr/local/lib/python3.5/asyncio/futures.py”, line 381, in iter
yield self # This tells Task to wait for completion.
File “/usr/local/lib/python3.5/asyncio/tasks.py”, line 310, in _wakeup
future.result()
File “/usr/local/lib/python3.5/asyncio/futures.py”, line 294, in result
raise self._exception
File “/usr/local/lib/python3.5/concurrent/futures/thread.py”, line 55, in run
result = self.fn(*self.args, **self.kwargs)
File “/usr/local/lib/python3.5/site-packages/homeassistant/util/init.py”, line 224, in wrapper
result = method(*args, **kwargs)
File “/root/.homeassistant/custom_components/environment_canada/sensor.py”, line 153, in update
for s in sensor_data])
File “/root/.homeassistant/custom_components/environment_canada/sensor.py”, line 153, in
for s in sensor_data])
AttributeError: ‘str’ object has no attribute ‘get’

Any thoughts on what the problem could be?

edit: In case you see this and the warning is no longer posted, I saved the xml file and the warnings page HTML.

It seems that your installation is still trying to use v0.0.8. In that version each alert was a string, while in v0.0.9 each one is a dictionary. Have you tried restarting your server?

Ah right the restart thing. I restarted once more and the alert details are now showing up and the errors are gone. I still don’t know why upgrading env_canada often needs several reboots, but in any case it’s working now. Thanks!

Everything working here with v0.0.9 :grinning: