mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-10 07:26:38 +02:00
* increased number of inverters
* name, serial and type can be configured using setup.html
This commit is contained in:
parent
97dfbb5936
commit
9e6cae26a7
9 changed files with 139 additions and 87 deletions
|
@ -44,12 +44,21 @@ void app::setup(const char *ssid, const char *pwd, uint32_t timeout) {
|
|||
if(mSettingsValid) {
|
||||
uint16_t interval;
|
||||
uint64_t invSerial;
|
||||
char invName[MAX_NAME_LENGTH + 1] = {0};
|
||||
uint8_t invType;
|
||||
|
||||
// inverter
|
||||
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) {
|
||||
mEep->read(ADDR_INV_ADDR + (i * 8), &invSerial);
|
||||
mEep->read(ADDR_INV_NAME + (i * MAX_NAME_LENGTH), invName, MAX_NAME_LENGTH);
|
||||
mEep->read(ADDR_INV_TYPE + i, &invType);
|
||||
if(0ULL != invSerial) {
|
||||
mSys->addInverter(invName, invSerial, invType);
|
||||
Serial.println("add inverter: " + String(invName) + ", SN: " + String(invSerial, HEX) + ", type: " + String(invType));
|
||||
}
|
||||
}
|
||||
|
||||
// hoymiles
|
||||
mEep->read(ADDR_INV0_ADDR, &invSerial);
|
||||
mEep->read(ADDR_INV_INTERVAL, &interval);
|
||||
mSys->addInverter("HM1200", invSerial, INV_TYPE_HM1200);
|
||||
|
||||
if(interval < 1000)
|
||||
interval = 1000;
|
||||
mSendTicker->attach_ms(interval, std::bind(&app::sendTicker, this));
|
||||
|
@ -129,29 +138,32 @@ void app::loop(void) {
|
|||
mFlagSend = false;
|
||||
|
||||
uint8_t size = 0;
|
||||
inverter_t *inv = mSys->getInverterByPos(0);
|
||||
inverter_t *inv;
|
||||
|
||||
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) {
|
||||
inv = mSys->getInverterByPos(i);
|
||||
if(NULL != inv) {
|
||||
//if((mSendCnt % 6) == 0)
|
||||
size = mSys->Radio.getTimePacket(&inv->radioId.u64, mSendBuf, mTimestamp);
|
||||
/*else if((mSendCnt % 6) == 1)
|
||||
size = mSys->Radio.getCmdPacket(&inv->radioId.u64, mSendBuf, 0x15, 0x81);
|
||||
else if((mSendCnt % 6) == 2)
|
||||
size = mSys->Radio.getCmdPacket(&inv->radioId.u64, mSendBuf, 0x15, 0x80);
|
||||
else if((mSendCnt % 6) == 3)
|
||||
size = mSys->Radio.getCmdPacket(&inv->radioId.u64, mSendBuf, 0x15, 0x83);
|
||||
else if((mSendCnt % 6) == 4)
|
||||
size = mSys->Radio.getCmdPacket(&inv->radioId.u64, mSendBuf, 0x15, 0x82);
|
||||
else if((mSendCnt % 6) == 5)
|
||||
size = mSys->Radio.getCmdPacket(&inv->radioId.u64, mSendBuf, 0x15, 0x84);*/
|
||||
|
||||
//if((mSendCnt % 6) == 0)
|
||||
size = mSys->Radio.getTimePacket(&inv->radioId.u64, mSendBuf, mTimestamp);
|
||||
/*else if((mSendCnt % 6) == 1)
|
||||
size = mSys->Radio.getCmdPacket(&inv->radioId.u64, mSendBuf, 0x15, 0x81);
|
||||
else if((mSendCnt % 6) == 2)
|
||||
size = mSys->Radio.getCmdPacket(&inv->radioId.u64, mSendBuf, 0x15, 0x80);
|
||||
else if((mSendCnt % 6) == 3)
|
||||
size = mSys->Radio.getCmdPacket(&inv->radioId.u64, mSendBuf, 0x15, 0x83);
|
||||
else if((mSendCnt % 6) == 4)
|
||||
size = mSys->Radio.getCmdPacket(&inv->radioId.u64, mSendBuf, 0x15, 0x82);
|
||||
else if((mSendCnt % 6) == 5)
|
||||
size = mSys->Radio.getCmdPacket(&inv->radioId.u64, mSendBuf, 0x15, 0x84);*/
|
||||
//Serial.println("sent packet: #" + String(mSendCnt));
|
||||
//dumpBuf("SEN ", mSendBuf, size);
|
||||
sendPacket(inv, mSendBuf, size);
|
||||
mSendCnt++;
|
||||
|
||||
|
||||
|
||||
//Serial.println("sent packet: #" + String(mSendCnt));
|
||||
//dumpBuf("SEN ", mSendBuf, size);
|
||||
sendPacket(inv, mSendBuf, size);
|
||||
|
||||
mSendCnt++;
|
||||
delay(20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -169,7 +181,7 @@ void app::loop(void) {
|
|||
snprintf(topic, 30, "%s/ch%d/%s", iv->name, iv->assign[i].ch, fields[iv->assign[i].fieldId]);
|
||||
snprintf(val, 10, "%.3f", mSys->getValue(iv, i));
|
||||
mMqtt.sendMsg(topic, val);
|
||||
delay(10);
|
||||
delay(20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -328,25 +340,35 @@ void app::showSetup(void) {
|
|||
html.replace("{VERSION}", String(mVersion));
|
||||
|
||||
String inv;
|
||||
inverter_t *pInv;
|
||||
uint64_t invSerial;
|
||||
char invName[MAX_NAME_LENGTH + 1] = {0};
|
||||
uint8_t invType;
|
||||
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) {
|
||||
pInv = mSys->getInverterByPos(i);
|
||||
mEep->read(ADDR_INV_ADDR + (i * 8), &invSerial);
|
||||
mEep->read(ADDR_INV_NAME + (i * MAX_NAME_LENGTH), invName, MAX_NAME_LENGTH);
|
||||
mEep->read(ADDR_INV_TYPE + i, &invType);
|
||||
inv += "<p class=\"subdes\">Inverter "+ String(i) + "</p>";
|
||||
|
||||
inv += "<label for=\"inv" + String(i) + "Addr\">Address</label>";
|
||||
inv += "<input type=\"text\" class=\"text\" name=\"inv" + String(i) + "Addr\" value=\"";
|
||||
inv += (NULL != pInv) ? String(mSys->getSerial(pInv), HEX) : "";
|
||||
inv += "\"/>";
|
||||
if(0ULL != invSerial)
|
||||
inv += String(invSerial, HEX);
|
||||
inv += "\"/ maxlength=\"12\">";
|
||||
|
||||
inv += "<label for=\"inv" + String(i) + "Name\">Name</label>";
|
||||
inv += "<input type=\"text\" class=\"text\" name=\"inv" + String(i) + "Name\" value=\"";
|
||||
inv += (NULL != pInv) ? String(pInv->name) : "";
|
||||
inv += "\"/>";
|
||||
inv += String(invName);
|
||||
inv += "\"/ maxlength=\"" + String(MAX_NAME_LENGTH) + "\">";
|
||||
|
||||
inv += "<label for=\"inv" + String(i) + "Type\">Type</label>";
|
||||
inv += "<input type=\"text\" class=\"text\" name=\"inv" + String(i) + "Name\" value=\"";
|
||||
inv += (NULL != pInv) ? String(pInv->type) : "";
|
||||
inv += "\"/>";
|
||||
inv += "<select name=\"inv" + String(i) + "Type\">";
|
||||
for(uint8_t t = 0; t < NUM_INVERTER_TYPES; t++) {
|
||||
inv += "<option value=\"" + String(t) + "\"";
|
||||
if(invType == t)
|
||||
inv += " selected";
|
||||
inv += ">" + String(invTypes[t]) + "</option>";
|
||||
}
|
||||
inv += "</select>";
|
||||
}
|
||||
html.replace("{INVERTERS}", String(inv));
|
||||
|
||||
|
@ -416,45 +438,50 @@ void app::showHoymiles(void) {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
void app::showLiveData(void) {
|
||||
String modHtml = "<pre>";
|
||||
|
||||
char topic[20], val[10];
|
||||
String modHtml;
|
||||
for(uint8_t id = 0; id < mSys->getNumInverters(); id++) {
|
||||
inverter_t *iv = mSys->getInverterByPos(id);
|
||||
if(NULL != iv) {
|
||||
/*uint8_t modNum;
|
||||
#ifdef LIVEDATA_VISUALIZED
|
||||
uint8_t modNum, pos;
|
||||
switch(iv->type) {
|
||||
default: modNum = 1; break;
|
||||
case INV_TYPE_HM600: modNum = 2; break;
|
||||
case INV_TYPE_HM1200: modNum = 4; break;
|
||||
}
|
||||
|
||||
for(uint8_t mod = 1; mod <= modNum; mod ++) {
|
||||
modHtml += "<div class=\"module\"><span class=\"header\">CHANNEL " + String(i) + "</span>";
|
||||
for(uint8_t ch = 1; ch <= modNum; ch ++) {
|
||||
modHtml += "<div class=\"ch\"><span class=\"head\">CHANNEL " + String(ch) + "</span>";
|
||||
for(uint8_t j = 0; j < 5; j++) {
|
||||
modHtml += "<span class=\"value\">";
|
||||
switch(j) {
|
||||
default: modHtml += String(mDecoder->mData.ch_dc[i/2].u); break;
|
||||
case 1: modHtml += String(mDecoder->mData.ch_dc[i].i); break;
|
||||
case 2: modHtml += String(mDecoder->mData.ch_dc[i].p); break;
|
||||
case 3: modHtml += String(mDecoder->mData.ch_dc[i].y_d); break;
|
||||
case 4: modHtml += String(mDecoder->mData.ch_dc[i].y_t); break;
|
||||
default: pos = (mSys->getPosByChField(iv, ch, FLD_UDC)); break;
|
||||
case 1: pos = (mSys->getPosByChField(iv, ch, FLD_IDC)); break;
|
||||
case 2: pos = (mSys->getPosByChField(iv, ch, FLD_PDC)); break;
|
||||
case 3: pos = (mSys->getPosByChField(iv, ch, FLD_YD)); break;
|
||||
case 4: pos = (mSys->getPosByChField(iv, ch, FLD_YT)); break;
|
||||
}
|
||||
if(0xff != pos) {
|
||||
modHtml += "<span class=\"value\">" + String(mSys->getValue(iv, pos));
|
||||
modHtml += "<span class=\"unit\">" + String(mSys->getUnit(iv, pos)) + "</span></span>";
|
||||
modHtml += "<span class=\"info\">" + String(mSys->getFieldName(iv, pos)) + "</span>";
|
||||
}
|
||||
modHtml += "<span class=\"unit\">" + unit[j] + "</span></span>";
|
||||
modHtml += "<span class=\"info\">" + info[j] + "</span>";
|
||||
}
|
||||
modHtml += "</div>";
|
||||
}*/
|
||||
|
||||
}
|
||||
#else
|
||||
// dump all data to web frontend
|
||||
modHtml = "<pre>";
|
||||
char topic[30], val[10];
|
||||
for(uint8_t i = 0; i < iv->listLen; i++) {
|
||||
sprintf(topic, "%s/ch%d/%s", iv->name, iv->assign[i].ch, mSys->getFieldName(iv, i));
|
||||
sprintf(val, "%.3f %s", mSys->getValue(iv, i), mSys->getUnit(iv, i));
|
||||
snprintf(topic, 30, "%s/ch%d/%s", iv->name, iv->assign[i].ch, mSys->getFieldName(iv, i));
|
||||
snprintf(val, 10, "%.3f %s", mSys->getValue(iv, i), mSys->getUnit(iv, i));
|
||||
modHtml += String(topic) + ": " + String(val) + "\n";
|
||||
}
|
||||
modHtml += "</pre>";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
modHtml += "</pre>";
|
||||
|
||||
mWeb->send(200, "text/html", modHtml);
|
||||
}
|
||||
|
@ -481,18 +508,25 @@ void app::saveValues(bool webSend = true) {
|
|||
|
||||
// inverter
|
||||
serial_u addr;
|
||||
mWeb->arg("inv0Addr").toCharArray(buf, 20);
|
||||
addr.u64 = Serial2u64(buf);
|
||||
mSys->updateSerial(mSys->getInverterByPos(0), addr.u64);
|
||||
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) {
|
||||
// address
|
||||
mWeb->arg("inv" + String(i) + "Addr").toCharArray(buf, 20);
|
||||
if(strlen(buf) == 0)
|
||||
snprintf(buf, 20, "\0");
|
||||
addr.u64 = Serial2u64(buf);
|
||||
mEep->write(ADDR_INV_ADDR + (i * 8), addr.u64);
|
||||
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
Serial.print(String(addr.b[i], HEX) + " ");
|
||||
// name
|
||||
mWeb->arg("inv" + String(i) + "Name").toCharArray(buf, 20);
|
||||
mEep->write(ADDR_INV_NAME + (i * MAX_NAME_LENGTH), buf, MAX_NAME_LENGTH);
|
||||
|
||||
// type
|
||||
mWeb->arg("inv" + String(i) + "Type").toCharArray(buf, 20);
|
||||
uint8_t type = atoi(buf);
|
||||
mEep->write(ADDR_INV_TYPE + (i * MAX_NAME_LENGTH), type);
|
||||
}
|
||||
Serial.println();
|
||||
Serial.println("addr: " + String(addr.u64, HEX));
|
||||
|
||||
interval = mWeb->arg("invInterval").toInt();
|
||||
mEep->write(ADDR_INV0_ADDR, addr.u64);
|
||||
mEep->write(ADDR_INV_INTERVAL, interval);
|
||||
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
typedef HmRadio<RF24_CE_PIN, RF24_CS_PIN, RF24_IRQ_PIN> RadioType;
|
||||
typedef CircularBuffer<packet_t, PACKET_BUFFER_SIZE> BufferType;
|
||||
typedef HmSystem<RadioType, BufferType, MAX_NUM_INVERTERS, double> HmSystemType;
|
||||
typedef HmSystem<RadioType, BufferType, MAX_NUM_INVERTERS, float> HmSystemType;
|
||||
|
||||
class app : public Main {
|
||||
public:
|
||||
|
@ -59,6 +59,8 @@ class app : public Main {
|
|||
for(uint8_t i = 0; i < 6; i++) {
|
||||
tmp[0] = val[i*2];
|
||||
tmp[1] = val[i*2 + 1];
|
||||
if((tmp[0] == '\0') || (tmp[1] == '\0'))
|
||||
break;
|
||||
u64 = strtol(tmp, NULL, 16);
|
||||
ret |= (u64 << ((5-i) << 3));
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
//-------------------------------------
|
||||
#define PACKET_BUFFER_SIZE 30
|
||||
#define MAX_NUM_INVERTERS 3
|
||||
#define MAX_NAME_LENGTH 16
|
||||
#define LIVEDATA_VISUALIZED // show live data pv-module wise or as dump
|
||||
|
||||
|
||||
//-------------------------------------
|
||||
|
@ -23,7 +25,7 @@
|
|||
//-------------------------------------
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 2
|
||||
#define VERSION_PATCH 2
|
||||
#define VERSION_PATCH 3
|
||||
|
||||
|
||||
//-------------------------------------
|
||||
|
@ -34,8 +36,10 @@
|
|||
#define DEVNAME_LEN 16
|
||||
#define CRC_LEN 2
|
||||
|
||||
#define INV_ADDR_LEN 8 // uint64_t
|
||||
#define INV_INTERVAL_LEN 2 // uint16_t
|
||||
#define INV_ADDR_LEN MAX_NUM_INVERTERS * 8 // uint64_t
|
||||
#define INV_NAME_LEN MAX_NUM_INVERTERS * MAX_NAME_LENGTH // char[]
|
||||
#define INV_TYPE_LEN MAX_NUM_INVERTERS * 1 // uint8_t
|
||||
#define INV_INTERVAL_LEN 2 // uint16_t
|
||||
|
||||
|
||||
#define MQTT_ADDR_LEN 4 // IP
|
||||
|
@ -49,8 +53,10 @@
|
|||
#define ADDR_SSID ADDR_START
|
||||
#define ADDR_PWD ADDR_SSID + SSID_LEN
|
||||
#define ADDR_DEVNAME ADDR_PWD + PWD_LEN
|
||||
#define ADDR_INV0_ADDR ADDR_DEVNAME + DEVNAME_LEN
|
||||
#define ADDR_INV_INTERVAL ADDR_INV0_ADDR + INV_ADDR_LEN
|
||||
#define ADDR_INV_ADDR ADDR_DEVNAME + DEVNAME_LEN
|
||||
#define ADDR_INV_NAME ADDR_INV_ADDR + INV_ADDR_LEN
|
||||
#define ADDR_INV_TYPE ADDR_INV_NAME + INV_NAME_LEN
|
||||
#define ADDR_INV_INTERVAL ADDR_INV_TYPE + INV_TYPE_LEN
|
||||
|
||||
#define ADDR_MQTT_ADDR ADDR_INV_INTERVAL + INV_INTERVAL_LEN
|
||||
#define ADDR_MQTT_USER ADDR_MQTT_ADDR + MQTT_ADDR_LEN
|
||||
|
|
|
@ -21,7 +21,8 @@ enum {CH0 = 0, CH1, CH2, CH3, CH4};
|
|||
enum {CMD01 = 0x01, CMD02, CMD03, CMD83 = 0x83, CMD84};
|
||||
|
||||
enum {INV_TYPE_HM600 = 0, INV_TYPE_HM1200};
|
||||
|
||||
const char* const invTypes[] = {"HM600", "HM1200"};
|
||||
#define NUM_INVERTER_TYPES 2
|
||||
|
||||
typedef struct {
|
||||
uint8_t fieldId; // field id
|
||||
|
@ -41,7 +42,7 @@ union serial_u {
|
|||
|
||||
typedef struct {
|
||||
uint8_t id; // unique id
|
||||
char name[20]; // human readable name, eg. "HM-600.1"
|
||||
char name[MAX_NAME_LENGTH]; // human readable name, eg. "HM-600.1"
|
||||
uint8_t type; // integer which refers to inverter type
|
||||
byteAssign_t* assign; // type of inverter
|
||||
uint8_t listLen; // length of assignments
|
||||
|
|
|
@ -31,11 +31,11 @@ class HmSystem {
|
|||
return NULL;
|
||||
}
|
||||
inverter_t *p = &mInverter[mNumInv];
|
||||
p->id = mNumInv++;
|
||||
p->id = mNumInv;
|
||||
p->serial.u64 = serial;
|
||||
p->type = type;
|
||||
uint8_t len = strlen(name);
|
||||
strncpy(p->name, name, (len > 20) ? 20 : len);
|
||||
strncpy(p->name, name, (len > MAX_NAME_LENGTH) ? MAX_NAME_LENGTH : len);
|
||||
getAssignment(p);
|
||||
toRadioId(p);
|
||||
|
||||
|
@ -44,8 +44,9 @@ class HmSystem {
|
|||
return NULL;
|
||||
}
|
||||
else {
|
||||
mRecord = new RECORDTYPE[p->listLen];
|
||||
memset(mRecord, 0, sizeof(RECORDTYPE) * p->listLen);
|
||||
mRecord[p->id] = new RECORDTYPE[p->listLen];
|
||||
memset(mRecord[p->id], 0, sizeof(RECORDTYPE) * p->listLen);
|
||||
mNumInv ++;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
@ -105,11 +106,20 @@ class HmSystem {
|
|||
val |= buf[ptr];
|
||||
} while(++ptr != end);
|
||||
|
||||
mRecord[pos] = (RECORDTYPE)(val) / (RECORDTYPE)(div);
|
||||
mRecord[p->id][pos] = (RECORDTYPE)(val) / (RECORDTYPE)(div);
|
||||
}
|
||||
|
||||
RECORDTYPE getValue(inverter_t *p, uint8_t pos) {
|
||||
return mRecord[pos];
|
||||
return mRecord[p->id][pos];
|
||||
}
|
||||
|
||||
uint8_t getPosByChField(inverter_t *p, uint8_t channel, uint8_t fieldId) {
|
||||
uint8_t pos = 0;
|
||||
for(; pos < p->listLen; pos++) {
|
||||
if((p->assign[pos].ch == channel) && (p->assign[pos].fieldId == fieldId))
|
||||
break;
|
||||
}
|
||||
return (pos >= p->listLen) ? 0xff : pos;
|
||||
}
|
||||
|
||||
uint8_t getNumInverters(void) {
|
||||
|
@ -141,9 +151,9 @@ class HmSystem {
|
|||
}
|
||||
}
|
||||
|
||||
inverter_t mInverter[MAX_INVERTER]; // TODO: only one inverter supported!!!
|
||||
inverter_t mInverter[MAX_INVERTER];
|
||||
uint8_t mNumInv;
|
||||
RECORDTYPE *mRecord;
|
||||
RECORDTYPE *mRecord[MAX_INVERTER];
|
||||
};
|
||||
|
||||
#endif /*__HM_SYSTEM_H__*/
|
||||
|
|
|
@ -1 +1 @@
|
|||
String setup_html = "<!doctype html><html><head><title>Setup - {DEVICE}</title><link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\"/><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"></head><body><h1>Setup</h1><div id=\"setup\" class=\"content\"><div id=\"content\"><p> Enter the credentials to your prefered WiFi station. After rebooting the device tries to connect with this information. </p><form method=\"post\" action=\"/save\"><p class=\"des\">WiFi</p><label for=\"ssid\">SSID</label><input type=\"text\" class=\"text\" name=\"ssid\" value=\"{SSID}\"/><label for=\"pwd\">Password</label><input type=\"password\" class=\"text\" name=\"pwd\" value=\"{PWD}\"/><p class=\"des\">Device Host Name</p><label for=\"device\">Device Name</label><input type=\"text\" class=\"text\" name=\"device\" value=\"{DEVICE}\"/><p class=\"des\">Inverter</p> {INVERTERS}<br/><label for=\"invInterval\">Interval (ms)</label><input type=\"text\" class=\"text\" name=\"invInterval\" value=\"{INV_INTERVAL}\"/><p class=\"des\">MQTT</p><label for=\"mqttAddr\">Broker / Server IP</label><input type=\"text\" class=\"text\" name=\"mqttAddr\" value=\"{MQTT_ADDR}\"/><label for=\"mqttUser\">Username (optional)</label><input type=\"text\" class=\"text\" name=\"mqttUser\" value=\"{MQTT_USER}\"/><label for=\"mqttPwd\">Password (optional)</label><input type=\"text\" class=\"text\" name=\"mqttPwd\" value=\"{MQTT_PWD}\"/><label for=\"mqttTopic\">Topic</label><input type=\"text\" class=\"text\" name=\"mqttTopic\" value=\"{MQTT_TOPIC}\"/><label for=\"mqttInterval\">Interval (seconds)</label><input type=\"text\" class=\"text\" name=\"mqttInterval\" value=\"{MQTT_INTERVAL}\"/><p class=\"des\"> </p><input type=\"checkbox\" class=\"cb\" name=\"reboot\"/><label for=\"reboot\">Reboot device after successful save</label><input type=\"submit\" value=\"save\" class=\"button\" /></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\">AHOY - {VERSION}</p></div></body></html>";
|
||||
String setup_html = "<!doctype html><html><head><title>Setup - {DEVICE}</title><link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\"/><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"></head><body><h1>Setup</h1><div id=\"setup\" class=\"content\"><div id=\"content\"><p> Enter the credentials to your prefered WiFi station. After rebooting the device tries to connect with this information. </p><form method=\"post\" action=\"/save\"><p class=\"des\">WiFi</p><label for=\"ssid\">SSID</label><input type=\"text\" class=\"text\" name=\"ssid\" value=\"{SSID}\"/><label for=\"pwd\">Password</label><input type=\"password\" class=\"text\" name=\"pwd\" value=\"{PWD}\"/><p class=\"des\">Device Host Name</p><label for=\"device\">Device Name</label><input type=\"text\" class=\"text\" name=\"device\" value=\"{DEVICE}\"/><p class=\"des\">Inverter</p> {INVERTERS}<br/><p class=\"subdes\">General</p><label for=\"invInterval\">Interval (ms)</label><input type=\"text\" class=\"text\" name=\"invInterval\" value=\"{INV_INTERVAL}\"/><p class=\"des\">MQTT</p><label for=\"mqttAddr\">Broker / Server IP</label><input type=\"text\" class=\"text\" name=\"mqttAddr\" value=\"{MQTT_ADDR}\"/><label for=\"mqttUser\">Username (optional)</label><input type=\"text\" class=\"text\" name=\"mqttUser\" value=\"{MQTT_USER}\"/><label for=\"mqttPwd\">Password (optional)</label><input type=\"text\" class=\"text\" name=\"mqttPwd\" value=\"{MQTT_PWD}\"/><label for=\"mqttTopic\">Topic</label><input type=\"text\" class=\"text\" name=\"mqttTopic\" value=\"{MQTT_TOPIC}\"/><label for=\"mqttInterval\">Interval (seconds)</label><input type=\"text\" class=\"text\" name=\"mqttInterval\" value=\"{MQTT_INTERVAL}\"/><p class=\"des\"> </p><input type=\"checkbox\" class=\"cb\" name=\"reboot\"/><label for=\"reboot\">Reboot device after successful save</label><input type=\"submit\" value=\"save\" class=\"button\" /></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\">AHOY - {VERSION}</p></div></body></html>";
|
||||
|
|
|
@ -1 +1 @@
|
|||
String style_css = "h1 { margin: 0; padding: 20pt; font-size: 22pt; color: #fff; background-color: #006ec0; display: block; text-transform: uppercase; } html, body { font-family: Arial; margin: 0; padding: 0; } p { text-align: justify; font-size: 13pt; } .des { margin-top: 35px; font-size: 14pt; color: #006ec0; } .subdes { font-size: 13pt; color: #006ec0; margin-left: 7px; } .fw { width: 60px; display: block; float: left; } .color { width: 50px; height: 50px; border: 1px solid #ccc; } .range { width: 300px; } a:link, a:visited { text-decoration: none; font-size: 13pt; color: #006ec0; } a:hover, a:focus { color: #f00; } #content { padding: 15px 15px 60px 15px; } #footer { position: fixed; bottom: 0px; height: 45px; background-color: #006ec0; width: 100%; } #footer p { color: #fff; padding-left: 20px; padding-right: 20px; font-size: 10pt !important; } #footer a { color: #fff; } div.content { background-color: #fff; padding-bottom: 65px; overflow: hidden; } input { padding: 7px; font-size: 13pt; } input.text, input.password { width: 70%; box-sizing: border-box; margin-bottom: 10px; /*float: right;*/ border: 1px solid #ccc; } input.button { background-color: #006ec0; color: #fff; border: 0px; float: right; text-transform: uppercase; } input.cb { margin-bottom: 20px; } label { width: 20%; display: inline-block; font-size: 12pt; padding-right: 10px; margin-left: 10px; } .left { float: left; } .right { float: right; } div.module { display: block; width: 250px; height: 410px; background-color: #006ec0; display: inline-block; position: relative; margin-right: 20px; margin-bottom: 20px; } div.module .value, div.module .info, div.module .header { color: #fff; display: block; width: 100%; text-align: center; } div.module .unit { font-size: 19px; margin-left: 10px; } div.module .value { margin-top: 20px; font-size: 30px; } div.module .info { margin-top: 3px; font-size: 10px; } div.module .header { background-color: #003c80; padding: 10px 0 10px 0; } ";
|
||||
String style_css = "h1 { margin: 0; padding: 20pt; font-size: 22pt; color: #fff; background-color: #006ec0; display: block; text-transform: uppercase; } html, body { font-family: Arial; margin: 0; padding: 0; } p { text-align: justify; font-size: 13pt; } .des { margin-top: 35px; font-size: 14pt; color: #006ec0; } .subdes { font-size: 13pt; color: #006ec0; margin-left: 7px; } .fw { width: 60px; display: block; float: left; } .color { width: 50px; height: 50px; border: 1px solid #ccc; } .range { width: 300px; } a:link, a:visited { text-decoration: none; font-size: 13pt; color: #006ec0; } a:hover, a:focus { color: #f00; } #content { padding: 15px 15px 60px 15px; } #footer { position: fixed; bottom: 0px; height: 45px; background-color: #006ec0; width: 100%; } #footer p { color: #fff; padding-left: 20px; padding-right: 20px; font-size: 10pt !important; } #footer a { color: #fff; } div.content { background-color: #fff; padding-bottom: 65px; overflow: hidden; } input { padding: 7px; font-size: 13pt; } input.text, input.password { width: 70%; box-sizing: border-box; margin-bottom: 10px; /*float: right;*/ border: 1px solid #ccc; } input.button { background-color: #006ec0; color: #fff; border: 0px; float: right; text-transform: uppercase; } input.cb { margin-bottom: 20px; } label { width: 20%; display: inline-block; font-size: 12pt; padding-right: 10px; margin-left: 10px; } .left { float: left; } .right { float: right; } div.ch { width: 250px; height: 410px; background-color: #006ec0; display: inline-block; margin-right: 20px; margin-bottom: 20px; } div.ch .value, div.ch .info, div.ch .head { color: #fff; display: block; width: 100%; text-align: center; } div.ch .unit { font-size: 19px; margin-left: 10px; } div.ch .value { margin-top: 20px; font-size: 30px; } div.ch .info { margin-top: 3px; font-size: 10px; } div.ch .head { background-color: #003c80; padding: 10px 0 10px 0; } ";
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
<p class="des">Inverter</p>
|
||||
{INVERTERS}<br/>
|
||||
<p class="subdes">General</p>
|
||||
<label for="invInterval">Interval (ms)</label>
|
||||
<input type="text" class="text" name="invInterval" value="{INV_INTERVAL}"/>
|
||||
|
||||
|
|
|
@ -127,39 +127,37 @@ label {
|
|||
float: right;
|
||||
}
|
||||
|
||||
div.module {
|
||||
display: block;
|
||||
div.ch {
|
||||
width: 250px;
|
||||
height: 410px;
|
||||
background-color: #006ec0;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
margin-right: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
div.module .value, div.module .info, div.module .header {
|
||||
div.ch .value, div.ch .info, div.ch .head {
|
||||
color: #fff;
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
div.module .unit {
|
||||
div.ch .unit {
|
||||
font-size: 19px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
div.module .value {
|
||||
div.ch .value {
|
||||
margin-top: 20px;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
div.module .info {
|
||||
div.ch .info {
|
||||
margin-top: 3px;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
div.module .header {
|
||||
div.ch .head {
|
||||
background-color: #003c80;
|
||||
padding: 10px 0 10px 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue