Add Streamlabs Water Monitor (#21205)

* Add Streamlabs Water Monitor

* Fail Streamlabswater component setup when given invalid parameters

The Streamlabs Water component is unable to recover if it is given
an invalid API key or location id so this change is to ensure
we validate they are correct during setup and return a failure
if they are not.

* Prime Streamlabswater component sensors so data is available immediately

The sensors for the component were not causing an immediate load of
data from the API when being set up so there was some lag after
startup before values would show up.  This change does an explicit
update when the sensors are setup to ensure data is viewable
immediately after startup.

* Switch Streamlabswater logging to use %s for string formatting

* Update Streamlabswater component with correct dependencies

Dependencies were incorrectly specified using DEPENDS rather
than DEPENDENCIES

* Streamlabswater pull request feedback

Remove detailed class docstrings since they're in the documentation,
reduce code duplication in sensor classes, and remove periods from
the end of log messages.

* Reduce line length in Streamlabswater sensor

* Add docstring on Streamlabswater service callback method

* Get rid of unnecessary initializers in Streamlabswater sensor

* Add manifest file for Streamlabs Water Monitor

* Remove unused REQUIREMENTS
This commit is contained in:
cpopp 2019-06-06 15:55:08 -05:00 committed by Paulus Schoutsen
parent 984d41e334
commit 1bca313421
7 changed files with 303 additions and 0 deletions

View file

@ -0,0 +1,128 @@
"""Support for Streamlabs Water Monitor Usage."""
from datetime import timedelta
from homeassistant.components.streamlabswater import (
DOMAIN as STREAMLABSWATER_DOMAIN)
from homeassistant.const import VOLUME_GALLONS
from homeassistant.helpers.entity import Entity
from homeassistant.util import Throttle
DEPENDENCIES = ['streamlabswater']
WATER_ICON = 'mdi:water'
MIN_TIME_BETWEEN_USAGE_UPDATES = timedelta(seconds=60)
NAME_DAILY_USAGE = "Daily Water"
NAME_MONTHLY_USAGE = "Monthly Water"
NAME_YEARLY_USAGE = "Yearly Water"
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up water usage sensors."""
client = hass.data[STREAMLABSWATER_DOMAIN]['client']
location_id = hass.data[STREAMLABSWATER_DOMAIN]['location_id']
location_name = hass.data[STREAMLABSWATER_DOMAIN]['location_name']
streamlabs_usage_data = StreamlabsUsageData(location_id, client)
streamlabs_usage_data.update()
add_devices([
StreamLabsDailyUsage(location_name, streamlabs_usage_data),
StreamLabsMonthlyUsage(location_name, streamlabs_usage_data),
StreamLabsYearlyUsage(location_name, streamlabs_usage_data)
])
class StreamlabsUsageData:
"""Track and query usage data."""
def __init__(self, location_id, client):
"""Initialize the usage data."""
self._location_id = location_id
self._client = client
self._today = None
self._this_month = None
self._this_year = None
@Throttle(MIN_TIME_BETWEEN_USAGE_UPDATES)
def update(self):
"""Query and store usage data."""
water_usage = self._client.get_water_usage_summary(self._location_id)
self._today = round(water_usage['today'], 1)
self._this_month = round(water_usage['thisMonth'], 1)
self._this_year = round(water_usage['thisYear'], 1)
def get_daily_usage(self):
"""Return the day's usage."""
return self._today
def get_monthly_usage(self):
"""Return the month's usage."""
return self._this_month
def get_yearly_usage(self):
"""Return the year's usage."""
return self._this_year
class StreamLabsDailyUsage(Entity):
"""Monitors the daily water usage."""
def __init__(self, location_name, streamlabs_usage_data):
"""Initialize the daily water usage device."""
self._location_name = location_name
self._streamlabs_usage_data = streamlabs_usage_data
self._state = None
@property
def name(self):
"""Return the name for daily usage."""
return "{} {}".format(self._location_name, NAME_DAILY_USAGE)
@property
def icon(self):
"""Return the daily usage icon."""
return WATER_ICON
@property
def state(self):
"""Return the current daily usage."""
return self._streamlabs_usage_data.get_daily_usage()
@property
def unit_of_measurement(self):
"""Return gallons as the unit measurement for water."""
return VOLUME_GALLONS
def update(self):
"""Retrieve the latest daily usage."""
self._streamlabs_usage_data.update()
class StreamLabsMonthlyUsage(StreamLabsDailyUsage):
"""Monitors the monthly water usage."""
@property
def name(self):
"""Return the name for monthly usage."""
return "{} {}".format(self._location_name, NAME_MONTHLY_USAGE)
@property
def state(self):
"""Return the current monthly usage."""
return self._streamlabs_usage_data.get_monthly_usage()
class StreamLabsYearlyUsage(StreamLabsDailyUsage):
"""Monitors the yearly water usage."""
@property
def name(self):
"""Return the name for yearly usage."""
return "{} {}".format(self._location_name, NAME_YEARLY_USAGE)
@property
def state(self):
"""Return the current yearly usage."""
return self._streamlabs_usage_data.get_yearly_usage()