mirror of https://github.com/arendst/Tasmota.git
v5.12.0h - Add HSBColor and Channel commands
5.12.0h * Add PWM status to command State if PWM enabled (#2203) * Add command HSBColor Hue,Sat,Bri (#1642, #2203) * Add command Channel 0..100 to control dimmer value for individual color channels (#2111, #2203)
This commit is contained in:
parent
2ba4d6fb47
commit
2c4b8a4a3b
|
@ -1,6 +1,9 @@
|
|||
/* 5.12.0h
|
||||
* Add support for Software Serial bridge using commands SerialDelimiter, SBaudrate and SSerialSend. Supports 8N1 and text only (#2190)
|
||||
* Add support for Hardware Serial bridge using commands SerialDelimiter, Baudrate and SerialSend. Supports 8N1 and text only (#2182)
|
||||
* Add PWM status to command State if PWM enabled (#2203)
|
||||
* Add command HSBColor Hue,Sat,Bri (#1642, #2203)
|
||||
* Add command Channel 0..100 to control dimmer value for individual color channels (#2111, #2203)
|
||||
*
|
||||
* 5.12.0f
|
||||
* Add compile time support for WS2812 BRG and RBG led configurations to be defined in user_config.h (#1690)
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
#define D_JSON_GATEWAY "Gateway"
|
||||
#define D_JSON_HEAPSIZE "Heap"
|
||||
#define D_JSON_HIGH "High"
|
||||
#define D_JSON_HSBCOLOR "HSBColor"
|
||||
#define D_JSON_HUMIDITY "Humidity"
|
||||
#define D_JSON_I2CSCAN_DEVICES_FOUND_AT "Device(s) found at"
|
||||
#define D_JSON_I2CSCAN_UNKNOWN_ERROR_AT "Unknown error at"
|
||||
|
@ -247,9 +248,11 @@
|
|||
#define D_CMND_EXCEPTION "Exception"
|
||||
|
||||
// Commands xdrv_01_light.ino
|
||||
#define D_CMND_CHANNEL "Channel"
|
||||
#define D_CMND_COLOR "Color"
|
||||
#define D_CMND_COLORTEMPERATURE "CT"
|
||||
#define D_CMND_DIMMER "Dimmer"
|
||||
#define D_CMND_HSBCOLOR "HSBColor"
|
||||
#define D_CMND_LED "Led"
|
||||
#define D_CMND_LEDTABLE "LedTable"
|
||||
#define D_CMND_FADE "Fade"
|
||||
|
@ -483,4 +486,4 @@ const char S_INFORMATION[] PROGMEM = D_INFORMATION;
|
|||
const char S_RESTART[] PROGMEM = D_RESTART;
|
||||
#endif // USE_WEBSERVER
|
||||
|
||||
#endif // _I18N_H_
|
||||
#endif // _I18N_H_
|
||||
|
|
|
@ -737,15 +737,9 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
|
|||
Settings.pwm_value[index -1] = payload;
|
||||
analogWrite(pin[GPIO_PWM1 + index -1], bitRead(pwm_inverted, index -1) ? Settings.pwm_range - payload : payload);
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_PWM "\":{"));
|
||||
bool first = true;
|
||||
for (byte i = 0; i < MAX_PWMS; i++) {
|
||||
if (pin[GPIO_PWM1 + i] < 99) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_PWM "%d\":%d"), mqtt_data, first ? "" : ",", i+1, Settings.pwm_value[i]);
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}}"),mqtt_data);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{"));
|
||||
MqttShowPWMState(); // Render the PWM status to MQTT
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
||||
}
|
||||
else if (CMND_PWMFREQUENCY == command_code) {
|
||||
if ((1 == payload) || ((payload >= 100) && (payload <= 4000))) {
|
||||
|
@ -1327,6 +1321,19 @@ void PublishStatus(uint8_t payload)
|
|||
|
||||
}
|
||||
|
||||
void MqttShowPWMState()
|
||||
{
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"" D_CMND_PWM "\":{"), mqtt_data);
|
||||
bool first = true;
|
||||
for (byte i = 0; i < MAX_PWMS; i++) {
|
||||
if (pin[GPIO_PWM1 + i] < 99) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_PWM "%d\":%d"), mqtt_data, first ? "" : ",", i+1, Settings.pwm_value[i]);
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
||||
}
|
||||
|
||||
void MqttShowState()
|
||||
{
|
||||
char stemp1[33];
|
||||
|
@ -1345,6 +1352,11 @@ void MqttShowState()
|
|||
}
|
||||
}
|
||||
|
||||
if (pwm_present) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,"), mqtt_data);
|
||||
MqttShowPWMState();
|
||||
}
|
||||
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_JSON_WIFI "\":{\"" D_JSON_AP "\":%d,\"" D_JSON_SSID "\":\"%s\",\"" D_JSON_RSSI "\":%d,\"" D_JSON_APMAC_ADDRESS "\":\"%s\"}}"),
|
||||
mqtt_data, Settings.sta_active +1, Settings.sta_ssid[Settings.sta_active], WifiGetRssiAsQuality(WiFi.RSSI()), WiFi.BSSIDstr().c_str());
|
||||
}
|
||||
|
|
|
@ -223,7 +223,7 @@ char* Unescape(char* buffer, uint16_t* size)
|
|||
case 'f': che = '\f'; break; // 0C Formfeed
|
||||
case 'n': che = '\n'; break; // 0A Linefeed (Newline)
|
||||
case 'r': che = '\r'; break; // 0D Carriage return
|
||||
// case 's': che = ' '; break; // 20 Space
|
||||
case 's': che = ' '; break; // 20 Space
|
||||
case 't': che = '\t'; break; // 09 Horizontal tab
|
||||
case 'v': che = '\v'; break; // 0B Vertical tab
|
||||
// case '?': che = '\?'; break; // 3F Question mark
|
||||
|
|
|
@ -55,10 +55,12 @@
|
|||
|
||||
enum LightCommands {
|
||||
CMND_COLOR, CMND_COLORTEMPERATURE, CMND_DIMMER, CMND_LED, CMND_LEDTABLE, CMND_FADE,
|
||||
CMND_PIXELS, CMND_ROTATION, CMND_SCHEME, CMND_SPEED, CMND_WAKEUP, CMND_WAKEUPDURATION, CMND_WIDTH, CMND_UNDOCA };
|
||||
CMND_PIXELS, CMND_ROTATION, CMND_SCHEME, CMND_SPEED, CMND_WAKEUP, CMND_WAKEUPDURATION,
|
||||
CMND_WIDTH, CMND_CHANNEL, CMND_HSBCOLOR, CMND_UNDOCA };
|
||||
const char kLightCommands[] PROGMEM =
|
||||
D_CMND_COLOR "|" D_CMND_COLORTEMPERATURE "|" D_CMND_DIMMER "|" D_CMND_LED "|" D_CMND_LEDTABLE "|" D_CMND_FADE "|"
|
||||
D_CMND_PIXELS "|" D_CMND_ROTATION "|" D_CMND_SCHEME "|" D_CMND_SPEED "|" D_CMND_WAKEUP "|" D_CMND_WAKEUPDURATION "|" D_CMND_WIDTH "|UNDOCA" ;
|
||||
D_CMND_PIXELS "|" D_CMND_ROTATION "|" D_CMND_SCHEME "|" D_CMND_SPEED "|" D_CMND_WAKEUP "|" D_CMND_WAKEUPDURATION "|"
|
||||
D_CMND_WIDTH "|" D_CMND_CHANNEL "|" D_CMND_HSBCOLOR "|UNDOCA" ;
|
||||
|
||||
struct LRgbColor {
|
||||
uint8_t R, G, B;
|
||||
|
@ -535,6 +537,8 @@ void LightState(uint8_t append)
|
|||
{
|
||||
char scolor[25];
|
||||
char scommand[33];
|
||||
float hsb[3];
|
||||
int16_t h,s,b;
|
||||
|
||||
if (append) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,"), mqtt_data);
|
||||
|
@ -546,6 +550,15 @@ void LightState(uint8_t append)
|
|||
mqtt_data, scommand, GetStateText(light_power), Settings.light_dimmer);
|
||||
if (light_subtype > LST_SINGLE) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_COLOR "\":\"%s\""), mqtt_data, LightGetColor(0, scolor));
|
||||
|
||||
// Add status for HSB
|
||||
LightGetHsb(&hsb[0],&hsb[1],&hsb[2]);
|
||||
// Scale these percentages up to the numbers expected byt he client
|
||||
h = round(hsb[0] * 360);
|
||||
s = round(hsb[1] * 100);
|
||||
b = round(hsb[2] * 100);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_HSBCOLOR "\":\"%d,%d,%d\""), mqtt_data, h,s,b);
|
||||
|
||||
}
|
||||
if ((LST_COLDWARM == light_subtype) || (LST_RGBWC == light_subtype)) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_COLORTEMPERATURE "\":%d"), mqtt_data, LightGetColorTemp());
|
||||
|
@ -1053,6 +1066,48 @@ boolean LightCommand()
|
|||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, XdrvMailbox.index, scolor);
|
||||
}
|
||||
}
|
||||
else if ((CMND_CHANNEL == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= light_subtype ) ) {
|
||||
// Set "Channel" directly - this allows Color and Direct PWM control to coexist
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) {
|
||||
uint8_t level = XdrvMailbox.payload;
|
||||
light_current_color[XdrvMailbox.index-1] = round(level * 2.55);
|
||||
LightSetColor();
|
||||
coldim = true;
|
||||
}
|
||||
snprintf_P(scolor, 25, PSTR("%d"), round(light_current_color[XdrvMailbox.index -1] / 2.55));
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, XdrvMailbox.index, scolor);
|
||||
}
|
||||
else if ((CMND_HSBCOLOR == command_code) && ( light_subtype >= LST_RGB)) {
|
||||
// Implement method to "direct set" color by HSB (HSB is passed comma separated, 0<H<360 0<S<100 0<B<100 )
|
||||
uint16_t HSB[3];
|
||||
bool validHSB = true;
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
char *substr;
|
||||
|
||||
if (0 == i) {
|
||||
substr = strtok(XdrvMailbox.data, ",");
|
||||
} else {
|
||||
substr = strtok(NULL, ",");
|
||||
}
|
||||
if (substr != NULL) {
|
||||
HSB[i] = atoi(substr);
|
||||
} else {
|
||||
validHSB = false;
|
||||
}
|
||||
}
|
||||
if (validHSB) {
|
||||
// Translate to fractional elements as required by LightHsbToRgb
|
||||
// Keep the results <=1 in the event someone passes something
|
||||
// out of range.
|
||||
LightSetHsb(( (HSB[0]>360) ? (HSB[0] % 360) : HSB[0] ) /360.0,
|
||||
( (HSB[1]>100) ? (HSB[1] % 100) : HSB[1] ) /100.0,
|
||||
( (HSB[2]>100) ? (HSB[2] % 100) : HSB[2] ) /100.0,
|
||||
0);
|
||||
} else {
|
||||
LightState(0);
|
||||
}
|
||||
}
|
||||
#ifdef USE_WS2812 // ***********************************************************************
|
||||
else if ((CMND_LED == command_code) && (LT_WS2812 == light_type) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= Settings.light_pixels)) {
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
|
|
Loading…
Reference in New Issue