Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def mock_today(monkeypatch) -> None:
datetime_mock = MagicMock(wraps=datetime.datetime)
# Montag 16.05.2022, 8:40:52 "05/16/2022, 08:40:52" Unix: 1652683252
datetime_mock.today.return_value = datetime.datetime(2022, 5, 16, 8, 40, 52)
datetime_mock.now.return_value = datetime.datetime(2022, 5, 16, 8, 40, 52)
monkeypatch.setattr(datetime, "datetime", datetime_mock)
mock_today_timestamp = Mock(return_value=1652683252)
monkeypatch.setattr(timecheck, "create_timestamp", mock_today_timestamp)
Expand Down
309 changes: 104 additions & 205 deletions packages/control/chargelog/chargelog.py

Large diffs are not rendered by default.

238 changes: 116 additions & 122 deletions packages/control/chargelog/chargelog_test.py
Original file line number Diff line number Diff line change
@@ -1,46 +1,13 @@

import datetime
from unittest.mock import Mock
import json
from unittest.mock import Mock, mock_open, patch

import pytest

from control import data
from control.chargelog import chargelog
from control.chargelog.chargelog import calculate_charge_cost
from control.chargelog.chargelog import calc_energy_costs
from control.chargepoint.chargepoint import Chargepoint
from helpermodules import timecheck
from test_utils.test_environment import running_on_github


def mock_daily_log_with_charging(date: str, num_of_intervalls, monkeypatch):
"""erzeugt ein daily_log, im ersten Eintrag gibt es keine Änderung, danach wird bis inklusive dem letzten Beitrag
geladen"""
bat_exported = pv_exported = cp_imported = counter_imported = 2000
date = datetime.datetime.strptime(date, "%m/%d/%Y, %H:%M")
daily_log = {"entries": []}
for i in range(0, num_of_intervalls):
if i != 0:
bat_exported += 1000
pv_exported += 500
cp_imported += 2000
counter_imported += 500
daily_log["entries"].append({'bat': {'all': {'exported': bat_exported, 'imported': 2000, 'soc': 100},
'bat2': {'exported': bat_exported, 'imported': 2000, 'soc': 100}},
'counter': {'counter0': {'exported': 2000,
'grid': True,
'imported': counter_imported}},
'cp': {'all': {'exported': 0, 'imported': cp_imported},
'cp4': {'exported': 0, 'imported': cp_imported}},
'date': date.strftime("%H:%M"),
'ev': {'ev0': {'soc': None}},
'hc': {'all': {'imported': 0}},
'pv': {'all': {'exported': pv_exported}, 'pv1': {'exported': pv_exported}},
'sh': {},
'timestamp': date.timestamp()})
date += datetime.timedelta(minutes=5)
mock_todays_daily_log = Mock(return_value=daily_log)
monkeypatch.setattr(chargelog, "get_todays_daily_log", mock_todays_daily_log)
return daily_log


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


