Support for Environment Canada platforms

Hey, thanks for the component. If I knew how to build it into the GUI I would help you, but alas I do not. Anyway, an idea/request is to prepend ec_ or similar on each sensor that’s created by the sensors integration (e.g. sensor.ec_wind_chill). Its hard to group them all together or find a specific one if you don’t know the name, and also a pain to exclude them from the recorder one at a time.

BTW: I really love the advisories/warnings - I have some conditional cards set up to show them on my main tab if one exists - so I never miss them and also don’t get in the habit of looking past them.

I’ve started having an issue with getting the weather radar to show.

I have 2 instances of HA. Both with identical setup for environment canada.
1 running OS 5.10 and HA Core 2020.2.1
This one creates the camera entity

The other running OS 5.11 and HA Core 2020.2.3
This one used to create the camera entity but now it is not.

Logger: homeassistant.components.camera
Source: custom_components/environment_canada/camera.py:92
Integration: Camera (documentation, issues)
First occurred: 8:51:01 AM (1 occurrences)
Last logged: 8:51:01 AM

environment_canada: Error on device update!
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/xml/etree/ElementTree.py", line 1693, in feed
    self.parser.Parse(data, 0)
xml.parsers.expat.ExpatError: syntax error: line 1, column 49

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 358, in _async_add_entity
    await entity.async_device_update(warning=False)
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 466, in async_device_update
    await task
  File "/config/custom_components/environment_canada/camera.py", line 92, in async_update
    self.image = await self.radar_object.get_loop()
  File "/usr/local/lib/python3.8/site-packages/env_canada/ec_radar.py", line 233, in get_loop
    start, end = await self._get_dimensions()
  File "/usr/local/lib/python3.8/site-packages/env_canada/ec_radar.py", line 158, in _get_dimensions
    capabilities_tree = et.fromstring(
  File "/usr/local/lib/python3.8/xml/etree/ElementTree.py", line 1320, in XML
    parser.feed(text)
  File "/usr/local/lib/python3.8/xml/etree/ElementTree.py", line 1695, in feed
    self._raiseerror(v)
  File "/usr/local/lib/python3.8/xml/etree/ElementTree.py", line 1602, in _raiseerror
    raise err
  File "<string>", line None
xml.etree.ElementTree.ParseError: syntax error: line 1, column 49

EDIT: For some reason, it’s back. Didn’t change anything, but it’s working again. :man_shrugging:

Gone again today, and not just the weather radar but all of it. My older version is still plugging away with no issues.

Logger: homeassistant.components.camera
Source: custom_components/environment_canada/camera.py:92
Integration: Camera (documentation, issues)
First occurred: 16:41:49 (1 occurrences)
Last logged: 16:41:49

environment_canada: Error on device update!
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 358, in _async_add_entity
    await entity.async_device_update(warning=False)
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 466, in async_device_update
    await task
  File "/config/custom_components/environment_canada/camera.py", line 92, in async_update
    self.image = await self.radar_object.get_loop()
  File "/usr/local/lib/python3.8/site-packages/env_canada/ec_radar.py", line 254, in get_loop
    frames.append(await self._combine_layers(f, frame_times[i]))
  File "/usr/local/lib/python3.8/site-packages/env_canada/ec_radar.py", line 179, in _combine_layers
    radar = Image.open(BytesIO(radar_bytes)).convert("RGBA")
  File "/usr/local/lib/python3.8/site-packages/PIL/Image.py", line 2958, in open
    raise UnidentifiedImageError(
PIL.UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0x7f9ce8429310>
Logger: homeassistant.components.sensor
Source: custom_components/environment_canada/sensor.py:84
Integration: Sensor (documentation, issues)
First occurred: 16:39:57 (1 occurrences)
Last logged: 16:39:57

Error while setting up environment_canada platform for sensor
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 198, in _async_setup_platform
    await asyncio.shield(task)
  File "/config/custom_components/environment_canada/sensor.py", line 84, in async_setup_platform
    async_add_entities(
TypeError: 'NoneType' object is not iterable

When I first installed Home Assistant 18 months ago, it was still using the yr weather component (service provided by met.no), and I have stuck with that version. Last June it failed when met.no marked their version 1.9 api deprecated, but it was possible to patch the HA component to ignore the warning and keep using it. But they finally turned off the old version 1.9 api as of March 1, 2021. They also removed the ability to link to their library of online weather icons (version 1.1), although they are still available as a tar file download for local use.
I always found met.no inaccurate for my location, and I earlier explored using the Env Canada component instead, but it wouldn’t work in my old version of HA. The other weather services I looked at also would’t work - either changed too much or gone commercial - so I stuck with the yr component to the end, which was 2 days ago.
But my weather service in HA is back up and using Env Canada as the source now, as I got exasperated with all the changes to the other services and just rolled my own solution. I have a Google Script running once an hour in my online Google account that checks the Env Canada public web page for my location and grabs the temperature, pressure, current condition text, and current condition icon. Then it sends that to my Node Red. Node Red uses the useful HA set_state python script service to stuff those values into the former yr weather sensor, and I replaced the yr component with new template sensors of the same name. I was actually surprised that set_state can update a badge icon via the entity_picture attribute, since I had earlier failed to find a way to do that. So that was a useful bit of knowledge gained.
It may seem a bit of an end-run around HA to avoid updating, but really it was the most direct path to the goal for me, and now I have the easy ability to control which weather service I use and adapt quickly to any changes using my own code.

Good evening all!

After updating HA today to 2021.3.0 I noticed that my forecast highs and lows are reversed as follows:

forecast:
  - datetime: '2021-03-04T19:47:02.032589-05:00'
    condition: partlycloudy
    precipitation_probability: 0
    templow: -15
    temperature: -6
  - datetime: '2021-03-05T19:47:02.032816-05:00'
    temperature: -13
    templow: -6
    condition: snowy
    precipitation_probability: 0
  - datetime: '2021-03-06T19:47:02.033045-05:00'
    temperature: -18
    templow: -5
    condition: clear-night
    precipitation_probability: 0
  - datetime: '2021-03-07T19:47:02.033253-05:00'
    temperature: -15
    templow: 2
    condition: clear-night
    precipitation_probability: 0
  - datetime: '2021-03-08T19:47:02.033461-05:00'
    temperature: -4
    templow: 8
    condition: partlycloudy
    precipitation_probability: 0
  - datetime: '2021-03-09T19:47:02.033674-05:00'
    temperature: 0
    templow: 10
    condition: partlycloudy
    precipitation_probability: 0
friendly_name: Ottawa (Kanata - Orléans)

I have not changed my configuration. Should I raise a bug for this? I’d be happy to help somebody test.

Thanks!

Thanks for letting me know, I’m seeing the same thing. I’ll take a look at this.

Please let me know if I can help. I assume I can pull it as a custom component for testing?

Cheers!

How do that Configuration? Cam you help me to configure forecast in text?

I have very minimal configuration for this component. @michaeldavie has done a good job of making it easy to get going … at least on my end.

I have the following in my configuration.yaml

# Weather
weather:
    - platform: environment_canada

This would give you a weather.xxxxxxxx entry in HA where the xxxxxxxx is your closest city.

Hope that helps!

Hello, I have been trying to use your components but it seems none are working for me.

I’m on a core - docker installation - running 2021.3.2

my config.yaml contains:

  - platform: environment_canada

camera:
  - platform: environment_canada
    name: 'env_can'

and in the sensor section i put:

  - platform: environment_canada
    latitude: 45.54008865356445
    longitude: -73.54712677001953
    temperature: true
    dew_point: true
    wind_chill: true
    humidex: true
    air_quality_health_index: true
    humidity: true
    visibility: true
    condition: true
    wind_speed: true
    wind_gust: true
    high_temperature: true
    low_temperature: true
    uv_index: true
    chance_of_precip: true
    forecast: true
    precipitation_yesterday: true
    warnings: true
    watches: true
    advisories: true
    statements: true
    endings: true
  - platform: template
    sensors:
      feels_like:
        friendly_name: "Feels Like"
        device_class: temperature
        unit_of_measurement: "°C"
        value_template: >
          {% if not is_state('sensor.humidex', 'unknown') %}
            {{ states('sensor.humidex') }}
          {% elif not is_state('sensor.wind_chill', 'unknown') %}
            {{ states('sensor.wind_chill') }}
          {% else %}
            {{ states('sensor.temperature') | round(0) }}
          {% endif %}

Maybe theres something i’m missing not understanding but i’m getting multiple errors:

notifications:
The following integrations and platforms could not be set up:

Please check your config and logs.

and in the log:

Setup of camera platform environment_canada is taking over 10 seconds.

1:05:22 AM – Camera (WARNING)

in conf validation:
Invalid config for [sensor.environment_canada]: [temperature] is an invalid option for [sensor.environment_canada]. Check: sensor.environment_canada->temperature. (See ?, line ?)…

Could you help me with this situation?

Thank you from a fellow Quebecois/Canadian

This is all you should need:

weather:
  - platform: environment_canada

camera:
  - platform: environment_canada
    precip_type: RAIN
    name: radar-rain

  - platform: environment_canada
    precip_type: SNOW
    name: radar-snow

sensor:
  - platform: environment_canada

It does take the camera 10-15 seconds to initialize, so that’s normal. You can specify the longitude and latitude if you’d like to use a different station than the closest one.

The feels_like looks right to me.

Thanks for this integration, I can’t believe I only just noticed it.

Firstly, an apology, I raised a bug in github about my weather card not looking correct instead of looking here for a suitable thread.

I did notice one other issue and it’s the fact my sensors aren’t updating very often. I think there are 2 issues here and apologies if I got this wrong.

  • I have both the sensor and weather component defined. The weather component updates every 30 seconds and that fills the rate limit for the update() call of ECData. You can see in this log the call the temperature update will fail because weather made 2 calls in the preceding minute.
# 2 calls to update() for weather in a minute
2021-03-08 22:12:29 INFO (SyncWorker_6) [homeassistant.components.environment_canada.weather] updating env_ca weather                            
2021-03-08 22:13:14 INFO (SyncWorker_8) [homeassistant.components.environment_canada.weather] updating env_ca weather                            
# And a 3rd one, this to a  sensor... this fails because of rate limiting
2021-03-08 22:13:14 INFO (SyncWorker_0) [homeassistant.components.environment_canada.sensor] updating env_ca temperature                         
2021-03-08 22:13:14 INFO (SyncWorker_7) [homeassistant.components.environment_canada.sensor] updating env_ca dewpoint                            

I think the workaround here is to increase the scan_interval to the weather component, that way it can’t call update() twice in 1 minute. I’m currently trying this config:

weather:
  - platform: environment_canada
    scan_interval: 90

sensor:
  - platform: environment_canada
    scan_interval: 300
  • The other issue is I think there needs to be a lock around the sensor’s update() call. All the sensors are sharing the same ec_data instance and update is being called, on my system at least, by up to 10 threads at a time. The rate limiting means only the first 2 of these are even going to work. The lock just ensures the internal consistency of ec_data and that the rate limited calls don’t use stale data.

Something like:

# Near the top of the file
_UPDATE_LOCK = threading.Lock()

    # Inside ECSensor
    def update(self):
        """Update current conditions."""
        with _UPDATE_LOCK:
            self.ec_data.update()
            self.ec_data.conditions.update(self.ec_data.alerts)

Again, thanks for the integration!

Also, the temperature sensor shows unknown for temperatures of 0. It looks like ECData or Environment Canada is returning None as the temperature value when it’s 0 out.

 'temperature': {'label': 'Temperature', 'unit': 'C', 'value': None},

I worked around it by checking for None against certain types of sensors.

diff -aur /home/steve/ha/src/3rdparty/home-assistant/homeassistant/components/environment_canada/sensor.py environment_canada.smaller/sensor.py
--- /home/steve/ha/src/3rdparty/home-assistant/homeassistant/components/environment_canada/sensor.py	2020-12-26 09:01:10.483922726 -0500
+++ environment_canada.smaller/sensor.py	2021-03-09 08:38:57.432044685 -0500
@@ -131,6 +131,20 @@
         else:
             self._state = value
 
+        if self._state is None and self.sensor_type in [
+            "dewpoint",
+            "high_temp",
+            "humidity",
+            "low_temp",
+            "pop",
+            "pressure",
+            "temperature",
+            "uv_index",
+            "visibility",
+            "wind_speed",
+        ]:
+            self._state = 0
+
         if sensor_data.get("unit") == "C" or self.sensor_type in [
             "wind_chill",
             "humidex",

Which gives me this:

zero-degrees

Good morning michaeldavie.

So what I think is happening is that in the afternoons the daily high for the current day gets removed. So on the Environment Canada app I get a (-) for the high.

I am wondering if all the data then gets shifted.

So in the code where you have this line:

if half_days[0]["temperature_class"] == "high":

Perhaps half_days[0] is the afternoon and half_days[1] would be TOMORROW and is NOT today anymore? I’m just unsure where to test and fix this. Do you think the issue is in the component or do you think it is upstream in the python component - https://github.com/michaeldavie/env_canada?

I’d be happy to help but I think I need a bit of guidance on where to start :slight_smile:

Thanks!

Sorry, and I don’t want to come across as “that guy” suddenly appearing out of nowhere and posting lots to the group but I raised a bug against this issue before I found this discussion.

The bottom comment has a workaround that does something similar to your suggestion. It’s working well for me. My feeling is the fault is Environment Canada works with a moving daytime/nighttime window and Home Assistant works in days and nights - but I’ll leave the proper solution to @michaeldavie

No worries @ sherrell. Thanks for your help.

No problem, thanks for letting me know!

On the update frequency, I think this is fixed (or at least better handled) in the latest unmerged version:

This version is still not merged because it has breaking changes and those can’t be merged until I get it set up for configuration via the GUI. If anyone is able to help with that effort I would appreciate it!

I’m not sure why the temperature would return None if it was 0; it should only do that if the temperature data was not there at all.

I thought I had handled the shifting forecasts correctly, but apparently not. The Python component just returns a list of the half-day forecasts that are in the XML, it’s the HA component that needs to wrangle these into the low/high combinations that HA expects. I’ll take a look at this.

Thanks for the link, your updated component is working great.

  • the temperature is updating correctly
  • the weather forecast looks good
1 Like

Hi, thanks for this integration. I have a problem, the forecast and the camera work perfectly, but the sensor won’t appear in home assistant, I tried different way, bu no luck.
I’m using Home Assistant 2021.3.3 on an Intel NUC with supervised home assistant.

Here’s the sensor config

####### Environnement Canada

# Montreal
- platform: environment_canada
#  latitude: !secret latitude_peloquin
#  longitude: !secret longitude_peloquin
  station: QC/s0000635
  language: french

# Chalet
- platform: environment_canada
#  latitude: !secret latitude_chalet
#  longitude: !secret longitude_chalet
  station: QC/s0000348
  language: french

HAs you can see, I tried with the long/lat data or simply with station.

I les to use Dark Sky, and since I changed to Environment Canada, I don’t have any sensor anymore.

I tried to put simply.
- platform: environment_canada

Look like there was a conflict in the sensors.yaml file, I deleted everything except the environment_canada sensor lines. and now I have all the entities, the first one with French name and the second one with a “_2” at the end.

But now no data… every single sensor report unavailable…

Tried to put the basic config alone only one .

- platform: environment_canada

No luck… any help?