Skip to content

Commit e497539

Browse files
committed
calc charge cost by used energy source in 5 min intervall
1 parent ef3c97b commit e497539

8 files changed

Lines changed: 357 additions & 332 deletions

File tree

packages/conftest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ def mock_today(monkeypatch) -> None:
3333
datetime_mock = MagicMock(wraps=datetime.datetime)
3434
# Montag 16.05.2022, 8:40:52 "05/16/2022, 08:40:52" Unix: 1652683252
3535
datetime_mock.today.return_value = datetime.datetime(2022, 5, 16, 8, 40, 52)
36+
datetime_mock.now.return_value = datetime.datetime(2022, 5, 16, 8, 40, 52)
3637
monkeypatch.setattr(datetime, "datetime", datetime_mock)
3738
mock_today_timestamp = Mock(return_value=1652683252)
3839
monkeypatch.setattr(timecheck, "create_timestamp", mock_today_timestamp)

packages/control/chargelog/chargelog.py

Lines changed: 102 additions & 205 deletions
Large diffs are not rendered by default.
Lines changed: 116 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,13 @@
11

2-
import datetime
3-
from unittest.mock import Mock
2+
import json
3+
from unittest.mock import Mock, mock_open, patch
44

55
import pytest
66

77
from control import data
88
from control.chargelog import chargelog
9-
from control.chargelog.chargelog import calculate_charge_cost
9+
from control.chargelog.chargelog import calc_energy_costs
1010
from control.chargepoint.chargepoint import Chargepoint
11-
from helpermodules import timecheck
12-
from test_utils.test_environment import running_on_github
13-
14-
15-
def mock_daily_log_with_charging(date: str, num_of_intervalls, monkeypatch):
16-
"""erzeugt ein daily_log, im ersten Eintrag gibt es keine Änderung, danach wird bis inklusive dem letzten Beitrag
17-
geladen"""
18-
bat_exported = pv_exported = cp_imported = counter_imported = 2000
19-
date = datetime.datetime.strptime(date, "%m/%d/%Y, %H:%M")
20-
daily_log = {"entries": []}
21-
for i in range(0, num_of_intervalls):
22-
if i != 0:
23-
bat_exported += 1000
24-
pv_exported += 500
25-
cp_imported += 2000
26-
counter_imported += 500
27-
daily_log["entries"].append({'bat': {'all': {'exported': bat_exported, 'imported': 2000, 'soc': 100},
28-
'bat2': {'exported': bat_exported, 'imported': 2000, 'soc': 100}},
29-
'counter': {'counter0': {'exported': 2000,
30-
'grid': True,
31-
'imported': counter_imported}},
32-
'cp': {'all': {'exported': 0, 'imported': cp_imported},
33-
'cp4': {'exported': 0, 'imported': cp_imported}},
34-
'date': date.strftime("%H:%M"),
35-
'ev': {'ev0': {'soc': None}},
36-
'hc': {'all': {'imported': 0}},
37-
'pv': {'all': {'exported': pv_exported}, 'pv1': {'exported': pv_exported}},
38-
'sh': {},
39-
'timestamp': date.timestamp()})
40-
date += datetime.timedelta(minutes=5)
41-
mock_todays_daily_log = Mock(return_value=daily_log)
42-
monkeypatch.setattr(chargelog, "get_todays_daily_log", mock_todays_daily_log)
43-
return daily_log
4411

4512

4613
@pytest.fixture()
@@ -49,106 +16,133 @@ def mock_data() -> None:
4916
data.data.optional_data.et_module = None
5017

5118

52-
def mock_create_entry_reference_end(clock, daily_log, monkeypatch):
53-
current_log = daily_log["entries"][-1]
54-
current_log["cp"]["all"]["imported"] += 500
55-
current_log["cp"]["cp4"]["imported"] += 500
56-
current_log["counter"]["counter0"]["imported"] += 500
57-
current_log["date"] = clock
58-
current_log["timestamp"] = datetime.datetime.strptime(f"05/16/2022, {clock}", "%m/%d/%Y, %H:%M").timestamp()
59-
mock_create_entry = Mock(return_value=current_log)
60-
monkeypatch.setattr(chargelog, "create_entry", mock_create_entry)
19+
def mock_daily_log(monkeypatch):
20+
daily_log = {"entries": [{'bat': {'all': {'exported': 2000, 'imported': 2000, 'soc': 100},
21+
'bat2': {'exported': 2000, 'imported': 2000, 'soc': 100}},
22+
'counter': {'counter0': {'exported': 2000,
23+
'grid': True,
24+
'imported': 500}},
25+
'cp': {'all': {'exported': 0, 'imported': 2000},
26+
'cp4': {'exported': 0, 'imported': 2000}},
27+
'date': "8:35",
28+
'ev': {'ev0': {'soc': None}},
29+
'hc': {'all': {'imported': 0}},
30+
'pv': {'all': {'exported': 2000}, 'pv1': {'exported': 2000}},
31+
'sh': {},
32+
'timestamp': 1652682900,
33+
'prices': {'grid': 0.0003, 'pv': 0.00015, 'bat': 0.0002, 'cp': 0}},
34+
{'bat': {'all': {'exported': 3000, 'imported': 2000, 'soc': 100},
35+
'bat2': {'exported': 3000, 'imported': 2000, 'soc': 100}},
36+
'counter': {'counter0': {'exported': 2000,
37+
'grid': True,
38+
'imported': 2500}},
39+
'cp': {'all': {'exported': 0, 'imported': 4000},
40+
'cp4': {'exported': 0, 'imported': 4000}},
41+
'date': "8:40",
42+
'ev': {'ev0': {'soc': None}},
43+
'hc': {'all': {'imported': 0}},
44+
'pv': {'all': {'exported': 2500}, 'pv1': {'exported': 2500}},
45+
'sh': {},
46+
'timestamp': 1652683200,
47+
'prices': {'grid': 0.0003, 'pv': 0.00015, 'bat': 0.0002, 'cp': 0}}]}
48+
mock_todays_daily_log = Mock(return_value=daily_log)
49+
monkeypatch.setattr(chargelog, "get_todays_daily_log", mock_todays_daily_log)
50+
return daily_log
6151

6252

63-
def init_cp(charged_energy, costs, start_hour, start_minute=47):
53+
def test_calc_charge_cost_reference_middle(mock_data, monkeypatch):
6454
cp = Chargepoint(4, None)
65-
cp.data.set.log.imported_since_plugged = cp.data.set.log.imported_since_mode_switch = charged_energy
66-
cp.data.set.log.timestamp_start_charging = datetime.datetime(2022, 5, 16, start_hour, start_minute).timestamp()
67-
cp.data.get.imported = charged_energy + 2000
68-
cp.data.set.log.costs = costs
69-
return cp
70-
71-
72-
def test_calc_charge_cost_no_hour_change_reference_end(mock_data, monkeypatch):
73-
cp = init_cp(6500, 0, 10, start_minute=27)
74-
daily_log = mock_daily_log_with_charging("05/16/2022, 10:25", 4, monkeypatch)
75-
mock_create_entry_reference_end("10:42", daily_log, monkeypatch)
76-
77-
calculate_charge_cost(cp, True)
78-
79-
assert cp.data.set.log.costs == 1.425
80-
55+
cp.data.set.log.imported_since_plugged = cp.data.set.log.imported_since_mode_switch = 3950
56+
cp.data.set.log.timestamp_start_charging = 1652682600 # 8:30
57+
cp.data.get.imported = 4050
58+
cp.data.set.log.charged_energy_by_source = {'bat': 100, 'cp': 0, 'grid': 100, 'pv': 100}
59+
daily_log = mock_daily_log(monkeypatch)
8160

82-
def test_calc_charge_cost_first_hour_change_reference_begin(mock_data, monkeypatch):
83-
cp = init_cp(6000, 0, 7)
84-
daily_log = mock_daily_log_with_charging("05/16/2022, 07:45", 4, monkeypatch)
85-
current_log = daily_log["entries"][-1]
86-
current_log["date"] = "08:00"
87-
current_log["timestamp"] = datetime.datetime.strptime("05/16/2022, 08:00", "%m/%d/%Y, %H:%M").timestamp()
88-
mock_create_entry = Mock(return_value=current_log)
89-
monkeypatch.setattr(chargelog, "create_entry", mock_create_entry)
61+
with patch("builtins.open", mock_open(read_data=json.dumps(daily_log))):
62+
calc_energy_costs(cp)
9063

