emhass 0.11.4__py3-none-any.whl → 0.15.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- emhass/command_line.py +1481 -811
- emhass/connection_manager.py +108 -0
- emhass/data/associations.csv +37 -2
- emhass/data/cec_inverters.pbz2 +0 -0
- emhass/data/cec_modules.pbz2 +0 -0
- emhass/data/config_defaults.json +53 -49
- emhass/forecast.py +1264 -731
- emhass/img/emhass_icon.png +0 -0
- emhass/machine_learning_forecaster.py +534 -281
- emhass/machine_learning_regressor.py +141 -125
- emhass/optimization.py +1173 -585
- emhass/retrieve_hass.py +958 -263
- emhass/static/advanced.html +7 -0
- emhass/static/configuration_list.html +5 -1
- emhass/static/configuration_script.js +146 -62
- emhass/static/data/param_definitions.json +215 -48
- emhass/static/script.js +58 -26
- emhass/static/style.css +6 -8
- emhass/templates/configuration.html +5 -3
- emhass/templates/index.html +8 -6
- emhass/templates/template.html +4 -5
- emhass/utils.py +1152 -403
- emhass/web_server.py +565 -379
- emhass/websocket_client.py +224 -0
- emhass-0.15.5.dist-info/METADATA +164 -0
- emhass-0.15.5.dist-info/RECORD +34 -0
- {emhass-0.11.4.dist-info → emhass-0.15.5.dist-info}/WHEEL +1 -2
- emhass-0.15.5.dist-info/entry_points.txt +2 -0
- emhass-0.11.4.dist-info/METADATA +0 -666
- emhass-0.11.4.dist-info/RECORD +0 -32
- emhass-0.11.4.dist-info/entry_points.txt +0 -2
- emhass-0.11.4.dist-info/top_level.txt +0 -1
- {emhass-0.11.4.dist-info → emhass-0.15.5.dist-info/licenses}/LICENSE +0 -0
emhass/static/advanced.html
CHANGED
|
@@ -18,6 +18,13 @@
|
|
|
18
18
|
</br></br>
|
|
19
19
|
<button type="button" id="regressor-model-fit" class="button button1">ML regressor model fit</button>
|
|
20
20
|
<button type="button" id="regressor-model-predict" class="button button2">ML regressor model predict</button>
|
|
21
|
+
</br></br>
|
|
22
|
+
<div id="export-influxdb-section" style="display: none;">
|
|
23
|
+
<h4>Export InfluxDB data to CSV for ML training</h4>
|
|
24
|
+
<p style="font-size: 0.9em; color: #666; margin-top: -10px;">Export historical sensor data from InfluxDB to train ML regressor models</p>
|
|
25
|
+
<button type="button" id="export-influxdb-to-csv" class="button button1">Export InfluxDB to CSV</button>
|
|
26
|
+
</br></br>
|
|
27
|
+
</div>
|
|
21
28
|
<!-- -->
|
|
22
29
|
<!--dynamic runtime parameter input (list and box) elements section -->
|
|
23
30
|
<h4>Input Runtime Parameters</h4>
|
|
@@ -29,13 +29,17 @@
|
|
|
29
29
|
<div id="Solar System (PV)" class="section-card">
|
|
30
30
|
<div class="section-card-header">
|
|
31
31
|
<h4>Solar System (PV)</h4>
|
|
32
|
+
<label class="switch" for="set_use_pv"> <!-- switch connected to set_use_pv -->
|
|
33
|
+
<input id="set_use_pv" type="checkbox">
|
|
34
|
+
<span class="slider"></span>
|
|
35
|
+
</label>
|
|
32
36
|
</div>
|
|
33
37
|
<div class="section-body"> </div> <!-- parameters will get generated here -->
|
|
34
38
|
</div>
|
|
35
39
|
<div id="Battery" class="section-card">
|
|
36
40
|
<div class="section-card-header">
|
|
37
41
|
<h4>Battery</h4>
|
|
38
|
-
<label class="switch"> <!-- switch connected to set_use_battery -->
|
|
42
|
+
<label class="switch" for="set_use_battery"> <!-- switch connected to set_use_battery -->
|
|
39
43
|
<input id="set_use_battery" type="checkbox">
|
|
40
44
|
<span class="slider"></span>
|
|
41
45
|
</label>
|
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
//on page reload
|
|
20
20
|
window.onload = async function () {
|
|
21
21
|
///fetch configuration parameters from definitions json file
|
|
22
|
-
param_definitions = await getParamDefinitions();
|
|
22
|
+
let param_definitions = await getParamDefinitions();
|
|
23
23
|
//obtain configuration from emhass (pull)
|
|
24
|
-
config = await obtainConfig();
|
|
24
|
+
let config = await obtainConfig();
|
|
25
25
|
//obtain configuration_list.html html as a template to dynamically to render parameters in a list view (parameters as input items)
|
|
26
|
-
list_html = await getListHTML();
|
|
26
|
+
let list_html = await getListHTML();
|
|
27
27
|
//load list parameter page (default)
|
|
28
28
|
loadConfigurationListView(param_definitions, config, list_html);
|
|
29
29
|
|
|
@@ -70,14 +70,14 @@ async function obtainConfig() {
|
|
|
70
70
|
const response = await fetch(`get-config`, {
|
|
71
71
|
method: "GET",
|
|
72
72
|
});
|
|
73
|
-
response_status =
|
|
73
|
+
let response_status = response.status; //return status
|
|
74
74
|
//if request failed
|
|
75
75
|
if (response_status !== 200 && response_status !== 201) {
|
|
76
76
|
showChangeStatus(response_status, await response.json());
|
|
77
77
|
return {};
|
|
78
78
|
}
|
|
79
79
|
//else extract json rom data
|
|
80
|
-
blob = await response.blob(); //get data blob
|
|
80
|
+
let blob = await response.blob(); //get data blob
|
|
81
81
|
config = await new Response(blob).json(); //obtain json from blob
|
|
82
82
|
showChangeStatus(response_status, {});
|
|
83
83
|
return config;
|
|
@@ -90,13 +90,13 @@ async function ObtainDefaultConfig() {
|
|
|
90
90
|
method: "GET",
|
|
91
91
|
});
|
|
92
92
|
//if request failed
|
|
93
|
-
response_status =
|
|
93
|
+
let response_status = response.status; //return status
|
|
94
94
|
if (response_status !== 200 && response_status !== 201) {
|
|
95
95
|
showChangeStatus(response_status, await response.json());
|
|
96
96
|
return {};
|
|
97
97
|
}
|
|
98
98
|
//else extract json rom data
|
|
99
|
-
blob = await response.blob(); //get data blob
|
|
99
|
+
let blob = await response.blob(); //get data blob
|
|
100
100
|
config = await new Response(blob).json(); //obtain json from blob
|
|
101
101
|
showChangeStatus(response_status, {});
|
|
102
102
|
return config;
|
|
@@ -109,9 +109,9 @@ async function getListHTML() {
|
|
|
109
109
|
errorAlert("Unable to obtain configuration_list.html file");
|
|
110
110
|
return {};
|
|
111
111
|
}
|
|
112
|
-
blob = await response.blob(); //get data blob
|
|
113
|
-
htmlTemplateData = await new Response(blob).text(); //obtain html from blob
|
|
114
|
-
return
|
|
112
|
+
let blob = await response.blob(); //get data blob
|
|
113
|
+
let htmlTemplateData = await new Response(blob).text(); //obtain html from blob
|
|
114
|
+
return htmlTemplateData;
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
//load list configuration view
|
|
@@ -121,13 +121,13 @@ function loadConfigurationListView(param_definitions, config, list_html) {
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
//list parameters used in the section headers
|
|
124
|
-
header_input_list = ["set_use_battery", "number_of_deferrable_loads"];
|
|
124
|
+
let header_input_list = ["set_use_battery", "set_use_pv", "number_of_deferrable_loads"];
|
|
125
125
|
|
|
126
126
|
//get the main container and append list template html
|
|
127
127
|
document.getElementById("configuration-container").innerHTML = list_html;
|
|
128
128
|
|
|
129
|
-
//loop
|
|
130
|
-
for (
|
|
129
|
+
//loop through configuration sections ('Local','System','Tariff','Solar System (PV)') in definitions file
|
|
130
|
+
for (let section in param_definitions) {
|
|
131
131
|
// build each section by adding parameters with their corresponding input elements
|
|
132
132
|
buildParamContainers(
|
|
133
133
|
section,
|
|
@@ -138,12 +138,12 @@ function loadConfigurationListView(param_definitions, config, list_html) {
|
|
|
138
138
|
|
|
139
139
|
//after sections have been built, add event listeners for section header inputs
|
|
140
140
|
//loop though headers
|
|
141
|
-
for (header_input_param of header_input_list) {
|
|
141
|
+
for (let header_input_param of header_input_list) {
|
|
142
142
|
if (param_definitions[section].hasOwnProperty(header_input_param)) {
|
|
143
143
|
//grab default from definitions file
|
|
144
|
-
value = param_definitions[section][header_input_param]["default_value"];
|
|
144
|
+
let value = param_definitions[section][header_input_param]["default_value"];
|
|
145
145
|
//find input element (using the parameter name as the input element ID)
|
|
146
|
-
header_input_element = document.getElementById(header_input_param);
|
|
146
|
+
let header_input_element = document.getElementById(header_input_param);
|
|
147
147
|
if (header_input_element !== null) {
|
|
148
148
|
//add event listener to element (trigger on input change)
|
|
149
149
|
header_input_element.addEventListener("input", (e) =>
|
|
@@ -164,6 +164,74 @@ function loadConfigurationListView(param_definitions, config, list_html) {
|
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
|
+
|
|
168
|
+
// Dynamic hiding for InfluxDB options
|
|
169
|
+
const use_influx_param = "use_influxdb";
|
|
170
|
+
const influx_related_params = [
|
|
171
|
+
"influxdb_host",
|
|
172
|
+
"influxdb_port",
|
|
173
|
+
"influxdb_username",
|
|
174
|
+
"influxdb_password",
|
|
175
|
+
"influxdb_database",
|
|
176
|
+
"influxdb_measurement",
|
|
177
|
+
"influxdb_retention_policy",
|
|
178
|
+
"influxdb_use_ssl",
|
|
179
|
+
"influxdb_verify_ssl"
|
|
180
|
+
];
|
|
181
|
+
|
|
182
|
+
const influx_toggle_div = document.getElementById(use_influx_param);
|
|
183
|
+
if (influx_toggle_div) {
|
|
184
|
+
// The actual input is inside the div with the ID
|
|
185
|
+
const influx_input = influx_toggle_div.querySelector("input");
|
|
186
|
+
if (influx_input) {
|
|
187
|
+
const toggleInfluxVisibility = () => {
|
|
188
|
+
const isChecked = influx_input.checked;
|
|
189
|
+
influx_related_params.forEach(paramId => {
|
|
190
|
+
const paramDiv = document.getElementById(paramId);
|
|
191
|
+
if (paramDiv) {
|
|
192
|
+
paramDiv.style.display = isChecked ? "" : "none";
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
// Add listener and set initial state
|
|
198
|
+
influx_input.addEventListener("change", toggleInfluxVisibility);
|
|
199
|
+
toggleInfluxVisibility();
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// ML Forecaster Visibility Logic
|
|
204
|
+
const forecast_method_param = "load_forecast_method";
|
|
205
|
+
const ml_related_params = [
|
|
206
|
+
"model_type",
|
|
207
|
+
"var_model",
|
|
208
|
+
"sklearn_model",
|
|
209
|
+
"regression_model",
|
|
210
|
+
"num_lags",
|
|
211
|
+
"split_date_delta",
|
|
212
|
+
"n_trials",
|
|
213
|
+
"perform_backtest"
|
|
214
|
+
];
|
|
215
|
+
|
|
216
|
+
const forecast_method_div = document.getElementById(forecast_method_param);
|
|
217
|
+
if (forecast_method_div) {
|
|
218
|
+
const method_select = forecast_method_div.querySelector("select, input");
|
|
219
|
+
if (method_select) {
|
|
220
|
+
const toggleMLVisibility = () => {
|
|
221
|
+
const isML = method_select.value === "mlforecaster";
|
|
222
|
+
ml_related_params.forEach(paramId => {
|
|
223
|
+
const paramDiv = document.getElementById(paramId);
|
|
224
|
+
if (paramDiv) {
|
|
225
|
+
paramDiv.style.display = isML ? "" : "none";
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
};
|
|
229
|
+
// Add listener and set initial state
|
|
230
|
+
method_select.addEventListener("change", toggleMLVisibility);
|
|
231
|
+
method_select.addEventListener("input", toggleMLVisibility); // Handle both select and text input types
|
|
232
|
+
toggleMLVisibility();
|
|
233
|
+
}
|
|
234
|
+
}
|
|
167
235
|
}
|
|
168
236
|
|
|
169
237
|
//build sections body, containing parameter/param containers (containing parameter/param inputs)
|
|
@@ -174,9 +242,9 @@ function buildParamContainers(
|
|
|
174
242
|
header_input_list
|
|
175
243
|
) {
|
|
176
244
|
//get the section container element
|
|
177
|
-
SectionContainer = document.getElementById(section);
|
|
245
|
+
let SectionContainer = document.getElementById(section);
|
|
178
246
|
//get the body container inside the section (where the parameters will be appended)
|
|
179
|
-
SectionParamElement = SectionContainer.getElementsByClassName("section-body");
|
|
247
|
+
let SectionParamElement = SectionContainer.getElementsByClassName("section-body");
|
|
180
248
|
if (SectionContainer == null || SectionParamElement.length == 0) {
|
|
181
249
|
console.error("Unable to find Section container or Section Body");
|
|
182
250
|
return 0;
|
|
@@ -217,7 +285,7 @@ function buildParamContainers(
|
|
|
217
285
|
}
|
|
218
286
|
|
|
219
287
|
//if parameter type == array.* and not in "Deferrable Loads" section, append plus and minus buttons in param div
|
|
220
|
-
array_buttons = "";
|
|
288
|
+
let array_buttons = "";
|
|
221
289
|
if (
|
|
222
290
|
parameter_definition_object["input"].search("array.") > -1 &&
|
|
223
291
|
section != "Deferrable Loads"
|
|
@@ -265,7 +333,7 @@ function buildParamContainers(
|
|
|
265
333
|
});
|
|
266
334
|
|
|
267
335
|
//check initial checkbox state, check "value" of input and match to "checked" value
|
|
268
|
-
let checkbox =
|
|
336
|
+
let checkbox = SectionContainer.querySelectorAll("input[type='checkbox']");
|
|
269
337
|
checkbox.forEach(function (answer) {
|
|
270
338
|
let value = answer.value === "true";
|
|
271
339
|
answer.checked = value;
|
|
@@ -305,7 +373,7 @@ function buildParamContainers(
|
|
|
305
373
|
}
|
|
306
374
|
|
|
307
375
|
//obtain required param inputs, add event listeners
|
|
308
|
-
requirement_inputs =
|
|
376
|
+
let requirement_inputs =
|
|
309
377
|
requirement_element.getElementsByClassName("param_input");
|
|
310
378
|
//grab required value
|
|
311
379
|
const requirement_value = Object.values(
|
|
@@ -334,10 +402,11 @@ function buildParamElement(
|
|
|
334
402
|
parameter_definition_name,
|
|
335
403
|
config
|
|
336
404
|
) {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
405
|
+
let type = "";
|
|
406
|
+
let inputs = "";
|
|
407
|
+
let type_specific_html = "";
|
|
408
|
+
let type_specific_html_end = "";
|
|
409
|
+
let placeholder = ""
|
|
341
410
|
|
|
342
411
|
//switch statement to adjust generated html according to the parameter data type (definitions in definitions file)
|
|
343
412
|
switch (parameter_definition_object["input"]) {
|
|
@@ -345,12 +414,12 @@ function buildParamElement(
|
|
|
345
414
|
//number
|
|
346
415
|
case "int":
|
|
347
416
|
type = "number";
|
|
348
|
-
placeholder = parseInt(parameter_definition_object["default_value"]);
|
|
417
|
+
placeholder = Number.parseInt(parameter_definition_object["default_value"]);
|
|
349
418
|
break;
|
|
350
419
|
case "array.float":
|
|
351
420
|
case "float":
|
|
352
421
|
type = "number";
|
|
353
|
-
placeholder = parseFloat(parameter_definition_object["default_value"]);
|
|
422
|
+
placeholder = Number.parseFloat(parameter_definition_object["default_value"]);
|
|
354
423
|
break;
|
|
355
424
|
//text (string)
|
|
356
425
|
case "array.string":
|
|
@@ -384,9 +453,8 @@ function buildParamElement(
|
|
|
384
453
|
|
|
385
454
|
//check default values saved in param definitions
|
|
386
455
|
//definitions default value is used if none is found in the configs, or an array element has been added in the ui (deferrable load number increase or plus button pressed)
|
|
387
|
-
value = parameter_definition_object["default_value"];
|
|
388
456
|
//check if a param value is saved in the config file (if so overwrite definition default)
|
|
389
|
-
value = checkConfigParam(
|
|
457
|
+
let value = checkConfigParam(placeholder, config, parameter_definition_name);
|
|
390
458
|
|
|
391
459
|
//generate and return param input html,
|
|
392
460
|
//check if param value is not an object, if so assume its a single value.
|
|
@@ -395,7 +463,7 @@ function buildParamElement(
|
|
|
395
463
|
if (parameter_definition_object["input"] == "select") {
|
|
396
464
|
let inputs = `<select class="param_input">`;
|
|
397
465
|
for (const options of parameter_definition_object["select_options"]) {
|
|
398
|
-
selected = ""
|
|
466
|
+
let selected = ""
|
|
399
467
|
//if item in select is the same as the config value, then append "selected" tag
|
|
400
468
|
if (options==value) {selected = `selected="selected"`}
|
|
401
469
|
inputs += `<option ${selected}>${options}</option>`;
|
|
@@ -416,8 +484,8 @@ function buildParamElement(
|
|
|
416
484
|
else {
|
|
417
485
|
//for items such as load_peak_hour_periods (object of objects with arrays)
|
|
418
486
|
if (typeof Object.values(value)[0] === "object") {
|
|
419
|
-
for (param of Object.values(value)) {
|
|
420
|
-
for (items of Object.values(param)) {
|
|
487
|
+
for (let param of Object.values(value)) {
|
|
488
|
+
for (let items of Object.values(param)) {
|
|
421
489
|
inputs += `<input class="param_input" type="${type}" placeholder=${Object.values(items)[0]} value=${
|
|
422
490
|
Object.values(items)[0]
|
|
423
491
|
}>`;
|
|
@@ -429,7 +497,7 @@ function buildParamElement(
|
|
|
429
497
|
// array of values
|
|
430
498
|
else {
|
|
431
499
|
let inputs = "";
|
|
432
|
-
for (param of value) {
|
|
500
|
+
for (let param of value) {
|
|
433
501
|
inputs += `
|
|
434
502
|
${type_specific_html}
|
|
435
503
|
<input class="param_input" type="${type}" placeholder=${parameter_definition_object["default_value"]} value=${param}>
|
|
@@ -448,14 +516,14 @@ function plusElements(
|
|
|
448
516
|
section,
|
|
449
517
|
config
|
|
450
518
|
) {
|
|
451
|
-
param_element = document.getElementById(parameter_definition_name);
|
|
519
|
+
let param_element = document.getElementById(parameter_definition_name);
|
|
452
520
|
if (param_element == null) {
|
|
453
521
|
console.log(
|
|
454
522
|
"Unable to find " + parameter_definition_name + " param div container"
|
|
455
523
|
);
|
|
456
524
|
return 1;
|
|
457
525
|
}
|
|
458
|
-
param_input_container =
|
|
526
|
+
let param_input_container =
|
|
459
527
|
param_element.getElementsByClassName("param-input")[0];
|
|
460
528
|
// Add a copy of the param element
|
|
461
529
|
param_input_container.innerHTML += buildParamElement(
|
|
@@ -467,14 +535,15 @@ function plusElements(
|
|
|
467
535
|
|
|
468
536
|
//Remove param inputs in param div container (minimum 1)
|
|
469
537
|
function minusElements(param) {
|
|
470
|
-
param_element = document.getElementById(param);
|
|
538
|
+
let param_element = document.getElementById(param);
|
|
539
|
+
let param_input
|
|
471
540
|
if (param_element == null) {
|
|
472
541
|
console.log(
|
|
473
542
|
"Unable to find " + parameter_definition_name + " param div container"
|
|
474
543
|
);
|
|
475
544
|
return 1;
|
|
476
545
|
}
|
|
477
|
-
param_input_list = param_element.getElementsByTagName("input");
|
|
546
|
+
let param_input_list = param_element.getElementsByTagName("input");
|
|
478
547
|
if (param_input_list.length == 0) {
|
|
479
548
|
console.log(
|
|
480
549
|
"Unable to find " + parameter_definition_name + " param input/s"
|
|
@@ -493,7 +562,7 @@ function minusElements(param) {
|
|
|
493
562
|
//if param is "load_peak_hour_periods", remove both start and end param inputs as well as the line brake tag separating the inputs
|
|
494
563
|
if (param == "load_peak_hour_periods") {
|
|
495
564
|
if (param_input_list.length > 2) {
|
|
496
|
-
brs = document.getElementById(param).getElementsByTagName("br");
|
|
565
|
+
let brs = document.getElementById(param).getElementsByTagName("br");
|
|
497
566
|
param_input_list[param_input_list.length - 1].remove();
|
|
498
567
|
param_input_list[param_input_list.length - 1].remove();
|
|
499
568
|
brs[brs.length - 1].remove();
|
|
@@ -511,6 +580,7 @@ function checkRequirements(
|
|
|
511
580
|
param_element,
|
|
512
581
|
requirement_value
|
|
513
582
|
) {
|
|
583
|
+
let requirement_element_value
|
|
514
584
|
//get current value of required element
|
|
515
585
|
if (requirement_element.type == "checkbox") {
|
|
516
586
|
requirement_element_value = requirement_element.checked;
|
|
@@ -522,22 +592,22 @@ function checkRequirements(
|
|
|
522
592
|
if (!param_element.classList.contains("requirement-disable")) {
|
|
523
593
|
param_element.classList.add("requirement-disable");
|
|
524
594
|
}
|
|
525
|
-
} else {
|
|
526
|
-
if (param_element.classList.contains("requirement-disable")) {
|
|
595
|
+
} else if (param_element.classList.contains("requirement-disable")) {
|
|
527
596
|
param_element.classList.remove("requirement-disable");
|
|
528
|
-
}
|
|
529
597
|
}
|
|
530
598
|
}
|
|
531
599
|
|
|
532
600
|
//on header input change, execute accordingly
|
|
533
601
|
function headerElement(element, param_definitions, config) {
|
|
534
602
|
//obtain section body element
|
|
535
|
-
section_card = element.closest(".section-card");
|
|
603
|
+
let section_card = element.closest(".section-card");
|
|
604
|
+
let param_list
|
|
605
|
+
let difference
|
|
536
606
|
if (section_card == null) {
|
|
537
607
|
console.log("Unable to obtain section-card");
|
|
538
608
|
return 1;
|
|
539
609
|
}
|
|
540
|
-
param_container = section_card.getElementsByClassName("section-body");
|
|
610
|
+
let param_container = section_card.getElementsByClassName("section-body");
|
|
541
611
|
if (param_container.length > 0) {
|
|
542
612
|
param_container = section_card.getElementsByClassName("section-body")[0];
|
|
543
613
|
} else {
|
|
@@ -559,6 +629,19 @@ function headerElement(element, param_definitions, config) {
|
|
|
559
629
|
}
|
|
560
630
|
break;
|
|
561
631
|
|
|
632
|
+
//if set_use_pv, add or remove PV section (inc. related params)
|
|
633
|
+
case "set_use_pv":
|
|
634
|
+
if (element.checked) {
|
|
635
|
+
param_container.innerHTML = "";
|
|
636
|
+
buildParamContainers("Solar System (PV)", param_definitions["Solar System (PV)"], config, [
|
|
637
|
+
"set_use_pv",
|
|
638
|
+
]);
|
|
639
|
+
element.checked = true;
|
|
640
|
+
} else {
|
|
641
|
+
param_container.innerHTML = "";
|
|
642
|
+
}
|
|
643
|
+
break;
|
|
644
|
+
|
|
562
645
|
//if number_of_deferrable_loads, the number of inputs in the "Deferrable Loads" section should add up to number_of_deferrable_loads value in header
|
|
563
646
|
case "number_of_deferrable_loads":
|
|
564
647
|
//get a list of param in section
|
|
@@ -571,7 +654,7 @@ function headerElement(element, param_definitions, config) {
|
|
|
571
654
|
}
|
|
572
655
|
//calculate how much off the fist parameters input elements amount to is, compering to the number_of_deferrable_loads value
|
|
573
656
|
difference =
|
|
574
|
-
parseInt(element.value) -
|
|
657
|
+
Number.parseInt(element.value) -
|
|
575
658
|
param_container.firstElementChild.querySelectorAll("input").length;
|
|
576
659
|
//add elements based on how many elements are missing
|
|
577
660
|
if (difference > 0) {
|
|
@@ -608,22 +691,24 @@ function checkConfigParam(value, config, parameter_definition_name) {
|
|
|
608
691
|
//send all parameter input values to EMHASS, to save to config.json and param.pkl
|
|
609
692
|
async function saveConfiguration(param_definitions) {
|
|
610
693
|
//start wth none
|
|
611
|
-
config = {};
|
|
694
|
+
let config = {};
|
|
695
|
+
let param_inputs
|
|
696
|
+
let param_element
|
|
612
697
|
|
|
613
698
|
//if section-cards (config sections/list) exists
|
|
614
|
-
config_card = document.getElementsByClassName("section-card");
|
|
699
|
+
let config_card = document.getElementsByClassName("section-card");
|
|
615
700
|
//check if page is in list or box view
|
|
616
|
-
config_box_element = document.getElementById("config-box");
|
|
701
|
+
let config_box_element = document.getElementById("config-box");
|
|
617
702
|
|
|
618
703
|
//if true, in list view
|
|
619
704
|
if (Boolean(config_card.length)) {
|
|
620
705
|
//retrieve params and their input/s by looping though param_definitions list
|
|
621
706
|
//loop through the sections
|
|
622
|
-
for (
|
|
707
|
+
for (const [, section_object] of Object.entries(
|
|
623
708
|
param_definitions
|
|
624
709
|
)) {
|
|
625
710
|
//loop through parameters
|
|
626
|
-
for (
|
|
711
|
+
for (let [
|
|
627
712
|
parameter_definition_name,
|
|
628
713
|
parameter_definition_object,
|
|
629
714
|
] of Object.entries(section_object)) {
|
|
@@ -637,7 +722,6 @@ async function saveConfiguration(param_definitions) {
|
|
|
637
722
|
parameter_definition_name +
|
|
638
723
|
" param div container element, skipping this param"
|
|
639
724
|
);
|
|
640
|
-
continue;
|
|
641
725
|
}
|
|
642
726
|
//extract input/s and their value/s from param container div
|
|
643
727
|
else {
|
|
@@ -649,10 +733,10 @@ async function saveConfiguration(param_definitions) {
|
|
|
649
733
|
}
|
|
650
734
|
|
|
651
735
|
// loop though param_inputs, extract the element/s values
|
|
652
|
-
for (
|
|
736
|
+
for (let input of param_inputs) {
|
|
653
737
|
switch (input.type) {
|
|
654
738
|
case "number":
|
|
655
|
-
param_values.push(parseFloat(input.value));
|
|
739
|
+
param_values.push(Number.parseFloat(input.value));
|
|
656
740
|
break;
|
|
657
741
|
case "checkbox":
|
|
658
742
|
param_values.push(input.checked);
|
|
@@ -737,20 +821,20 @@ async function ToggleView(param_definitions, list_html, default_reset) {
|
|
|
737
821
|
config = {};
|
|
738
822
|
|
|
739
823
|
//find out if list or box view is active
|
|
740
|
-
configuration_container = document.getElementById("configuration-container");
|
|
824
|
+
let configuration_container = document.getElementById("configuration-container");
|
|
741
825
|
if (configuration_container == null) {
|
|
742
826
|
errorAlert("Unable to find Configuration Container element");
|
|
743
827
|
}
|
|
744
828
|
//get yaml button
|
|
745
|
-
yaml_button = document.getElementById("yaml");
|
|
829
|
+
let yaml_button = document.getElementById("yaml");
|
|
746
830
|
if (yaml_button == null) {
|
|
747
831
|
console.log("Unable to obtain yaml button");
|
|
748
832
|
}
|
|
749
833
|
|
|
750
834
|
// if section-cards (config sections/list) exists
|
|
751
|
-
config_card = configuration_container.getElementsByClassName("section-card");
|
|
835
|
+
let config_card = configuration_container.getElementsByClassName("section-card");
|
|
752
836
|
//selected view (0 = box)
|
|
753
|
-
selected_view = Boolean(config_card.length);
|
|
837
|
+
let selected_view = Boolean(config_card.length);
|
|
754
838
|
|
|
755
839
|
//if default_reset is passed do not switch views, instead reinitialize view with default config as values
|
|
756
840
|
if (default_reset) {
|
|
@@ -788,7 +872,7 @@ async function ToggleView(param_definitions, list_html, default_reset) {
|
|
|
788
872
|
//load box (json textarea) view
|
|
789
873
|
async function loadConfigurationBoxPage(config) {
|
|
790
874
|
//get configuration container element
|
|
791
|
-
configuration_container = document.getElementById("configuration-container");
|
|
875
|
+
let configuration_container = document.getElementById("configuration-container");
|
|
792
876
|
if (configuration_container == null) {
|
|
793
877
|
errorAlert("Unable to find Configuration Container element");
|
|
794
878
|
}
|
|
@@ -806,7 +890,7 @@ async function loadConfigurationBoxPage(config) {
|
|
|
806
890
|
|
|
807
891
|
//function in control of status icons and alert box from a fetch request
|
|
808
892
|
async function showChangeStatus(status, logJson) {
|
|
809
|
-
|
|
893
|
+
let loading = document.getElementById("loader"); //element showing statuses
|
|
810
894
|
if (loading === null) {
|
|
811
895
|
console.log("unable to find loader element");
|
|
812
896
|
return 1;
|
|
@@ -847,7 +931,7 @@ async function errorAlert(text) {
|
|
|
847
931
|
//convert yaml box into json box
|
|
848
932
|
async function yamlToJson() {
|
|
849
933
|
//get box element
|
|
850
|
-
config_box_element = document.getElementById("config-box");
|
|
934
|
+
let config_box_element = document.getElementById("config-box");
|
|
851
935
|
if (config_box_element == null) {
|
|
852
936
|
errorAlert("Unable to obtain config box");
|
|
853
937
|
} else {
|
|
@@ -858,10 +942,10 @@ async function yamlToJson() {
|
|
|
858
942
|
},
|
|
859
943
|
body: config_box_element.value,
|
|
860
944
|
});
|
|
861
|
-
response_status =
|
|
945
|
+
let response_status = response.status; //return status
|
|
862
946
|
if (response_status == 201) {
|
|
863
947
|
showChangeStatus(response_status, {});
|
|
864
|
-
blob = await response.blob(); //get data blob
|
|
948
|
+
let blob = await response.blob(); //get data blob
|
|
865
949
|
config = await new Response(blob).json(); //obtain json from blob
|
|
866
950
|
config_box_element.value = JSON.stringify(config, null, 2);
|
|
867
951
|
} else {
|
|
@@ -869,4 +953,4 @@ async function yamlToJson() {
|
|
|
869
953
|
}
|
|
870
954
|
}
|
|
871
955
|
return 0;
|
|
872
|
-
}
|
|
956
|
+
}
|