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

Utility Meter offset defined by a time_period #20926

Merged
merged 5 commits into from Mar 6, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 5 additions & 1 deletion homeassistant/components/utility_meter/__init__.py
Expand Up @@ -6,6 +6,7 @@
"""

import logging
from datetime import timedelta

import voluptuous as vol

Expand All @@ -29,6 +30,8 @@

ATTR_TARIFFS = 'tariffs'

DEFAULT_OFFSET = timedelta(hours=0)

SERVICE_METER_SCHEMA = vol.Schema({
vol.Required(ATTR_ENTITY_ID): cv.entity_ids,
})
Expand All @@ -41,7 +44,8 @@
vol.Required(CONF_SOURCE_SENSOR): cv.entity_id,
vol.Optional(CONF_NAME): cv.string,
vol.Optional(CONF_METER_TYPE): vol.In(METER_TYPES),
vol.Optional(CONF_METER_OFFSET, default=0): cv.positive_int,
vol.Optional(CONF_METER_OFFSET, default=DEFAULT_OFFSET):
vol.All(cv.time_period, cv.positive_timedelta),
vol.Optional(CONF_TARIFFS, default=[]): vol.All(
cv.ensure_list, [cv.string]),
})
Expand Down
31 changes: 17 additions & 14 deletions homeassistant/components/utility_meter/sensor.py
Expand Up @@ -5,7 +5,7 @@
https://home-assistant.io/components/sensor.utility_meter/
"""
import logging

from datetime import date, timedelta
from decimal import Decimal, DecimalException

import homeassistant.util.dt as dt_util
Expand Down Expand Up @@ -133,14 +133,16 @@ def async_tariff_change(self, entity, old_state, new_state):

async def _async_reset_meter(self, event):
"""Determine cycle - Helper function for larger then daily cycles."""
dgomes marked this conversation as resolved.
Show resolved Hide resolved
now = dt_util.now()
if self._period == WEEKLY and now.weekday() != self._period_offset:
now = dt_util.now().date()
if self._period == WEEKLY and\
now != now - timedelta(days=now.weekday())\
+ self._period_offset:
return
if self._period == MONTHLY and\
now.day != (1 + self._period_offset):
now != date(now.year, now.month, 1) + self._period_offset:
return
if self._period == YEARLY and\
(now.month != (1 + self._period_offset) or now.day != 1):
now != date(now.year, 1, 1) + self._period_offset:
return
await self.async_reset_meter(self._tariff_entity)

Expand All @@ -159,15 +161,16 @@ async def async_added_to_hass(self):
await super().async_added_to_hass()

if self._period == HOURLY:
async_track_time_change(self.hass, self._async_reset_meter,
minute=self._period_offset, second=0)
elif self._period == DAILY:
async_track_time_change(self.hass, self._async_reset_meter,
hour=self._period_offset, minute=0,
second=0)
elif self._period in [WEEKLY, MONTHLY, YEARLY]:
async_track_time_change(self.hass, self._async_reset_meter,
hour=0, minute=0, second=0)
async_track_time_change(
self.hass, self._async_reset_meter,
minute=self._period_offset.seconds // 60,
second=self._period_offset.seconds % 60)
elif self._period in [DAILY, WEEKLY, MONTHLY, YEARLY]:
async_track_time_change(
self.hass, self._async_reset_meter,
hour=self._period_offset.seconds // 3600,
minute=self._period_offset.seconds % 3600 // 60,
second=self._period_offset.seconds % 3600 % 60)

async_dispatcher_connect(
self.hass, SIGNAL_RESET_METER, self.async_reset_meter)
Expand Down
48 changes: 40 additions & 8 deletions tests/components/utility_meter/test_sensor.py
Expand Up @@ -57,8 +57,8 @@ async def test_state(hass):
assert state.state == '1'


async def _test_self_reset(hass, cycle, start_time, expect_reset=True):
"""Test energy sensor self reset."""
def gen_config(cycle, offset=None):
"""Generate configuration."""
config = {
'utility_meter': {
'energy_bill': {
Expand All @@ -68,6 +68,18 @@ async def _test_self_reset(hass, cycle, start_time, expect_reset=True):
}
}

if offset:
config['utility_meter']['energy_bill']['offset'] = {
'days': offset.days,
'seconds': offset.seconds
}
import pprint
pprint.pprint(config)
dgomes marked this conversation as resolved.
Show resolved Hide resolved
return config


async def _test_self_reset(hass, config, start_time, expect_reset=True):
"""Test energy sensor self reset."""
assert await async_setup_component(hass, DOMAIN, config)
assert await async_setup_component(hass, SENSOR_DOMAIN, config)
await hass.async_block_till_done()
Expand Down Expand Up @@ -107,30 +119,50 @@ async def _test_self_reset(hass, cycle, start_time, expect_reset=True):

async def test_self_reset_hourly(hass):
"""Test hourly reset of meter."""
await _test_self_reset(hass, 'hourly', "2017-12-31T23:59:00.000000+00:00")
await _test_self_reset(hass, gen_config('hourly'),
"2017-12-31T23:59:00.000000+00:00")


async def test_self_reset_daily(hass):
"""Test daily reset of meter."""
await _test_self_reset(hass, 'daily', "2017-12-31T23:59:00.000000+00:00")
await _test_self_reset(hass, gen_config('daily'),
"2017-12-31T23:59:00.000000+00:00")


async def test_self_reset_weekly(hass):
"""Test weekly reset of meter."""
await _test_self_reset(hass, 'weekly', "2017-12-31T23:59:00.000000+00:00")
await _test_self_reset(hass, gen_config('weekly'),
"2017-12-31T23:59:00.000000+00:00")


async def test_self_reset_monthly(hass):
"""Test monthly reset of meter."""
await _test_self_reset(hass, 'monthly', "2017-12-31T23:59:00.000000+00:00")
await _test_self_reset(hass, gen_config('monthly'),
"2017-12-31T23:59:00.000000+00:00")


async def test_self_reset_yearly(hass):
"""Test yearly reset of meter."""
await _test_self_reset(hass, 'yearly', "2017-12-31T23:59:00.000000+00:00")
await _test_self_reset(hass, gen_config('yearly'),
"2017-12-31T23:59:00.000000+00:00")


async def test_self_no_reset_yearly(hass):
"""Test yearly reset of meter does not occur after 1st January."""
await _test_self_reset(hass, 'yearly', "2018-01-01T23:59:00.000000+00:00",
await _test_self_reset(hass, gen_config('yearly'),
"2018-01-01T23:59:00.000000+00:00",
expect_reset=False)


async def test_reset_yearly_offset(hass):
"""Test yearly reset of meter."""
await _test_self_reset(hass,
gen_config('yearly', timedelta(days=1, minutes=10)),
"2018-01-02T00:09:00.000000+00:00")


async def test_no_reset_yearly_offset(hass):
"""Test yearly reset of meter."""
await _test_self_reset(hass, gen_config('yearly', timedelta(31)),
"2018-01-30T23:59:00.000000+00:00",
expect_reset=False)