diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index 612fb4f96..daa933601 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -1,6 +1,7 @@ -/* 5.5.2b +/* 5.5.2c * Fix Sonoff Pow intermittent exception 0 * Change Sonoff Pow sending Domoticz telemetry data only + * Add Sonoff B1 support (experimental) * * 5.5.2 20170808 * Extent max number of WS2812 pixels from 256 to 512 (#667) diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index ad7708866..8d99a51f3 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -25,7 +25,7 @@ - Select IDE Tools - Flash Size: "1M (no SPIFFS)" ====================================================*/ -#define VERSION 0x05050202 // 5.5.2b +#define VERSION 0x05050203 // 5.5.2c enum log_t {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL}; enum week_t {Last, First, Second, Third, Fourth}; @@ -303,7 +303,7 @@ uint8_t hlw_flg = 0; // Power monitor configured uint8_t i2c_flg = 0; // I2C configured uint8_t spi_flg = 0; // SPI configured uint8_t pwm_flg = 0; // PWM configured -uint8_t sfl_flg = 0; // Sonoff Led flag (0 = No led, 1 = BN-SZ01, 2 = Sonoff Led) +uint8_t sfl_flg = 0; // Sonoff Led flag (0 = No led, 1 = BN-SZ01, 2 = Sonoff Led, 5 = Sonoff B1) uint8_t pwm_idxoffset = 0; // Allowed PWM command offset (change for Sonoff Led) boolean mDNSbegun = false; @@ -2318,7 +2318,7 @@ void stateloop() button_handler(); switch_handler(); - if (sfl_flg) { // Sonoff BN-SZ01 or Sonoff Led + if (sfl_flg) { // Sonoff B1, led or BN-SZ01 sl_animate(); } @@ -2633,6 +2633,9 @@ void GPIO_init() else if (SONOFF_LED == sysCfg.module) { sfl_flg = 2; } + else if (SONOFF_B1 == sysCfg.module) { + sfl_flg = 5; + } else { Maxdevice = 0; for (byte i = 0; i < 4; i++) { @@ -2660,20 +2663,9 @@ void GPIO_init() } } - if (sfl_flg) { // Sonoff Led or BN-SZ01 - pwm_idxoffset = sfl_flg; // 1 for BN-SZ01, 2 for Sonoff Led - pin[GPIO_WS2812] = 99; // I do not allow both Sonoff Led AND WS2812 led - if (!my_module.gp.io[4]) { - pinMode(4, OUTPUT); // Stop floating outputs - digitalWrite(4, LOW); - } - if (!my_module.gp.io[5]) { - pinMode(5, OUTPUT); // Stop floating outputs - digitalWrite(5, LOW); - } - if (!my_module.gp.io[14]) { - pinMode(14, OUTPUT); // Stop floating outputs - digitalWrite(14, LOW); + if (sfl_flg) { // Sonoff B1, Led or BN-SZ01 + if (sfl_flg < 5) { + pwm_idxoffset = sfl_flg; // 1 for BN-SZ01, 2 for Sonoff Led } sl_init(); } diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index 1d4400bc3..7ceea9263 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -118,6 +118,8 @@ enum fpins_t { GPIO_HLW_CF, // HLW8012 CF power (Sonoff Pow) GPIO_ADC0, // ADC GPIO_USER, // User configurable + GPIO_DI, // my9231 PWM input + GPIO_DCKI, // my9231 CLK input GPIO_MAX }; /********************************************************************************************/ @@ -149,6 +151,7 @@ enum module_t { SONOFF_4CHPRO, HUAFAN_SS, SONOFF_BRIDGE, + SONOFF_B1, MAXMODULE }; /********************************************************************************************/ @@ -489,6 +492,22 @@ const mytmplt modules[MAXMODULE] PROGMEM = { 0, GPIO_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) 0, 0, 0, 0 + }, + { "Sonoff B1", // Sonoff B1 (ESP8285 - my9231) + GPIO_KEY1, // GPIO00 Pad + GPIO_USER, // GPIO01 Serial RXD and Optional sensor pad + GPIO_USER, // GPIO02 Optional sensor SDA pad + GPIO_USER, // GPIO03 Serial TXD and Optional sensor pad + 0, 0, + 0, 0, 0, // Flash connection + 0, 0, + 0, // Flash connection + GPIO_DI, // GPIO12 my9231 DI + 0, + GPIO_DCKI, // GPIO14 my9231 DCKI + 0, + 0, 0 } + }; diff --git a/sonoff/xdrv_snfled.ino b/sonoff/xdrv_snfled.ino index 9f5acdf0c..d44139255 100644 --- a/sonoff/xdrv_snfled.ino +++ b/sonoff/xdrv_snfled.ino @@ -18,7 +18,7 @@ */ /*********************************************************************************************\ - * Sonoff Led and BN-SZ01 + * Sonoff B1, Led and BN-SZ01 \*********************************************************************************************/ uint8_t ledTable[] = { @@ -39,9 +39,9 @@ uint8_t ledTable[] = { 184,186,189,191,193,195,197,199,201,204,206,208,210,212,215,217, 219,221,224,226,228,231,233,235,238,240,243,245,248,250,253,255 }; -uint8_t sl_dcolor[2]; -uint8_t sl_tcolor[2]; -uint8_t sl_lcolor[2]; +uint8_t sl_dcolor[5]; +uint8_t sl_tcolor[5]; +uint8_t sl_lcolor[5]; uint8_t sl_power; uint8_t sl_any; @@ -49,54 +49,201 @@ uint8_t sl_wakeupActive = 0; uint8_t sl_wakeupDimmer = 0; uint16_t sl_wakeupCntr = 0; -/********************************************************************************************/ +/*********************************************************************************************\ + * Sonoff B1 based on OpenLight https://github.com/icamgo/noduino-sdk +\*********************************************************************************************/ -void sl_setDim(uint8_t myDimmer) +uint8_t sl_last_command; + +void sl_di_pulse(byte times) { - if ((1 == sfl_flg) && (100 == myDimmer)) { - myDimmer = 99; // BN-SZ01 starts flickering at dimmer = 100 + for (byte i = 0; i < times; i++) { + digitalWrite(pin[GPIO_DI], HIGH); + digitalWrite(pin[GPIO_DI], LOW); } - float newDim = 100 / (float)myDimmer; - float fmyCld = (float)sysCfg.led_color[0] / newDim; - sl_dcolor[0] = (uint8_t)fmyCld; - float fmyWrm = (float)sysCfg.led_color[1] / newDim; - sl_dcolor[1] = (uint8_t)fmyWrm; } +void sl_dcki_pulse(byte times) +{ + for (byte i = 0; i < times; i++) { + digitalWrite(pin[GPIO_DCKI], HIGH); + digitalWrite(pin[GPIO_DCKI], LOW); + } +} + +void sl_send_command(uint8_t command) +{ + uint8_t command_data; + + sl_last_command = command; + +// ets_intr_lock(); + delayMicroseconds(12); // TStop > 12us. + // Send 12 DI pulse, after 6 pulse's falling edge store duty data, and 12 + // pulse's rising edge convert to command mode. + sl_di_pulse(12); + delayMicroseconds(12); // Delay >12us, begin send CMD data + + for (byte n = 0; n < 2; n++) { // Send CMD data + command_data = command; + + for (byte i = 0; i < 4; i++) { // Send byte + digitalWrite(pin[GPIO_DCKI], LOW); + if (command_data & 0x80) { + digitalWrite(pin[GPIO_DI], HIGH); + } else { + digitalWrite(pin[GPIO_DI], LOW); + } + +// digitalWrite(pin[GPIO_DI], (command_data & 0x80)); + + digitalWrite(pin[GPIO_DCKI], HIGH); + command_data = command_data << 1; + if (command_data & 0x80) { + digitalWrite(pin[GPIO_DI], HIGH); + } else { + digitalWrite(pin[GPIO_DI], LOW); + } + digitalWrite(pin[GPIO_DCKI], LOW); + digitalWrite(pin[GPIO_DI], LOW); + command_data = command_data << 1; + } + } + + delayMicroseconds(12); // TStart > 12us. Delay 12 us. + // Send 16 DI pulse, at 14 pulse's falling edge store CMD data, and + // at 16 pulse's falling edge convert to duty mode. + sl_di_pulse(16); + delayMicroseconds(12); // TStop > 12us. +// ets_intr_unlock(); +} + +void sl_send_duty(uint16_t duty_r, uint16_t duty_g, uint16_t duty_b, uint16_t duty_w, uint16_t duty_c) +{ + uint8_t bit_length = 8; + uint16_t duty_current = 0; + + uint16_t duty[8] = { duty_r, duty_g, duty_b, 0, duty_w, duty_c, 0, 0 }; // Definition for RGBWC channels + +// ets_intr_lock(); + delayMicroseconds(12); // TStop > 12us. + + for (byte channel = 0; channel < 8; channel++) { // RGB0WC00 8CH + duty_current = duty[channel]; // RGBWC Channel + for (byte i = 0; i < bit_length / 2; i++) { // Send 8bit/12bit/14bit/16bit Data + digitalWrite(pin[GPIO_DCKI], LOW); + if (duty_current & (0x01 << (bit_length - 1))) { + digitalWrite(pin[GPIO_DI], HIGH); + } else { + digitalWrite(pin[GPIO_DI], LOW); + } + digitalWrite(pin[GPIO_DCKI], HIGH); + duty_current = duty_current << 1; + if (duty_current & (0x01 << (bit_length - 1))) { + digitalWrite(pin[GPIO_DI], HIGH); + } else { + digitalWrite(pin[GPIO_DI], LOW); + } + digitalWrite(pin[GPIO_DCKI], LOW); + digitalWrite(pin[GPIO_DI], LOW); + duty_current = duty_current << 1; + } + } + + delayMicroseconds(12); // TStart > 12us. Ready for send DI pulse. + sl_di_pulse(8); // Send 8 DI pulse. After 8 pulse falling edge, store old data. + delayMicroseconds(12); // TStop > 12us. +// ets_intr_unlock(); +} + +/********************************************************************************************/ + void sl_init(void) { - sysCfg.pwmvalue[0] = 0; // We use dimmer / led_color - if (2 == sfl_flg) { - sysCfg.pwmvalue[1] = 0; // We use led_color + pin[GPIO_WS2812] = 99; // I do not allow both Sonoff Led AND WS2812 led + if (sfl_flg < 5) { + if (!my_module.gp.io[4]) { + pinMode(4, OUTPUT); // Stop floating outputs + digitalWrite(4, LOW); + } + if (!my_module.gp.io[5]) { + pinMode(5, OUTPUT); // Stop floating outputs + digitalWrite(5, LOW); + } + if (!my_module.gp.io[14]) { + pinMode(14, OUTPUT); // Stop floating outputs + digitalWrite(14, LOW); + } + sysCfg.pwmvalue[0] = 0; // We use dimmer / led_color + if (2 == sfl_flg) { + sysCfg.pwmvalue[1] = 0; // We use led_color + } + } else { + pinMode(pin[GPIO_DI], OUTPUT); + pinMode(pin[GPIO_DCKI], OUTPUT); + digitalWrite(pin[GPIO_DI], LOW); + digitalWrite(pin[GPIO_DCKI], LOW); + + // Clear all duty register + sl_dcki_pulse(64); + sl_send_command(0x18); // ONE_SHOT_DISABLE, REACTION_FAST, BIT_WIDTH_8, FREQUENCY_DIVIDE_1, SCATTER_APDM + + // Test + sl_send_duty(16, 0, 0, 0, 0); // Red } + sl_power = 0; sl_any = 0; sl_wakeupActive = 0; } -void sl_setColor(char* colstr) +void sl_setDim(uint8_t myDimmer) { - uint8_t my_color[2]; - char *p; - - uint16_t temp = strtol(colstr, &p, 16); - my_color[1] = temp & 0xFF; // Warm - temp >>= 8; - my_color[0] = temp & 0xFF; // Cold - if (temp < my_color[1]) { - temp = my_color[1]; + float temp; + + if ((1 == sfl_flg) && (100 == myDimmer)) { + myDimmer = 99; // BN-SZ01 starts flickering at dimmer = 100 } - float mDim = (float)temp / 2.55; + float newDim = 100 / (float)myDimmer; + for (byte i = 0; i < sfl_flg; i++) { + temp = (float)sysCfg.led_color[i] / newDim; + sl_dcolor[i] = (uint8_t)temp; + } +} + +void sl_setColor() +{ + uint8_t highest = 0; + float temp; + + for (byte i = 0; i < sfl_flg; i++) { + if (highest < sl_dcolor[i]) { + highest = sl_dcolor[i]; + } + } + float mDim = (float)highest / 2.55; sysCfg.led_dimmer[0] = (uint8_t)mDim; float newDim = 100 / mDim; - float fmyCold = (float)my_color[0] * newDim; - float fmyWarm = (float)my_color[1] * newDim; - sysCfg.led_color[0] = (uint8_t)fmyCold; - sysCfg.led_color[1] = (uint8_t)fmyWarm; + for (byte i = 0; i < sfl_flg; i++) { + temp = (float)sl_dcolor[i] * newDim; + sysCfg.led_color[i] = (uint8_t)temp; + } +} + +char* sl_getColor(char* scolor) +{ + sl_setDim(sysCfg.led_dimmer[0]); + scolor[0] = '\0'; + for (byte i = 0; i < sfl_flg; i++) { + snprintf_P(scolor, 11, PSTR("%s%02X"), scolor, sl_dcolor[i]); + } + return scolor; } void sl_prepPower(char *svalue, uint16_t ssvalue) { + char scolor[11]; + // do_cmnd_power(index, (sysCfg.led_dimmer[0]>0)); if (sysCfg.led_dimmer[0] && !(power&1)) { do_cmnd_power(1, 7); // No publishPowerState @@ -107,12 +254,9 @@ void sl_prepPower(char *svalue, uint16_t ssvalue) #ifdef USE_DOMOTICZ mqtt_publishDomoticzPowerState(1); #endif // USE_DOMOTICZ - sl_setDim(sysCfg.led_dimmer[0]); - if (2 == sfl_flg) { - uint16_t color = (uint16_t)sl_dcolor[0] << 8; - color += (uint16_t)sl_dcolor[1]; - snprintf_P(svalue, ssvalue, PSTR("{\"POWER\":\"%s\", \"Dimmer\":%d, \"Color\":\"%04X\"}"), - getStateText(power &1), sysCfg.led_dimmer[0], color); + if (sfl_flg > 1) { + snprintf_P(svalue, ssvalue, PSTR("{\"POWER\":\"%s\", \"Dimmer\":%d, \"Color\":\"%s\"}"), + getStateText(power &1), sysCfg.led_dimmer[0], sl_getColor(scolor)); } else { snprintf_P(svalue, ssvalue, PSTR("{\"POWER\":\"%s\", \"Dimmer\":%d}"), getStateText(power &1), sysCfg.led_dimmer[0]); @@ -133,40 +277,38 @@ void sl_animate() // {"Wakeup":"Done"} char svalue[32]; // was MESSZ uint8_t fadeValue; + uint8_t cur_col[5]; if (0 == sl_power) { // Power Off - sl_tcolor[0] = 0; - sl_tcolor[1] = 0; + for (byte i = 0; i < sfl_flg; i++) { + sl_tcolor[i] = 0; + } } else { if (!sl_wakeupActive) { // Power On sl_setDim(sysCfg.led_dimmer[0]); if (0 == sysCfg.led_fade) { - sl_tcolor[0] = sl_dcolor[0]; - sl_tcolor[1] = sl_dcolor[1]; - } else { - if (sl_tcolor[0] != sl_dcolor[0]) { - if (sl_tcolor[0] < sl_dcolor[0]) { - sl_tcolor[0] += ((sl_dcolor[0] - sl_tcolor[0]) >> sysCfg.led_speed) +1; - } - if (sl_tcolor[0] > sl_dcolor[0]) { - sl_tcolor[0] -= ((sl_tcolor[0] - sl_dcolor[0]) >> sysCfg.led_speed) +1; - } + for (byte i = 0; i < sfl_flg; i++) { + sl_tcolor[i] = sl_dcolor[i]; } - if ((2 == sfl_flg) && (sl_tcolor[1] != sl_dcolor[1])) { - if (sl_tcolor[1] < sl_dcolor[1]) { - sl_tcolor[1] += ((sl_dcolor[1] - sl_tcolor[1]) >> sysCfg.led_speed) +1; - } - if (sl_tcolor[1] > sl_dcolor[1]) { - sl_tcolor[1] -= ((sl_tcolor[1] - sl_dcolor[1]) >> sysCfg.led_speed) +1; + } else { + for (byte i = 0; i < sfl_flg; i++) { + if (sl_tcolor[i] != sl_dcolor[i]) { + if (sl_tcolor[i] < sl_dcolor[i]) { + sl_tcolor[i] += ((sl_dcolor[i] - sl_tcolor[i]) >> sysCfg.led_speed) +1; + } + if (sl_tcolor[i] > sl_dcolor[i]) { + sl_tcolor[i] -= ((sl_tcolor[i] - sl_dcolor[i]) >> sysCfg.led_speed) +1; + } } } } } else { // Power On using wake up duration if (2 == sl_wakeupActive) { sl_wakeupActive = 1; - sl_tcolor[0] = 0; - sl_tcolor[1] = 0; + for (byte i = 0; i < sfl_flg; i++) { + sl_tcolor[i] = 0; + } sl_wakeupCntr = 0; sl_wakeupDimmer = 0; } @@ -176,8 +318,9 @@ void sl_animate() sl_wakeupDimmer++; if (sl_wakeupDimmer <= sysCfg.led_dimmer[0]) { sl_setDim(sl_wakeupDimmer); - sl_tcolor[0] = sl_dcolor[0]; - sl_tcolor[1] = sl_dcolor[1]; + for (byte i = 0; i < sfl_flg; i++) { + sl_tcolor[i] = sl_dcolor[i]; + } } else { snprintf_P(svalue, sizeof(svalue), PSTR("{\"Wakeup\":\"Done\"}")); mqtt_publish_topic_P(2, PSTR("WAKEUP"), svalue); @@ -186,15 +329,25 @@ void sl_animate() } } } - if ((sl_lcolor[0] != sl_tcolor[0]) || (sl_lcolor[1] != sl_tcolor[1]) || sl_any) { + for (byte i = 0; i < sfl_flg; i++) { + if (sl_lcolor[i] != sl_tcolor[i]) { + sl_any = 1; + } + } + if (sl_any) { sl_any = 0; - sl_lcolor[0] = sl_tcolor[0]; - sl_lcolor[1] = sl_tcolor[1]; for (byte i = 0; i < sfl_flg; i++) { - if (pin[GPIO_PWM1 +i] < 99) { - analogWrite(pin[GPIO_PWM1 +i], ((sysCfg.led_table) ? ledTable[sl_lcolor[i]] : sl_lcolor[i]) * (PWM_RANGE / 255)); + sl_lcolor[i] = sl_tcolor[i]; + cur_col[i] = (sysCfg.led_table) ? ledTable[sl_lcolor[i]] : sl_lcolor[i]; + if (sfl_flg < 5) { + if (pin[GPIO_PWM1 +i] < 99) { + analogWrite(pin[GPIO_PWM1 +i], cur_col[i] * (PWM_RANGE / 255)); + } } } + if (5 == sfl_flg) { + sl_send_duty(cur_col[0], cur_col[1], cur_col[2], cur_col[3], cur_col[4]); + } } } @@ -202,28 +355,135 @@ void sl_animate() * Hue support \*********************************************************************************************/ +void sl_rgb2hsb(float *hue, float *sat, float *bri) +{ + sl_setDim(sysCfg.led_dimmer[0]); + + float r = (float)(sl_dcolor[0] / 255.0f); + float g = (float)(sl_dcolor[1] / 255.0f); + float b = (float)(sl_dcolor[2] / 255.0f); + + float max = fmax(fmax(r, g), b); + float min = fmin(fmin(r, g), b); + + *bri = (max + min) / 2.0f; + + if (max == min) { + *hue = *sat = 0.0f; + } else { + float d = max - min; + *sat = (*bri > 0.5f) ? d / (2.0f - max - min) : d / (max + min); + + if (r > g && r > b) { + *hue = (g - b) / d + (g < b ? 6.0f : 0.0f); + } + else if (g > b) { + *hue = (b - r) / d + 2.0f; + } + else { + *hue = (r - g) / d + 4.0f; + } + *hue /= 6.0f; + } +} + +float sl_hue2rgb(float p, float q, float t) +{ + if (t < 0.0f) { + t += 1.0f; + } + if (t > 1.0f) { + t -= 1.0f; + } + if (t < 1.0f / 6.0f) { + return p + (q - p) * 6.0f * t; + } + if (t < 1.0f / 2.0f) { + return q; + } + if (t < 2.0f / 3.0f) { + return p + (q - p) * (2.0f / 3.0f - t) * 6.0f; + } + return p; +} + +void sl_hsb2rgb(float hue, float sat, float bri) +{ + float r; + float g; + float b; + + if (sat == 0.0f) { + r = g = b = bri; + } else { + float q = bri < 0.5f ? bri * (1.0f + sat) : bri + sat - bri * sat; + float p = 2.0f * bri - q; + r = sl_hue2rgb(p, q, hue + 1.0f / 3.0f); + g = sl_hue2rgb(p, q, hue); + b = sl_hue2rgb(p, q, hue - 1.0f / 3.0f); + } + sl_dcolor[0] = (uint8_t)(r * 255 + 0.5f); + sl_dcolor[1] = (uint8_t)(g * 255 + 0.5f); + sl_dcolor[2] = (uint8_t)(b * 255 + 0.5f); + sl_setColor(); +} + +/********************************************************************************************/ + void sl_replaceHSB(String *response) { - response->replace("{h}", "0"); - response->replace("{s}", "0"); - response->replace("{b}", String((uint8_t)(2.54f * (float)sysCfg.led_dimmer[0]))); + float hue; + float sat; + float bri; + + if (5 == sfl_flg) { + sl_rgb2hsb(&hue, &sat, &bri); + response->replace("{h}", String((uint16_t)(65535.0f * hue))); + response->replace("{s}", String((uint8_t)(254.0f * sat))); + response->replace("{b}", String((uint8_t)(254.0f * bri))); + } else { + response->replace("{h}", "0"); + response->replace("{s}", "0"); + response->replace("{b}", String((uint8_t)(2.54f * (float)sysCfg.led_dimmer[0]))); + } } void sl_getHSB(float *hue, float *sat, float *bri) { - *hue = 0; - *sat = 0; - *bri = (2.54f * (float)sysCfg.led_dimmer[0]); + if (5 == sfl_flg) { + sl_rgb2hsb(hue, sat, bri); + } else { + *hue = 0; + *sat = 0; + *bri = (2.54f * (float)sysCfg.led_dimmer[0]); + } } void sl_setHSB(float hue, float sat, float bri) { char svalue[MESSZ]; - - uint8_t tmp = (uint8_t)(bri * 100); - sysCfg.led_dimmer[0] = tmp; - sl_prepPower(svalue, sizeof(svalue)); - mqtt_publish_topic_P(5, "DIMMER", svalue); + +/* + char log[LOGSZ]; + char stemp1[10]; + char stemp2[10]; + char stemp3[10]; + dtostrf(hue, 1, 3, stemp1); + dtostrf(sat, 1, 3, stemp2); + dtostrf(bri, 1, 3, stemp3); + snprintf_P(log, sizeof(log), PSTR("LED: Hue %s, Sat %s, Bri %s"), stemp1, stemp2, stemp3); + addLog(LOG_LEVEL_DEBUG, log); +*/ + if (5 == sfl_flg) { + sl_hsb2rgb(hue, sat, bri); + sl_prepPower(svalue, sizeof(svalue)); + mqtt_publish_topic_P(5, "COLOR", svalue); + } else { + uint8_t tmp = (uint8_t)(bri * 100); + sysCfg.led_dimmer[0] = tmp; + sl_prepPower(svalue, sizeof(svalue)); + mqtt_publish_topic_P(5, "DIMMER", svalue); + } } /*********************************************************************************************\ @@ -234,18 +494,19 @@ boolean sl_command(char *type, uint16_t index, char *dataBufUc, uint16_t data_le { boolean serviced = true; boolean coldim = false; + char scolor[11]; + char *p; - if ((2 == sfl_flg) && !strcmp_P(type,PSTR("COLOR"))) { - uint8_t my_color[2]; - char *p; - if (4 == data_len) { - sl_setColor(dataBufUc); + if ((sfl_flg > 1) && !strcmp_P(type,PSTR("COLOR"))) { + if ((2 * sfl_flg) == data_len) { + for (byte i = 0; i < sfl_flg; i++) { + strlcpy(scolor, dataBufUc + (i *2), 3); + sl_dcolor[i] = (uint8_t)strtol(scolor, &p, 16); + } + sl_setColor(); coldim = true; } else { - sl_setDim(sysCfg.led_dimmer[0]); - uint16_t color = (uint16_t)sl_dcolor[0] << 8; - color += (uint16_t)sl_dcolor[1]; - snprintf_P(svalue, ssvalue, PSTR("{\"Color\":\"%04X\"}"), color); + snprintf_P(svalue, ssvalue, PSTR("{\"Color\":\"%s\"}"), sl_getColor(scolor)); } } else if (!strcmp_P(type,PSTR("DIMMER"))) {