def mock_create_entry_reference_end(clock, daily_log, monkeypatch):
current_log = daily_log["entries"][-1]
current_log["cp"]["all"]["imported"] += 500
current_log["cp"]["cp4"]["imported"] += 500
current_log["counter"]["counter0"]["imported"] += 500
current_log["date"] = clock
current_log["timestamp"] = datetime.datetime.strptime(f"05/16/2022, {clock}", "%m/%d/%Y, %H:%M").timestamp()
mock_create_entry = Mock(return_value=current_log)
monkeypatch.setattr(chargelog, "create_entry", mock_create_entry)
def mock_daily_log(monkeypatch):
daily_log = {"entries": [{'bat': {'all': {'exported': 2000, 'imported': 2000, 'soc': 100},
'bat2': {'exported': 2000, 'imported': 2000, 'soc': 100}},
'counter': {'counter0': {'exported': 2000,
'grid': True,
'imported': 500}},
'cp': {'all': {'exported': 0, 'imported': 2000},
'cp4': {'exported': 0, 'imported': 2000}},
'date': "8:35",
'ev': {'ev0': {'soc': None}},
'hc': {'all': {'imported': 0}},
'pv': {'all': {'exported': 2000}, 'pv1': {'exported': 2000}},
'sh': {},
'timestamp': 1652682900,
'prices': {'grid': 0.0003, 'pv': 0.00015, 'bat': 0.0002, 'cp': 0}},
{'bat': {'all': {'exported': 3000, 'imported': 2000, 'soc': 100},
'bat2': {'exported': 3000, 'imported': 2000, 'soc': 100}},
'counter': {'counter0': {'exported': 2000,
'grid': True,
'imported': 2500}},
'cp': {'all': {'exported': 0, 'imported': 4000},
'cp4': {'exported': 0, 'imported': 4000}},
'date': "8:40",
'ev': {'ev0': {'soc': None}},
'hc': {'all': {'imported': 0}},
'pv': {'all': {'exported': 2500}, 'pv1': {'exported': 2500}},
'sh': {},
'timestamp': 1652683200,
'prices': {'grid': 0.0003, 'pv': 0.00015, 'bat': 0.0002, 'cp': 0}}]}
mock_todays_daily_log = Mock(return_value=daily_log)
monkeypatch.setattr(chargelog, "get_todays_daily_log", mock_todays_daily_log)
return daily_log


def init_cp(charged_energy, costs, start_hour, start_minute=47):
def test_calc_charge_cost_reference_middle(mock_data, monkeypatch):
cp = Chargepoint(4, None)
cp.data.set.log.imported_since_plugged = cp.data.set.log.imported_since_mode_switch = charged_energy
cp.data.set.log.timestamp_start_charging = datetime.datetime(2022, 5, 16, start_hour, start_minute).timestamp()
cp.data.get.imported = charged_energy + 2000
cp.data.set.log.costs = costs
return cp


def test_calc_charge_cost_no_hour_change_reference_end(mock_data, monkeypatch):
cp = init_cp(6500, 0, 10, start_minute=27)
daily_log = mock_daily_log_with_charging("05/16/2022, 10:25", 4, monkeypatch)
mock_create_entry_reference_end("10:42", daily_log, monkeypatch)

calculate_charge_cost(cp, True)

assert cp.data.set.log.costs == 1.425

cp.data.set.log.imported_since_plugged = cp.data.set.log.imported_since_mode_switch = 3950
cp.data.set.log.timestamp_start_charging = 1652682600 # 8:30
cp.data.get.imported = 4050
cp.data.set.log.charged_energy_by_source = {'bat': 100, 'cp': 0, 'grid': 100, 'pv': 100}
daily_log = mock_daily_log(monkeypatch)

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

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

assert cp.data.set.log.costs == 1.275

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

def test_calc_charge_cost_first_hour_change_reference_begin_day_change(mock_data, monkeypatch):
cp = init_cp(6000, 0, 23)
daily_log = mock_daily_log_with_charging("05/16/2022, 23:45", 4, monkeypatch)
current_log = daily_log["entries"][-1]
current_log["date"] = "00:00"
current_log["timestamp"] = datetime.datetime.strptime("05/17/2022, 00:00", "%m/%d/%Y, %H:%M").timestamp()
mock_create_entry = Mock(return_value=current_log)
monkeypatch.setattr(chargelog, "create_entry", mock_create_entry)
mock_today_timestamp = Mock(return_value=1652738421)
monkeypatch.setattr(timecheck, "create_timestamp", mock_today_timestamp)

calculate_charge_cost(cp, False)

assert cp.data.set.log.costs == 1.275


def test_calc_charge_cost_one_hour_change_reference_end(mock_data, monkeypatch):
if running_on_github():
# ToDo Zeitzonen berücksichtigen, damit Tests auf Github laufen
return
cp = init_cp(22500, 1.275, 7)
daily_log = mock_daily_log_with_charging("05/16/2022, 07:45", 12, monkeypatch)
mock_create_entry_reference_end("08:40", daily_log, monkeypatch)

