Skip to content

Commit

Permalink
Merge pull request #149 from gisce/fix_get_coef_by_tariff
Browse files Browse the repository at this point in the history
Corrección reparto periodos por horas en estimación y ajuste de curvas
  • Loading branch information
tinogis committed Jul 30, 2021
2 parents 5c1c8a1 + 529ba25 commit 53d1fb7
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 33 deletions.
23 changes: 15 additions & 8 deletions enerdata/profiles/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -479,13 +479,15 @@ def get_hours_per_period(self, tariff, only_valid=False):
if only_valid:
for m in self.measures:
if m.valid:
period = tariff.get_period_by_date(m.date)
dt = m.date - timedelta(minutes=1)
period = tariff.get_period_by_date(dt)
hours_per_period[period.code] += 1
else:
start_idx = self.start_date
end = self.end_date
while start_idx <= end:
period = tariff.get_period_by_date(start_idx)
dt = start_idx - timedelta(minutes=1)
period = tariff.get_period_by_date(dt)
hours_per_period[period.code] += 1
start_idx += timedelta(hours=1)
return hours_per_period
Expand All @@ -497,7 +499,8 @@ def get_consumption_per_period(self, tariff):
consumption_per_period[period] = 0
for m in self.measures:
if m.valid:
period = tariff.get_period_by_date(m.date)
dt = m.date - timedelta(minutes=1)
period = tariff.get_period_by_date(dt)
consumption_per_period[period.code] += m.measure
return consumption_per_period

Expand Down Expand Up @@ -550,8 +553,9 @@ def estimate(self, tariff, balance):
cofs_per_period = Counter()

for gap in self.gaps:
period = tariff.get_period_by_date(gap)
gap_cof = cofs.get(gap)
dt = gap - timedelta(minutes=1)
period = tariff.get_period_by_date(dt)
gap_cof = cofs.get(dt)
cofs_per_period[period.code] += gap_cof.cof[tariff.cof]

logger.debug('Coefficients per period calculated: {0}'.format(
Expand All @@ -569,15 +573,17 @@ def estimate(self, tariff, balance):
if not self.drag_by_periods:
init_drag_key = "default"
else:
init_drag_key = tariff.get_period_by_date(self.gaps[0]).code
dt = self.gaps[0] - timedelta(minutes=1)
init_drag_key = tariff.get_period_by_date(dt).code

dragger.drag(self.accumulated, key=init_drag_key)

for idx, gap in enumerate(self.gaps):
logger.debug('Gap {0}/{1}'.format(
idx + 1, len(self.gaps)
))
period = tariff.get_period_by_date(gap)
dt = gap - timedelta(minutes=1)
period = tariff.get_period_by_date(dt)

drag_key = period.code if not self.drag_by_periods else "default"

Expand Down Expand Up @@ -623,7 +629,8 @@ def adjust(self, tariff, balance, diff=0):
if not margin_bottom <= period_profile <= margin_top:
profile.adjusted_periods.append(period_name)
for idx, measure in enumerate(profile.measures):
period = tariff.get_period_by_date(measure.date).code
dt = measure.date - timedelta(minutes=1)
period = tariff.get_period_by_date(dt).code
if period != period_name:
continue
values = measure._asdict()
Expand Down
33 changes: 22 additions & 11 deletions spec/profiles/gaps_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@
tariff = T20DHA()
balance = Counter()
for ph in self.complete_profile:
period = tariff.get_period_by_date(ph.date)
dt = ph.date - timedelta(minutes=1)
period = tariff.get_period_by_date(dt)
balance[period.code] += ph.measure

total = sum(balance.values())
Expand All @@ -75,7 +76,8 @@
tariff = T20DHA()
tariff.cof = 'A'
for ph in self.complete_profile:
period = tariff.get_period_by_date(ph.date)
dt = ph.date - timedelta(minutes=1)
period = tariff.get_period_by_date(dt)
balance[period.code] += ph.measure
with vcr.use_cassette('spec/fixtures/ree/201503-201504.yaml'):
profile_estimated = self.profile.estimate(tariff, balance)
Expand Down Expand Up @@ -103,7 +105,8 @@
self.profile.start_date, self.profile.end_date, []
)
for ph in self.complete_profile:
period = tariff.get_period_by_date(ph.date)
dt = ph.date - timedelta(minutes=1)
period = tariff.get_period_by_date(dt)
balance[period.code] += ph.measure
with vcr.use_cassette('spec/fixtures/ree/201503-201504.yaml'):
profile_estimated = profile.estimate(tariff, balance)
Expand All @@ -119,7 +122,8 @@

measures = []
for ph in self.complete_profile:
period = tariff.get_period_by_date(ph.date)
dt = ph.date - timedelta(minutes=1)
period = tariff.get_period_by_date(dt)
balance[period.code] += ph.measure
measures.append(ProfileHour(ph.date, ph.measure, False, 0.0))

Expand Down Expand Up @@ -163,7 +167,8 @@
balance = Counter()
tariff = T20DHA()
for ph in self.profile.measures:
period = tariff.get_period_by_date(ph.date)
dt = ph.date - timedelta(minutes=1)
period = tariff.get_period_by_date(dt)
balance[period.code] += ph.measure
expect(len(self.profile.gaps)).to(be_above(0))

Expand Down Expand Up @@ -205,7 +210,8 @@ def adjust_error():
)

