Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds allergy/disease sensor platform from Pollen.com #11573

Merged
merged 7 commits into from
Jan 26, 2018

Conversation

bachya
Copy link
Contributor

@bachya bachya commented Jan 11, 2018

Description:

Adds a sensor platform for allergy and disease information from Pollen.com.

Related issue (if applicable): N/A

Pull request in home-assistant.github.io with documentation (if applicable): home-assistant/home-assistant.io#4392

Example entry for configuration.yaml (if applicable):

sensor:
  platform: pollen
  zip_code: 80919
  monitored_conditions:
    - allergy_average_forecasted
    - allergy_average_historical
    - allergy_index_today
    - allergy_index_tomorrow
    - allergy_index_yesterday
    - disease_average_forecasted

Checklist:

  • The code change is tested and works locally.

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

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

  • Local tests with tox run successfully. Your PR cannot be merged unless tests pass
  • New dependencies have been added to the REQUIREMENTS variable (example).
  • New dependencies are only imported inside functions that use them (example).
  • New dependencies have been added to requirements_all.txt by running script/gen_requirements_all.py.
  • New files were added to .coveragerc.

Copy link
Member

@MartinHjelmare MartinHjelmare left a comment

Choose a reason for hiding this comment

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

Looks good overall. See comments below.

For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/sensor.pollen/
"""
from logging import getLogger
Copy link
Member

Choose a reason for hiding this comment

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

Please import logging like most modules do.

data.update()

sensors = []
for condition in config.get(CONF_MONITORED_CONDITIONS, []):
Copy link
Member

Choose a reason for hiding this comment

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

This is a required key in the config schema so don't use dict.get.

sensors = []
for condition in config.get(CONF_MONITORED_CONDITIONS, []):
name, sensor_class, data_key, params, icon = CONDITIONS[condition]
sensors.append(globals()[sensor_class](
Copy link
Member

Choose a reason for hiding this comment

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

I don't think you need to use globals. Is there a specific reason you want that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This so that I can dynamically instantiate objects of a certain type from the CONDITIONS dict. Open to better suggestions!

Copy link
Member

Choose a reason for hiding this comment

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

Can't you just call sensor_class and instantiate? I think that should work.

Copy link
Member

Choose a reason for hiding this comment

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

Sorry I wasn't clear. If you replace the string representing the class name in CONDITIONS with the actual class name you could call it directly from here. You might have to move the conditions dict below the class defines though, so that might be uglier. You decide.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, I see. Putting CONDITIONS at the bottom of the file feels confusing to me (given all other constants are at the top). Given that, are you okay with me keeping as-is?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I'm ok with it.


def average_of_list(list_of_nums, decimal_places=1):
"""Return the average of a list of ints."""
return round(sum(list_of_nums, 0.0)/len(list_of_nums), decimal_places)
Copy link
Member

Choose a reason for hiding this comment

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



def calculate_trend(list_of_nums):
"""Return the average of a list of ints."""
Copy link
Member

Choose a reason for hiding this comment

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

Stale docstring.


def calculate_trend(list_of_nums):
"""Return the average of a list of ints."""
ratings = list(
Copy link
Member

Choose a reason for hiding this comment

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

You can achieve the same with a two level nested generator expression and next. That wouldn't be super readable either but I'd prefer that over this.

ratings = next((
    r['label'] for n in list_of_nums
    for r in RATING_MAPPING
    if r['minimum'] <= n <= r['maximum']), None)

@property
def device_state_attributes(self):
"""Return the device state attributes."""
return merge_two_dicts(
Copy link
Member

Choose a reason for hiding this comment

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

Why do you need this? Can't you just update the attributes?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm merging common attributes of the base class (e.g. ATTR_ATTRIBUTION) why (pseudo-)dynamic attributes of the subclasses. I've done this before; not good?

Copy link
Member

Choose a reason for hiding this comment

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

Why do you need to copy before updating? You can just do:

self._attr.update({...})
return self._attr

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh wow, silly on me. Thanks!

from pypollencom.exceptions import HTTPError

try:
self.extended_data = self._client.allergens.extended()
Copy link
Member

Choose a reason for hiding this comment

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

You could break out a function to access a client method inside a try except block, since you do the same thing 6 times.


@Throttle(MIN_TIME_UPDATE_INDICES)
def update(self):
"""Update with new AirVisual data."""
Copy link
Member

Choose a reason for hiding this comment

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

Stale docstring.


@Throttle(MIN_TIME_UPDATE_INDICES)
def update(self):
"""Update with new AirVisual data."""
Copy link
Member

Choose a reason for hiding this comment

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

Same as above.

@bachya
Copy link
Contributor Author

bachya commented Jan 26, 2018

@MartinHjelmare Need anything else from me on this one?

Copy link
Member

@MartinHjelmare MartinHjelmare left a comment

Choose a reason for hiding this comment

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

Looks great!

@MartinHjelmare MartinHjelmare merged commit 5af7666 into home-assistant:dev Jan 26, 2018
@bachya bachya deleted the allergen-disease branch February 4, 2018 17:36
@balloob balloob mentioned this pull request Feb 9, 2018
@grantalewis
Copy link

I'm getting data from

    monitored_conditions:
      - allergy_index_today
      - allergy_index_tomorrow

but not from

      - allergy_average_forecasted

Anyone else experiencing this?

@bachya
Copy link
Contributor Author

bachya commented Feb 15, 2018

@grantalewis Please open a new bug report and we'll be able to help debug.

@home-assistant home-assistant locked and limited conversation to collaborators May 29, 2018
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.

4 participants