Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Divert_sim summary #627

Merged
merged 11 commits into from
May 9, 2023
148 changes: 148 additions & 0 deletions divert_sim/run_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
#!/usr/bin/env python3
# PYTHON_ARGCOMPLETE_OK

from os import EX_OK, path
from subprocess import PIPE, Popen
from datetime import datetime

OPENEVSE_STATE_STARTING = 0
OPENEVSE_STATE_NOT_CONNECTED = 1
OPENEVSE_STATE_CONNECTED = 2
OPENEVSE_STATE_CHARGING = 3
OPENEVSE_STATE_VENT_REQUIRED = 4
OPENEVSE_STATE_DIODE_CHECK_FAILED = 5
OPENEVSE_STATE_GFI_FAULT = 6
OPENEVSE_STATE_NO_EARTH_GROUND = 7
OPENEVSE_STATE_STUCK_RELAY = 8
OPENEVSE_STATE_GFI_SELF_TEST_FAILED = 9
OPENEVSE_STATE_OVER_TEMPERATURE = 0
OPENEVSE_STATE_OVER_CURRENT = 1
OPENEVSE_STATE_SLEEPING = 4
OPENEVSE_STATE_DISABLED = 5

def divert_test(summary_file, dataset: str, config: bool = False, grid_ie_col: bool = False,
solar_col: bool = False, voltage_col: bool = False,
separator: str = ',', is_kw: bool = False) -> None:
"""Run the divert_sim process on the given dataset and return the results"""
line_number = 0

last_date = None
last_state = 0
charge_start_date = None

total_solar_wh = 0
total_ev_wh = 0
wh_from_solar = 0
wh_from_grid = 0
number_of_charges = 0
min_time_charging = 0
max_time_charging = 0
total_time_charging = 0

print("Testing dataset: " + dataset)

# Read in the dataset and pass to the divert_sim process
with open(path.join('data', dataset+'.csv'), 'r', encoding="utf-8") as input_data:
with open(path.join('output', dataset+'.csv'), 'w', encoding="utf-8") as output_data:
# open the divert_sim process
command = ["./divert_sim"]
if config:
command.append("-c")
command.append(config)
if grid_ie_col:
command.append("-g")
command.append(str(grid_ie_col))
if solar_col:
command.append("-s")
command.append(str(solar_col))
if voltage_col:
command.append("-v")
command.append(str(voltage_col))
if separator:
command.append("--sep")
command.append(separator)
if is_kw:
command.append("--kw")

divert_process = Popen(command, stdin=input_data, stdout=PIPE,
stderr=PIPE, universal_newlines=True)
while True:
output = divert_process.stdout.readline()
if output == '' and divert_process.poll() is not None:
break
if output:
output_data.write(output)
line_number += 1
if line_number > 1:
# read in the csv line
csv_line = output.split(',')
date = datetime.strptime(csv_line[0], '%d/%m/%Y %H:%M:%S')
solar = float(csv_line[1])
# grid_ie = float(csv_line[2])
# pilot = int(csv_line[3])
charge_power = float(csv_line[4])
# min_charge_power = float(csv_line[5])
state = int(csv_line[6])
# smoothed_available = float(csv_line[7])

if last_date is not None:
# Get the difference between this date and last date
diff = date - last_date

hours = diff.seconds / 3600

total_solar_wh += solar * hours
ev_wh = charge_power * hours
total_ev_wh += charge_power * hours
charge_from_solar_wh = min(solar, charge_power) * hours
wh_from_solar += charge_from_solar_wh
wh_from_grid += ev_wh - charge_from_solar_wh

if state == OPENEVSE_STATE_CHARGING and last_state != OPENEVSE_STATE_CHARGING:
number_of_charges += 1
charge_start_date = date

if state != OPENEVSE_STATE_CHARGING and last_state == OPENEVSE_STATE_CHARGING:
this_session_time_charging = (date - charge_start_date).seconds
total_time_charging += this_session_time_charging
if min_time_charging == 0 or this_session_time_charging < min_time_charging:
min_time_charging = this_session_time_charging
if this_session_time_charging > max_time_charging:
max_time_charging = this_session_time_charging

last_date = date
last_state = state

solar_kwh=total_solar_wh / 1000
ev_kwh=total_ev_wh / 1000
kwh_from_solar=wh_from_solar / 1000
kwh_from_grid=wh_from_grid / 1000

summary_file.write(f'"{dataset}",{solar_kwh},{ev_kwh},{kwh_from_solar},{kwh_from_grid},{number_of_charges},{min_time_charging},{max_time_charging},{total_time_charging}\n')


def main() -> int:
"""Run the divert_sim process on all the datasets in the data directory"""
with open(path.join('output', 'summary.csv'), 'w', encoding="utf-8") as summary_file:
summary_file.write('"Dataset","Total Solar (kWh)","Total EV Charge (kWh)","Charge from solar (kWh)","Charge from grid (kWh)","Number of charges","Min time charging","Max time charging","Total time charging"\n')
divert_test(summary_file, 'almostperfect')
divert_test(summary_file, 'CloudyMorning')
divert_test(summary_file, 'day1')
divert_test(summary_file, 'day2')
divert_test(summary_file, 'day3')
divert_test(summary_file, 'day1_grid_ie', grid_ie_col=2)
divert_test(summary_file, 'day2_grid_ie', grid_ie_col=2)
divert_test(summary_file, 'day3_grid_ie', grid_ie_col=2)
divert_test(summary_file, 'solar-vrms', voltage_col=2)
divert_test(summary_file, 'Energy_and_Power_Day_2020-03-22', separator=';',
is_kw=True, config='{"divert_decay_smoothing_factor":0.4}')
divert_test(summary_file, 'Energy_and_Power_Day_2020-03-31', separator=';',
is_kw=True, config='{"divert_decay_smoothing_factor":0.4}')
divert_test(summary_file, 'Energy_and_Power_Day_2020-04-01', separator=';',
is_kw=True, config='{"divert_decay_smoothing_factor":0.4}')

return EX_OK

if __name__ == '__main__':
# Run the script
exit(main())
63 changes: 49 additions & 14 deletions divert_sim/view.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<script type="text/javascript" src="https://canvasjs.com/assets/script/jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
<script type="text/javascript">
window.onload = function () {
var dataPoints = [];
Expand Down Expand Up @@ -43,7 +44,7 @@
toolTip: {
shared: true,
contentFormatter: (e) => {

var str = "<strong>"+moment(e.entries[0].dataPoint.x).format('h:mm a') + "</strong> <br/>";
for (var i = 0; i < e.entries.length; i++){
str += "<span style=\"color:"+e.entries[i].dataSeries.color+"\">" + e.entries[i].dataSeries.name + "</span> <strong>"+ e.entries[i].dataPoint.y + "</strong> <br/>";
Expand Down Expand Up @@ -114,6 +115,37 @@
});

});

$.ajax({
url: "output/summary.csv",
dataType: "text",
success: function (data) {
var summary_data = data.split(/\r?\n|\r/);
var table_data = '<table class="table table-bordered table-striped">';
for (var count = 0; count < summary_data.length; count++) {
var cell_data = summary_data[count].split(",");
table_data += '<tr>';
for (var cell_count = 0; cell_count < cell_data.length; cell_count++) {
var val = cell_data[cell_count].replaceAll("\"", "");
if (count === 0) {
table_data += '<th>' + val + '</th>';
} else if(0 == cell_count) {
table_data += '<td><a href="#' + val + '">' + val + '</a></td>';
} else if(1 <= cell_count && cell_count <= 4) {
table_data += '<td>' + parseFloat(val).toFixed(2) + '</td>';
} else if(6 <= cell_count && cell_count <= 8) {
table_data += '<td>' + (new Date(parseInt(val) * 1000).toISOString().slice(11, 19)) + '</td>';
} else {
table_data += '<td>' + val + '</td>';
}
}
table_data += '</tr>';
}
table_data += '</table>';
$('#summary_table').html(table_data);
}
});

}
</script>
<style type="text/css" media="print">
Expand All @@ -126,21 +158,24 @@

