Merge branch 'dev-chunks' into development

This commit is contained in:
Theo Arends 2019-03-07 18:34:51 +01:00
commit ae50f663fe
9 changed files with 698 additions and 720 deletions

View File

@ -1,4 +1,7 @@
/* 6.4.1.19 20190222 /* 6.4.1.20 20190304
* Changed webserver content handling from single String to small Chunks increasing RAM
*
* 6.4.1.19 20190222
* Add command SetOption37 for RGBCW color mapping (#5326) * Add command SetOption37 for RGBCW color mapping (#5326)
* Add Korean language translations (#5344) * Add Korean language translations (#5344)
* Fix Energy TotalStartTime when commands EnergyReset0 and/or EnergyReset3 used (#5373) * Fix Energy TotalStartTime when commands EnergyReset0 and/or EnergyReset3 used (#5373)

View File

@ -20,7 +20,7 @@
#ifndef _SONOFF_VERSION_H_ #ifndef _SONOFF_VERSION_H_
#define _SONOFF_VERSION_H_ #define _SONOFF_VERSION_H_
#define VERSION 0x06040113 #define VERSION 0x06040114
#define D_PROGRAMNAME "Sonoff-Tasmota" #define D_PROGRAMNAME "Sonoff-Tasmota"
#define D_AUTHOR "Theo Arends" #define D_AUTHOR "Theo Arends"

View File

@ -1279,6 +1279,17 @@ void AddLog_P(uint8_t loglevel, const char *formatP, const char *formatP2)
AddLog(loglevel); AddLog(loglevel);
} }
void AddLog_P2(uint8_t loglevel, PGM_P formatP, ...)
{
// This uses char strings. Be aware of sending %% if % is needed
va_list arg;
va_start(arg, formatP);
int len = vsnprintf_P(log_data, sizeof(log_data), formatP, arg);
va_end(arg);
AddLog(loglevel);
}
void AddLogBuffer(uint8_t loglevel, uint8_t *buffer, int count) void AddLogBuffer(uint8_t loglevel, uint8_t *buffer, int count)
{ {
snprintf_P(log_data, sizeof(log_data), PSTR("DMP:")); snprintf_P(log_data, sizeof(log_data), PSTR("DMP:"));

File diff suppressed because it is too large Load Diff

View File

@ -900,16 +900,17 @@ const char S_CONFIGURE_MQTT[] PROGMEM = D_CONFIGURE_MQTT;
const char HTTP_BTN_MENU_MQTT[] PROGMEM = const char HTTP_BTN_MENU_MQTT[] PROGMEM =
"<p><form action='" WEB_HANDLE_MQTT "' method='get'><button>" D_CONFIGURE_MQTT "</button></form></p>"; "<p><form action='" WEB_HANDLE_MQTT "' method='get'><button>" D_CONFIGURE_MQTT "</button></form></p>";
const char HTTP_FORM_MQTT[] PROGMEM = const char HTTP_FORM_MQTT1[] PROGMEM =
"<fieldset><legend><b>&nbsp;" D_MQTT_PARAMETERS "&nbsp;</b></legend>" "<fieldset><legend><b>&nbsp;" D_MQTT_PARAMETERS "&nbsp;</b></legend>"
"<form method='get' action='" WEB_HANDLE_MQTT "'>" "<form method='get' action='" WEB_HANDLE_MQTT "'>"
"<p><b>" D_HOST "</b> (" MQTT_HOST ")<br/><input id='mh' name='mh' placeholder='" MQTT_HOST" ' value='{m1'></p>" "<p><b>" D_HOST "</b> (" MQTT_HOST ")<br/><input id='mh' name='mh' placeholder='" MQTT_HOST" ' value='%s'></p>"
"<p><b>" D_PORT "</b> (" STR(MQTT_PORT) ")<br/><input id='ml' name='ml' placeholder='" STR(MQTT_PORT) "' value='{m2'></p>" "<p><b>" D_PORT "</b> (" STR(MQTT_PORT) ")<br/><input id='ml' name='ml' placeholder='" STR(MQTT_PORT) "' value='%d'></p>"
"<p><b>" D_CLIENT "</b> ({m0)<br/><input id='mc' name='mc' placeholder='" MQTT_CLIENT_ID "' value='{m3'></p>" "<p><b>" D_CLIENT "</b> (%s)<br/><input id='mc' name='mc' placeholder='%s' value='%s'></p>";
"<p><b>" D_USER "</b> (" MQTT_USER ")<br/><input id='mu' name='mu' placeholder='" MQTT_USER "' value='{m4'></p>" const char HTTP_FORM_MQTT2[] PROGMEM =
"<p><b>" D_USER "</b> (" MQTT_USER ")<br/><input id='mu' name='mu' placeholder='" MQTT_USER "' value='%s'></p>"
"<p><b>" D_PASSWORD "</b><br/><input id='mp' name='mp' type='password' placeholder='" D_PASSWORD "' value='" D_ASTERISK_PWD "'></p>" "<p><b>" D_PASSWORD "</b><br/><input id='mp' name='mp' type='password' placeholder='" D_PASSWORD "' value='" D_ASTERISK_PWD "'></p>"
"<p><b>" D_TOPIC "</b> = %topic% (" MQTT_TOPIC ")<br/><input id='mt' name='mt' placeholder='" MQTT_TOPIC" ' value='{m6'></p>" "<p><b>" D_TOPIC "</b> = %%topic%% (" MQTT_TOPIC ")<br/><input id='mt' name='mt' placeholder='" MQTT_TOPIC "' value='%s'></p>"
"<p><b>" D_FULL_TOPIC "</b> (" MQTT_FULLTOPIC ")<br/><input id='mf' name='mf' placeholder='" MQTT_FULLTOPIC" ' value='{m7'></p>"; "<p><b>" D_FULL_TOPIC "</b> (%s)<br/><input id='mf' name='mf' placeholder='%s' value='%s'></p>";
void HandleMqttConfiguration(void) void HandleMqttConfiguration(void)
{ {
@ -923,23 +924,24 @@ void HandleMqttConfiguration(void)
return; return;
} }
String page = FPSTR(HTTP_HEAD);
page.replace(F("{v}"), FPSTR(S_CONFIGURE_MQTT));
page += FPSTR(HTTP_HEAD_STYLE);
page += FPSTR(HTTP_FORM_MQTT);
char str[sizeof(Settings.mqtt_client)]; char str[sizeof(Settings.mqtt_client)];
page.replace(F("{m0"), Format(str, MQTT_CLIENT_ID, sizeof(Settings.mqtt_client)));
page.replace(F("{m1"), Settings.mqtt_host);
page.replace(F("{m2"), String(Settings.mqtt_port));
page.replace(F("{m3"), Settings.mqtt_client);
page.replace(F("{m4"), (Settings.mqtt_user[0] == '\0')?"0":Settings.mqtt_user);
page.replace(F("{m6"), Settings.mqtt_topic);
page.replace(F("{m7"), Settings.mqtt_fulltopic);
page += FPSTR(HTTP_FORM_END); WSContentStart(FPSTR(S_CONFIGURE_MQTT));
page += FPSTR(HTTP_BTN_CONF); WSContentSendStyle();
ShowPage(page); WSContentSend_P(HTTP_FORM_MQTT1,
Settings.mqtt_host,
Settings.mqtt_port,
Format(str, MQTT_CLIENT_ID, sizeof(Settings.mqtt_client)),
MQTT_CLIENT_ID,
Settings.mqtt_client);
WSContentSend_P(HTTP_FORM_MQTT2,
(Settings.mqtt_user[0] == '\0') ? "0" : Settings.mqtt_user,
Settings.mqtt_topic,
MQTT_FULLTOPIC, MQTT_FULLTOPIC,
Settings.mqtt_fulltopic);
WSContentSend(FPSTR(HTTP_FORM_END));
WSContentSend(FPSTR(HTTP_BTN_CONF));
WSContentEnd();
} }
void MqttSaveSettings(void) void MqttSaveSettings(void)
@ -988,7 +990,7 @@ bool Xdrv02(uint8_t function)
switch (function) { switch (function) {
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
case FUNC_WEB_ADD_BUTTON: case FUNC_WEB_ADD_BUTTON:
strncat_P(mqtt_data, HTTP_BTN_MENU_MQTT, sizeof(mqtt_data) - strlen(mqtt_data) -1); WSContentSend(FPSTR(HTTP_BTN_MENU_MQTT));
break; break;
case FUNC_WEB_ADD_HANDLER: case FUNC_WEB_ADD_HANDLER:
WebServer->on("/" WEB_HANDLE_MQTT, HandleMqttConfiguration); WebServer->on("/" WEB_HANDLE_MQTT, HandleMqttConfiguration);

View File

@ -439,14 +439,14 @@ const char HTTP_FORM_DOMOTICZ[] PROGMEM =
"<br/>" "<br/>"
"<table>"; "<table>";
const char HTTP_FORM_DOMOTICZ_RELAY[] PROGMEM = const char HTTP_FORM_DOMOTICZ_RELAY[] PROGMEM =
"<tr><td style='width:260px'><b>" D_DOMOTICZ_IDX " {1</b></td><td style='width:70px'><input id='r{1' name='r{1' placeholder='0' value='{2'></td></tr>" "<tr><td style='width:260px'><b>" D_DOMOTICZ_IDX " %d</b></td><td style='width:70px'><input id='r%d' name='r%d' placeholder='0' value='%d'></td></tr>"
"<tr><td style='width:260px'><b>" D_DOMOTICZ_KEY_IDX " {1</b></td><td style='width:70px'><input id='k{1' name='k{1' placeholder='0' value='{3'></td></tr>"; "<tr><td style='width:260px'><b>" D_DOMOTICZ_KEY_IDX " %d</b></td><td style='width:70px'><input id='k%d' name='k%d' placeholder='0' value='%d'></td></tr>";
const char HTTP_FORM_DOMOTICZ_SWITCH[] PROGMEM = const char HTTP_FORM_DOMOTICZ_SWITCH[] PROGMEM =
"<tr><td style='width:260px'><b>" D_DOMOTICZ_SWITCH_IDX " {1</b></td><td style='width:70px'><input id='s{1' name='s{1' placeholder='0' value='{4'></td></tr>"; "<tr><td style='width:260px'><b>" D_DOMOTICZ_SWITCH_IDX " %d</b></td><td style='width:70px'><input id='s%d' name='s%d' placeholder='0' value='%d'></td></tr>";
const char HTTP_FORM_DOMOTICZ_SENSOR[] PROGMEM = const char HTTP_FORM_DOMOTICZ_SENSOR[] PROGMEM =
"<tr><td style='width:260px'><b>" D_DOMOTICZ_SENSOR_IDX " {1</b> {2</td><td style='width:70px'><input id='l{1' name='l{1' placeholder='0' value='{5'></td></tr>"; "<tr><td style='width:260px'><b>" D_DOMOTICZ_SENSOR_IDX " %d</b> %s</td><td style='width:70px'><input id='l%d' name='l%d' placeholder='0' value='%d'></td></tr>";
const char HTTP_FORM_DOMOTICZ_TIMER[] PROGMEM = const char HTTP_FORM_DOMOTICZ_TIMER[] PROGMEM =
"<tr><td style='width:260px'><b>" D_DOMOTICZ_UPDATE_TIMER "</b> (" STR(DOMOTICZ_UPDATE_TIMER) ")</td><td style='width:70px'><input id='ut' name='ut' placeholder='" STR(DOMOTICZ_UPDATE_TIMER) "' value='{6'</td></tr>"; "<tr><td style='width:260px'><b>" D_DOMOTICZ_UPDATE_TIMER "</b> (" STR(DOMOTICZ_UPDATE_TIMER) ")</td><td style='width:70px'><input id='ut' name='ut' placeholder='" STR(DOMOTICZ_UPDATE_TIMER) "' value='%d'</td></tr>";
void HandleDomoticzConfiguration(void) void HandleDomoticzConfiguration(void)
{ {
@ -462,35 +462,30 @@ void HandleDomoticzConfiguration(void)
char stemp[32]; char stemp[32];
String page = FPSTR(HTTP_HEAD); WSContentStart(FPSTR(S_CONFIGURE_DOMOTICZ));
page.replace(F("{v}"), FPSTR(S_CONFIGURE_DOMOTICZ)); WSContentSendStyle();
page += FPSTR(HTTP_HEAD_STYLE); WSContentSend(FPSTR(HTTP_FORM_DOMOTICZ));
page += FPSTR(HTTP_FORM_DOMOTICZ);
for (int i = 0; i < MAX_DOMOTICZ_IDX; i++) { for (int i = 0; i < MAX_DOMOTICZ_IDX; i++) {
if (i < devices_present) { if (i < devices_present) {
page += FPSTR(HTTP_FORM_DOMOTICZ_RELAY); WSContentSend_P(HTTP_FORM_DOMOTICZ_RELAY,
page.replace("{2", String((int)Settings.domoticz_relay_idx[i])); i +1, i, i, Settings.domoticz_relay_idx[i],
page.replace("{3", String((int)Settings.domoticz_key_idx[i])); i +1, i, i, Settings.domoticz_key_idx[i]);
} }
if (pin[GPIO_SWT1 +i] < 99) { if (pin[GPIO_SWT1 +i] < 99) {
page += FPSTR(HTTP_FORM_DOMOTICZ_SWITCH); WSContentSend_P(HTTP_FORM_DOMOTICZ_SWITCH,
page.replace("{4", String((int)Settings.domoticz_switch_idx[i])); i +1, i, i, Settings.domoticz_switch_idx[i]);
} }
page.replace("{1", String(i +1));
if ((SONOFF_IFAN02 == my_module_type) && (1 == i)) { break; } if ((SONOFF_IFAN02 == my_module_type) && (1 == i)) { break; }
} }
for (int i = 0; i < DZ_MAX_SENSORS; i++) { for (int i = 0; i < DZ_MAX_SENSORS; i++) {
page += FPSTR(HTTP_FORM_DOMOTICZ_SENSOR); WSContentSend_P(HTTP_FORM_DOMOTICZ_SENSOR,
page.replace("{1", String(i +1)); i +1, GetTextIndexed(stemp, sizeof(stemp), i, kDomoticzSensors), i, i, Settings.domoticz_sensor_idx[i]);
page.replace("{2", GetTextIndexed(stemp, sizeof(stemp), i, kDomoticzSensors));
page.replace("{5", String((int)Settings.domoticz_sensor_idx[i]));
} }
page += FPSTR(HTTP_FORM_DOMOTICZ_TIMER); WSContentSend_P(HTTP_FORM_DOMOTICZ_TIMER, Settings.domoticz_update_timer);
page.replace("{6", String((int)Settings.domoticz_update_timer)); WSContentSend(F("</table>"));
page += F("</table>"); WSContentSend(FPSTR(HTTP_FORM_END));
page += FPSTR(HTTP_FORM_END); WSContentSend(FPSTR(HTTP_BTN_CONF));
page += FPSTR(HTTP_BTN_CONF); WSContentEnd();
ShowPage(page);
} }
void DomoticzSaveSettings(void) void DomoticzSaveSettings(void)
@ -500,19 +495,19 @@ void DomoticzSaveSettings(void)
char tmp[100]; char tmp[100];
for (uint8_t i = 0; i < MAX_DOMOTICZ_IDX; i++) { for (uint8_t i = 0; i < MAX_DOMOTICZ_IDX; i++) {
snprintf_P(stemp, sizeof(stemp), PSTR("r%d"), i +1); snprintf_P(stemp, sizeof(stemp), PSTR("r%d"), i);
WebGetArg(stemp, tmp, sizeof(tmp)); WebGetArg(stemp, tmp, sizeof(tmp));
Settings.domoticz_relay_idx[i] = (!strlen(tmp)) ? 0 : atoi(tmp); Settings.domoticz_relay_idx[i] = (!strlen(tmp)) ? 0 : atoi(tmp);
snprintf_P(stemp, sizeof(stemp), PSTR("k%d"), i +1); snprintf_P(stemp, sizeof(stemp), PSTR("k%d"), i);
WebGetArg(stemp, tmp, sizeof(tmp)); WebGetArg(stemp, tmp, sizeof(tmp));
Settings.domoticz_key_idx[i] = (!strlen(tmp)) ? 0 : atoi(tmp); Settings.domoticz_key_idx[i] = (!strlen(tmp)) ? 0 : atoi(tmp);
snprintf_P(stemp, sizeof(stemp), PSTR("s%d"), i +1); snprintf_P(stemp, sizeof(stemp), PSTR("s%d"), i);
WebGetArg(stemp, tmp, sizeof(tmp)); WebGetArg(stemp, tmp, sizeof(tmp));
Settings.domoticz_switch_idx[i] = (!strlen(tmp)) ? 0 : atoi(tmp); Settings.domoticz_switch_idx[i] = (!strlen(tmp)) ? 0 : atoi(tmp);
} }
ssensor_indices[0] = '\0'; ssensor_indices[0] = '\0';
for (uint8_t i = 0; i < DZ_MAX_SENSORS; i++) { for (uint8_t i = 0; i < DZ_MAX_SENSORS; i++) {
snprintf_P(stemp, sizeof(stemp), PSTR("l%d"), i +1); snprintf_P(stemp, sizeof(stemp), PSTR("l%d"), i);
WebGetArg(stemp, tmp, sizeof(tmp)); WebGetArg(stemp, tmp, sizeof(tmp));
Settings.domoticz_sensor_idx[i] = (!strlen(tmp)) ? 0 : atoi(tmp); Settings.domoticz_sensor_idx[i] = (!strlen(tmp)) ? 0 : atoi(tmp);
snprintf_P(ssensor_indices, sizeof(ssensor_indices), PSTR("%s%s%d"), ssensor_indices, (strlen(ssensor_indices)) ? "," : "", Settings.domoticz_sensor_idx[i]); snprintf_P(ssensor_indices, sizeof(ssensor_indices), PSTR("%s%s%d"), ssensor_indices, (strlen(ssensor_indices)) ? "," : "", Settings.domoticz_sensor_idx[i]);
@ -541,7 +536,7 @@ bool Xdrv07(uint8_t function)
switch (function) { switch (function) {
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
case FUNC_WEB_ADD_BUTTON: case FUNC_WEB_ADD_BUTTON:
strncat_P(mqtt_data, HTTP_BTN_MENU_DOMOTICZ, sizeof(mqtt_data) - strlen(mqtt_data) -1); WSContentSend(FPSTR(HTTP_BTN_MENU_DOMOTICZ));
break; break;
case FUNC_WEB_ADD_HANDLER: case FUNC_WEB_ADD_HANDLER:
WebServer->on("/" WEB_HANDLE_DOMOTICZ, HandleDomoticzConfiguration); WebServer->on("/" WEB_HANDLE_DOMOTICZ, HandleDomoticzConfiguration);

View File

@ -519,7 +519,7 @@ const char S_CONFIGURE_TIMER[] PROGMEM = D_CONFIGURE_TIMER;
const char HTTP_BTN_MENU_TIMER[] PROGMEM = const char HTTP_BTN_MENU_TIMER[] PROGMEM =
"<p><form action='" WEB_HANDLE_TIMER "' method='get'><button>" D_CONFIGURE_TIMER "</button></form></p>"; "<p><form action='" WEB_HANDLE_TIMER "' method='get'><button>" D_CONFIGURE_TIMER "</button></form></p>";
const char HTTP_TIMER_SCRIPT[] PROGMEM = const char HTTP_TIMER_SCRIPT1[] PROGMEM =
"var pt=[],ct=99;" "var pt=[],ct=99;"
"function qs(s){" // Alias to save code space "function qs(s){" // Alias to save code space
"return document.querySelector(s);" "return document.querySelector(s);"
@ -528,8 +528,9 @@ const char HTTP_TIMER_SCRIPT[] PROGMEM =
"var o=document.createElement('option');" "var o=document.createElement('option');"
"o.textContent=i;" "o.textContent=i;"
"q.appendChild(o);" "q.appendChild(o);"
"}" "}";
#ifdef USE_SUNRISE #ifdef USE_SUNRISE
const char HTTP_TIMER_SCRIPT2[] PROGMEM =
"function gt(){" // Set hours and minutes according to mode "function gt(){" // Set hours and minutes according to mode
"var m,p,q;" "var m,p,q;"
"m=qs('input[name=\"rd\"]:checked').value;" // Get mode "m=qs('input[name=\"rd\"]:checked').value;" // Get mode
@ -558,8 +559,9 @@ const char HTTP_TIMER_SCRIPT[] PROGMEM =
"qs('#dr').disabled='disabled';" "qs('#dr').disabled='disabled';"
"if(e<23){for(i=12;i<=23;i++){ce(i,o);}}" // Create hours select options "if(e<23){for(i=12;i<=23;i++){ce(i,o);}}" // Create hours select options
"}" "}"
"}" "}";
#endif #endif
const char HTTP_TIMER_SCRIPT3[] PROGMEM =
"function st(){" // Save parameters to hidden area "function st(){" // Save parameters to hidden area
"var i,l,m,n,p,s;" "var i,l,m,n,p,s;"
"m=0;s=0;" "m=0;s=0;"
@ -570,7 +572,7 @@ const char HTTP_TIMER_SCRIPT[] PROGMEM =
"m=qs('input[name=\"rd\"]:checked').value;" // Check mode "m=qs('input[name=\"rd\"]:checked').value;" // Check mode
"s|=(qs('input[name=\"rd\"]:checked').value<<29);" // Get mode "s|=(qs('input[name=\"rd\"]:checked').value<<29);" // Get mode
#endif #endif
"if(}1>0){" "if(%d>0){"
"i=qs('#d1').selectedIndex;if(i>=0){s|=(i<<23);}" // Get output "i=qs('#d1').selectedIndex;if(i>=0){s|=(i<<23);}" // Get output
"s|=(qs('#p1').selectedIndex<<27);" // Get action "s|=(qs('#p1').selectedIndex<<27);" // Get action
"}else{" "}else{"
@ -587,7 +589,8 @@ const char HTTP_TIMER_SCRIPT[] PROGMEM =
"s|=((qs('#mw').selectedIndex)&0x0F)<<11;" // Get window minutes "s|=((qs('#mw').selectedIndex)&0x0F)<<11;" // Get window minutes
"pt[ct]=s;" "pt[ct]=s;"
"eb('t0').value=pt.join();" // Save parameters from array to hidden area "eb('t0').value=pt.join();" // Save parameters from array to hidden area
"}" "}";
const char HTTP_TIMER_SCRIPT4[] PROGMEM =
"function ot(t,e){" // Select tab and update elements "function ot(t,e){" // Select tab and update elements
"var i,n,o,p,q,s;" "var i,n,o,p,q,s;"
"if(ct<99){st();}" // Save changes "if(ct<99){st();}" // Save changes
@ -602,23 +605,24 @@ const char HTTP_TIMER_SCRIPT[] PROGMEM =
#else #else
"p=s&0x7FF;" // Get time "p=s&0x7FF;" // Get time
"q=Math.floor(p/60);if(q<10){q='0'+q;}qs('#ho').value=q;" // Set hours "q=Math.floor(p/60);if(q<10){q='0'+q;}qs('#ho').value=q;" // Set hours
"q=p%60;if(q<10){q='0'+q;}qs('#mi').value=q;" // Set minutes "q=p%%60;if(q<10){q='0'+q;}qs('#mi').value=q;" // Set minutes
#endif #endif
"q=(s>>11)&0xF;if(q<10){q='0'+q;}qs('#mw').value=q;" // Set window minutes "q=(s>>11)&0xF;if(q<10){q='0'+q;}qs('#mw').value=q;" // Set window minutes
"for(i=0;i<7;i++){p=(s>>(16+i))&1;eb('w'+i).checked=p;}" // Set weekdays "for(i=0;i<7;i++){p=(s>>(16+i))&1;eb('w'+i).checked=p;}" // Set weekdays
"if(}1>0){" "if(%d>0){"
"p=(s>>23)&0xF;qs('#d1').value=p+1;" // Set output "p=(s>>23)&0xF;qs('#d1').value=p+1;" // Set output
"p=(s>>27)&3;qs('#p1').selectedIndex=p;" // Set action "p=(s>>27)&3;qs('#p1').selectedIndex=p;" // Set action
"}" "}"
"p=(s>>15)&1;eb('r0').checked=p;" // Set repeat "p=(s>>15)&1;eb('r0').checked=p;" // Set repeat
"p=(s>>31)&1;eb('a0').checked=p;" // Set arm "p=(s>>31)&1;eb('a0').checked=p;" // Set arm
"}" "}";
const char HTTP_TIMER_SCRIPT5[] PROGMEM =
"function it(){" // Initialize elements and select first tab "function it(){" // Initialize elements and select first tab
"var b,i,o,s;" "var b,i,o,s;"
"pt=eb('t0').value.split(',').map(Number);" // Get parameters from hidden area to array "pt=eb('t0').value.split(',').map(Number);" // Get parameters from hidden area to array
"s='';for(i=0;i<" STR(MAX_TIMERS) ";i++){b='';if(0==i){b=\" id='dP'\";}s+=\"<button type='button' class='tl' onclick='ot(\"+i+\",this)'\"+b+\">\"+(i+1)+\"</button>\"}" "s='';for(i=0;i<" STR(MAX_TIMERS) ";i++){b='';if(0==i){b=\" id='dP'\";}s+=\"<button type='button' class='tl' onclick='ot(\"+i+\",this)'\"+b+\">\"+(i+1)+\"</button>\"}"
"eb('bt').innerHTML=s;" // Create tabs "eb('bt').innerHTML=s;" // Create tabs
"if(}1>0){" // Create Output and Action drop down boxes "if(%d>0){" // Create Output and Action drop down boxes
"eb('oa').innerHTML=\"<b>" D_TIMER_OUTPUT "</b>&nbsp;<span><select style='width:60px;' id='d1' name='d1'></select></span>&emsp;<b>" D_TIMER_ACTION "</b>&nbsp;<select style='width:99px;' id='p1' name='p1'></select>\";" "eb('oa').innerHTML=\"<b>" D_TIMER_OUTPUT "</b>&nbsp;<span><select style='width:60px;' id='d1' name='d1'></select></span>&emsp;<b>" D_TIMER_ACTION "</b>&nbsp;<select style='width:99px;' id='p1' name='p1'></select>\";"
"o=qs('#p1');ce('" D_OFF "',o);ce('" D_ON "',o);ce('" D_TOGGLE "',o);" // Create offset direction select options "o=qs('#p1');ce('" D_OFF "',o);ce('" D_ON "',o);ce('" D_TOGGLE "',o);" // Create offset direction select options
#ifdef USE_RULES #ifdef USE_RULES
@ -628,48 +632,52 @@ const char HTTP_TIMER_SCRIPT[] PROGMEM =
#endif #endif
"}else{" "}else{"
"eb('oa').innerHTML=\"<b>" D_TIMER_ACTION "</b> " D_RULE "\";" // No outputs but rule is allowed "eb('oa').innerHTML=\"<b>" D_TIMER_ACTION "</b> " D_RULE "\";" // No outputs but rule is allowed
"}" "}";
const char HTTP_TIMER_SCRIPT6[] PROGMEM =
#ifdef USE_SUNRISE #ifdef USE_SUNRISE
"o=qs('#dr');ce('+',o);ce('-',o);" // Create offset direction select options "o=qs('#dr');ce('+',o);ce('-',o);" // Create offset direction select options
#endif #endif
"o=qs('#ho');for(i=0;i<=23;i++){ce((i<10)?('0'+i):i,o);}" // Create hours select options "o=qs('#ho');for(i=0;i<=23;i++){ce((i<10)?('0'+i):i,o);}" // Create hours select options
"o=qs('#mi');for(i=0;i<=59;i++){ce((i<10)?('0'+i):i,o);}" // Create minutes select options "o=qs('#mi');for(i=0;i<=59;i++){ce((i<10)?('0'+i):i,o);}" // Create minutes select options
"o=qs('#mw');for(i=0;i<=15;i++){ce((i<10)?('0'+i):i,o);}" // Create window minutes select options "o=qs('#mw');for(i=0;i<=15;i++){ce((i<10)?('0'+i):i,o);}" // Create window minutes select options
"o=qs('#d1');for(i=0;i<}1;i++){ce(i+1,o);}" // Create outputs "o=qs('#d1');for(i=0;i<%d;i++){ce(i+1,o);}" // Create outputs
"var a='" D_DAY3LIST "';" "var a='" D_DAY3LIST "';"
"s='';for(i=0;i<7;i++){s+=\"<input id='w\"+i+\"' name='w\"+i+\"' type='checkbox'><b>\"+a.substring(i*3,(i*3)+3)+\"</b> \"}" "s='';for(i=0;i<7;i++){s+=\"<input id='w\"+i+\"' name='w\"+i+\"' type='checkbox'><b>\"+a.substring(i*3,(i*3)+3)+\"</b> \"}"
"eb('ds').innerHTML=s;" // Create weekdays "eb('ds').innerHTML=s;" // Create weekdays
"eb('dP').click();" // Get the element with id='dP' and click on it "eb('dP').click();" // Get the element with id='dP' and click on it
"}"; "}"
"window.onload=it;";
const char HTTP_TIMER_STYLE[] PROGMEM = const char HTTP_TIMER_STYLE[] PROGMEM =
".tl{float:left;border-radius:0;border:1px solid #f2f2f2;padding:1px;width:6.25%;}" // Border color needs to be the same as Fieldset background color from HTTP_HEAD_STYLE (transparent won't work) ".tl{float:left;border-radius:0;border:1px solid #f2f2f2;padding:1px;width:6.25%;}"; // Border color needs to be the same as Fieldset background color from HTTP_HEAD_STYLE1 (transparent won't work)
"</style>"; const char HTTP_FORM_TIMER1[] PROGMEM =
const char HTTP_FORM_TIMER[] PROGMEM =
"<fieldset style='min-width:470px;text-align:center;'>" "<fieldset style='min-width:470px;text-align:center;'>"
"<legend style='text-align:left;'><b>&nbsp;" D_TIMER_PARAMETERS "&nbsp;</b></legend>" "<legend style='text-align:left;'><b>&nbsp;" D_TIMER_PARAMETERS "&nbsp;</b></legend>"
"<form method='post' action='" WEB_HANDLE_TIMER "' onsubmit='return st();'>" "<form method='post' action='" WEB_HANDLE_TIMER "' onsubmit='return st();'>"
"<br/><input id='e0' name='e0' type='checkbox'{e0><b>" D_TIMER_ENABLE "</b><br/><br/><hr/>" "<br/><input id='e0' name='e0' type='checkbox'%s><b>" D_TIMER_ENABLE "</b><br/><br/><hr/>"
"<input id='t0' name='t0' value='"; "<input id='t0' name='t0' value='";
const char HTTP_FORM_TIMER1[] PROGMEM = const char HTTP_FORM_TIMER2[] PROGMEM =
"' hidden><div id='bt' name='bt'></div><br/><br/><br/>" "' hidden><div id='bt' name='bt'></div><br/><br/><br/>"
"<div id='oa' name='oa'></div><br/>" "<div id='oa' name='oa'></div><br/>"
"<div>" "<div>"
"<input id='a0' name='a0' type='checkbox'><b>" D_TIMER_ARM "</b>&emsp;" "<input id='a0' name='a0' type='checkbox'><b>" D_TIMER_ARM "</b>&emsp;"
"<input id='r0' name='r0' type='checkbox'><b>" D_TIMER_REPEAT "</b>" "<input id='r0' name='r0' type='checkbox'><b>" D_TIMER_REPEAT "</b>"
"</div><br/>" "</div><br/>"
"<div>" "<div>";
#ifdef USE_SUNRISE #ifdef USE_SUNRISE
"<fieldset style='width:299px;margin:auto;text-align:left;border:0;'>" // 299 used in page.replace(F("299") const char HTTP_FORM_TIMER3[] PROGMEM =
"<fieldset style='width:%dpx;margin:auto;text-align:left;border:0;'>"
"<input id='b0' name='rd' type='radio' value='0' onclick='gt();'><b>" D_TIMER_TIME "</b><br/>" "<input id='b0' name='rd' type='radio' value='0' onclick='gt();'><b>" D_TIMER_TIME "</b><br/>"
"<input id='b1' name='rd' type='radio' value='1' onclick='gt();'><b>" D_SUNRISE "</b> (}8)<br/>" "<input id='b1' name='rd' type='radio' value='1' onclick='gt();'><b>" D_SUNRISE "</b> (%s)<br/>"
"<input id='b2' name='rd' type='radio' value='2' onclick='gt();'><b>" D_SUNSET "</b> (}9)<br/>" "<input id='b2' name='rd' type='radio' value='2' onclick='gt();'><b>" D_SUNSET "</b> (%s)<br/>"
"</fieldset>" "</fieldset>"
"<p></p>" "<p></p>"
"<span><select style='width:46px;' id='dr' name='dr'></select></span>" "<span><select style='width:46px;' id='dr' name='dr'></select></span>"
"&nbsp;" "&nbsp;";
#else #else
"<b>" D_TIMER_TIME "</b>&nbsp;" const char HTTP_FORM_TIMER3[] PROGMEM =
"<b>" D_TIMER_TIME "</b>&nbsp;";
#endif // USE_SUNRISE #endif // USE_SUNRISE
const char HTTP_FORM_TIMER4[] PROGMEM =
"<span><select style='width:60px;' id='ho' name='ho'></select></span>" "<span><select style='width:60px;' id='ho' name='ho'></select></span>"
"&nbsp;" D_HOUR_MINUTE_SEPARATOR "&nbsp;" "&nbsp;" D_HOUR_MINUTE_SEPARATOR "&nbsp;"
"<span><select style='width:60px;' id='mi' name='mi'></select></span>" "<span><select style='width:60px;' id='mi' name='mi'></select></span>"
@ -690,28 +698,30 @@ void HandleTimerConfiguration(void)
return; return;
} }
String page = FPSTR(HTTP_HEAD); WSContentStart(FPSTR(S_CONFIGURE_TIMER));
page.replace(F("{v}"), FPSTR(S_CONFIGURE_TIMER)); WSContentSend(FPSTR(HTTP_TIMER_SCRIPT1));
page += FPSTR(HTTP_TIMER_SCRIPT);
page += FPSTR(HTTP_HEAD_STYLE);
page.replace(F("</style>"), FPSTR(HTTP_TIMER_STYLE));
page += FPSTR(HTTP_FORM_TIMER);
page.replace(F("{e0"), (Settings.flag3.timers_enable) ? F(" checked") : F(""));
for (uint8_t i = 0; i < MAX_TIMERS; i++) {
if (i > 0) { page += F(","); }
page += String(Settings.timer[i].data);
}
page += FPSTR(HTTP_FORM_TIMER1);
page.replace(F("}1"), String(devices_present));
#ifdef USE_SUNRISE #ifdef USE_SUNRISE
page.replace(F("}8"), GetSun(0)); // Add Sunrise WSContentSend(FPSTR(HTTP_TIMER_SCRIPT2));
page.replace(F("}9"), GetSun(1)); // Add Sunset
page.replace(F("299"), String(100 + (strlen(D_SUNSET) *12))); // Fix string length to keep radios centered
#endif // USE_SUNRISE #endif // USE_SUNRISE
page += FPSTR(HTTP_FORM_END); WSContentSend_P(HTTP_TIMER_SCRIPT3, devices_present);
page += F("<script>it();</script>"); // Init elements and select first tab/button WSContentSend_P(HTTP_TIMER_SCRIPT4, devices_present);
page += FPSTR(HTTP_BTN_CONF); WSContentSend_P(HTTP_TIMER_SCRIPT5, devices_present);
ShowPage(page); WSContentSend_P(HTTP_TIMER_SCRIPT6, devices_present);
WSContentSendStyle(FPSTR(HTTP_TIMER_STYLE));
WSContentSend_P(HTTP_FORM_TIMER1, (Settings.flag3.timers_enable) ? " checked" : "");
for (uint8_t i = 0; i < MAX_TIMERS; i++) {
WSContentSend_P(PSTR("%s%u"), (i > 0) ? "," : "", Settings.timer[i].data);
}
WSContentSend(FPSTR(HTTP_FORM_TIMER2));
#ifdef USE_SUNRISE
WSContentSend_P(HTTP_FORM_TIMER3, 100 + (strlen(D_SUNSET) *12), GetSun(0).c_str(), GetSun(1).c_str());
#else
WSContentSend(FPSTR(HTTP_FORM_TIMER3));
#endif // USE_SUNRISE
WSContentSend(FPSTR(HTTP_FORM_TIMER4));
WSContentSend(FPSTR(HTTP_FORM_END));
WSContentSend(FPSTR(HTTP_BTN_CONF));
WSContentEnd();
} }
void TimerSaveSettings(void) void TimerSaveSettings(void)
@ -754,9 +764,9 @@ bool Xdrv09(uint8_t function)
#ifdef USE_TIMERS_WEB #ifdef USE_TIMERS_WEB
case FUNC_WEB_ADD_BUTTON: case FUNC_WEB_ADD_BUTTON:
#ifdef USE_RULES #ifdef USE_RULES
strncat_P(mqtt_data, HTTP_BTN_MENU_TIMER, sizeof(mqtt_data) - strlen(mqtt_data) -1); WSContentSend(FPSTR(HTTP_BTN_MENU_TIMER));
#else #else
if (devices_present) { strncat_P(mqtt_data, HTTP_BTN_MENU_TIMER, sizeof(mqtt_data) - strlen(mqtt_data) -1); } if (devices_present) { WSContentSend(FPSTR(HTTP_BTN_MENU_TIMER)); }
#endif // USE_RULES #endif // USE_RULES
break; break;
case FUNC_WEB_ADD_HANDLER: case FUNC_WEB_ADD_HANDLER:

View File

@ -755,13 +755,14 @@ const char HTTP_BTN_MENU_KNX[] PROGMEM =
"<p><form action='kn' method='get'><button>" D_CONFIGURE_KNX "</button></form></p>"; "<p><form action='kn' method='get'><button>" D_CONFIGURE_KNX "</button></form></p>";
const char HTTP_FORM_KNX[] PROGMEM = const char HTTP_FORM_KNX[] PROGMEM =
"<fieldset><legend style='text-align:left;'><b>&nbsp;" D_KNX_PARAMETERS "&nbsp;</b>" "<fieldset style='min-width:530px;'>"
"</legend><form method='post' action='kn'>" "<legend style='text-align:left;'><b>&nbsp;" D_KNX_PARAMETERS "&nbsp;</b></legend>"
"<form method='post' action='kn'>"
"<br/><center>" "<br/><center>"
"<b>" D_KNX_PHYSICAL_ADDRESS " </b>" "<b>" D_KNX_PHYSICAL_ADDRESS " </b>"
"<input style='width:12%;' type='number' name='area' min='0' max='15' value='{kna'> . " "<input style='width:12%%;' type='number' name='area' min='0' max='15' value='%d'> . "
"<input style='width:12%;' type='number' name='line' min='0' max='15' value='{knl'> . " "<input style='width:12%%;' type='number' name='line' min='0' max='15' value='%d'> . "
"<input style='width:12%;' type='number' name='member' min='0' max='255' value='{knm'>" "<input style='width:12%%;' type='number' name='member' min='0' max='255' value='%d'>"
"<br/><br/>" D_KNX_PHYSICAL_ADDRESS_NOTE "<br/><br/>" "<br/><br/>" D_KNX_PHYSICAL_ADDRESS_NOTE "<br/><br/>"
"<input id='b1' name='b1' type='checkbox'"; "<input id='b1' name='b1' type='checkbox'";
@ -777,20 +778,20 @@ const char HTTP_FORM_KNX2[] PROGMEM =
"<select name='GAop' style='width:25%;'>"; "<select name='GAop' style='width:25%;'>";
const char HTTP_FORM_KNX_OPT[] PROGMEM = const char HTTP_FORM_KNX_OPT[] PROGMEM =
"<option value='{vop}'>{nop}</option>"; "<option value='%d'>%s</option>";
const char HTTP_FORM_KNX_GA[] PROGMEM = const char HTTP_FORM_KNX_GA[] PROGMEM =
"<input style='width:12%;' type='number' id='GAfnum' name='GAfnum' min='0' max='31' value='0'> / " "<input style='width:12%%;' type='number' id='%s' name='%s' min='0' max='31' value='0'> / "
"<input style='width:12%;' type='number' id='GAarea' name='GAarea' min='0' max='7' value='0'> / " "<input style='width:12%%;' type='number' id='%s' name='%s' min='0' max='7' value='0'> / "
"<input style='width:12%;' type='number' id='GAfdef' name='GAfdef' min='0' max='255' value='0'> "; "<input style='width:12%%;' type='number' id='%s' name='%s' min='0' max='255' value='0'> ";
const char HTTP_FORM_KNX_ADD_BTN[] PROGMEM = const char HTTP_FORM_KNX_ADD_BTN[] PROGMEM =
"<button type='submit' onclick='fncbtnadd()' btndis name='btn_add' value='{btnval}' style='width:18%;'>" D_ADD "</button><br/><br/>" "<button type='submit' onclick='%s()' %s name='btn_add' value='%d' style='width:18%%;'>" D_ADD "</button><br/><br/>"
"<table style='width:80%; font-size: 14px;'><col width='250'><col width='30'>"; "<table style='width:80%%; font-size: 14px;'><col width='250'><col width='30'>";
const char HTTP_FORM_KNX_ADD_TABLE_ROW[] PROGMEM = const char HTTP_FORM_KNX_ADD_TABLE_ROW[] PROGMEM =
"<tr><td><b>{optex} -> GAfnum / GAarea / GAfdef </b></td>" "<tr><td><b>%s -> %d / %d / %d </b></td>"
"<td><button type='submit' name='btn_del_ga' value='{opval}' class='button bred'> " D_DELETE " </button></td></tr>"; "<td><button type='submit' name='btn_del_ga' value='%d' class='button bred'> " D_DELETE " </button></td></tr>";
const char HTTP_FORM_KNX3[] PROGMEM = const char HTTP_FORM_KNX3[] PROGMEM =
"</table></center></fieldset><br/>" "</table></center></fieldset><br/>"
@ -801,8 +802,8 @@ const char HTTP_FORM_KNX4[] PROGMEM =
"-> <select name='CBop' style='width:25%;'>"; "-> <select name='CBop' style='width:25%;'>";
const char HTTP_FORM_KNX_ADD_TABLE_ROW2[] PROGMEM = const char HTTP_FORM_KNX_ADD_TABLE_ROW2[] PROGMEM =
"<tr><td><b>GAfnum / GAarea / GAfdef -> {optex}</b></td>" "<tr><td><b>%d / %d / %d -> %s</b></td>"
"<td><button type='submit' name='btn_del_cb' value='{opval}' class='button bred'> " D_DELETE " </button></td></tr>"; "<td><button type='submit' name='btn_del_cb' value='%d' class='button bred'> " D_DELETE " </button></td></tr>";
void HandleKNXConfiguration(void) void HandleKNXConfiguration(void)
{ {
@ -871,113 +872,8 @@ void HandleKNXConfiguration(void)
} }
String page = FPSTR(HTTP_HEAD); WSContentStart(FPSTR(S_CONFIGURE_KNX));
page.replace(F("{v}"), FPSTR(S_CONFIGURE_KNX)); WSContentSend(
page += FPSTR(HTTP_HEAD_STYLE);
page.replace(F("340px"), F("530px"));
page += FPSTR(HTTP_FORM_KNX);
KNX_physs_addr.value = Settings.knx_physsical_addr;
page.replace(F("{kna"), String(KNX_physs_addr.pa.area));
page.replace(F("{knl"), String(KNX_physs_addr.pa.line));
page.replace(F("{knm"), String(KNX_physs_addr.pa.member));
if ( Settings.flag.knx_enabled ) { page += F(" checked"); }
page += FPSTR(HTTP_FORM_KNX1);
if ( Settings.flag.knx_enable_enhancement ) { page += F(" checked"); }
page += FPSTR(HTTP_FORM_KNX2);
for (uint8_t i = 0; i < KNX_MAX_device_param ; i++)
{
if ( device_param[i].show )
{
page += FPSTR(HTTP_FORM_KNX_OPT);
page.replace(F("{vop}"), String(device_param[i].type));
page.replace(F("{nop}"), String(device_param_ga[i]));
}
}
page += F("</select> -> ");
page += FPSTR(HTTP_FORM_KNX_GA);
page.replace(F("GAfnum"), F("GA_FNUM"));
page.replace(F("GAarea"), F("GA_AREA"));
page.replace(F("GAfdef"), F("GA_FDEF"));
page.replace(F("GAfnum"), F("GA_FNUM"));
page.replace(F("GAarea"), F("GA_AREA"));
page.replace(F("GAfdef"), F("GA_FDEF"));
page += FPSTR(HTTP_FORM_KNX_ADD_BTN);
page.replace(F("{btnval}"), String(1));
if (Settings.knx_GA_registered < MAX_KNX_GA) {
page.replace(F("btndis"), F(" "));
}
else
{
page.replace(F("btndis"), F("disabled"));
}
page.replace(F("fncbtnadd"), F("GAwarning"));
for (uint8_t i = 0; i < Settings.knx_GA_registered ; ++i)
{
if ( Settings.knx_GA_param[i] )
{
page += FPSTR(HTTP_FORM_KNX_ADD_TABLE_ROW);
page.replace(F("{opval}"), String(i+1));
page.replace(F("{optex}"), String(device_param_ga[Settings.knx_GA_param[i]-1]));
KNX_addr.value = Settings.knx_GA_addr[i];
page.replace(F("GAfnum"), String(KNX_addr.ga.area));
page.replace(F("GAarea"), String(KNX_addr.ga.line));
page.replace(F("GAfdef"), String(KNX_addr.ga.member));
}
}
page += FPSTR(HTTP_FORM_KNX3);
page += FPSTR(HTTP_FORM_KNX_GA);
page.replace(F("GAfnum"), F("CB_FNUM"));
page.replace(F("GAarea"), F("CB_AREA"));
page.replace(F("GAfdef"), F("CB_FDEF"));
page.replace(F("GAfnum"), F("CB_FNUM"));
page.replace(F("GAarea"), F("CB_AREA"));
page.replace(F("GAfdef"), F("CB_FDEF"));
page += FPSTR(HTTP_FORM_KNX4);
uint8_t j;
for (uint8_t i = 0; i < KNX_MAX_device_param ; i++)
{
// Check How many Relays are available and add: RelayX and TogleRelayX
if ( (i > 8) && (i < 16) ) { j=i-8; } else { j=i; }
if ( i == 8 ) { j = 0; }
if ( device_param[j].show )
{
page += FPSTR(HTTP_FORM_KNX_OPT);
page.replace(F("{vop}"), String(device_param[i].type));
page.replace(F("{nop}"), String(device_param_cb[i]));
}
}
page += F("</select> ");
page += FPSTR(HTTP_FORM_KNX_ADD_BTN);
page.replace(F("{btnval}"), String(2));
if (Settings.knx_CB_registered < MAX_KNX_CB) {
page.replace(F("btndis"), F(" "));
}
else
{
page.replace(F("btndis"), F("disabled"));
}
page.replace(F("fncbtnadd"), F("CBwarning"));
for (uint8_t i = 0; i < Settings.knx_CB_registered ; ++i)
{
if ( Settings.knx_CB_param[i] )
{
page += FPSTR(HTTP_FORM_KNX_ADD_TABLE_ROW2);
page.replace(F("{opval}"), String(i+1));
page.replace(F("{optex}"), String(device_param_cb[Settings.knx_CB_param[i]-1]));
KNX_addr.value = Settings.knx_CB_addr[i];
page.replace(F("GAfnum"), String(KNX_addr.ga.area));
page.replace(F("GAarea"), String(KNX_addr.ga.line));
page.replace(F("GAfdef"), String(KNX_addr.ga.member));
}
}
page += F("</table></center></fieldset>");
page += F("<br/><button name='save' type='submit' class='button bgrn'>" D_SAVE "</button></form></fieldset>");
page += FPSTR(HTTP_BTN_CONF);
page.replace( F("</script>"),
F("function GAwarning()" F("function GAwarning()"
"{" "{"
"var GA_FNUM = eb('GA_FNUM');" "var GA_FNUM = eb('GA_FNUM');"
@ -995,9 +891,63 @@ void HandleKNXConfiguration(void)
"if ( CB_FNUM != null && CB_FNUM.value == '0' && CB_AREA.value == '0' && CB_FDEF.value == '0' ) {" "if ( CB_FNUM != null && CB_FNUM.value == '0' && CB_AREA.value == '0' && CB_FDEF.value == '0' ) {"
"alert('" D_KNX_WARNING "');" "alert('" D_KNX_WARNING "');"
"}" "}"
"}" "}"));
"</script>") ); WSContentSendStyle();
ShowPage(page); WSContentSend_P(HTTP_FORM_KNX, KNX_physs_addr.pa.area, KNX_physs_addr.pa.line, KNX_physs_addr.pa.member);
if ( Settings.flag.knx_enabled ) { WSContentSend(F(" checked")); }
WSContentSend(FPSTR(HTTP_FORM_KNX1));
if ( Settings.flag.knx_enable_enhancement ) { WSContentSend(F(" checked")); }
WSContentSend(FPSTR(HTTP_FORM_KNX2));
for (uint8_t i = 0; i < KNX_MAX_device_param ; i++)
{
if ( device_param[i].show )
{
WSContentSend_P(HTTP_FORM_KNX_OPT, device_param[i].type, device_param_ga[i]);
}
}
WSContentSend(F("</select> -> "));
WSContentSend_P(HTTP_FORM_KNX_GA, "GA_FNUM", "GA_FNUM", "GA_AREA", "GA_AREA", "GA_FDEF", "GA_FDEF");
WSContentSend_P(HTTP_FORM_KNX_ADD_BTN, "GAwarning", (Settings.knx_GA_registered < MAX_KNX_GA) ? "" : "disabled", 1);
for (uint8_t i = 0; i < Settings.knx_GA_registered ; ++i)
{
if ( Settings.knx_GA_param[i] )
{
KNX_addr.value = Settings.knx_GA_addr[i];
WSContentSend_P(HTTP_FORM_KNX_ADD_TABLE_ROW, device_param_ga[Settings.knx_GA_param[i]-1], KNX_addr.ga.area, KNX_addr.ga.line, KNX_addr.ga.member, i +1);
}
}
WSContentSend(FPSTR(HTTP_FORM_KNX3));
WSContentSend_P(HTTP_FORM_KNX_GA, "CB_FNUM", "CB_FNUM", "CB_AREA", "CB_AREA", "CB_FDEF", "CB_FDEF");
WSContentSend(FPSTR(HTTP_FORM_KNX4));
uint8_t j;
for (uint8_t i = 0; i < KNX_MAX_device_param ; i++)
{
// Check How many Relays are available and add: RelayX and TogleRelayX
if ( (i > 8) && (i < 16) ) { j=i-8; } else { j=i; }
if ( i == 8 ) { j = 0; }
if ( device_param[j].show )
{
WSContentSend_P(HTTP_FORM_KNX_OPT, device_param[i].type, device_param_cb[i]);
}
}
WSContentSend(F("</select> "));
WSContentSend_P(HTTP_FORM_KNX_ADD_BTN, "CBwarning", (Settings.knx_CB_registered < MAX_KNX_CB) ? "" : "disabled", 2);
for (uint8_t i = 0; i < Settings.knx_CB_registered ; ++i)
{
if ( Settings.knx_CB_param[i] )
{
KNX_addr.value = Settings.knx_CB_addr[i];
WSContentSend_P(HTTP_FORM_KNX_ADD_TABLE_ROW2, KNX_addr.ga.area, KNX_addr.ga.line, KNX_addr.ga.member, device_param_cb[Settings.knx_CB_param[i]-1], i +1);
}
}
WSContentSend(F("</table></center></fieldset>"));
WSContentSend(FPSTR(HTTP_FORM_END));
WSContentSend(FPSTR(HTTP_BTN_CONF));
WSContentEnd();
} }
} }
@ -1299,7 +1249,7 @@ bool Xdrv11(uint8_t function)
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
#ifdef USE_KNX_WEB_MENU #ifdef USE_KNX_WEB_MENU
case FUNC_WEB_ADD_BUTTON: case FUNC_WEB_ADD_BUTTON:
strncat_P(mqtt_data, HTTP_BTN_MENU_KNX, sizeof(mqtt_data) - strlen(mqtt_data) -1); WSContentSend(FPSTR(HTTP_BTN_MENU_KNX));
break; break;
case FUNC_WEB_ADD_HANDLER: case FUNC_WEB_ADD_HANDLER:
WebServer->on("/kn", HandleKNXConfiguration); WebServer->on("/kn", HandleKNXConfiguration);

View File

@ -382,14 +382,14 @@ const char HTTP_BTN_MENU_HX711[] PROGMEM =
const char HTTP_FORM_HX711[] PROGMEM = const char HTTP_FORM_HX711[] PROGMEM =
"<fieldset><legend><b>&nbsp;" D_CALIBRATION "&nbsp;</b></legend>" "<fieldset><legend><b>&nbsp;" D_CALIBRATION "&nbsp;</b></legend>"
"<form method='post' action='" WEB_HANDLE_HX711 "'>" "<form method='post' action='" WEB_HANDLE_HX711 "'>"
"<p><b>" D_REFERENCE_WEIGHT "</b> (" D_UNIT_KILOGRAM ")<br/><input type='number' step='0.001' id='p1' name='p1' placeholder='0' value='{1'></p>" "<p><b>" D_REFERENCE_WEIGHT "</b> (" D_UNIT_KILOGRAM ")<br/><input type='number' step='0.001' id='p1' name='p1' placeholder='0' value='%s'></p>"
"<br/><button name='calibrate' type='submit'>" D_CALIBRATE "</button>" "<br/><button name='calibrate' type='submit'>" D_CALIBRATE "</button>"
"</form>" "</form>"
"</fieldset><br/><br/>" "</fieldset><br/><br/>"
"<fieldset><legend><b>&nbsp;" D_HX711_PARAMETERS "&nbsp;</b></legend>" "<fieldset><legend><b>&nbsp;" D_HX711_PARAMETERS "&nbsp;</b></legend>"
"<form method='post' action='" WEB_HANDLE_HX711 "'>" "<form method='post' action='" WEB_HANDLE_HX711 "'>"
"<p><b>" D_ITEM_WEIGHT "</b> (" D_UNIT_KILOGRAM ")<br/><input type='number' max='6.5535' step='0.0001' id='p2' name='p2' placeholder='0.0' value='{2'></p>"; "<p><b>" D_ITEM_WEIGHT "</b> (" D_UNIT_KILOGRAM ")<br/><input type='number' max='6.5535' step='0.0001' id='p2' name='p2' placeholder='0.0' value='%s'></p>";
void HandleHxAction(void) void HandleHxAction(void)
{ {
@ -403,41 +403,38 @@ void HandleHxAction(void)
return; return;
} }
char tmp[100]; char stemp1[20];
if (WebServer->hasArg("reset")) { if (WebServer->hasArg("reset")) {
snprintf_P(tmp, sizeof(tmp), PSTR("Sensor34 1")); // Reset snprintf_P(stemp1, sizeof(stemp1), PSTR("Sensor34 1")); // Reset
ExecuteWebCommand(tmp, SRC_WEBGUI); ExecuteWebCommand(stemp1, SRC_WEBGUI);
HandleRoot(); // Return to main screen HandleRoot(); // Return to main screen
return; return;
} }
if (WebServer->hasArg("calibrate")) { if (WebServer->hasArg("calibrate")) {
WebGetArg("p1", tmp, sizeof(tmp)); WebGetArg("p1", stemp1, sizeof(stemp1));
Settings.weight_reference = (!strlen(tmp)) ? 0 : (unsigned long)(CharToDouble(tmp) * 1000); Settings.weight_reference = (!strlen(stemp1)) ? 0 : (unsigned long)(CharToDouble(stemp1) * 1000);
HxLogUpdates(); HxLogUpdates();
snprintf_P(tmp, sizeof(tmp), PSTR("Sensor34 2")); // Start calibration snprintf_P(stemp1, sizeof(stemp1), PSTR("Sensor34 2")); // Start calibration
ExecuteWebCommand(tmp, SRC_WEBGUI); ExecuteWebCommand(stemp1, SRC_WEBGUI);
HandleRoot(); // Return to main screen HandleRoot(); // Return to main screen
return; return;
} }
String page = FPSTR(HTTP_HEAD); WSContentStart(FPSTR(D_CONFIGURE_HX711));
page.replace(F("{v}"), FPSTR(D_CONFIGURE_HX711)); WSContentSendStyle();
page += FPSTR(HTTP_HEAD_STYLE); dtostrfd((float)Settings.weight_reference / 1000, 3, stemp1);
page += FPSTR(HTTP_FORM_HX711); char stemp2[20];
dtostrfd((float)Settings.weight_reference / 1000, 3, tmp); dtostrfd((float)Settings.weight_item / 10000, 4, stemp2);
page.replace("{1", String(tmp)); WSContentSend_P(HTTP_FORM_HX711, stemp1, stemp2);
dtostrfd((float)Settings.weight_item / 10000, 4, tmp); WSContentSend(FPSTR(HTTP_FORM_END));
page.replace("{2", String(tmp)); WSContentSend(FPSTR(HTTP_BTN_CONF));
WSContentEnd();
page += FPSTR(HTTP_FORM_END);
page += FPSTR(HTTP_BTN_CONF);
ShowPage(page);
} }
void HxSaveSettings(void) void HxSaveSettings(void)
@ -495,10 +492,10 @@ bool Xsns34(uint8_t function)
break; break;
#ifdef USE_HX711_GUI #ifdef USE_HX711_GUI
case FUNC_WEB_ADD_MAIN_BUTTON: case FUNC_WEB_ADD_MAIN_BUTTON:
strncat_P(mqtt_data, HTTP_BTN_MENU_MAIN_HX711, sizeof(mqtt_data) - strlen(mqtt_data) -1); WSContentSend(FPSTR(HTTP_BTN_MENU_MAIN_HX711));
break; break;
case FUNC_WEB_ADD_BUTTON: case FUNC_WEB_ADD_BUTTON:
strncat_P(mqtt_data, HTTP_BTN_MENU_HX711, sizeof(mqtt_data) - strlen(mqtt_data) -1); WSContentSend(FPSTR(HTTP_BTN_MENU_HX711));
break; break;
case FUNC_WEB_ADD_HANDLER: case FUNC_WEB_ADD_HANDLER:
WebServer->on("/" WEB_HANDLE_HX711, HandleHxAction); WebServer->on("/" WEB_HANDLE_HX711, HandleHxAction);