11
2- import datetime
3- from unittest .mock import Mock
2+ import json
3+ from unittest .mock import Mock , mock_open , patch
44
55import pytest
66
77from control import data
88from control .chargelog import chargelog
9- from control .chargelog .chargelog import calculate_charge_cost
9+ from control .chargelog .chargelog import calc_energy_costs
1010from 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