|
|
|
<!doctype html>
|
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<title>Setup</title>
|
|
|
|
<link rel="stylesheet" type="text/css" href="style.css"/>
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
|
|
<script type="text/javascript" src="api.js"></script>
|
|
|
|
</head>
|
|
|
|
<body onload="load()">
|
|
|
|
<h1>Setup</h1>
|
|
|
|
<div id="setup" class="content">
|
|
|
|
<div id="content">
|
|
|
|
<a class="erase" href="/erase">ERASE SETTINGS (not WiFi)</a>
|
|
|
|
|
|
|
|
<form method="post" action="/save">
|
|
|
|
<fieldset>
|
|
|
|
<legend class="des">Device Host Name</legend>
|
|
|
|
<label for="device">Device Name</label>
|
|
|
|
<input type="text" name="device" class="text"/>
|
|
|
|
</fieldset>
|
|
|
|
|
|
|
|
<button type="button" class="s_collapsible">WiFi</button>
|
|
|
|
<div class="s_content">
|
|
|
|
<fieldset>
|
|
|
|
<legend class="des">WiFi</legend>
|
|
|
|
<p>Enter the credentials to your prefered WiFi station. After rebooting the device tries to connect with this information.</p>
|
|
|
|
<label for="ssid">SSID</label>
|
|
|
|
<input type="text" name="ssid" class="text"/>
|
|
|
|
<label for="pwd">Password</label>
|
|
|
|
<input type="password" class="text" name="pwd" value="{PWD}"/>
|
|
|
|
</fieldset>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<button type="button" class="s_collapsible">Inverter</button>
|
|
|
|
<div class="s_content">
|
|
|
|
<fieldset>
|
|
|
|
<legend class="des">Inverter</legend>
|
|
|
|
<div id="inverter"></div><br/>
|
|
|
|
<input type="button" name="btnAdd" value="Add Inverter"/>
|
|
|
|
<p class="subdes">General</p>
|
|
|
|
<label for="invInterval">Interval [s]</label>
|
|
|
|
<input type="text" class="text" name="invInterval"/>
|
|
|
|
<label for="invRetry">Max retries per Payload</label>
|
|
|
|
<input type="text" class="text" name="invRetry"/>
|
|
|
|
</fieldset>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<button type="button" class="s_collapsible">NTP Server</button>
|
|
|
|
<div class="s_content">
|
|
|
|
<fieldset>
|
|
|
|
<legend class="des">NTP Server</legend>
|
|
|
|
<label for="ntpAddr">NTP Server / IP</label>
|
|
|
|
<input type="text" class="text" name="ntpAddr"/>
|
|
|
|
<label for="ntpPort">NTP Port</label>
|
|
|
|
<input type="text" class="text" name="ntpPort"/>
|
|
|
|
</fieldset>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<button type="button" class="s_collapsible">MQTT</button>
|
|
|
|
<div class="s_content">
|
|
|
|
<fieldset>
|
|
|
|
<legend class="des">MQTT</legend>
|
|
|
|
<label for="mqttAddr">Broker / Server IP</label>
|
|
|
|
<input type="text" class="text" name="mqttAddr"/>
|
|
|
|
<label for="mqttPort">Port</label>
|
|
|
|
<input type="text" class="text" name="mqttPort"/>
|
|
|
|
<label for="mqttUser">Username (optional)</label>
|
|
|
|
<input type="text" class="text" name="mqttUser"/>
|
|
|
|
<label for="mqttPwd">Password (optional)</label>
|
|
|
|
<input type="text" class="text" name="mqttPwd"/>
|
|
|
|
<label for="mqttTopic">Topic</label>
|
|
|
|
<input type="text" class="text" name="mqttTopic"/>
|
|
|
|
</fieldset>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<button type="button" class="s_collapsible">System Config</button>
|
|
|
|
<div class="s_content">
|
|
|
|
<fieldset>
|
|
|
|
<legend class="des">System Config</legend>
|
|
|
|
<p class="des">Pinout (Wemos)</p>
|
|
|
|
<div id="pinout"></div>
|
|
|
|
|
|
|
|
<p class="des">Radio (NRF24L01+)</p>
|
|
|
|
<div id="rf24"></div>
|
|
|
|
|
|
|
|
<p class="des">Serial Console</p>
|
|
|
|
<label for="serEn">print inverter data</label>
|
|
|
|
<input type="checkbox" class="cb" name="serEn"/><br/>
|
|
|
|
<label for="serDbg">Serial Debug</label>
|
|
|
|
<input type="checkbox" class="cb" name="serDbg"/><br/>
|
|
|
|
<label for="serIntvl">Interval [s]</label>
|
|
|
|
<input type="text" class="text" name="serIntvl"/>
|
|
|
|
</fieldset>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<label for="reboot">Reboot device after successful save</label>
|
|
|
|
<input type="checkbox" class="cb" name="reboot"/>
|
|
|
|
<input type="submit" value="save" class="btn"/>
|
|
|
|
</form>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div id="footer">
|
|
|
|
<p class="left"><a href="/">Home</a></p>
|
|
|
|
<p class="left"><a href="/update">Update Firmware</a></p>
|
|
|
|
<p class="right" id="version"></p>
|
|
|
|
<p class="right"><a href="/factory">Factory Reset</a></p>
|
|
|
|
<p class="right"><a href="/reboot">Reboot</a></p>
|
|
|
|
</div>
|
|
|
|
<script type="text/javascript">
|
|
|
|
function load() {
|
|
|
|
document.querySelectorAll('input[name^="inv"][name$="Addr"]').forEach(elm => {
|
|
|
|
elm.addEventListener("keyup", (e) => {
|
|
|
|
serial = elm.value.substring(0,4);
|
|
|
|
iv = elm.name.substring(3,4);
|
|
|
|
max = 0;
|
|
|
|
for(i=0;i<4;i++) {
|
|
|
|
toggle("inv"+iv+"ModPwr"+i, true);
|
|
|
|
toggle("inv"+iv+"ModName"+i, true);
|
|
|
|
}
|
|
|
|
toggle("lbl"+iv+"ModPwr", true);
|
|
|
|
toggle("lbl"+iv+"ModName", true);
|
|
|
|
|
|
|
|
if(serial == "1161") max = 4;
|
|
|
|
else if(serial == "1141") max = 2;
|
|
|
|
else if(serial == "1121") max = 1;
|
|
|
|
|
|
|
|
for(i=0;i<max;i++) {
|
|
|
|
toggle("inv"+iv+"ModPwr"+i, false);
|
|
|
|
toggle("inv"+iv+"ModName"+i, false);
|
|
|
|
}
|
|
|
|
if(max != 0) {
|
|
|
|
toggle("lbl"+iv+"ModPwr", false);
|
|
|
|
toggle("lbl"+iv+"ModName", false);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
evt = document.createEvent("HTMLEvents");
|
|
|
|
evt.initEvent("keyup", false, true);
|
|
|
|
elm.dispatchEvent(evt);
|
|
|
|
});
|
|
|
|
|
|
|
|
for(it of document.getElementsByClassName("s_collapsible")) {
|
|
|
|
it.addEventListener("click", function() {
|
|
|
|
this.classList.toggle("active");
|
|
|
|
var content = this.nextElementSibling;
|
|
|
|
content.style.display = (content.style.display === "block") ? "none" : "block";
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var highestId = 0;
|
|
|
|
var maxInv = 0;
|
|
|
|
|
|
|
|
document.getElementsByName("btnAdd")[0].addEventListener("click", function() {
|
|
|
|
if(highestId < (maxInv-1))
|
|
|
|
ivHtml(JSON.parse('{"name":"","serial":"","channels":4,"ch_max_power":[0,0,0,0],"ch_name":["","","",""],"power_limit":1500,"power_limit_option":65535}'), highestId + 1);
|
|
|
|
});
|
|
|
|
|
|
|
|
function ivHtml(obj, id) {
|
|
|
|
highestId = id;
|
|
|
|
if(highestId == (maxInv - 1))
|
|
|
|
toggle("btnAdd", true);
|
|
|
|
iv = document.getElementById("inverter");
|
|
|
|
iv.appendChild(des("Inverter " + id));
|
|
|
|
id = "inv" + id;
|
|
|
|
|
|
|
|
for(var i of [["Addr", "serial", "Address*", 12], ["Name", "name", "Name*", 32], ["ActivePowerLimit", "power_limit", "Active Power Limit", 5]]) {
|
|
|
|
iv.appendChild(lbl(id + i[0], i[2]));
|
|
|
|
iv.appendChild(inp(id + i[0], obj[i[1]], i[3]));
|
|
|
|
}
|
|
|
|
|
|
|
|
iv.appendChild(lbl(id + "ActivePowerLimitConType", "Active Power Limit Control Type"));
|
|
|
|
iv.appendChild(sel(id + "ActivePowerLimitConType", [
|
|
|
|
[65535, "no power limit"],
|
|
|
|
[0, "absolute in Watt non persistent"],
|
|
|
|
[1, "absolute in Watt persistent"],
|
|
|
|
[256, "relativ in percent non persistent"],
|
|
|
|
[257, "relativ in percent persistent"]
|
|
|
|
], obj.power_limit_option));
|
|
|
|
|
|
|
|
for(var j of [["ModPwr", "ch_max_power", "Max Module Power (Wp)"], ["ModName", "ch_name", "Module Name"]]) {
|
|
|
|
iv.appendChild(lbl(id + j[0], j[2]));
|
|
|
|
d = div(j[0]);
|
|
|
|
i = 0;
|
|
|
|
for(it of obj[j[1]]) {
|
|
|
|
d.appendChild(inp(id + j[0] + i, it, 4, ["text", "sh"]));
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
iv.appendChild(d);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function ivGlob(obj) {
|
|
|
|
for(var i of [["invInterval", "interval"], ["invRetry", "retries"]])
|
|
|
|
document.getElementsByName(i[0])[0].value = obj[i[1]];
|
|
|
|
}
|
|
|
|
|
|
|
|
function parseSys(obj) {
|
|
|
|
for(var i of [["device", "device_name"], ["ssid", "ssid"]])
|
|
|
|
document.getElementsByName(i[0])[0].value = obj[i[1]];
|
|
|
|
document.getElementById("version").innerHTML = "Git SHA: " + obj["build"] + " :: " + obj["version"];
|
|
|
|
}
|
|
|
|
|
|
|
|
function parseIv(obj) {
|
|
|
|
for(var i = 0; i < obj.inverter.length; i++)
|
|
|
|
ivHtml(obj.inverter[i], i);
|
|
|
|
ivGlob(obj);
|
|
|
|
maxInv = obj["max_num_inverters"];
|
|
|
|
}
|
|
|
|
|
|
|
|
function parseMqtt(obj) {
|
|
|
|
for(var i of [["Addr", "broker"], ["Port", "port"], ["User", "user"], ["Pwd", "pwd"], ["Topic", "topic"]])
|
|
|
|
document.getElementsByName("mqtt"+i[0])[0].value = obj[i[1]];
|
|
|
|
}
|
|
|
|
|
|
|
|
function parseNtp(obj) {
|
|
|
|
for(var i of [["ntpAddr", "addr"], ["ntpPort", "port"]])
|
|
|
|
document.getElementsByName(i[0])[0].value = obj[i[1]];
|
|
|
|
}
|
|
|
|
|
|
|
|
function parsePinout(obj) {
|
|
|
|
var e = document.getElementById("pinout");
|
|
|
|
pins = [['cs', 'pinCs'], ['ce', 'pinCe'], ['irq', 'pinIrq']];
|
|
|
|
for(p of pins) {
|
|
|
|
e.appendChild(lbl(p[1], p[0].toUpperCase()));
|
|
|
|
e.appendChild(sel(p[1], [
|
|
|
|
[0, "D3 (GPIO0)"],
|
|
|
|
[1, "TX (GPIO1)"],
|
|
|
|
[2, "D4 (GPIO2)"],
|
|
|
|
[3, "RX (GPIO3)"],
|
|
|
|
[4, "D2 (GPIO4)"],
|
|
|
|
[5, "D1 (GPIO5)"],
|
|
|
|
[6, "GPIO6"],
|
|
|
|
[7, "GPIO7"],
|
|
|
|
[8, "GPIO8"],
|
|
|
|
[9, "GPIO9"],
|
|
|
|
[10, "GPIO10"],
|
|
|
|
[11, "GPIO11"],
|
|
|
|
[12, "D6 (GPIO12)"],
|
|
|
|
[13, "D7 (GPIO13)"],
|
|
|
|
[14, "D5 (GPIO14)"],
|
|
|
|
[15, "D8 (GPIO15)"],
|
|
|
|
[16, "D0 (GPIO16 - no IRQ!)"]
|
|
|
|
], obj[p[0]]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function parseRadio(obj) {
|
|
|
|
var e = document.getElementById("rf24");
|
|
|
|
e.appendChild(lbl("rf24Power", "Amplifier Power Level"));
|
|
|
|
e.appendChild(sel("rf24Power", [
|
|
|
|
[0, "MIN"],
|
|
|
|
[1, "LOW"],
|
|
|
|
[2, "HIGH"],
|
|
|
|
[3, "MAX"]
|
|
|
|
], obj["power_level"]));
|
|
|
|
}
|
|
|
|
|
|
|
|
function parseSerial(obj) {
|
|
|
|
for(var i of [["serEn", "show_live_data"], ["serDbg", "debug"]])
|
|
|
|
document.getElementsByName(i[0])[0].checked = obj[i[1]];
|
|
|
|
document.getElementsByName("serIntvl")[0].value = obj["interval"];
|
|
|
|
}
|
|
|
|
|
|
|
|
getAjax("/api/system", parseSys);
|
|
|
|
getAjax("/api/inverter/list", parseIv);
|
|
|
|
getAjax("/api/mqtt", parseMqtt);
|
|
|
|
getAjax("/api/ntp", parseNtp);
|
|
|
|
getAjax("/api/pinout", parsePinout);
|
|
|
|
getAjax("/api/radio", parseRadio);
|
|
|
|
getAjax("/api/serial", parseSerial);
|
|
|
|
</script>
|
|
|
|
</body>
|
|
|
|
</html>
|