for ph in self.profile.measures:
period = tariff.get_period_by_date(ph.date)
dt = ph.date - timedelta(minutes=1)
period = tariff.get_period_by_date(dt)
complete_hours[period.code] += 1

for period in complete_hours:
Expand All @@ -215,7 +221,8 @@ def adjust_error():
tariff = T20DHA()
balance = Counter()
for ph in self.profile.measures:
period = tariff.get_period_by_date(ph.date)
dt = ph.date - timedelta(minutes=1)
period = tariff.get_period_by_date(dt)
balance[period.code] += ph.measure
with vcr.use_cassette('spec/fixtures/ree/201503-201504.yaml'):
profile = self.profile.estimate(tariff, balance)
Expand All @@ -238,7 +245,8 @@ def adjust_error():
)

for ph in profile.measures:
period = tariff.get_period_by_date(ph.date)
dt = ph.date - timedelta(minutes=1)
period = tariff.get_period_by_date(dt)
balance[period.code] += ph.measure

balance[period.code] -= 940
Expand All @@ -251,7 +259,8 @@ def adjust_error():
balance = Counter()

for ph in profile.measures:
period = tariff.get_period_by_date(ph.date)
dt = ph.date - timedelta(minutes=1)
period = tariff.get_period_by_date(dt)
balance[period.code] += ph.measure

balance[period.code] += 360
Expand All @@ -267,7 +276,8 @@ def adjust_error():
balance = Counter()

for ph in self.profile.measures:
period = tariff.get_period_by_date(ph.date)
dt = ph.date - timedelta(minutes=1)
period = tariff.get_period_by_date(dt)
balance[period.code] += ph.measure

balance[period.code] += 10
Expand All @@ -280,7 +290,8 @@ def adjust_error():

adjusted_balance = Counter()
for ph in profile.measures:
period = tariff.get_period_by_date(ph.date)
dt = ph.date - timedelta(minutes=1)
period = tariff.get_period_by_date(dt)
adjusted_balance[period.code] += ph.measure

for period in adjusted_balance:
Expand Down
9 changes: 6 additions & 3 deletions spec/profiles/integration_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ def convert_to_profilehour(measure):
tariff.cof = 'A'

for ph in self.measures:
period = tariff.get_period_by_date(ph['timestamp'])
dt = ph['timestamp'] - timedelta(minutes=1)
period = tariff.get_period_by_date(dt)
balance[period.code] += ph['ai']

with vcr.use_cassette('spec/fixtures/ree/201505.yaml'):
Expand Down Expand Up @@ -170,15 +171,17 @@ def convert_to_profilehour(measure):

# Fix the gaps
for ph in self.measures:
period = tariff.get_period_by_date(ph['timestamp'])
dt = ph['timestamp'] - timedelta(minutes=1)
period = tariff.get_period_by_date(dt)
balance[period.code] += ph['ai']

with vcr.use_cassette('spec/fixtures/ree/201505.yaml'):
profile = profile.estimate(tariff, balance)

# Fake balance to adjust the profile
for ph in self.measures:
period = tariff.get_period_by_date(ph['timestamp'])
dt = ph['timestamp'] - timedelta(minutes=1)
period = tariff.get_period_by_date(dt)
balance[period.code] += ph['ai'] + 1

profile_estimated = profile.adjust(tariff, balance)
Expand Down
24 changes: 13 additions & 11 deletions spec/profiles/profile_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -698,8 +698,8 @@ def get_range_error():
with before.all:

self.measures = []
self.start = TIMEZONE.localize(datetime(2017, 9, 1))
self.end = TIMEZONE.localize(datetime(2017, 9, 5))
self.start = TIMEZONE.localize(datetime(2017, 9, 1, 1))
self.end = TIMEZONE.localize(datetime(2017, 9, 5, 0))

dates_difference_seconds = (self.end - self.start).total_seconds()
# Invoice hours with fixed first hour (timedelta performs natural substraction, so first hour must be handled)
Expand Down Expand Up @@ -881,15 +881,15 @@ def get_range_error():
tariff = T21DHS()
periods = tariff.energy_periods

# This scenario, with an initial accumulated of 0.636 will raise a -1 total energy with an ending accumulated of 0.333962070125
# This scenario, with an initial accumulated of 0.636 will raise a -1 total energy with an ending accumulated of 0.2999999999978
total_expected = 0
balance = {
'P1': 6.8,
'P2': 3,
'P3': 3.5,
}
total_expected = round(sum(balance.values()))
expected_last_accumulated = Decimal(0.3000000000036)
expected_last_accumulated = Decimal(0.2999999999978)

estimation = self.profile.estimate(tariff, balance)
total_estimated = sum([x.measure for x in estimation.measures])
Expand All @@ -907,14 +907,14 @@ def get_range_error():
# [!] Now estimate it using a by hour dragging
# total energy will be +1kWh!
drag_by_perdiod = False
total_expected += 1
expected_last_accumulated = Decimal(2.2E-12)
# total_expected += 1
expected_last_accumulated = Decimal(-0.2000000000006)

self.profile = Profile(self.start, self.end, self.measures, accumulated, drag_by_perdiod)
estimation = self.profile.estimate(tariff, balance)
total_estimated_by_hour = sum([x.measure for x in estimation.measures])
last_accumulated_by_hour = estimation.measures[-1].accumulated
assert total_expected == total_estimated_by_hour, "Total energy dragged by hour '{}' must match the expected +1 '{}'".format(total_estimated_by_hour, total_expected)
assert total_expected <= total_estimated_by_hour <= total_expected + 1, "Total energy dragged by hour '{}' must match the expected +1 '{}'".format(total_estimated_by_hour, total_expected)
assert float(last_accumulated_by_hour) == float(expected_last_accumulated), "Last accumulated by hour '{}' must match the expected '{}'".format(last_accumulated_by_hour, expected_last_accumulated)


Expand Down Expand Up @@ -1042,13 +1042,14 @@ def get_range_error():
# set balances without losses
while start_idx <= end:
consumption = random.randint(0, 10)
period = the_tariff.get_period_by_date(start_idx).code
dt = start_idx - timedelta(minutes=1)
period = the_tariff.get_period_by_date(dt).code
if period in balance_without_losses:
balance_without_losses[period] += consumption
else:
balance_without_losses[period] = consumption
measures.append(ProfileHour(
TIMEZONE.normalize(start_idx), consumption, True, 0.0
TIMEZONE.normalize(dt), consumption, True, 0.0
))
start_idx += timedelta(hours=1)
# check curve and billings sum is equal
Expand Down Expand Up @@ -1078,14 +1079,15 @@ def get_range_error():
while start_idx <= end:
gap_flag = random.randint(0, 1)
consumption = random.randint(0, 10)
period = the_tariff.get_period_by_date(start_idx).code
dt = start_idx - timedelta(minutes=1)
period = the_tariff.get_period_by_date(dt).code
if period in balance_without_losses:
balance_without_losses[period] += consumption
else:
balance_without_losses[period] = consumption
if not gap_flag:
measures.append(ProfileHour(
TIMEZONE.normalize(start_idx), consumption, True, 0.0
TIMEZONE.normalize(dt), consumption, True, 0.0
))
start_idx += timedelta(hours=1)
counter += 1
Expand Down

0 comments on commit 53d1fb7

Please sign in to comment.