91-
calculate_charge_cost(cp, False)
64+
assert cp.data.set.log.charged_energy_by_source == {
65+
'grid': 1243, 'pv': 386, 'bat': 671, 'cp': 0.0}
66+
assert round(cp.data.set.log.costs, 5) == 0.5
9267

93-
assert cp.data.set.log.costs == 1.275
9468

69+
def test_calc_charge_cost_reference_start(mock_data, monkeypatch):
70+
cp = Chargepoint(4, None)
71+
cp.data.set.log.imported_since_plugged = cp.data.set.log.imported_since_mode_switch = 100
72+
cp.data.set.log.timestamp_start_charging = 1652683230 # 8:40:30
73+
cp.data.get.imported = 4100
74+
cp.data.set.log.charged_energy_by_source = {'bat': 0, 'cp': 0, 'grid': 0, 'pv': 0}
75+
daily_log = mock_daily_log(monkeypatch)
9576

96-
def test_calc_charge_cost_first_hour_change_reference_begin_day_change(mock_data, monkeypatch):
97-
cp = init_cp(6000, 0, 23)
98-
daily_log = mock_daily_log_with_charging("05/16/2022, 23:45", 4, monkeypatch)
99-
current_log = daily_log["entries"][-1]
100-
current_log["date"] = "00:00"
101-
current_log["timestamp"] = datetime.datetime.strptime("05/17/2022, 00:00", "%m/%d/%Y, %H:%M").timestamp()
102-
mock_create_entry = Mock(return_value=current_log)
103-
monkeypatch.setattr(chargelog, "create_entry", mock_create_entry)
104-
mock_today_timestamp = Mock(return_value=1652738421)
105-
monkeypatch.setattr(timecheck, "create_timestamp", mock_today_timestamp)
106-
107-
calculate_charge_cost(cp, False)
108-
109-
assert cp.data.set.log.costs == 1.275
110-
111-
112-
def test_calc_charge_cost_one_hour_change_reference_end(mock_data, monkeypatch):
113-
if running_on_github():
114-
# ToDo Zeitzonen berücksichtigen, damit Tests auf Github laufen
115-
return
116-
cp = init_cp(22500, 1.275, 7)
117-
daily_log = mock_daily_log_with_charging("05/16/2022, 07:45", 12, monkeypatch)
118-
mock_create_entry_reference_end("08:40", daily_log, monkeypatch)
119-
120-
calculate_charge_cost(cp, True)
77+
with patch("builtins.open", mock_open(read_data=json.dumps(daily_log))):
78+
calc_energy_costs(cp)
12179

122-
assert cp.data.set.log.costs == 4.8248999999999995
80+
assert cp.data.set.log.charged_energy_by_source == {
81+
'bat': 28.549999999999997, 'cp': 0.0, 'grid': 57.15, 'pv': 14.299999999999999}
82+
assert round(cp.data.set.log.costs, 5) == 0.025
12383

12484

125-
def test_calc_charge_cost_two_hour_change_reference_middle(mock_data, monkeypatch):
126-
if running_on_github():
127-
# ToDo Zeitzonen berücksichtigen, damit Tests auf Github laufen
128-
return
129-
cp = init_cp(22500, 1.275, 6)
130-
daily_log = mock_daily_log_with_charging("05/16/2022, 06:45", 16, monkeypatch)
131-
current_log = daily_log["entries"][-1]
132-
current_log["date"] = "08:00"
133-
current_log["timestamp"] = datetime.datetime(2022, 5, 16, 8).timestamp()
134-
mock_create_entry = Mock(return_value=current_log)
135-
monkeypatch.setattr(chargelog, "create_entry", mock_create_entry)
136-
mock_today_timestamp = Mock(return_value=1652680801)
137-
monkeypatch.setattr(timecheck, "create_timestamp", mock_today_timestamp)
85+
def test_calc_charge_cost_reference_end(mock_data, monkeypatch):
86+
cp = Chargepoint(4, None)
87+
cp.data.set.log.imported_since_plugged = cp.data.set.log.imported_since_mode_switch = 3950
88+
cp.data.set.log.timestamp_start_charging = 1652682600 # 8:30
89+
cp.data.get.imported = 4100
90+
cp.data.set.log.charged_energy_by_source = {'grid': 1243, 'pv': 386, 'bat': 671, 'cp': 0.0}
91+
daily_log = mock_daily_log(monkeypatch)
13892

139-
calculate_charge_cost(cp, False)
93+
with patch("builtins.open", mock_open(read_data=json.dumps(daily_log))):
94+
calc_energy_costs(cp, True)
14095

141-
assert cp.data.set.log.costs == 6.375
96+
assert cp.data.set.log.charged_energy_by_source == {'bat': 699.55, 'cp': 0.0, 'grid': 1300.15, 'pv': 400.3}
97+
assert round(cp.data.set.log.costs, 5) == 0.025
14298

14399

144-
def test_calc_charge_cost_two_hour_change_reference_end(mock_data, monkeypatch):
145-
if running_on_github():
146-
# ToDo Zeitzonen berücksichtigen, damit Tests auf Github laufen
147-
return
148-
cp = init_cp(46500, 6.375, 6)
149-
daily_log = mock_daily_log_with_charging("05/16/2022, 06:45", 24, monkeypatch)
150-
mock_create_entry_reference_end("08:40", daily_log, monkeypatch)
100+
def test_calc_charge_cost_reference_middle_day_change(mock_data, monkeypatch):
101+
cp = Chargepoint(4, None)
102+
cp.data.set.log.imported_since_plugged = cp.data.set.log.imported_since_mode_switch = 3950
103+
cp.data.set.log.timestamp_start_charging = 1652682600 # 8:30
104+
cp.data.get.imported = 4050
105+
cp.data.set.log.charged_energy_by_source = {'bat': 100, 'cp': 0, 'grid': 100, 'pv': 100}
106+
yesterday_daily_log = {"entries": [{'bat': {'all': {'exported': 2000, 'imported': 2000, 'soc': 100},
107+
'bat2': {'exported': 2000, 'imported': 2000, 'soc': 100}},
108+
'counter': {'counter0': {'exported': 2000,
109+
'grid': True,
110+
'imported': 500}},
111+
'cp': {'all': {'exported': 0, 'imported': 2000},
112+
'cp4': {'exported': 0, 'imported': 2000}},
113+
'date': "8:35",
114+
'ev': {'ev0': {'soc': None}},
115+
'hc': {'all': {'imported': 0}},
116+
'pv': {'all': {'exported': 2000}, 'pv1': {'exported': 2000}},
117+
'sh': {},
118+
'timestamp': 1652682900,
119+
'prices': {'grid': 0.0003, 'pv': 0.00015, 'bat': 0.0002, 'cp': 0}}]}
120+
mock_yesterdays_daily_log = Mock(return_value=yesterday_daily_log)
121+
monkeypatch.setattr(chargelog, "get_daily_log", mock_yesterdays_daily_log)
122+
123+
daily_log = {"entries": [{'bat': {'all': {'exported': 3000, 'imported': 2000, 'soc': 100},
124+
'bat2': {'exported': 3000, 'imported': 2000, 'soc': 100}},
125+
'counter': {'counter0': {'exported': 2000,
126+
'grid': True,
127+
'imported': 2500}},
128+
'cp': {'all': {'exported': 0, 'imported': 4000},
129+
'cp4': {'exported': 0, 'imported': 4000}},
130+
'date': "8:40",
131+
'ev': {'ev0': {'soc': None}},
132+
'hc': {'all': {'imported': 0}},
133+
'pv': {'all': {'exported': 2500}, 'pv1': {'exported': 2500}},
134+
'sh': {},
135+
'timestamp': 1652683200,
136+
'prices': {'grid': 0.0003, 'pv': 0.00015, 'bat': 0.0002, 'cp': 0}}]}
137+
mock_todays_daily_log = Mock(return_value=daily_log)
138+
monkeypatch.setattr(chargelog, "get_todays_daily_log", mock_todays_daily_log)
151139

152-
calculate_charge_cost(cp, True)
140+
with patch("builtins.open", side_effect=[
141+
mock_open(read_data=json.dumps(daily_log)),
142+
mock_open(read_data=json.dumps(yesterday_daily_log))
143+
]):
144+
calc_energy_costs(cp)
153145

154-
assert cp.data.set.log.costs == 9.924900000000001
146+
assert cp.data.set.log.charged_energy_by_source == {
147+
'grid': 1243, 'pv': 386, 'bat': 671, 'cp': 0.0}
148+
assert round(cp.data.set.log.costs, 5) == 0.5

0 commit comments

Comments
 (0)