mirror of https://github.com/arendst/Tasmota.git
v5.2.3
5.2.3 20170630 * Change Sonoff Led color conversion code * Fix SetOption12 handling * Simplify auto configuration upgrade * Add option Upgrade <version_number> to only upgrade to any higher version (Old PR #213) * Change FallbackTopic to cmnd/<MQTTClient>/<command> <parameter> bypassing FullTopic and Prefix (#538)
This commit is contained in:
parent
e914053041
commit
ee883bdcb8
|
@ -1,7 +1,7 @@
|
||||||
## Sonoff-Tasmota
|
## 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.
|
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.2.2** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information.
|
Current version is **5.2.3** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information.
|
||||||
|
|
||||||
### **** ATTENTION Version 5.x.x specific information ****
|
### **** ATTENTION Version 5.x.x specific information ****
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
/* 5.2.2 20170625
|
/* 5.2.3 20170630
|
||||||
|
* Change Sonoff Led color conversion code
|
||||||
|
* Fix SetOption12 handling
|
||||||
|
* Simplify auto configuration upgrade
|
||||||
|
* Add option Upgrade <version_number> to only upgrade to any higher version (Old PR #213)
|
||||||
|
* Change FallbackTopic to cmnd/<MQTTClient>/<command> <parameter> bypassing FullTopic and Prefix (#538)
|
||||||
|
*
|
||||||
|
* 5.2.2 20170625
|
||||||
* Add configuration SaveAddress to Status 1 and Information Page
|
* Add configuration SaveAddress to Status 1 and Information Page
|
||||||
* Change Sonoff Led Color conversion from AtoH to strtol
|
* Change Sonoff Led Color conversion from AtoH to strtol
|
||||||
* Fix possible wrong uploads due to configuration overwrites (#542)
|
* Fix possible wrong uploads due to configuration overwrites (#542)
|
||||||
|
|
|
@ -200,15 +200,26 @@ uint32_t CFG_Address()
|
||||||
return _cfgLocation * SPI_FLASH_SEC_SIZE;
|
return _cfgLocation * SPI_FLASH_SEC_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFG_Save(byte no_rotate)
|
void CFG_Save(byte rotate)
|
||||||
{
|
{
|
||||||
|
/* Save configuration in eeprom or one of 7 slots below
|
||||||
|
*
|
||||||
|
* rotate 0 = Save in next flash slot
|
||||||
|
* rotate 1 = Save only in eeprom flash slot until SetOption12 0 or restart
|
||||||
|
* rotate 2 = Save in eeprom flash slot and continue depending on stop_flash_rotate
|
||||||
|
* stop_flash_rotate 0 = Allow flash slot rotation (SetOption12 0)
|
||||||
|
* stop_flash_rotate 1 = Allow only eeprom flash slot use (SetOption12 1)
|
||||||
|
*/
|
||||||
char log[LOGSZ];
|
char log[LOGSZ];
|
||||||
|
|
||||||
#ifndef BE_MINIMAL
|
#ifndef BE_MINIMAL
|
||||||
if ((getHash() != _cfgHash) || no_rotate) {
|
if ((getHash() != _cfgHash) || rotate) {
|
||||||
if (no_rotate) {
|
if (1 == rotate) {
|
||||||
stop_flash_rotate = 1; // Disable flash rotate from now on
|
stop_flash_rotate = 1; // Disable flash rotate from now on
|
||||||
}
|
}
|
||||||
|
if (2 == rotate) {
|
||||||
|
_cfgLocation = CFG_LOCATION +1;
|
||||||
|
}
|
||||||
if (stop_flash_rotate) {
|
if (stop_flash_rotate) {
|
||||||
_cfgLocation = CFG_LOCATION;
|
_cfgLocation = CFG_LOCATION;
|
||||||
} else {
|
} else {
|
||||||
|
@ -222,7 +233,7 @@ void CFG_Save(byte no_rotate)
|
||||||
spi_flash_erase_sector(_cfgLocation);
|
spi_flash_erase_sector(_cfgLocation);
|
||||||
spi_flash_write(_cfgLocation * SPI_FLASH_SEC_SIZE, (uint32*)&sysCfg, sizeof(SYSCFG));
|
spi_flash_write(_cfgLocation * SPI_FLASH_SEC_SIZE, (uint32*)&sysCfg, sizeof(SYSCFG));
|
||||||
interrupts();
|
interrupts();
|
||||||
if (!stop_flash_rotate && no_rotate) {
|
if (!stop_flash_rotate && rotate) {
|
||||||
for (byte i = 1; i < CFG_ROTATES; i++) {
|
for (byte i = 1; i < CFG_ROTATES; i++) {
|
||||||
noInterrupts();
|
noInterrupts();
|
||||||
spi_flash_erase_sector(_cfgLocation -i); // Delete previous configurations by resetting to 0xFF
|
spi_flash_erase_sector(_cfgLocation -i); // Delete previous configurations by resetting to 0xFF
|
||||||
|
@ -240,6 +251,8 @@ void CFG_Save(byte no_rotate)
|
||||||
|
|
||||||
void CFG_Load()
|
void CFG_Load()
|
||||||
{
|
{
|
||||||
|
/* Load configuration from eeprom or one of 7 slots below if first load does not stop_flash_rotate
|
||||||
|
*/
|
||||||
char log[LOGSZ];
|
char log[LOGSZ];
|
||||||
|
|
||||||
struct SYSCFGH {
|
struct SYSCFGH {
|
||||||
|
@ -258,7 +271,7 @@ void CFG_Load()
|
||||||
// snprintf_P(log, sizeof(log), PSTR("Cnfg: Check at %X with count %d and holder %X"), _cfgLocation -1, _sysCfgH.saveFlag, _sysCfgH.cfg_holder);
|
// snprintf_P(log, sizeof(log), PSTR("Cnfg: Check at %X with count %d and holder %X"), _cfgLocation -1, _sysCfgH.saveFlag, _sysCfgH.cfg_holder);
|
||||||
// addLog(LOG_LEVEL_DEBUG, log);
|
// addLog(LOG_LEVEL_DEBUG, log);
|
||||||
|
|
||||||
if (sysCfg.flag.stop_flash_rotate || (sysCfg.cfg_holder != _sysCfgH.cfg_holder) || (sysCfg.saveFlag > _sysCfgH.saveFlag)) {
|
if (((sysCfg.version > 0x05000200) && sysCfg.flag.stop_flash_rotate) || (sysCfg.cfg_holder != _sysCfgH.cfg_holder) || (sysCfg.saveFlag > _sysCfgH.saveFlag)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
delay(1);
|
delay(1);
|
||||||
|
@ -271,8 +284,9 @@ void CFG_Load()
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
if (sysCfg.cfg_holder != CFG_HOLDER) {
|
if (sysCfg.cfg_holder != CFG_HOLDER) {
|
||||||
|
/*
|
||||||
// Auto upgrade
|
// Auto upgrade
|
||||||
if ((sysCfg.version < 0x04020000) || (sysCfg.version > 0x06000000)) {
|
if ((sysCfg.version < 0x04020000) || (sysCfg.version > VERSION)) {
|
||||||
noInterrupts();
|
noInterrupts();
|
||||||
spi_flash_read((CFG_LOCATION_3) * SPI_FLASH_SEC_SIZE, (uint32*)&sysCfg, sizeof(SYSCFG));
|
spi_flash_read((CFG_LOCATION_3) * SPI_FLASH_SEC_SIZE, (uint32*)&sysCfg, sizeof(SYSCFG));
|
||||||
spi_flash_read((CFG_LOCATION_3 + 1) * SPI_FLASH_SEC_SIZE, (uint32*)&_sysCfgH, sizeof(SYSCFGH));
|
spi_flash_read((CFG_LOCATION_3 + 1) * SPI_FLASH_SEC_SIZE, (uint32*)&_sysCfgH, sizeof(SYSCFGH));
|
||||||
|
@ -287,6 +301,17 @@ void CFG_Load()
|
||||||
} else {
|
} else {
|
||||||
CFG_Default();
|
CFG_Default();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
// Auto upgrade
|
||||||
|
noInterrupts();
|
||||||
|
spi_flash_read((CFG_LOCATION_3) * SPI_FLASH_SEC_SIZE, (uint32*)&sysCfg, sizeof(SYSCFG));
|
||||||
|
spi_flash_read((CFG_LOCATION_3 + 1) * SPI_FLASH_SEC_SIZE, (uint32*)&_sysCfgH, sizeof(SYSCFGH));
|
||||||
|
if (sysCfg.saveFlag < _sysCfgH.saveFlag)
|
||||||
|
spi_flash_read((CFG_LOCATION_3 + 1) * SPI_FLASH_SEC_SIZE, (uint32*)&sysCfg, sizeof(SYSCFG));
|
||||||
|
interrupts();
|
||||||
|
if ((sysCfg.cfg_holder != CFG_HOLDER) || (sysCfg.version >= 0x04020000)) {
|
||||||
|
CFG_Default();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_cfgHash = getHash();
|
_cfgHash = getHash();
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
- Select IDE Tools - Flash size: "1M (no SPIFFS)"
|
- Select IDE Tools - Flash size: "1M (no SPIFFS)"
|
||||||
====================================================*/
|
====================================================*/
|
||||||
|
|
||||||
#define VERSION 0x05020200 // 5.2.2
|
#define VERSION 0x05020300 // 5.2.3
|
||||||
|
|
||||||
enum log_t {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL};
|
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};
|
enum week_t {Last, First, Second, Third, Fourth};
|
||||||
|
@ -230,6 +230,7 @@ char Version[16]; // Version string from VERSION define
|
||||||
char Hostname[33]; // Composed Wifi hostname
|
char Hostname[33]; // Composed Wifi hostname
|
||||||
char MQTTClient[33]; // Composed MQTT Clientname
|
char MQTTClient[33]; // Composed MQTT Clientname
|
||||||
uint8_t mqttcounter = 0; // MQTT connection retry counter
|
uint8_t mqttcounter = 0; // MQTT connection retry counter
|
||||||
|
uint8_t fallbacktopic = 0; // Use Topic or FallbackTopic
|
||||||
unsigned long timerxs = 0; // State loop timer
|
unsigned long timerxs = 0; // State loop timer
|
||||||
int state = 0; // State per second flag
|
int state = 0; // State per second flag
|
||||||
int mqttflag = 2; // MQTT connection messages flag
|
int mqttflag = 2; // MQTT connection messages flag
|
||||||
|
@ -328,19 +329,26 @@ void getClient(char* output, const char* input, byte size)
|
||||||
void getTopic_P(char *stopic, byte prefix, char *topic, const char* subtopic)
|
void getTopic_P(char *stopic, byte prefix, char *topic, const char* subtopic)
|
||||||
{
|
{
|
||||||
char romram[CMDSZ];
|
char romram[CMDSZ];
|
||||||
|
String fulltopic;
|
||||||
|
|
||||||
snprintf_P(romram, sizeof(romram), subtopic);
|
snprintf_P(romram, sizeof(romram), subtopic);
|
||||||
String fulltopic = sysCfg.mqtt_fulltopic;
|
if (fallbacktopic) {
|
||||||
if ((0 == prefix) && (-1 == fulltopic.indexOf(F(MQTT_TOKEN_PREFIX)))) {
|
fulltopic = FPSTR(PREFIXES[prefix]);
|
||||||
fulltopic += F("/" MQTT_TOKEN_PREFIX); // Need prefix for commands to handle mqtt topic loops
|
fulltopic += F("/");
|
||||||
}
|
fulltopic += MQTTClient;
|
||||||
for (byte i = 0; i < 3; i++) {
|
} else {
|
||||||
if ('\0' == sysCfg.mqtt_prefix[i][0]) {
|
fulltopic = sysCfg.mqtt_fulltopic;
|
||||||
snprintf_P(sysCfg.mqtt_prefix[i], sizeof(sysCfg.mqtt_prefix[i]), PREFIXES[i]);
|
if ((0 == prefix) && (-1 == fulltopic.indexOf(F(MQTT_TOKEN_PREFIX)))) {
|
||||||
|
fulltopic += F("/" MQTT_TOKEN_PREFIX); // Need prefix for commands to handle mqtt topic loops
|
||||||
}
|
}
|
||||||
|
for (byte i = 0; i < 3; i++) {
|
||||||
|
if ('\0' == sysCfg.mqtt_prefix[i][0]) {
|
||||||
|
snprintf_P(sysCfg.mqtt_prefix[i], sizeof(sysCfg.mqtt_prefix[i]), PREFIXES[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fulltopic.replace(F(MQTT_TOKEN_PREFIX), sysCfg.mqtt_prefix[prefix]);
|
||||||
|
fulltopic.replace(F(MQTT_TOKEN_TOPIC), topic);
|
||||||
}
|
}
|
||||||
fulltopic.replace(F(MQTT_TOKEN_PREFIX), sysCfg.mqtt_prefix[prefix]);
|
|
||||||
fulltopic.replace(F(MQTT_TOKEN_TOPIC), topic);
|
|
||||||
fulltopic.replace(F("#"), "");
|
fulltopic.replace(F("#"), "");
|
||||||
fulltopic.replace(F("//"), "/");
|
fulltopic.replace(F("//"), "/");
|
||||||
if (!fulltopic.endsWith("/")) {
|
if (!fulltopic.endsWith("/")) {
|
||||||
|
@ -536,7 +544,9 @@ void mqtt_connected()
|
||||||
getTopic_P(stopic, 0, sysCfg.mqtt_grptopic, PSTR("#"));
|
getTopic_P(stopic, 0, sysCfg.mqtt_grptopic, PSTR("#"));
|
||||||
mqttClient.subscribe(stopic);
|
mqttClient.subscribe(stopic);
|
||||||
mqttClient.loop(); // Solve LmacRxBlk:1 messages
|
mqttClient.loop(); // Solve LmacRxBlk:1 messages
|
||||||
|
fallbacktopic = 1;
|
||||||
getTopic_P(stopic, 0, MQTTClient, PSTR("#"));
|
getTopic_P(stopic, 0, MQTTClient, PSTR("#"));
|
||||||
|
fallbacktopic = 0;
|
||||||
mqttClient.subscribe(stopic);
|
mqttClient.subscribe(stopic);
|
||||||
mqttClient.loop(); // Solve LmacRxBlk:1 messages
|
mqttClient.loop(); // Solve LmacRxBlk:1 messages
|
||||||
}
|
}
|
||||||
|
@ -883,6 +893,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
|
||||||
#endif // USE_DOMOTICZ
|
#endif // USE_DOMOTICZ
|
||||||
|
|
||||||
grpflg = (strstr(topicBuf, sysCfg.mqtt_grptopic) != NULL);
|
grpflg = (strstr(topicBuf, sysCfg.mqtt_grptopic) != NULL);
|
||||||
|
fallbacktopic = (strstr(topicBuf, MQTTClient) != NULL);
|
||||||
type = strrchr(topicBuf, '/') +1; // Last part of received topic is always the command (type)
|
type = strrchr(topicBuf, '/') +1; // Last part of received topic is always the command (type)
|
||||||
|
|
||||||
index = 1;
|
index = 1;
|
||||||
|
@ -948,6 +959,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
|
||||||
payload = 9;
|
payload = 9;
|
||||||
}
|
}
|
||||||
do_cmnd_power(index, payload);
|
do_cmnd_power(index, payload);
|
||||||
|
fallbacktopic = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (!strcmp_P(type,PSTR("STATUS"))) {
|
else if (!strcmp_P(type,PSTR("STATUS"))) {
|
||||||
|
@ -955,6 +967,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
|
||||||
payload = 99;
|
payload = 99;
|
||||||
}
|
}
|
||||||
publish_status(payload);
|
publish_status(payload);
|
||||||
|
fallbacktopic = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if ((sysCfg.module != MOTOR) && !strcmp_P(type,PSTR("POWERONSTATE"))) {
|
else if ((sysCfg.module != MOTOR) && !strcmp_P(type,PSTR("POWERONSTATE"))) {
|
||||||
|
@ -1035,7 +1048,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
|
||||||
}
|
}
|
||||||
if (12 == index) { // stop_flash_rotate
|
if (12 == index) { // stop_flash_rotate
|
||||||
stop_flash_rotate = payload;
|
stop_flash_rotate = payload;
|
||||||
CFG_Save(stop_flash_rotate);
|
CFG_Save(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1275,11 +1288,15 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
|
||||||
snprintf_P(svalue, sizeof(svalue), PSTR("{\"FlashMode\":%d}"), ESP.getFlashChipMode());
|
snprintf_P(svalue, sizeof(svalue), PSTR("{\"FlashMode\":%d}"), ESP.getFlashChipMode());
|
||||||
}
|
}
|
||||||
else if (!strcmp_P(type,PSTR("UPGRADE")) || !strcmp_P(type,PSTR("UPLOAD"))) {
|
else if (!strcmp_P(type,PSTR("UPGRADE")) || !strcmp_P(type,PSTR("UPLOAD"))) {
|
||||||
if (1 == payload) {
|
// Check if the payload is numerically 1, and had no trailing chars.
|
||||||
|
// e.g. "1foo" or "1.2.3" could fool us.
|
||||||
|
// Check if the version we have been asked to upgrade to is higher than our current version.
|
||||||
|
// We also need at least 3 chars to make a valid version number string.
|
||||||
|
if (((1 == data_len) && (1 == payload)) || ((data_len >= 3) && newerVersion(dataBuf))) {
|
||||||
otaflag = 3;
|
otaflag = 3;
|
||||||
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Upgrade\":\"Version %s from %s\"}"), Version, sysCfg.otaUrl);
|
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Upgrade\":\"Version %s from %s\"}"), Version, sysCfg.otaUrl);
|
||||||
} else {
|
} else {
|
||||||
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Upgrade\":\"Option 1 to upgrade\"}"));
|
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Upgrade\":\"Option 1 or >%s to upgrade\"}"), Version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!strcmp_P(type,PSTR("OTAURL"))) {
|
else if (!strcmp_P(type,PSTR("OTAURL"))) {
|
||||||
|
@ -1573,6 +1590,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
|
||||||
if (svalue[0] != '\0') {
|
if (svalue[0] != '\0') {
|
||||||
mqtt_publish_topic_P(5, type, svalue);
|
mqtt_publish_topic_P(5, type, svalue);
|
||||||
}
|
}
|
||||||
|
fallbacktopic = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
|
|
|
@ -189,6 +189,50 @@ void mqttfy(byte option, char* str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Function to parse & check if version_str is newer than our currently installed version.
|
||||||
|
bool newerVersion(char* version_str)
|
||||||
|
{
|
||||||
|
uint32_t version = 0;
|
||||||
|
uint8_t i = 0;
|
||||||
|
char *str_ptr;
|
||||||
|
char* version_dup = strdup(version_str); // Duplicate the version_str as strtok_r will modify it.
|
||||||
|
|
||||||
|
if (!version_dup) {
|
||||||
|
return false; // Bail if we can't duplicate. Assume bad.
|
||||||
|
}
|
||||||
|
// Loop through the version string, splitting on '.' seperators.
|
||||||
|
for (char *str = strtok_r(version_dup, ".", &str_ptr); str && i < sizeof(VERSION); str = strtok_r(NULL, ".", &str_ptr), i++) {
|
||||||
|
int field = atoi(str);
|
||||||
|
// The fields in a version string can only range from 0-255.
|
||||||
|
if ((field < 0) || (field > 255)) {
|
||||||
|
free(version_dup);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Shuffle the accumulated bytes across, and add the new byte.
|
||||||
|
version = (version << 8) + field;
|
||||||
|
// Check alpha delimiter after 1.2.3 only
|
||||||
|
if ((2 == i) && isalpha(str[strlen(str)-1])) {
|
||||||
|
field = str[strlen(str)-1] & 0x1f;
|
||||||
|
version = (version << 8) + field;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(version_dup); // We no longer need this.
|
||||||
|
// A version string should have 2-4 fields. e.g. 1.2, 1.2.3, or 1.2.3a (= 1.2.3.1).
|
||||||
|
// If not, then don't consider it a valid version string.
|
||||||
|
if ((i < 2) || (i > sizeof(VERSION))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Keep shifting the parsed version until we hit the maximum number of tokens.
|
||||||
|
// VERSION stores the major number of the version in the most significant byte of the uint32_t.
|
||||||
|
while (i < sizeof(VERSION)) {
|
||||||
|
version <<= 8;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
// Now we should have a fully constructed version number in uint32_t form.
|
||||||
|
return (version > VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Wifi
|
* Wifi
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
|
@ -152,19 +152,15 @@ boolean sl_command(char *type, uint16_t index, char *dataBufUc, uint16_t data_le
|
||||||
{
|
{
|
||||||
boolean serviced = true;
|
boolean serviced = true;
|
||||||
boolean coldim = false;
|
boolean coldim = false;
|
||||||
char *p;
|
|
||||||
|
|
||||||
if (!strcmp_P(type,PSTR("COLOR"))) {
|
if (!strcmp_P(type,PSTR("COLOR"))) {
|
||||||
uint8_t my_color[5];
|
uint8_t my_color[2];
|
||||||
|
char *p;
|
||||||
if (4 == data_len) {
|
if (4 == data_len) {
|
||||||
char ccold[3], cwarm[3];
|
uint16_t temp = strtol(dataBufUc, &p, 16);
|
||||||
memcpy(ccold, dataBufUc, 2);
|
my_color[1] = temp & 0xFF; // Warm
|
||||||
ccold[2] = '\0';
|
temp >>= 8;
|
||||||
memcpy(cwarm, dataBufUc + 2, 2);
|
my_color[0] = temp & 0xFF; // Cold
|
||||||
cwarm[2] = '\0';
|
|
||||||
my_color[0] = strtol(ccold, &p, 16);
|
|
||||||
my_color[1] = strtol(cwarm, &p, 16);
|
|
||||||
uint16_t temp = my_color[0];
|
|
||||||
if (temp < my_color[1]) {
|
if (temp < my_color[1]) {
|
||||||
temp = my_color[1];
|
temp = my_color[1];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue