Utility Meter offset defined by a time_period (#20926)
* change offset from int to Time period dictionary * track according to offset * left overs... tks @fabaff * typo
This commit is contained in:
parent
54895fcb1e
commit
8e9a496002
3 changed files with 61 additions and 24 deletions
|
@ -1,5 +1,6 @@
|
|||
"""Support for tracking consumption over given periods of time."""
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
|
@ -23,6 +24,8 @@ TARIFF_ICON = 'mdi:clock-outline'
|
|||
|
||||
ATTR_TARIFFS = 'tariffs'
|
||||
|
||||
DEFAULT_OFFSET = timedelta(hours=0)
|
||||
|
||||
SERVICE_METER_SCHEMA = vol.Schema({
|
||||
vol.Required(ATTR_ENTITY_ID): cv.entity_ids,
|
||||
})
|
||||
|
@ -35,7 +38,8 @@ METER_CONFIG_SCHEMA = vol.Schema({
|
|||
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_METER_NET_CONSUMPTION, default=False): cv.boolean,
|
||||
vol.Optional(CONF_TARIFFS, default=[]): vol.All(
|
||||
cv.ensure_list, [cv.string]),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
"""Utility meter from sensors providing raw data."""
|
||||
import logging
|
||||
|
||||
from datetime import date, timedelta
|
||||
from decimal import Decimal, DecimalException
|
||||
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
@ -128,15 +128,17 @@ class UtilityMeterSensor(RestoreEntity):
|
|||
self.async_schedule_update_ha_state()
|
||||
|
||||
async def _async_reset_meter(self, event):
|
||||
"""Determine cycle - Helper function for larger then daily cycles."""
|
||||
now = dt_util.now()
|
||||
if self._period == WEEKLY and now.weekday() != self._period_offset:
|
||||
"""Determine cycle - Helper function for larger than daily cycles."""
|
||||
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)
|
||||
|
||||
|
@ -155,15 +157,16 @@ class UtilityMeterSensor(RestoreEntity):
|
|||
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)
|
||||
|
|
|
@ -123,8 +123,8 @@ async def test_non_net_consumption(hass):
|
|||
assert state.state == '0'
|
||||
|
||||
|
||||
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': {
|
||||
|
@ -134,6 +134,16 @@ 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
|
||||
}
|
||||
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()
|
||||
|
@ -173,30 +183,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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue