Skip to content

Move temperature conversions to sensor base class (1/8)#48261

Merged
emontnemery merged 34 commits intohome-assistant:devfrom
emontnemery:sensor_temperature_conversion_1
Aug 11, 2021
Merged

Move temperature conversions to sensor base class (1/8)#48261
emontnemery merged 34 commits intohome-assistant:devfrom
emontnemery:sensor_temperature_conversion_1

Conversation

@emontnemery
Copy link
Copy Markdown
Contributor

@emontnemery emontnemery commented Mar 23, 2021

Breaking change

Although not a breaking change from a user's perspective, this is a significant change from a developer's perspective.
More details here: home-assistant/developers.home-assistant#1024

Proposed change

Move temperature conversions to sensor base class SensorEntity (1/8)

Temperature conversion will only be done for sensors with device class set to temperature.
Temperature conversion will still be done for other sensor entities during a transition period, which will end with Home Assistant Core 2022.3.0.
Temperature conversion for non sensor entities is unaffected by this PR.

This PR migrates sensors in integrations a-c to be compatible with unit conversion in SensorEntity.

Full list of PRs migrating sensor integrations:
#48261 (integrations a-c)
#54468 (integrations d-e)
#54469 (integrations f-h)
#54472 (integrations i-m)
#54475 (integrations n-q)
#54476 (integrations r-s)
#54482 (integrations s-u)
#54483 (integrations v-z)
#54623 (additional integrations which were added or updated)

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New integration (thank you!)
  • New feature (which adds functionality to an existing integration)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Additional information

Checklist

  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • I have followed the development checklist
  • The code has been formatted using Black (black --fast homeassistant tests)
  • Tests have been added to verify that the new code works.

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • The manifest file has all fields filled out correctly.
    Updated and included derived files by running: python3 -m script.hassfest.
  • New or updated dependencies have been added to requirements_all.txt.
    Updated by running python3 -m script.gen_requirements_all.
  • Untested files have been added to .coveragerc.

The integration reached or maintains the following Integration Quality Scale:

  • No score or internal
  • 🥈 Silver
  • 🥇 Gold
  • 🏆 Platinum

To help with the load of incoming pull requests:

@probot-home-assistant
Copy link
Copy Markdown

Hey there @shred86, mind taking a look at this pull request as its been labeled with an integration (abode) you are listed as a codeowner for? Thanks!
(message by CodeOwnersMention)

if not self._temperature_conversion_reported:
self._temperature_conversion_reported = True
_LOGGER.warning(
"Entity %s reports a temperature, but it doesn't extend "
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure you document this on the dev blog.

await self.async_turn_on(**kwargs)


class MeasurableUnitEntity(Entity):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the plan to create a measurable entity that can handle any unit conversion or should we consider mixins per unit conversion (ie TemperatureEntity)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the former, it's fairly common pattern for integrations to have a shared class for all sensors, then just set the attributes, including unit_of_measurement, based on some input from the lib.
If we want to specialize like this, those integrations would have to be refactored.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. Besides temperature, I think we should only convert units based on device class. That will allow us to have a look up table for the conversion to apply and a clean implementation in a single class.

Copy link
Copy Markdown
Contributor Author

@emontnemery emontnemery Mar 24, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should only convert units based on device class

I actually implemented it like that first, but there are two issues:

  1. We will need to be backwards compatible for some time to handle integrations which don't set device_ class on their sensors.
  2. How to handle integrations such as input_number which allow configuring a unit_of_measurement but not a device_class?

The first issue is not a problem, but I'm not sure about the second one.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the unit of measurement is configured by the user we probably shouldn't convert it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, that makes sense for input_number.
Not doing the conversion could be considered a breaking change since we currently do convert all temperatures, but maybe it would be for the better?

unit_of_measurement is also used by base components geo_location (for distance) and air_quality (concentrations, I think).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really don't think device class and unit of measurement should be coupled. I think in the long run it would make more sense to device a measurement class/type.

We are more and more mixing up the object and the measurement it provides. For example, temperature vs garage door.

In the long run, this is going to bite.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

device class and unit of measurement need to be coupled for blueprints and to export it to Homekit/Google/Alexa. It's not possible to make code that can work with everything. If it's a device class, we can categorize the entity and know how to deal with it.

"""An abstract class for entities which state is a measurable unit."""

@property
def native_value(self) -> str | None:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Native or raw?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

raw is not so good, I would expect that to be the raw binary value read out from the sensor, before conversion to a standard unit.



class SensorEntity(Entity):
class SensorEntity(MeasurableUnitEntity):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should all sensors get this logic or should be applied to the right ones? I guess that is a migration we can't do anymore at this point.

Copy link
Copy Markdown
Contributor Author

@emontnemery emontnemery Mar 24, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, because it's a migration it's not feasible to do anything else.
We could do something like this though:

class SensorEntity(Entity):
    """Base class for sensor entities"""

class MeasurableSensorEntity(MeasurableUnitEntity, SensorEntity):
    """Base class for sensor entities which represent a measurable unit."""
"""

The migration would then be to MeasurableSensorEntity, but integrations can move to SensorEntity for sensors which don't represent a measurable unit?

@emontnemery emontnemery changed the title Move temperature conversions to entity base class (1/8) Move temperature conversions to sensor base class (1/8) Mar 26, 2021
@MartinHjelmare
Copy link
Copy Markdown
Member

Looks good! Before we merge this I suggest we search for sensor platforms that use a temperature unit and try to have them updated to use device class temperature if it's missing. We do that separately.

@emontnemery
Copy link
Copy Markdown
Contributor Author

search for sensor platforms that use a temperature unit and try to have them updated to use device class temperature if it's missing

After a quick check it's clear that many, possibly even most, integrations fail to set device_class.
Now that we have a SensorEntity, should we allow this behavior by setting device_class according to the unit_of_measurement if it's not set by the integration's sensor platform?

@MartinHjelmare
Copy link
Copy Markdown
Member

Maybe, but it would be even better to add the device class in the platforms. Not having it there will be less explicit and explicit is good.

@emontnemery emontnemery marked this pull request as draft March 29, 2021 15:33
@emontnemery
Copy link
Copy Markdown
Contributor Author

OK, I'm marking this as draft for now, we need to fix integrations not setting device_class in their sensor platforms first.

@github-actions
Copy link
Copy Markdown

There hasn't been any activity on this pull request recently. This pull request has been automatically marked as stale because of that and will be closed if no further activity occurs within 7 days.
Thank you for your contributions.

@github-actions
Copy link
Copy Markdown

There hasn't been any activity on this pull request recently. This pull request has been automatically marked as stale because of that and will be closed if no further activity occurs within 7 days.
Thank you for your contributions.

@github-actions
Copy link
Copy Markdown

There hasn't been any activity on this pull request recently. This pull request has been automatically marked as stale because of that and will be closed if no further activity occurs within 7 days.
Thank you for your contributions.

@github-actions github-actions bot added the stale label Jun 27, 2021
@github-actions github-actions bot closed this Jul 4, 2021
@emontnemery
Copy link
Copy Markdown
Contributor Author

This should still be done

@emontnemery emontnemery force-pushed the sensor_temperature_conversion_1 branch from 2ce8880 to 904adf4 Compare August 11, 2021 06:48
@emontnemery emontnemery merged commit 4e07ab1 into home-assistant:dev Aug 11, 2021
@github-actions github-actions bot locked and limited conversation to collaborators Aug 12, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants