Skip to content

Commit

Permalink
pvcalculator: compatible with unagreed data
Browse files Browse the repository at this point in the history
Beedata sent a data format which is not the agreed one.
In order to make it work while they adjust the format,
you can enable this behavior by defining an env var:

BEEDATA_UNAGREED_API=1
  • Loading branch information
vokimon committed Jun 14, 2022
1 parent 93a4abe commit 500eab7
Show file tree
Hide file tree
Showing 6 changed files with 745 additions and 25 deletions.
43 changes: 27 additions & 16 deletions heman/api/pvcalculator/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import json
import pymongo

import os
from flask import current_app
from flask_restful import request

Expand Down Expand Up @@ -36,6 +36,26 @@ def parseMongoAzimuth(azimuth, gabledroof):
return (int(azimuth),)
return (int(azimuth), int((azimuth+180) % 360))

def parseMongoAzimuthFromSettings(settings):
if os.environ.get("BEEDATA_UNAGREED_API"):
return parseMongoAzimuthFromSettings_unagreedVersion(settings)

return parseMongoAzimuth(
settings['azimuth'],
settings['gabledroof']
)

def parseMongoAzimuthFromSettings_unagreedVersion(settings):
azimuth0 = int(settings['azimuth0'])
try:
azimuth1 = int(settings['azimuth1'])
except ValueError:
return (azimuth0,)
return (azimuth0, azimuth1)

def parseTilt(settings):
return float(settings['tilt'])

def queryPeakPower(peakPower):
if not peakPower: return None
return float(peakPower)
Expand Down Expand Up @@ -77,11 +97,8 @@ def get(self, contract):
selectedScenarios = [
scenario
for i,scenario in enumerate(scenarios)
if scenario['settings']['tilt'] == tiltDegrees
and parseMongoAzimuth(
scenario['settings']['azimuth'],
scenario['settings']['gabledroof']
) == azimuthDegrees
if parseTilt(scenario['settings']) == tiltDegrees
and parseMongoAzimuthFromSettings(scenario['settings']) == azimuthDegrees
and (scenario['settings']['power'] == peakPowerKw or not peakPowerKw)
]
if not selectedScenarios:
Expand Down Expand Up @@ -109,11 +126,8 @@ def get(self, contract):
savingsEuroYear = bestScenario['generation']['savings'],
paybackYears = bestScenario['economics']['payback'],
installationCostEuro = bestScenario['settings']['cost'],
azimuthDegrees= parseMongoAzimuth(
bestScenario['settings']['azimuth'],
bestScenario['settings']['gabledroof']
),
tiltDegrees= bestScenario['settings']['tilt'],
azimuthDegrees= parseMongoAzimuthFromSettings(bestScenario['settings']),
tiltDegrees= parseTilt(bestScenario['settings']),
areaM2 = bestScenario['settings']['area'],
nModules = bestScenario['settings']['numModules'],
peakPowerKw = bestScenario['settings']['power'],
Expand Down Expand Up @@ -153,11 +167,8 @@ def get(self, contract):

tilts, azimuths, powers = zip(*[
(
scenario['settings']['tilt'],
parseMongoAzimuth(
scenario['settings']['azimuth'],
scenario['settings']['gabledroof']
),
parseTilt(scenario['settings']),
parseMongoAzimuthFromSettings(scenario['settings']),
scenario['settings']['power'],
)
for i,scenario in enumerate(scenarios)
Expand Down
67 changes: 58 additions & 9 deletions heman/api/pvcalculator/pvcalculator_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ def mongodb():
mongodb.drop_database('heman_pv_test')
mongodb.close()

@pytest.fixture
def scenario_data(mongodb):
@pytest.fixture(scope='function')
def agreed_scenario_data(mongodb):
contract = '666666'
token = 'mytoken'
user = APIUser(
Expand All @@ -60,7 +60,53 @@ def scenario_data(mongodb):
})
yield contract, token

def test__scenario_report__with_power(api, scenario_data, yaml_snapshot):
@pytest.fixture(scope='function')
def unagreed_scenario_data(mongodb):
"""This simulates the current API which is not the same
we agreed with BeeData.
"""
os.environ["BEEDATA_UNAGREED_API"]='1'
contract = '666666'
token = 'mytoken'
user = APIUser(
token,
[contract]
)
mongodb.tokens.insert_one({
'allowed_contracts': [
{'cups': 'ES1111111111111111VL0F', 'name': '666666'}
],
'token': token,
})

with open('testdata/pvautosize_example.json') as json_file:
data = json.load(json_file)

for scenario in data['_items'][0]['results']['pvAutoSize']['scenarios']:
settings = scenario['settings']
settings['tilt'] = str(int(float(settings['tilt'])))
settings['azimuth0'] = str(int(float(settings['azimuth'])))

if settings['gabledroof']:
settings['azimuth1'] = str((int(settings['azimuth0'])+180)%360)
else:
settings['azimuth1'] = '\\N'

del settings['azimuth']
del settings['gabledroof']

mongodb.photovoltaic_reports.insert_one({
'contractName': data['_items'][0]['contractId'],
'beedataUpdateDate': data['_items'][0]['_created'],
'beedataCreateDate': data['_items'][0]['_created'],
'results': data['_items'][0]['results'],
})
yield contract, token
del os.environ['BEEDATA_UNAGREED_API']

@pytest.mark.parametrize('scenario_data', [agreed_scenario_data, unagreed_scenario_data])
def test__scenario_report__with_power(api, scenario_data, yaml_snapshot, request):
scenario_data = request.getfixturevalue(scenario_data.__name__)
contract, token = scenario_data
r = api.get('/api/ScenarioReport/{}'.format(contract),
query_string=dict(
Expand All @@ -74,8 +120,9 @@ def test__scenario_report__with_power(api, scenario_data, yaml_snapshot):
)
yaml_snapshot(r.get_json())

def test__scenario_report__optimal_payback(api, scenario_data, yaml_snapshot):
contract, token = scenario_data
@pytest.mark.parametrize('scenario_data', [agreed_scenario_data, unagreed_scenario_data])
def test__scenario_report__optimal_payback(api, scenario_data, yaml_snapshot, request):
contract, token = request.getfixturevalue(scenario_data.__name__)
r = api.get('/api/ScenarioReport/{}'.format(contract),
query_string=dict(
tilt=30.0,
Expand All @@ -87,8 +134,9 @@ def test__scenario_report__optimal_payback(api, scenario_data, yaml_snapshot):
)
yaml_snapshot(r.get_json())

def test__scenario_report__parameter_value_not_found(api, scenario_data):
contract, token = scenario_data
@pytest.mark.parametrize('scenario_data', [agreed_scenario_data, unagreed_scenario_data])
def test__scenario_report__parameter_value_not_found(api, scenario_data, request):
contract, token = request.getfixturevalue(scenario_data.__name__)
r = api.get('/api/ScenarioReport/{}'.format(contract),
query_string=dict(
tilt=31.0, # Value for tilt not found
Expand All @@ -104,8 +152,9 @@ def test__scenario_report__parameter_value_not_found(api, scenario_data):
'message': "Scenario not found",
}

def test__scenario_params(api, scenario_data):
contract, token = scenario_data
@pytest.mark.parametrize('scenario_data', [agreed_scenario_data, unagreed_scenario_data])
def test__scenario_params(api, scenario_data, request):
contract, token = request.getfixturevalue(scenario_data.__name__)
r = api.get('/api/ScenarioParams/{}'.format(contract),
headers=dict(
Authorization = 'token {}'.format(token)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
snapshot:
areaM2: 1.87
azimuthDegrees:
- 180
- 0
dailyLoadProfileKwh:
- 0.24
- 0.235
- 0.188
- 0.119
- 0.112
- 0.111
- 0.11
- 0.11
- 0.112
- 0.128
- 0.163
- 0.164
- 0.159
- 0.169
- 0.173
- 0.184
- 0.185
- 0.176
- 0.185
- 0.201
- 0.227
- 0.297
- 0.27
- 0.242
dailyProductionProfileKwh:
- 0.0
- 0.0
- 0.0
- 0.0
- 0.0
- 0.0
- 0.0
- 0.0
- 0.0
- 0.18447877986758623
- 0.45050322989886715
- 0.6842496794010439
- 0.8586094276676137
- 0.9808886573128532
- 1.0320500689830303
- 1.044401117451371
- 0.8678159002376173
- 0.6475610849399653
- 0.346557928998376
- 0.028670851846208854
- 0.0
- 0.0
- 0.0
- 0.0
installationCostEuro: 4689.960000238015
loadByPeriodKwh:
p1: 803.794
p2: 755.707
p3: 1217.922
loadFromGridKwhYear: 2002.7536777993632
loadKwhYear: 2777.4230000000002
monthlyGridToLoadEuro:
- 14.627190411786263
- 45.27684512835782
- 27.327464726704072
- 19.518720505853416
- 17.740237003145936
- 19.696353160694297
- 46.67243568908299
- 83.86117900006046
- 37.81555613421613
- 41.24751258733735
- 13.32924137903866
- 9.058332953223646
monthlyGridToLoadKwh:
- 82.85100303263394
- 228.1379132726195
- 154.58782428092337
- 107.64669480981134
- 96.6631328650054
- 101.97759176698138
- 246.62320799467082
- 439.8872634660999
- 193.85230163604848
- 219.2506042949218
- 74.82304688234241
- 56.45309349730475
monthlyProductionKwh:
- 129.78385244825515
- 124.43717799431393
- 222.55726103086835
- 251.1174864391928
- 352.94469934002626
- 349.10814415890053
- 368.9957558014182
- 313.9687881598149
- 232.35290506011782
- 169.21855891720034
- 101.50987126752965
- 97.07097057321447
monthlyProductionToGridEuro:
- 14.567711698794122
- 19.781806593359462
- 19.82981722295994
- 13.538373889650854
- 9.687750145440988
- 5.188050697263836
- 5.399143408627698
- 6.50391168626602
- 6.293832943070472
- 12.79617151954637
- 13.32924137903866
- 9.058332953223646
monthlyProductionToGridKwh:
- 263.07612719153445
- 235.65766907403773
- 236.22961244073824
- 161.28059986992915
- 115.40870178220574
- 61.80446303451103
- 64.3191785678853
- 77.48011591435504
- 74.97747963036242
- 152.43885532579014
- 204.19153332153522
- 291.531812837331
monthlyProductionToLoadEuro:
- 19.91411118299925
- 29.596899718234805
- 16.343058432870063
- 16.251016826875055
- 11.813922141325762
- 8.586229583637659
- 7.4001786151556015
- 10.598602420722552
- 10.53902581049208
- 16.039476231209655
- 10.959780400097364
- 13.824901339648608
monthlyProductionToLoadKwh:
- 86.36531696736607
- 133.68249672738048
- 78.10277571907663
- 71.46620519018867
- 54.266377134994606
- 40.17202823301862
- 33.280022005329165
- 52.8046965339001
- 49.87682836395151
- 70.5395757050782
- 47.291573117657585
- 61.757296502695255
nModules: 6.0
paybackYears: 12.4569525340302
peakPowerKw: 2.28
productionKwhYear: 2713.065471190853
productionToGridEuroYear: 135.97414413724206
productionToGridKwhYear: 1938.3961489902156
productionToGridPercent: 71.26478514879176
productionToLoadEuroYear: 171.86720270326845
productionToLoadKwhYear: 779.605192200637
productionToLoadPercent: 28.73521485120825
savingsEuroYear: 307.05135592354816
tiltDegrees: 30.0
Loading

0 comments on commit 500eab7

Please sign in to comment.