calculate_charge_cost(cp, True)
with patch("builtins.open", mock_open(read_data=json.dumps(daily_log))):
calc_energy_costs(cp)

assert cp.data.set.log.costs == 4.8248999999999995
assert cp.data.set.log.charged_energy_by_source == {
'bat': 28.549999999999997, 'cp': 0.0, 'grid': 57.15, 'pv': 14.299999999999999}
assert round(cp.data.set.log.costs, 5) == 0.025


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

calculate_charge_cost(cp, False)
with patch("builtins.open", mock_open(read_data=json.dumps(daily_log))):
calc_energy_costs(cp, True)

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


def test_calc_charge_cost_two_hour_change_reference_end(mock_data, monkeypatch):
if running_on_github():
# ToDo Zeitzonen berücksichtigen, damit Tests auf Github laufen
return
cp = init_cp(46500, 6.375, 6)
daily_log = mock_daily_log_with_charging("05/16/2022, 06:45", 24, monkeypatch)
mock_create_entry_reference_end("08:40", daily_log, monkeypatch)
def test_calc_charge_cost_reference_middle_day_change(mock_data, monkeypatch):
cp = Chargepoint(4, None)
cp.data.set.log.imported_since_plugged = cp.data.set.log.imported_since_mode_switch = 3950
cp.data.set.log.timestamp_start_charging = 1652682600 # 8:30
cp.data.get.imported = 4050
cp.data.set.log.charged_energy_by_source = {'bat': 100, 'cp': 0, 'grid': 100, 'pv': 100}
yesterday_daily_log = {"entries": [{'bat': {'all': {'exported': 2000, 'imported': 2000, 'soc': 100},
'bat2': {'exported': 2000, 'imported': 2000, 'soc': 100}},
'counter': {'counter0': {'exported': 2000,
'grid': True,
'imported': 500}},
'cp': {'all': {'exported': 0, 'imported': 2000},
'cp4': {'exported': 0, 'imported': 2000}},
'date': "8:35",
'ev': {'ev0': {'soc': None}},
'hc': {'all': {'imported': 0}},
'pv': {'all': {'exported': 2000}, 'pv1': {'exported': 2000}},
'sh': {},
'timestamp': 1652682900,
'prices': {'grid': 0.0003, 'pv': 0.00015, 'bat': 0.0002, 'cp': 0}}]}
mock_yesterdays_daily_log = Mock(return_value=yesterday_daily_log)
monkeypatch.setattr(chargelog, "get_daily_log", mock_yesterdays_daily_log)

daily_log = {"entries": [{'bat': {'all': {'exported': 3000, 'imported': 2000, 'soc': 100},
'bat2': {'exported': 3000, 'imported': 2000, 'soc': 100}},
'counter': {'counter0': {'exported': 2000,
'grid': True,
'imported': 2500}},
'cp': {'all': {'exported': 0, 'imported': 4000},
'cp4': {'exported': 0, 'imported': 4000}},
'date': "8:40",
'ev': {'ev0': {'soc': None}},
'hc': {'all': {'imported': 0}},
'pv': {'all': {'exported': 2500}, 'pv1': {'exported': 2500}},
'sh': {},
'timestamp': 1652683200,
'prices': {'grid': 0.0003, 'pv': 0.00015, 'bat': 0.0002, 'cp': 0}}]}
mock_todays_daily_log = Mock(return_value=daily_log)
monkeypatch.setattr(chargelog, "get_todays_daily_log", mock_todays_daily_log)

calculate_charge_cost(cp, True)
with patch("builtins.open", side_effect=[
mock_open(read_data=json.dumps(daily_log)),
mock_open(read_data=json.dumps(yesterday_daily_log))
]):
calc_energy_costs(cp)

assert cp.data.set.log.costs == 9.924900000000001
assert cp.data.set.log.charged_energy_by_source == {
'grid': 1243, 'pv': 386, 'bat': 671, 'cp': 0.0}
assert round(cp.data.set.log.costs, 5) == 0.5
Loading