|
| 1 | + |
| 2 | +import datetime |
| 3 | +from unittest.mock import Mock |
| 4 | + |
| 5 | +import pytest |
| 6 | + |
| 7 | +from control import data |
| 8 | +from control.chargelog import chargelog |
| 9 | +from control.chargelog.chargelog import calculate_charge_cost |
| 10 | +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 |
| 44 | + |
| 45 | + |
| 46 | +@pytest.fixture() |
| 47 | +def mock_data() -> None: |
| 48 | + data.data_init(Mock()) |
| 49 | + data.data.optional_data.et_module = None |
| 50 | + |
| 51 | + |
| 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) |
| 61 | + |
| 62 | + |
| 63 | +def init_cp(charged_energy, costs, start_hour, start_minute=47): |
| 64 | + 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 | + |
| 81 | + |
| 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) |
| 90 | + |
| 91 | + calculate_charge_cost(cp, False) |
| 92 | + |
| 93 | + assert cp.data.set.log.costs == 1.275 |
| 94 | + |
| 95 | + |
| 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) |
| 121 | + |
| 122 | + assert cp.data.set.log.costs == 4.8248999999999995 |
| 123 | + |
| 124 | + |
| 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) |
| 138 | + |
| 139 | + calculate_charge_cost(cp, False) |
| 140 | + |
| 141 | + assert cp.data.set.log.costs == 6.375 |
| 142 | + |
| 143 | + |
| 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) |
| 151 | + |
| 152 | + calculate_charge_cost(cp, True) |
| 153 | + |
| 154 | + assert cp.data.set.log.costs == 9.924900000000001 |
0 commit comments