<body>
<h1>OpenEVSE Solar Divert Simulations</h1>
<h2>Summary</h2>
<div id="summary_table">
</div>
<h2>Solar only</h2>
<div id="solar1" style="width:100%; height:300px;" class="solar" csv="output/day1.csv" title="Day 1"></div>
<div id="solar2" style="width:100%; height:300px;" class="solar" csv="output/day2.csv" title="Day 2"></div>
<div id="solar3" style="width:100%; height:300px;" class="solar" csv="output/day3.csv" title="Day 3"></div>
<div id="solar4" style="width:100%; height:300px;" class="solar" csv="output/almostperfect.csv" title="Almost Perfect"></div>
<div id="solar5" style="width:100%; height:300px;" class="solar" csv="output/CloudyMorning.csv" title="Cloudy Morning"></div>
<div id="solar6" style="width:100%; height:300px;" class="solar" csv="output/solar-vrms.csv" title="Solar with Voltage feed"></div>
<div id="day1" style="width:100%; height:300px;" class="solar" csv="output/day1.csv" title="Day 1"></div>
<div id="day2" style="width:100%; height:300px;" class="solar" csv="output/day2.csv" title="Day 2"></div>
<div id="day3" style="width:100%; height:300px;" class="solar" csv="output/day3.csv" title="Day 3"></div>
<div id="almostperfect" style="width:100%; height:300px;" class="solar" csv="output/almostperfect.csv" title="Almost Perfect"></div>
<div id="CloudyMorning" style="width:100%; height:300px;" class="solar" csv="output/CloudyMorning.csv" title="Cloudy Morning"></div>
<div id="solar-vrms" style="width:100%; height:300px;" class="solar" csv="output/solar-vrms.csv" title="Solar with Voltage feed"></div>
<h2>Grid IE</h2>
<div id="gridie1" style="width:100%; height:550px;" class="gridie" csv="output/day1_grid_ie.csv" title="Day 1"></div>
<div id="gridie2" style="width:100%; height:550px;" class="gridie" csv="output/day2_grid_ie.csv" title="Day 2"></div>
<div id="gridie3" style="width:100%; height:550px;" class="gridie" csv="output/day3_grid_ie.csv" title="Day 3"></div>
<div id="day1_grid_ie" style="width:100%; height:550px;" class="gridie" csv="output/day1_grid_ie.csv" title="Day 1"></div>
<div id="day2_grid_ie" style="width:100%; height:550px;" class="gridie" csv="output/day2_grid_ie.csv" title="Day 2"></div>
<div id="day3_grid_ie" style="width:100%; height:550px;" class="gridie" csv="output/day3_grid_ie.csv" title="Day 3"></div>
<h2>Other</h2>
<div id="solar7" style="width:100%; height:300px;" class="solar" csv="output/Energy_and_Power_Day_2020-03-22.csv" title="Energy_and_Power_Day_2020-03-22.csv"></div>
<div id="solar8" style="width:100%; height:300px;" class="solar" csv="output/Energy_and_Power_Day_2020-03-31.csv" title="Energy_and_Power_Day_2020-03-31.csv"></div>
<div id="solar9" style="width:100%; height:300px;" class="solar" csv="output/Energy_and_Power_Day_2020-04-01.csv" title="Energy_and_Power_Day_2020-04-01.csv"></div>
<div id="Energy_and_Power_Day_2020-03-22" style="width:100%; height:300px;" class="solar" csv="output/Energy_and_Power_Day_2020-03-22.csv" title="Energy_and_Power_Day_2020-03-22.csv"></div>
<div id="Energy_and_Power_Day_2020-03-31" style="width:100%; height:300px;" class="solar" csv="output/Energy_and_Power_Day_2020-03-31.csv" title="Energy_and_Power_Day_2020-03-31.csv"></div>
<div id="Energy_and_Power_Day_2020-04-01" style="width:100%; height:300px;" class="solar" csv="output/Energy_and_Power_Day_2020-04-01.csv" title="Energy_and_Power_Day_2020-04-01.csv"></div>
</body>

</html>
</html>