v5.8.0k - Add support for 8 relays

5.8.0k
 * Add support for up to 8 relays (#995)
 * Fix Blocked Loop when
erasing large flash using command reset 2 (#1002)
This commit is contained in:
arendst 2017-10-12 11:29:40 +02:00
parent ca431184e6
commit 804bd8fb53
10 changed files with 143 additions and 91 deletions

View File

@ -1,7 +1,7 @@
## Sonoff-Tasmota
Provide ESP8266 based Sonoff by [iTead Studio](https://www.itead.cc/) and ElectroDragon IoT Relay with Serial, Web and MQTT control allowing 'Over the Air' or OTA firmware updates using Arduino IDE.
Current version is **5.8.0j** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information.
Current version is **5.8.0k** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information.
### ATTENTION All versions

View File

@ -1,4 +1,8 @@
/* 5.8.0j
/* 5.8.0k
* Add support for up to 8 relays (#995)
* Fix Blocked Loop when erasing large flash using command reset 2 (#1002)
*
* 5.8.0j
* Set default altitude to 0 to be used with pressure sensors
* Document flash settings area for future use
* Prepare for 32-bit power control (#995)

View File

@ -92,8 +92,8 @@ struct SYSCFG {
byte free_2E6[2]; // 2E6
power_t power; // 2E8
byte free_2EC[10]; // 2EC
uint16_t pwmvalue[MAX_PWMS]; // 2EC
// byte free_2EC[10]; // 2EC
int16_t altitude; // 2F6 Add since 5.8.0i
uint16_t tele_period; // 2F8
@ -108,8 +108,8 @@ struct SYSCFG {
byte free_342[2]; // 342
unsigned long domoticz_relay_idx[4]; // 344
unsigned long domoticz_key_idx[4]; // 354
unsigned long domoticz_relay_idx[MAX_DOMOTICZ_IDX]; // 344
unsigned long domoticz_key_idx[MAX_DOMOTICZ_IDX]; // 354
unsigned long hlw_pcal; // 364
unsigned long hlw_ucal; // 368
@ -152,13 +152,13 @@ struct SYSCFG {
byte free_3A9[1]; // 3A9
uint16_t ws_wakeup; // 3AA Not used since 5.8.0
char friendlyname[4][33]; // 3AC
char friendlyname[MAX_FRIENDLYNAMES][33]; // 3AC
char switch_topic[33]; // 430
byte free_451[2]; // 451
uint8_t sleep; // 453
uint16_t domoticz_switch_idx[4]; // 454
uint16_t domoticz_switch_idx[MAX_DOMOTICZ_IDX]; // 454
uint16_t domoticz_sensor_idx[12]; // 45C
uint8_t module; // 474
@ -184,13 +184,16 @@ struct SYSCFG {
byte free_4A8[1]; // 4A8
char web_password[33]; // 4A9
uint8_t switchmode[4]; // 4CA
uint8_t switchmode[MAX_SWITCHES]; // 4CA
char ntp_server[3][33]; // 4CE
byte free_531[1]; // 531
uint16_t pulsetime[MAX_PULSETIMERS]; // 532
uint16_t pwmvalue[5]; // 53A
//uint16_t ex_pwmvalue[MAX_PWMS]; // 53A
byte free_542[2]; // 542
uint32_t ip_address[4]; // 544
unsigned long hlw_kWhtotal; // 554
char mqtt_fulltopic[101]; // 558

View File

@ -305,6 +305,7 @@ void CFG_Erase()
}
delay(10);
}
osw_loop();
}
}
@ -731,6 +732,17 @@ void CFG_Delta()
sysCfg.power = sysCfg.ex_power;
sysCfg.altitude = 0;
}
if (sysCfg.version < 0x0508000B) {
for (byte i = 0; i < MAX_GPIO_PIN; i++) { // Move GPIO_LEDs
if ((sysCfg.my_gp.io[i] >= 25) && (sysCfg.my_gp.io[i] <= 32)) { // Was GPIO_LED1
sysCfg.my_gp.io[i] += 23; // Move GPIO_LED1
}
}
for (byte i = 0; i < MAX_PWMS; i++) { // Move pwmvalue and reset additional pulsetimers
sysCfg.pwmvalue[i] = sysCfg.pulsetime[4 +i];
sysCfg.pulsetime[4 +i] = 0;
}
}
sysCfg.version = VERSION;
CFG_Save(1);

View File

@ -28,13 +28,16 @@ typedef unsigned long power_t; // Power (Relay) type
* Defines
\*********************************************************************************************/
#define MAX_RELAYS 4 // Max number of relays
#define MAX_BUTTONS 4 // Max number of buttons or keys
#define MAX_SWITCHES 4 // Max number of switches
// Changes to the following MAX_ defines will impact settings layout
#define MAX_RELAYS 8 // Max number of relays
#define MAX_LEDS 4 // Max number of leds
#define MAX_KEYS 4 // Max number of keys or buttons
#define MAX_SWITCHES 4 // Max number of switches
#define MAX_PWMS 5 // Max number of PWM channels
#define MAX_COUNTERS 4 // Max number of counter sensors
#define MAX_PULSETIMERS 4 // Max number of supported pulse timers
#define MAX_PULSETIMERS 8 // Max number of supported pulse timers
#define MAX_FRIENDLYNAMES 4 // Max number of Friendly names
#define MAX_DOMOTICZ_IDX 4 // Max number of Domoticz device, key and switch indices
#define MODULE SONOFF_BASIC // [Module] Select default model

View File

@ -25,7 +25,7 @@
- Select IDE Tools - Flash Size: "1M (no SPIFFS)"
====================================================*/
#define VERSION 0x0508000A // 5.8.0j
#define VERSION 0x0508000B // 5.8.0k
#include "sonoff.h"
#include "user_config.h"
@ -215,10 +215,10 @@ int blinks = 201; // Number of LED blinks
uint8_t blinkstate = 0; // LED state
uint8_t blockgpio0 = 4; // Block GPIO0 for 4 seconds after poweron to workaround Wemos D1 RTS circuit
uint8_t lastbutton[MAX_BUTTONS] = { NOT_PRESSED, NOT_PRESSED, NOT_PRESSED, NOT_PRESSED }; // Last button states
uint8_t holdbutton[MAX_BUTTONS] = { 0 }; // Timer for button hold
uint8_t multiwindow[MAX_BUTTONS] = { 0 }; // Max time between button presses to record press count
uint8_t multipress[MAX_BUTTONS] = { 0 }; // Number of button presses within multiwindow
uint8_t lastbutton[MAX_KEYS] = { NOT_PRESSED, NOT_PRESSED, NOT_PRESSED, NOT_PRESSED }; // Last button states
uint8_t holdbutton[MAX_KEYS] = { 0 }; // Timer for button hold
uint8_t multiwindow[MAX_KEYS] = { 0 }; // Max time between button presses to record press count
uint8_t multipress[MAX_KEYS] = { 0 }; // Number of button presses within multiwindow
uint8_t lastwallswitch[MAX_SWITCHES]; // Last wall switch states
uint8_t holdwallswitch[MAX_SWITCHES] = { 0 }; // Timer for wallswitch push button hold
@ -367,7 +367,8 @@ void setRelay(power_t rpower)
setLatchingRelay(rpower, 1);
}
else {
for (byte i = 0; i < Maxdevice; i++) {
uint8_t maxdev = (Maxdevice > MAX_RELAYS) ? MAX_RELAYS : Maxdevice;
for (byte i = 0; i < maxdev; i++) {
state = rpower &1;
if (pin[GPIO_REL1 +i] < 99) {
digitalWrite(pin[GPIO_REL1 +i], bitRead(rel_inverted, i) ? !state : state);
@ -1554,13 +1555,7 @@ boolean send_button_power(byte key, byte device, byte state)
if (!key && (device > Maxdevice)) {
device = 1;
}
// snprintf_P(stemp1, sizeof(stemp1), PSTR("%d"), device);
// snprintf_P(scommand, sizeof(scommand), PSTR("POWER%s"), (key || (Maxdevice > 1)) ? stemp1 : "");
// getTopic_P(stopic, 0, key_topic, scommand);
getTopic_P(stopic, 0, key_topic, getPowerDevice(scommand, device, sizeof(scommand), key));
if (9 == state) {
mqtt_data[0] = '\0';
} else {
@ -1991,7 +1986,8 @@ void button_handler()
uint8_t flag = 0;
char scmnd[20];
for (byte i = 0; i < Maxdevice; i++) {
uint8_t maxdev = (Maxdevice > MAX_KEYS) ? MAX_KEYS : Maxdevice;
for (byte i = 0; i < maxdev; i++) {
button = NOT_PRESSED;
butt_present = 0;
@ -2649,7 +2645,7 @@ void GPIO_init()
// }
}
}
for (byte i = 0; i < MAX_BUTTONS; i++) {
for (byte i = 0; i < MAX_KEYS; i++) {
if (pin[GPIO_KEY1 +i] < 99) {
pinMode(pin[GPIO_KEY1 +i], (16 == pin[GPIO_KEY1 +i]) ? INPUT_PULLDOWN_16 : INPUT_PULLUP);
}
@ -2821,10 +2817,13 @@ void setup()
}
// Issue #526
for (byte i = 0; i < Maxdevice; i++) {
if ((pin[GPIO_REL1 +i] < 99) && (digitalRead(pin[GPIO_REL1 +i]) ^ bitRead(rel_inverted, i))) {
bitSet(power, i);
pulse_timer[i] = sysCfg.pulsetime[i];
uint8_t maxdev = (Maxdevice > MAX_RELAYS) ? MAX_RELAYS : Maxdevice;
for (byte i = 0; i < maxdev; i++) {
if (pin[GPIO_REL1 +i] < 99) {
if (digitalRead(pin[GPIO_REL1 +i]) ^ bitRead(rel_inverted, i)) {
bitSet(power, i);
pulse_timer[i] = sysCfg.pulsetime[i]; // MAX_PULSETIMERS must be equal to MAX_RELAYS for this to work here
}
}
}

View File

@ -40,18 +40,18 @@ enum upins_t {
GPIO_REL2,
GPIO_REL3,
GPIO_REL4,
GPIO_REL5,
GPIO_REL6,
GPIO_REL7,
GPIO_REL8,
GPIO_REL1_INV,
GPIO_REL2_INV,
GPIO_REL3_INV,
GPIO_REL4_INV,
GPIO_LED1, // Leds
GPIO_LED2,
GPIO_LED3,
GPIO_LED4,
GPIO_LED1_INV,
GPIO_LED2_INV,
GPIO_LED3_INV,
GPIO_LED4_INV,
GPIO_REL5_INV,
GPIO_REL6_INV,
GPIO_REL7_INV,
GPIO_REL8_INV,
GPIO_PWM1, // RGB Red or C Cold White
GPIO_PWM2, // RGB Green or CW Warm White
GPIO_PWM3, // RGB Blue
@ -67,6 +67,14 @@ enum upins_t {
GPIO_PWM4_INV, // RGBW (Cold) White
GPIO_PWM5_INV, // RGBCW Warm White
GPIO_IRRECV, // IR receiver
GPIO_LED1, // Leds
GPIO_LED2,
GPIO_LED3,
GPIO_LED4,
GPIO_LED1_INV,
GPIO_LED2_INV,
GPIO_LED3_INV,
GPIO_LED4_INV,
GPIO_SENSOR_END };
// Text in webpage Module Parameters and commands GPIOS and GPIO
@ -92,18 +100,18 @@ const char sensors[GPIO_SENSOR_END][9] PROGMEM = {
D_SENSOR_RELAY "2",
D_SENSOR_RELAY "3",
D_SENSOR_RELAY "4",
D_SENSOR_RELAY "1I",
D_SENSOR_RELAY "2I",
D_SENSOR_RELAY "3I",
D_SENSOR_RELAY "4I",
D_SENSOR_LED "1",
D_SENSOR_LED "2",
D_SENSOR_LED "3",
D_SENSOR_LED "4",
D_SENSOR_LED "1I",
D_SENSOR_LED "2I",
D_SENSOR_LED "3I",
D_SENSOR_LED "4I",
D_SENSOR_RELAY "5",
D_SENSOR_RELAY "6",
D_SENSOR_RELAY "7",
D_SENSOR_RELAY "8",
D_SENSOR_RELAY "1i",
D_SENSOR_RELAY "2i",
D_SENSOR_RELAY "3i",
D_SENSOR_RELAY "4i",
D_SENSOR_RELAY "5i",
D_SENSOR_RELAY "6i",
D_SENSOR_RELAY "7i",
D_SENSOR_RELAY "8i",
D_SENSOR_PWM "1",
D_SENSOR_PWM "2",
D_SENSOR_PWM "3",
@ -113,13 +121,21 @@ const char sensors[GPIO_SENSOR_END][9] PROGMEM = {
D_SENSOR_COUNTER "2",
D_SENSOR_COUNTER "3",
D_SENSOR_COUNTER "4",
D_SENSOR_PWM "1I",
D_SENSOR_PWM "2I",
D_SENSOR_PWM "3I",
D_SENSOR_PWM "4I",
D_SENSOR_PWM "5I",
D_SENSOR_IRRECV
};
D_SENSOR_PWM "1i",
D_SENSOR_PWM "2i",
D_SENSOR_PWM "3i",
D_SENSOR_PWM "4i",
D_SENSOR_PWM "5i",
D_SENSOR_IRRECV,
D_SENSOR_LED "1",
D_SENSOR_LED "2",
D_SENSOR_LED "3",
D_SENSOR_LED "4",
D_SENSOR_LED "1i",
D_SENSOR_LED "2i",
D_SENSOR_LED "3i",
D_SENSOR_LED "4i"
};
// Programmer selectable GPIO functionality offset by user selectable GPIOs
enum fpins_t {

View File

@ -456,8 +456,8 @@ void handleRoot()
page += F("<tr>");
for (byte idx = 1; idx <= Maxdevice; idx++) {
snprintf_P(stemp, sizeof(stemp), PSTR(" %d"), idx);
snprintf_P(line, sizeof(line), PSTR("<td style='width:%d%'><button onclick='la(\"?o=%d\");'>" D_BUTTON_TOGGLE "%s</button></td>"),
100 / Maxdevice, idx, (Maxdevice > 1) ? stemp : "");
snprintf_P(line, sizeof(line), PSTR("<td style='width:%d%'><button onclick='la(\"?o=%d\");'>%s%s</button></td>"),
100 / Maxdevice, idx, (Maxdevice < 5) ? D_BUTTON_TOGGLE : "", (Maxdevice > 1) ? stemp : "");
page += line;
}
page += F("</tr></table>");
@ -563,9 +563,11 @@ void handleAjax2()
if (Maxdevice) {
page += FPSTR(HTTP_TABLE100);
page += F("<tr>");
uint8_t fsize = (Maxdevice < 5) ? 70 - (Maxdevice * 8) : 32;
for (byte idx = 1; idx <= Maxdevice; idx++) {
snprintf_P(line, sizeof(line), PSTR("<td style='width:%d%'><div style='text-align:center;font-weight:bold;font-size:%dpx'>%s</div></td>"),
100 / Maxdevice, 70 - (Maxdevice * 8), getStateText(bitRead(power, idx -1)));
snprintf_P(svalue, sizeof(svalue), PSTR("%d"), bitRead(power, idx -1));
snprintf_P(line, sizeof(line), PSTR("<td style='width:%d%'><div style='text-align:center;font-weight:%s;font-size:%dpx'>%s</div></td>"),
100 / Maxdevice, (bitRead(power, idx -1)) ? "bold" : "normal", fsize, (Maxdevice < 5) ? getStateText(bitRead(power, idx -1)) : svalue);
page += line;
}
page += F("</tr></table>");
@ -633,16 +635,24 @@ boolean inModule(byte val, uint8_t *arr)
return true;
}
#endif
if (((val >= GPIO_REL1) && (val <= GPIO_REL4)) || ((val >= GPIO_LED1) && (val <= GPIO_LED4))) {
if ((val >= GPIO_REL1) && (val < GPIO_REL1 + MAX_RELAYS)) {
offset = (GPIO_REL1_INV - GPIO_REL1);
}
if (((val >= GPIO_REL1_INV) && (val <= GPIO_REL4_INV)) || ((val >= GPIO_LED1_INV) && (val <= GPIO_LED4_INV))) {
if ((val >= GPIO_REL1_INV) && (val < GPIO_REL1_INV + MAX_RELAYS)) {
offset = -(GPIO_REL1_INV - GPIO_REL1);
}
if ((val >= GPIO_PWM1) && (val <= GPIO_PWM5)) {
if ((val >= GPIO_LED1) && (val < GPIO_LED1 + MAX_LEDS)) {
offset = (GPIO_LED1_INV - GPIO_LED1);
}
if ((val >= GPIO_LED1_INV) && (val < GPIO_LED1_INV + MAX_LEDS)) {
offset = -(GPIO_LED1_INV - GPIO_LED1);
}
if ((val >= GPIO_PWM1) && (val < GPIO_PWM1 + MAX_PWMS)) {
offset = (GPIO_PWM1_INV - GPIO_PWM1);
}
if ((val >= GPIO_PWM1_INV) && (val <= GPIO_PWM5_INV)) {
if ((val >= GPIO_PWM1_INV) && (val < GPIO_PWM1_INV + MAX_PWMS)) {
offset = -(GPIO_PWM1_INV - GPIO_PWM1);
}
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
@ -697,7 +707,7 @@ void handleModule()
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
if (GPIO_USER == cmodule.gp.io[i]) {
snprintf_P(line, sizeof(line), PSTR("<br/><b>" D_GPIO "%d</b> %s<select id='g%d' name='g%d'></select></br>"),
i, (0==i)? D_SENSOR_BUTTON "1":(1==i)? D_SERIAL_OUT :(3==i)? D_SERIAL_IN :(12==i)? D_SENSOR_RELAY "1":(13==i)? D_SENSOR_LED "1I":(14==i)? D_SENSOR :"", i, i);
i, (0==i)? D_SENSOR_BUTTON "1":(1==i)? D_SERIAL_OUT :(3==i)? D_SERIAL_IN :(12==i)? D_SENSOR_RELAY "1":(13==i)? D_SENSOR_LED "1i":(14==i)? D_SENSOR :"", i, i);
page += line;
snprintf_P(line, sizeof(line), PSTR("sk(%d,%d);"), my_module.gp.io[i], i); // g0 - g16
func += line;
@ -923,7 +933,8 @@ void handleOther()
page.replace(F("{4"), (i == EMUL_NONE) ? F("") : (i == EMUL_WEMO) ? F(" " D_SINGLE_DEVICE) : F(" " D_MULTI_DEVICE));
}
page += F("<br/>");
for (int i = 1; i < Maxdevice; i++) {
uint8_t maxfn = (Maxdevice > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : Maxdevice;
for (byte i = 1; i < maxfn; i++) {
page += FPSTR(HTTP_FORM_OTHER2);
page.replace(F("{1"), String(i +1));
snprintf_P(stemp, sizeof(stemp), PSTR(FRIENDLY_NAME"%d"), i +1);
@ -1499,7 +1510,8 @@ void handleInfo()
page += F("<tr><th>" D_FLASH_WRITE_COUNT "</th><td>"); page += String(sysCfg.saveFlag); page += stopic; page += F("</td></tr>");
page += F("<tr><th>" D_BOOT_COUNT "</th><td>"); page += String(sysCfg.bootcount); page += F("</td></tr>");
page += F("<tr><th>" D_RESTART_REASON "</th><td>"); page += getResetReason(); page += F("</td></tr>");
for (byte i = 0; i < Maxdevice; i++) {
uint8_t maxfn = (Maxdevice > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : Maxdevice;
for (byte i = 0; i < maxfn; i++) {
page += F("<tr><th>" D_FRIENDLY_NAME " ");
page += i +1;
page += F("</th><td>"); page += sysCfg.friendlyname[i]; page += F("</td></tr>");

View File

@ -65,17 +65,15 @@ byte domoticz_update_flag = 1;
void mqtt_publishDomoticzPowerState(byte device)
{
char sdimmer[8];
if ((device < 1) || (device > Maxdevice)) {
device = 1;
}
if (sysCfg.flag.mqtt_enabled && sysCfg.domoticz_relay_idx[device -1]) {
if (sfl_flg) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"idx\":%d,\"nvalue\":%d,\"svalue\":\"%d\"}"),
sysCfg.domoticz_relay_idx[device -1], (power & (1 << (device -1))) ? 1 : 0, sysCfg.led_dimmer);
} else {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"idx\":%d,\"nvalue\":%d,\"svalue\":\"\"}"),
sysCfg.domoticz_relay_idx[device -1], (power & (1 << (device -1))) ? 1 : 0);
}
snprintf_P(sdimmer, sizeof(sdimmer), PSTR("%d"), sysCfg.led_dimmer);
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"idx\":%d,\"nvalue\":%d,\"svalue\":\"%s\"}"),
sysCfg.domoticz_relay_idx[device -1], (power & (1 << (device -1))) ? 1 : 0, (sfl_flg) ? sdimmer : "");
mqtt_publish(domoticz_in_topic);
}
}
@ -108,7 +106,8 @@ void domoticz_setUpdateTimer(uint16_t value)
void domoticz_mqttSubscribe()
{
for (byte i = 0; i < Maxdevice; i++) {
uint8_t maxdev = (Maxdevice > MAX_DOMOTICZ_IDX) ? MAX_DOMOTICZ_IDX : Maxdevice;
for (byte i = 0; i < maxdev; i++) {
if (sysCfg.domoticz_relay_idx[i]) {
domoticz_subscribe = true;
}
@ -170,7 +169,8 @@ boolean domoticz_mqttData(char *topicBuf, uint16_t stopicBuf, char *dataBuf, uin
addLog(LOG_LEVEL_DEBUG_MORE);
if ((idx > 0) && (nvalue >= 0) && (nvalue <= 2)) {
for (byte i = 0; i < Maxdevice; i++) {
uint8_t maxdev = (Maxdevice > MAX_DOMOTICZ_IDX) ? MAX_DOMOTICZ_IDX : Maxdevice;
for (byte i = 0; i < maxdev; i++) {
if (idx == sysCfg.domoticz_relay_idx[i]) {
snprintf_P(stemp1, sizeof(stemp1), PSTR("%d"), i +1);
if (2 == nvalue) {
@ -215,20 +215,20 @@ boolean domoticz_command(const char *type, uint16_t index, char *dataBuf, uint16
uint8_t dmtcz_len = strlen(D_CMND_DOMOTICZ); // Prep for string length change
if (!strncasecmp_P(type, PSTR(D_CMND_DOMOTICZ), dmtcz_len)) { // Prefix
if (!strcasecmp_P(type +dmtcz_len, PSTR(D_CMND_IDX)) && (index > 0) && (index <= Maxdevice)) {
if (!strcasecmp_P(type +dmtcz_len, PSTR(D_CMND_IDX)) && (index > 0) && (index <= MAX_DOMOTICZ_IDX)) {
if (payload >= 0) {
sysCfg.domoticz_relay_idx[index -1] = payload;
restartflag = 2;
}
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_DOMOTICZ D_CMND_IDX "%d\":%d}"), index, sysCfg.domoticz_relay_idx[index -1]);
}
else if (!strcasecmp_P(type +dmtcz_len, PSTR(D_CMND_KEYIDX)) && (index > 0) && (index <= Maxdevice)) {
else if (!strcasecmp_P(type +dmtcz_len, PSTR(D_CMND_KEYIDX)) && (index > 0) && (index <= MAX_DOMOTICZ_IDX)) {
if (payload >= 0) {
sysCfg.domoticz_key_idx[index -1] = payload;
}
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_DOMOTICZ D_CMND_KEYIDX "%d\":%d}"), index, sysCfg.domoticz_key_idx[index -1]);
}
else if (!strcasecmp_P(type +dmtcz_len, PSTR(D_CMND_SWITCHIDX)) && (index > 0) && (index <= Maxdevice)) {
else if (!strcasecmp_P(type +dmtcz_len, PSTR(D_CMND_SWITCHIDX)) && (index > 0) && (index <= MAX_DOMOTICZ_IDX)) {
if (payload >= 0) {
sysCfg.domoticz_switch_idx[index -1] = payload;
}
@ -335,7 +335,7 @@ void handleDomoticz()
String page = FPSTR(HTTP_HEAD);
page.replace(F("{v}"), FPSTR(S_CONFIGURE_DOMOTICZ));
page += FPSTR(HTTP_FORM_DOMOTICZ);
for (int i = 0; i < 4; i++) {
for (int i = 0; i < MAX_DOMOTICZ_IDX; i++) {
if (i < Maxdevice) {
page += FPSTR(HTTP_FORM_DOMOTICZ_RELAY);
page.replace("{2", String((int)sysCfg.domoticz_relay_idx[i]));
@ -366,7 +366,7 @@ void domoticz_saveSettings()
{
char stemp[20];
for (byte i = 0; i < 4; i++) {
for (byte i = 0; i < MAX_DOMOTICZ_IDX; i++) {
snprintf_P(stemp, sizeof(stemp), PSTR("r%d"), i +1);
sysCfg.domoticz_relay_idx[i] = (!strlen(webServer->arg(stemp).c_str())) ? 0 : atoi(webServer->arg(stemp).c_str());
snprintf_P(stemp, sizeof(stemp), PSTR("k%d"), i +1);

View File

@ -474,10 +474,11 @@ void hue_light_status(byte device, String *response)
void hue_global_cfg(String *path)
{
String response;
uint8_t maxhue = (Maxdevice > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : Maxdevice;
path->remove(0,1); // cut leading / to get <id>
response = F("{\"lights\":{\"");
for (uint8_t i = 1; i <= Maxdevice; i++) {
for (uint8_t i = 1; i <= maxhue; i++) {
response += i;
response += F("\":{\"state\":{");
hue_light_status(i, &response);
@ -485,7 +486,7 @@ void hue_global_cfg(String *path)
response += FPSTR(HUE_LIGHTS_STATUS_JSON);
response.replace("{j1}", sysCfg.friendlyname[i-1]);
response.replace("{j2}", hue_deviceId(i));
if (i < Maxdevice) {
if (i < maxhue) {
response += ",\"";
}
}
@ -520,11 +521,12 @@ void hue_lights(String *path)
bool on = false;
bool change = false;
char id[4];
uint8_t maxhue = (Maxdevice > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : Maxdevice;
path->remove(0,path->indexOf("/lights")); // Remove until /lights
if (path->endsWith("/lights")) { // Got /lights
response = "{\"";
for (uint8_t i = 1; i <= Maxdevice; i++) {
for (uint8_t i = 1; i <= maxhue; i++) {
response += i;
response += F("\":{\"state\":{");
hue_light_status(i, &response);
@ -532,7 +534,7 @@ void hue_lights(String *path)
response += FPSTR(HUE_LIGHTS_STATUS_JSON);
response.replace("{j1}", sysCfg.friendlyname[i-1]);
response.replace("{j2}", hue_deviceId(i));
if (i < Maxdevice) {
if (i < maxhue) {
response += ",\"";
}
}
@ -543,7 +545,7 @@ void hue_lights(String *path)
path->remove(0,8); // Remove /lights/
path->remove(path->indexOf("/state")); // Remove /state
device = atoi(path->c_str());
if ((device < 1) || (device > Maxdevice)) {
if ((device < 1) || (device > maxhue)) {
device = 1;
}
if (1 == webServer->args()) {
@ -645,7 +647,7 @@ void hue_lights(String *path)
else if(path->indexOf("/lights/") >= 0) { // Got /lights/ID
path->remove(0,8); // Remove /lights/
device = atoi(path->c_str());
if ((device < 1) || (device > Maxdevice)) {
if ((device < 1) || (device > maxhue)) {
device = 1;
}
response += F("{\"state\":{");
@ -667,11 +669,12 @@ void hue_groups(String *path)
* http://sonoff/api/username/groups?1={"name":"Woonkamer","lights":[],"type":"Room","class":"Living room"})
*/
String response = "{}";
uint8_t maxhue = (Maxdevice > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : Maxdevice;
if (path->endsWith("/0")) {
response = FPSTR(HUE_GROUP0_STATUS_JSON);
String lights = F("\"1\"");
for (uint8_t i = 2; i <= Maxdevice; i++) {
for (uint8_t i = 2; i <= maxhue; i++) {
lights += ",\"" + String(i) + "\"";
}
response.replace("{l1}", lights);