You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

332 lines
15 KiB

<!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>
<script type="text/javascript">
function load() {
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";
});
}
}
</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" id="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"/>
<label for="ntpBtn">set system time</label>
<input type="button" name="ntpBtn" id="ntpBtn" class="btn" value="from browser" onclick="setTime()"/>
<input type="button" name="ntpSync" id="ntpSync" class="btn" value="sync NTP" onclick="syncTime()"/>
<span id="apiResultNtp"></span>
</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" maxlength="32" />
<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="password" class="text" name="mqttPwd"/>
<label for="mqttTopic">Topic</label>
<input type="text" class="text" name="mqttTopic"/>
<label for="mqttBtn">Discovery Config (homeassistant)</label>
<input type="button" name="mqttDiscovery" id="mqttDiscovery" class="btn" value="send" onclick="sendDiscoveryConfig()"/>
<span id="apiResultMqtt"></span>
</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 right"/><br/>
<br/>
<a href="/get_setup" target="_blank">Download your settings (JSON file)</a> (only saved values)
</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">
var highestId = 0;
var maxInv = 0;
const re = /11[2,4,6]1.*/;
document.getElementById("btnAdd").addEventListener("click", function() {
if(highestId <= (maxInv-1))
ivHtml(JSON.parse('{"name":"","serial":"","channels":4,"ch_max_power":[0,0,0,0],"ch_name":["","","",""]}'), highestId + 1);
});
function apiCbNtp(obj) {
var e = document.getElementById("apiResultNtp");
if(obj["success"])
e.innerHTML = "command excuted";
else
e.innerHTML = "Error: " + obj["error"];
}
function apiCbMqtt(obj) {
var e = document.getElementById("apiResultMqtt");
if(obj["success"])
e.innerHTML = "command excuted";
else
e.innerHTML = "Error: " + obj["error"];
}
function setTime() {
var date = new Date();
var offset = date.getTimezoneOffset() * -60;
var obj = new Object();
obj.cmd = "set_time";
obj.ts = parseInt(offset + (date.getTime() / 1000));
getAjax("/api/setup", apiCbNtp, "POST", JSON.stringify(obj));
}
function syncTime() {
var obj = new Object();
obj.cmd = "sync_ntp";
getAjax("/api/setup", apiCbNtp, "POST", JSON.stringify(obj));
}
function sendDiscoveryConfig() {
var obj = new Object();
obj.cmd = "discovery_cfg";
getAjax("/api/setup", apiCbMqtt, "POST", JSON.stringify(obj));
}
function delIv() {
var id = this.id.substring(0,4);
var e = document.getElementsByName(id + "Addr")[0];
e.value = "";
e.dispatchEvent(new Event("keyup"));
document.getElementsByName(id + "Name")[0].value = "";
}
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;
iv.appendChild(lbl(id + "Addr", "Address*"));
var addr = inp(id + "Addr", obj["serial"], 12)
iv.appendChild(addr);
addr.addEventListener("keyup", (e) => {
var serial = addr.value.substring(0,4);
var max = 0;
for(var i=0;i<4;i++) {
toggle(id+"ModPwr"+i, true);
toggle(id+"ModName"+i, true);
}
toggle("lbl"+id+"ModPwr", true);
toggle("lbl"+id+"ModName", true);
if(serial == "1161") max = 4;
else if(serial == "1141") max = 2;
else if(serial == "1121") max = 1;
for(var i=0;i<max;i++) {
toggle(id+"ModPwr"+i, false);
toggle(id+"ModName"+i, false);
}
if(max != 0) {
toggle("lbl"+id+"ModPwr", false);
toggle("lbl"+id+"ModName", false);
}
});
for(var i of [["Name", "name", "Name*", 32]]) { // so richtig?
iv.appendChild(lbl(id + i[0], i[2]));
iv.appendChild(inp(id + i[0], obj[i[1]], i[3]));
}
for(var j of [["ModPwr", "ch_max_power", "Max Module Power (Wp)", 4], ["ModName", "ch_name", "Module Name", 16]]) {
var cl = (re.test(obj["serial"])) ? null : ["hide"];
iv.appendChild(lbl(null, j[2], cl, "lbl" + id + j[0]));
d = div([j[0]]);
i = 0;
cl = (re.test(obj["serial"])) ? ["text", "sh"] : ["text", "sh", "hide"];
for(it of obj[j[1]]) {
d.appendChild(inp(id + j[0] + i, it, j[3], cl, id + j[0] + i));
i++;
}
iv.appendChild(d);
}
iv.appendChild(br());
iv.appendChild(lbl(id + "lbldel", "Delete"));
var del = inp(id+"del", "X", 0, ["btn", "btnDel"], id+"del", "button");
iv.appendChild(del);
del.addEventListener("click", delIv);
}
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"];
}
function parse(root) {
if(null != root) {
parseSys(root["system"]);
parseIv(root["inverter"]);
parseMqtt(root["mqtt"]);
parseNtp(root["ntp"]);
parsePinout(root["pinout"]);
parseRadio(root["radio"]);
parseSerial(root["serial"]);
}
}
getAjax("/api/setup", parse);
</script>
</body>
</html>