Skip to main content

Paper Elements are being removed

· 2 min read

In the Home Assistant Core 2022.3 release, we are removing all of the paper-dropdown-menu and paper-input elements in the Frontend Repository. This means that any custom card that was previously using these elements in the card or card editor will no longer render correctly and will require updates to its codebase.

Custom Cards using the elements used in the Home Assistant Frontend have never been supported.

Why did we do this?

We are converting our codebase from the deprecated paper elements to the new Material Web Components from Google. This is to keep our frontend up to date with the latest components and features.

What should custom cards do?

Our advice is to bundle the Material Web Components in your custom card using Scoped Custom Element Registry. The Home Assistant Frontend loads the polyfill needed for this to work starting with the release of Home Assistant 2022.3.

This will allow any custom card to utilize the same MWC elements that are used in the Lovelace Editors. You can see an example of this usage in the Boilerplate Card. Other HA elements like the icon picker (<ha-icon-picker>) are not supported in this same way.

See this old blog post for more information.

Device configuration URL and entity categories

· 2 min read

Home Assistant Core 2021.11 introduces two new concepts to make managing devices easier, device configuration URL and entity categories.

Device configuration URL

It's now possible to provide a configuration_url as part of the device registry information. The configuration_url is used in the device card to allow the user to visit the device for configuration or diagnostics which is not available in Home Assistant. Note that the URL linked to is not proxied by Home Assistant, so this typically won't work when connecting to Home Assistant remotely.

Screenshot showing visit device

Entity categories

Entities now have an optional property entity_category for classifying non-primary entities. Set to config for entities that allow changing the configuration of a device, for example, a switching entity making it possible to turn the background illumination of a switch on and off. Set to diagnostic for an entity exposing some configuration parameter or diagnostics of a device but does not allow changing it, for example, a sensor showing RSSI or MAC address with allowed values.

Entities which have the entity_category set:

  • Are not included in a service call targetting a whole device or area.
  • Are, by default, not exposed to Google Assistant or Alexa.
  • Are shown on a separate card on the device configuration page.
  • Do not show up on the automatically generated Lovelace Dashboards.

Screenshot showing seperation of entity categories

New sensor state class: total

· 4 min read

Note: This post was edited 2021-10-21 to remove references to total accumulated increases and decreases which were removed and never included in the Home Assistant 2021.10 release.

A new state class, total has been added and the last_reset attribute has been added back to SensorEntity and is no longer deprecated. The driver for the change is to support cases where total_increasing, which was introduced in Home Assistant 2021.9, is too restrictive to cover all cases. Note that setting last_reset for sensors with state class measurement is still deprecated.

State classes

There are 3 defined state classes:

  • measurement, the state represents a measurement in present time, for example a temperature, electric power, etc. For supported sensors, statistics of min, max and average sensor readings are updated periodically.
  • total, the state represents a total amount that can both increase and decrease, e.g. a net energy meter. When supported, the accumulated growth or decline of the sensor's value since it was first added is updated periodically.
  • total_increasing, a monotonically increasing total, e.g. an amount of consumed gas, water or energy. When supported, the accumulated growth of the sensor's value since it was first added is updated periodically.

State class total

For sensors with state class total, the last_reset attribute can optionally be set to gain manual control of meter cycles. The sensor's state when it's first added to Home Assistant is used as an initial zero-point. When a last_reset changes, the zero-point will be set to 0. If last_reset is not set, the sensor's value when it was first added is used as the zero-point when calculating sum statistics.

Example of state class total without last_reset:

tstatesum
2021-08-01T13:00:0010000
2021-08-01T14:00:00101010
2021-08-01T15:00:000-1000
2021-08-01T16:00:005-995

Example of state class total with last_reset:

tstatelast_resetsum
2021-08-01T13:00:0010002021-08-01T13:00:000
2021-08-01T14:00:0010102021-08-01T13:00:0010
2021-08-01T15:00:0010052021-08-01T13:00:005
2021-08-01T16:00:0002021-09-01T16:00:005
2021-08-01T17:00:0052021-09-01T16:00:0010

Example of state class total where the there initial state at the beginning of the new meter cycle is not 0, but 0 is used as zero-point:

tstatelast_resetsum
2021-08-01T13:00:0010002021-08-01T13:00:000
2021-08-01T14:00:0010102021-08-01T13:00:0010
2021-08-01T15:00:0010052021-08-01T13:00:005
2021-08-01T16:00:0052021-09-01T16:00:0010
2021-08-01T17:00:00102021-09-01T16:00:0015

State class total_increasing

For sensors with state_class total_increasing, a decreasing value is interpreted as the start of a new meter cycle or the replacement of the meter. It is important that the integration ensures that the value cannot erroneously decrease in the case of calculating a value from a sensor with measurement noise present. This state class is useful for gas meters, electricity meters, water meters etc.

The sensor's state when it's first added to Home Assistant is used as an initial zero-point. When a new meter cycle is detected the zero-point will be set to 0. Please refer to the tables below for how this affects the statistics.

Example of state class total_increasing with a new meter cycle:

tstatesum
2021-08-01T13:00:0010000
2021-08-01T14:00:00101010
2021-08-01T15:00:00010
2021-08-01T16:00:00515

Example of state class total_increasing where the there initial state at the beginning of the new meter cycle is not 0, but 0 is used as zero-point:

tstatesum
2021-08-01T13:00:0010000
2021-08-01T14:00:00101010
2021-08-01T15:00:00515
2021-08-01T16:00:001020

Supervisor update

· 4 min read

It's been a while since we posted about changes to the Supervisor. Here are some highlights from the past year and the future. This information is mainly for add-on developers, but there is little something for everyone in here. If you have not yet seen it, we have posted a blog on the main site that you should read.

Snapshot -> Backup

First up, as mentioned in the blog on the main site, we have started a transition away from the name "snapshot" that has been with us since the beginning of the Supervisor and are now moving to the more recognizable "backup".

These changes are live now on the dev channel for the Supervisor, so you can start testing and adjusting your tools/add-ons to make sure they will still work when your users get this.

API changes

With the transition from "snapshot" to "backup", a new base section in the Supervisor API has been added /backups that operates the same way as /snapshots with all the same endpoints as the old section has but there are two key differences:

  • If you access /backups the data returned now will be {"backups": []} instead of {"snapshots": []}
  • To delete a snapshot you now have to use the DELETE HTTP method with the /backups endpoint, previously both POST and DELETE were supported.

The old /snapshots endpoints are now deprecated and are scheduled for removal in Q4 of this year.

Backup structure changes

For consistency, we have also changed the name of the meta file inside the backup tar from snapshot.json to backup.json. If you have a tool that uses that file you should look for both so your tool will work for existing as well as new backups.

Streaming ingress

Some add-ons need to receive large payloads from the user, for instance with uploading. Previously, there has been a limit of 16 MB per request for add-ons running behind ingress and this is still the default. If you need to receive larger payloads, you can enable this by setting ingress_stream to True in the add-on configuration. When you do this the request is streamed from the client to your add-on, and the request has no size limit and virtually no overhead.

Note that not all webservers are able to handle this by default, so you might need to adjust it.

Deprecated API endpoints

Over the past years, we have restructured parts of our API endpoints, but we have also kept old endpoints working. If you use any of the deprecated endpoints in your tools/add-ons you should move to use the new ones now. All deprecated endpoints are scheduled for removal in Q4 this year.

Here is a list of the deprecated endpoints and their replacements:

Deprecated endpointsReplaced with
/homeassistant/*/core/*
/snapshots/*/backups/*

In addition to this, the following are also deprecated and are also scheduled for removal in Q4 this year.

  • The environment variable HASSIO_TOKEN has been replaced with SUPERVISOR_TOKEN.
  • Using X-Hassio-Key header has been replaced with using Authorization with a Bearer token.
  • Using http://hassio/ to communicate with the Supervisor has been replaced with http://supervisor/.

Supervised installation

Maintaining a supervised installation is currently not the best experience. The script that most users use to install is behind what the Supervisor wants from the host. Since there are no real upgrade paths for those using it, users of it need to manually adjust their installation.

Recently we created the OS Agent as mentioned in the blog on the main site. This allows for better communication between the host OS and the Supervisor, and to bring in more features. To take advantage of these features users of current supervised installations have to install the OS Agent manually.

An alternative to this route is to package and distribute the supervised installation as a deb package that can be installed and upgraded with apt on the host. For this to be viable, we are looking for a person (or a group of people) that wants to create and maintain this type of deployment, and bring the supervised installation method up to par with our OS, and more importantly make updates needed on the host easier for the users.

If you have questions about these changes feel free to reach out in the #devs_supervisor channel on our Discord server.

Until next time 👋

New sensor state class: total_increasing

· 2 min read

A new state class, total_increasing has been added. In addition, the last_reset attribute is removed from SensorEntity. The driver for the changes is to make it easier to integrate with devices, like utility meters.

State classes

There are 2 defined state classes:

  • measurement, the state represents a measurement in present time, for example a temperature, electric power, the value of a stock portfolio, etc. For supported sensors, statistics of hourly min, max and average sensor readings or of the accumulated growth or decline of the sensor's value since it was first added is updated hourly.
  • total_increasing, a monotonically increasing total, e.g. an amount of consumed gas, water or energy. When supported, the accumulated growth of the sensor's value since it was first added is updated hourly.

STATE_CLASS_TOTAL_INCREASING

For sensors with state_class STATE_CLASS_TOTAL_INCREASING, a decreasing value is interpreted as the start of a new meter cycle or the replacement of the meter. It is important that the integration ensures that the value cannot erroneously decrease in the case of calculating a value from a sensor with measurement noise present. This state class is useful for gas meters, electricity meters, water meters etc.

The sensor's state when it's first added to Home Assistant is used as an initial zero-point. When a new meter cycle is detected the zero-point will be set to 0. Please refer to the tables below for how this affects the statistics.

Example of STATE_CLASS_TOTAL_INCREASING with a new meter cycle:

tstatesum
2021-08-01T13:00:0010000
2021-08-01T14:00:00101010
2021-08-01T15:00:00010
2021-08-01T16:00:00515

Example of STATE_CLASS_TOTAL_INCREASING where the there initial state at the beginning of the new meter cycle is not 0, but 0 is used as zero-point:

tstatesum
2021-08-01T13:00:0010000
2021-08-01T14:00:00101010
2021-08-01T15:00:00515
2021-08-01T16:00:001020

This state class used to be represented by state class measurement in combination with a last_reset value. This approach has been deprecated and will be interpreted as a total_increasing state class instead with an automatic last reset.

Temperature conversions moving to SensorEntity

· One min read

Temperature unit conversions are moving from the Entity base class to the SensorEntity base class. Unit conversions will only be done if the sensor's device_class attribute is set to DEVICE_CLASS_TEMPERATURE. If the device_class is not set or is not set to DEVICE_CLASS_TEMPERATURE temperature conversion will take place during a transition period and a warning will be logged.

To facilitate this, the sensor entity model has been updated with two new properties, native_value and native_unit_of_measurement. This allows us to add additional unit conversions in the future instead of relying on the integrations to do it themselves.

Sensor implementations should no longer implement the state() property function or set the _attr_state attribute. Sensor implementations should also not implement the unit_of_measurement property function, set the _attr_unit_of_measurement attribute or set the unit_of_measurement member of EntityDescription.

native_value

The value reported by the sensor. The actual state written to the state machine may be modified by SensorEntity due to unit conversions.

native_unit_of_measurement

The unit of measurement of the sensor, if any. The unit_of_measurement written to the state machine may be modified by SensorEntity due to unit conversions.

New sensor properties for long-term statistics

· 2 min read

The sensor entity model has been updated with two new properties, state_class and last_reset. The driver for both the new properties is to enable automatic generation of long-term statistics.

state_class

Sensor device classes such as DEVICE_CLASS_TEMPERATURE are used to represent wildly different types of data, for example:

  • A regularly updated temperature measurement
  • Historical or statistic data, for example daily average temperature
  • Future data, for example tomorrow's forecast

Differentiating between those sensors which represent a measurement and those which don't is needed in order to automatically make a reasonable selection of sensors to include in long-term statistics.

The state_class property classifies the type of state: The state could be a measurement in present time from a temperature sensor or an energy meter_, a historic value such as the average temperature during the last 24 hours or the amount of energy used last month, or a predicted value such as a weather forecast or the next garbage pickup schedule. If state_class="measurement", the state represents a current value, and not a historical aggregation or a prediction of the future. Otherwise, state_class=None. There is an architecture discussion with some additional background.

Note that measurement in present time above does not imply that the state has to be updated with a certain frequency, or that the sensor is not allowed to do indirect measurements such as integrating power to calculate energy. To put it in another way, if the sensor represents the latest observation or the newest data point in a time series it qualifies as state_class="measurement".

last_reset

The time when an accumulating sensor such as an electricity usage meter, gas meter, water meter etc. was initialized. If the time of initialization is unknown and the meter will never reset, set to UNIX epoch 0: homeassistant.util.dt.utc_from_timestamp(0). Note that the datetime.datetime returned by the last_reset property will be converted to an ISO 8601-formatted string when the entity's state attributes are updated. When changing last_reset, the state must be a valid number.

Upgrade to Lit 2.0

· 2 min read

We upgraded our frontend to use Lit 2.0, this is a major bump of both LitElement (3.0) and lit-html (2.0) that will now go further under the name Lit together.

This upgrade comes with a ton of great improvements, but also with some breaking changes.

If you have developed a custom card or view, and are using LitElement and lit-html from our components, your component will be using Lit 2.0 in the next release (2021.6). If you don't know if you are using LitElement from our components, your code will look something like this:

const LitElement = Object.getPrototypeOf(customElements.get("ha-panel-lovelace"));
const html = LitElement.prototype.html;
const css = LitElement.prototype.css;

This is not a recommended practice, we advise you to bundle Lit into your component, or import it from unpkg.com or another source like in this example. This way your card is not depending on the Lit version that is shipped with Home Assistant.

One of the things that changed, is that the creation of the shadowRoot is no longer done in the constructor, but just before the first update. This means that if you directly interact with the DOM, like with a query selector, you can no longer assume shadowRoot will always be available.

For all the changes check the upgrade guide in the Lit documentation.

We expect most of the cards to work without issues with Lit 2.0, but ask custom card developers to ensure compatibility. You can do this using the current dev version of Home Assistant or by using a nightly version of Home Assistant, both currently use Lit 2.0.

Replacing pytz with python-dateutil

· 2 min read

Three years ago Paul Ganssle wrote a comparison about time zone handling between pytz and python-dateutil. In this article he shows how it's easy to use pytz in an incorrect way that is hard to spot because it's almost correct:

import pytz
from datetime import datetime, timedelta

NYC = pytz.timezone('America/New_York')
dt = datetime(2018, 2, 14, 12, tzinfo=NYC)
print(dt)
# 2018-02-14 12:00:00-04:56

(link to part of the article explaining why it's -4:56)

In Home Assistant 2021.6 we're going to switch to python-dateutil. You will need to upgrade your custom integration if it relies on the unofficial interface my_time_zone.localize(my_dt). Use Python's official method my_dt.astimezone(my_time_zone) instead.

The property hass.config.time_zone will also change to a string instead of a time zone object.

Thanks to @bdraco for helping revive this effort and push this change past the finish line. We actually found a couple of bugs during the migration! Also thanks to Paul Ganssle for maintaining python-dateutil and the excellent write up.

Update May 10

Wow, time flies! Paul, the author of python-dateutil and also the author of the blog post that inspired us, pointed us to the fact that Python 3.9 includes upgraded timezone handling and that we should use that instead. With the help of Nick and Paul python-dateutil has been removed again and zoneinfo is used instead (PR).

Astral upgraded to version 2.2

· One min read

We recently merged a pull request to upgrade the astral library version used in Home Assistant Core to version 2.2. This will be released with Home Assistant 2021.5. This is a major version bump of Astral which includes some breaking changes, this caused us to update our built-in helpers and integrations that depend on astral. This has resulted in a couple of breaking changes to our sun helpers.

Custom integration authors that are maintaining integrations that use the sun helpers or the astral library directly, should review the breaking changes and update their custom integrations if needed.

The sun helper has changed its signature for get_astral_location and get_location_astral_event_next to include an elevation parameter. Also the return value of get_astral_location has changed to a tuple including elevation.

@callback
@bind_hass
def get_astral_location(
hass: HomeAssistant,
) -> tuple[astral.location.Location, astral.Elevation]:
"""Get an astral location for the current Home Assistant configuration."""

@callback
def get_location_astral_event_next(
location: astral.Location,
location: astral.location.Location,
elevation: astral.Elevation,
event: str,
utc_point_in_time: datetime.datetime | None = None,
offset: datetime.timedelta | None = None,
) -> datetime.datetime:
"""Calculate the next specified solar event."""

Please see the changelog of astral for further details.