mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-28 13:16:32 +00:00
commit
1d86a607a2
@ -1,4 +1,5 @@
|
|||||||
/* 6.1.1c
|
/* 6.1.1c
|
||||||
|
* Add rule triggers Wifi#Connected and Wifi#Disconnected (#3359)
|
||||||
* Fix unsecure main webpage update
|
* Fix unsecure main webpage update
|
||||||
* Add Turkish language file (#3332)
|
* Add Turkish language file (#3332)
|
||||||
* Fix command TimeDst/TimeStd invalid JSON (#3322)
|
* Fix command TimeDst/TimeStd invalid JSON (#3322)
|
||||||
|
@ -48,7 +48,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
|
|||||||
uint32_t not_power_linked : 1; // bit 20 (v5.11.1f)
|
uint32_t not_power_linked : 1; // bit 20 (v5.11.1f)
|
||||||
uint32_t no_power_on_check : 1; // bit 21 (v5.11.1i)
|
uint32_t no_power_on_check : 1; // bit 21 (v5.11.1i)
|
||||||
uint32_t mqtt_serial : 1; // bit 22 (v5.12.0f)
|
uint32_t mqtt_serial : 1; // bit 22 (v5.12.0f)
|
||||||
uint32_t rules_enabled : 1; // bit 23 (v5.12.0j) - free since v5.14.0b
|
uint32_t mqtt_serial_raw : 1; // bit 23 (vTDB)
|
||||||
uint32_t rules_once : 1; // bit 24 (v5.12.0k) - free since v5.14.0b
|
uint32_t rules_once : 1; // bit 24 (v5.12.0k) - free since v5.14.0b
|
||||||
uint32_t knx_enabled : 1; // bit 25 (v5.12.0l) KNX
|
uint32_t knx_enabled : 1; // bit 25 (v5.12.0l) KNX
|
||||||
uint32_t device_index_enable : 1; // bit 26 (v5.13.1a)
|
uint32_t device_index_enable : 1; // bit 26 (v5.13.1a)
|
||||||
@ -370,7 +370,7 @@ struct XDRVMAILBOX {
|
|||||||
char *data;
|
char *data;
|
||||||
} XdrvMailbox;
|
} XdrvMailbox;
|
||||||
|
|
||||||
#define MAX_RULES_FLAG 5 // Number of bits used in RulesBitfield (tricky I know...)
|
#define MAX_RULES_FLAG 7 // Number of bits used in RulesBitfield (tricky I know...)
|
||||||
typedef union { // Restricted by MISRA-C Rule 18.4 but so usefull...
|
typedef union { // Restricted by MISRA-C Rule 18.4 but so usefull...
|
||||||
uint16_t data; // Allow bit manipulation
|
uint16_t data; // Allow bit manipulation
|
||||||
struct {
|
struct {
|
||||||
@ -379,8 +379,8 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
|
|||||||
uint16_t time_set : 1;
|
uint16_t time_set : 1;
|
||||||
uint16_t mqtt_connected : 1;
|
uint16_t mqtt_connected : 1;
|
||||||
uint16_t mqtt_disconnected : 1;
|
uint16_t mqtt_disconnected : 1;
|
||||||
uint16_t spare05 : 1;
|
uint16_t wifi_connected : 1;
|
||||||
uint16_t spare06 : 1;
|
uint16_t wifi_disconnected : 1;
|
||||||
uint16_t spare07 : 1;
|
uint16_t spare07 : 1;
|
||||||
uint16_t spare08 : 1;
|
uint16_t spare08 : 1;
|
||||||
uint16_t spare09 : 1;
|
uint16_t spare09 : 1;
|
||||||
|
@ -756,7 +756,7 @@ void SettingsDelta()
|
|||||||
}
|
}
|
||||||
if (Settings.version < 0x050E0002) {
|
if (Settings.version < 0x050E0002) {
|
||||||
for (byte i = 1; i < MAX_RULE_SETS; i++) { Settings.rules[i][0] = '\0'; }
|
for (byte i = 1; i < MAX_RULE_SETS; i++) { Settings.rules[i][0] = '\0'; }
|
||||||
Settings.rule_enabled = Settings.flag.rules_enabled;
|
Settings.rule_enabled = Settings.flag.mqtt_serial_raw;
|
||||||
Settings.rule_once = Settings.flag.rules_once;
|
Settings.rule_once = Settings.flag.rules_once;
|
||||||
}
|
}
|
||||||
if (Settings.version < 0x06000000) {
|
if (Settings.version < 0x06000000) {
|
||||||
@ -778,7 +778,7 @@ void SettingsDelta()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Settings.version < 0x06000003) {
|
if (Settings.version < 0x06000003) {
|
||||||
Settings.flag.rules_enabled = 0;
|
Settings.flag.mqtt_serial_raw = 0;
|
||||||
Settings.flag.rules_once = 0;
|
Settings.flag.rules_once = 0;
|
||||||
Settings.flag3.data = 0;
|
Settings.flag3.data = 0;
|
||||||
}
|
}
|
||||||
|
@ -915,15 +915,19 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
|
|||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.baudrate * 1200);
|
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.baudrate * 1200);
|
||||||
}
|
}
|
||||||
else if ((CMND_SERIALSEND == command_code) && (index > 0) && (index <= 3)) {
|
else if ((CMND_SERIALSEND == command_code) && (index > 0) && (index <= 4)) {
|
||||||
SetSeriallog(LOG_LEVEL_NONE);
|
SetSeriallog(LOG_LEVEL_NONE);
|
||||||
Settings.flag.mqtt_serial = 1;
|
Settings.flag.mqtt_serial = 1;
|
||||||
|
Settings.flag.mqtt_serial_raw = (4 == index)?1:0;
|
||||||
if (data_len > 0) {
|
if (data_len > 0) {
|
||||||
if (1 == index) {
|
if (1 == index) {
|
||||||
Serial.printf("%s\n", dataBuf);
|
Serial.printf("%s\n", dataBuf);
|
||||||
}
|
}
|
||||||
else if (2 == index) {
|
else if (2 == index || 4 == index) {
|
||||||
Serial.printf("%s", dataBuf);
|
for (int i=0; i<data_len; i++)
|
||||||
|
{
|
||||||
|
Serial.write(dataBuf[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (3 == index) {
|
else if (3 == index) {
|
||||||
uint16_t dat_len = data_len;
|
uint16_t dat_len = data_len;
|
||||||
@ -2176,7 +2180,7 @@ void SerialInput()
|
|||||||
#endif // USE_ENERGY_SENSOR
|
#endif // USE_ENERGY_SENSOR
|
||||||
/*-------------------------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
if (serial_in_byte > 127) { // binary data...
|
if (serial_in_byte > 127 && !Settings.flag.mqtt_serial_raw) { // binary data...
|
||||||
serial_in_byte_counter = 0;
|
serial_in_byte_counter = 0;
|
||||||
Serial.flush();
|
Serial.flush();
|
||||||
return;
|
return;
|
||||||
@ -2190,8 +2194,9 @@ void SerialInput()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (serial_in_byte) {
|
if (serial_in_byte || Settings.flag.mqtt_serial_raw) {
|
||||||
if ((serial_in_byte_counter < INPUT_BUFFER_SIZE -1) && (serial_in_byte != Settings.serial_delimiter)) { // add char to string if it still fits
|
if ((serial_in_byte_counter < INPUT_BUFFER_SIZE -1) &&
|
||||||
|
((serial_in_byte != Settings.serial_delimiter) || Settings.flag.mqtt_serial_raw)) { // add char to string if it still fits
|
||||||
serial_in_buffer[serial_in_byte_counter++] = serial_in_byte;
|
serial_in_buffer[serial_in_byte_counter++] = serial_in_byte;
|
||||||
serial_polling_window = millis();
|
serial_polling_window = millis();
|
||||||
} else {
|
} else {
|
||||||
@ -2231,7 +2236,15 @@ void SerialInput()
|
|||||||
|
|
||||||
if (Settings.flag.mqtt_serial && serial_in_byte_counter && (millis() > (serial_polling_window + SERIAL_POLLING))) {
|
if (Settings.flag.mqtt_serial && serial_in_byte_counter && (millis() > (serial_polling_window + SERIAL_POLLING))) {
|
||||||
serial_in_buffer[serial_in_byte_counter] = 0; // serial data completed
|
serial_in_buffer[serial_in_byte_counter] = 0; // serial data completed
|
||||||
|
if (!Settings.flag.mqtt_serial_raw) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_SERIALRECEIVED "\":\"%s\"}"), serial_in_buffer);
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_SERIALRECEIVED "\":\"%s\"}"), serial_in_buffer);
|
||||||
|
} else {
|
||||||
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_SERIALRECEIVED "\":\""));
|
||||||
|
for (int i=0; i<serial_in_byte_counter; i++) {
|
||||||
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%02x"), mqtt_data, serial_in_buffer[i]);
|
||||||
|
}
|
||||||
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"}"), mqtt_data);
|
||||||
|
}
|
||||||
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_SERIALRECEIVED));
|
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_SERIALRECEIVED));
|
||||||
// XdrvRulesProcess();
|
// XdrvRulesProcess();
|
||||||
serial_in_byte_counter = 0;
|
serial_in_byte_counter = 0;
|
||||||
|
@ -1096,10 +1096,22 @@ void WifiBegin(uint8_t flag)
|
|||||||
AddLog(LOG_LEVEL_INFO);
|
AddLog(LOG_LEVEL_INFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WifiState(uint8_t state)
|
||||||
|
{
|
||||||
|
if (state == global_state.wifi_down) {
|
||||||
|
if (state) {
|
||||||
|
rules_flag.wifi_connected = 1;
|
||||||
|
} else {
|
||||||
|
rules_flag.wifi_disconnected = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
global_state.wifi_down = state ^1;
|
||||||
|
}
|
||||||
|
|
||||||
void WifiCheckIp()
|
void WifiCheckIp()
|
||||||
{
|
{
|
||||||
if ((WL_CONNECTED == WiFi.status()) && (static_cast<uint32_t>(WiFi.localIP()) != 0)) {
|
if ((WL_CONNECTED == WiFi.status()) && (static_cast<uint32_t>(WiFi.localIP()) != 0)) {
|
||||||
global_state.wifi_down = 0;
|
WifiState(1);
|
||||||
wifi_counter = WIFI_CHECK_SEC;
|
wifi_counter = WIFI_CHECK_SEC;
|
||||||
wifi_retry = wifi_retry_init;
|
wifi_retry = wifi_retry_init;
|
||||||
AddLog_P((wifi_status != WL_CONNECTED) ? LOG_LEVEL_INFO : LOG_LEVEL_DEBUG_MORE, S_LOG_WIFI, PSTR(D_CONNECTED));
|
AddLog_P((wifi_status != WL_CONNECTED) ? LOG_LEVEL_INFO : LOG_LEVEL_DEBUG_MORE, S_LOG_WIFI, PSTR(D_CONNECTED));
|
||||||
@ -1111,7 +1123,7 @@ void WifiCheckIp()
|
|||||||
}
|
}
|
||||||
wifi_status = WL_CONNECTED;
|
wifi_status = WL_CONNECTED;
|
||||||
} else {
|
} else {
|
||||||
global_state.wifi_down = 1;
|
WifiState(0);
|
||||||
uint8_t wifi_config_tool = Settings.sta_config;
|
uint8_t wifi_config_tool = Settings.sta_config;
|
||||||
wifi_status = WiFi.status();
|
wifi_status = WiFi.status();
|
||||||
switch (wifi_status) {
|
switch (wifi_status) {
|
||||||
@ -1222,7 +1234,7 @@ void WifiCheck(uint8_t param)
|
|||||||
WifiCheckIp();
|
WifiCheckIp();
|
||||||
}
|
}
|
||||||
if ((WL_CONNECTED == WiFi.status()) && (static_cast<uint32_t>(WiFi.localIP()) != 0) && !wifi_config_type) {
|
if ((WL_CONNECTED == WiFi.status()) && (static_cast<uint32_t>(WiFi.localIP()) != 0) && !wifi_config_type) {
|
||||||
global_state.wifi_down = 0;
|
WifiState(1);
|
||||||
#ifdef BE_MINIMAL
|
#ifdef BE_MINIMAL
|
||||||
if (1 == RtcSettings.ota_loader) {
|
if (1 == RtcSettings.ota_loader) {
|
||||||
RtcSettings.ota_loader = 0;
|
RtcSettings.ota_loader = 0;
|
||||||
@ -1258,7 +1270,7 @@ void WifiCheck(uint8_t param)
|
|||||||
}
|
}
|
||||||
#endif // USE_KNX
|
#endif // USE_KNX
|
||||||
} else {
|
} else {
|
||||||
global_state.wifi_down = 1;
|
WifiState(0);
|
||||||
#if defined(USE_WEBSERVER) && defined(USE_EMULATION)
|
#if defined(USE_WEBSERVER) && defined(USE_EMULATION)
|
||||||
UdpDisconnect();
|
UdpDisconnect();
|
||||||
#endif // USE_EMULATION
|
#endif // USE_EMULATION
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
uint8_t *efm8bb1_update = NULL;
|
uint8_t *efm8bb1_update = NULL;
|
||||||
#endif // USE_RF_FLASH
|
#endif // USE_RF_FLASH
|
||||||
|
|
||||||
|
#define D_TASMOTA_TOKEN "Tasmota-Token"
|
||||||
|
|
||||||
enum UploadTypes { UPL_TASMOTA, UPL_SETTINGS, UPL_EFM8BB1 };
|
enum UploadTypes { UPL_TASMOTA, UPL_SETTINGS, UPL_EFM8BB1 };
|
||||||
|
|
||||||
const char HTTP_HEAD[] PROGMEM =
|
const char HTTP_HEAD[] PROGMEM =
|
||||||
@ -57,7 +59,7 @@ const char HTTP_HEAD[] PROGMEM =
|
|||||||
"eb('p1').focus();"
|
"eb('p1').focus();"
|
||||||
"}"
|
"}"
|
||||||
"function lx(){"
|
"function lx(){"
|
||||||
"if(to==0){"
|
"if(to==1){"
|
||||||
"if(tp<30){"
|
"if(tp<30){"
|
||||||
"tp++;"
|
"tp++;"
|
||||||
"lt=setTimeout(lx,33);" // Wait for token from server
|
"lt=setTimeout(lx,33);" // Wait for token from server
|
||||||
@ -74,21 +76,22 @@ const char HTTP_HEAD[] PROGMEM =
|
|||||||
"eb('l1').innerHTML=s;"
|
"eb('l1').innerHTML=s;"
|
||||||
"}"
|
"}"
|
||||||
"};"
|
"};"
|
||||||
"x.open('GET','ay?t='+to+pc,true);" // Async request
|
"x.open('GET','ay'+pc,true);" // Async request
|
||||||
|
"x.setRequestHeader('" D_TASMOTA_TOKEN "',to);"
|
||||||
"x.send();" // Perform command if available and get updated information
|
"x.send();" // Perform command if available and get updated information
|
||||||
"pc='';"
|
"pc='';"
|
||||||
"lt=setTimeout(la,2345-(tp*33));"
|
"lt=setTimeout(la,2345-(tp*33));"
|
||||||
"}"
|
"}"
|
||||||
"function la(p){"
|
"function la(p){"
|
||||||
"if(la.arguments.length==1){"
|
"if(la.arguments.length==1){"
|
||||||
"pc='&'+p;"
|
"pc='?'+p;"
|
||||||
"clearTimeout(lt);"
|
"clearTimeout(lt);"
|
||||||
"}else{pc='';}"
|
"}else{pc='';}"
|
||||||
"to=0;tp=0;"
|
"to=1;tp=0;"
|
||||||
"if(x!=null){x.abort();}" // Abort if no response within 2 seconds (happens on restart 1)
|
"if(x!=null){x.abort();}" // Abort if no response within 2 seconds (happens on restart 1)
|
||||||
"x=new XMLHttpRequest();"
|
"x=new XMLHttpRequest();"
|
||||||
"x.onreadystatechange=function(){"
|
"x.onreadystatechange=function(){"
|
||||||
"if(x.readyState==4&&x.status==200){to=x.responseText;}else{to=0;}"
|
"if(x.readyState==4&&x.status==200){to=x.getResponseHeader('" D_TASMOTA_TOKEN "');}else{to=1;}"
|
||||||
"};"
|
"};"
|
||||||
"x.open('GET','az',true);" // Async request
|
"x.open('GET','az',true);" // Async request
|
||||||
"x.send();" // Get token from server
|
"x.send();" // Get token from server
|
||||||
@ -344,6 +347,8 @@ const char HDR_CTYPE_XML[] PROGMEM = "text/xml";
|
|||||||
const char HDR_CTYPE_JSON[] PROGMEM = "application/json";
|
const char HDR_CTYPE_JSON[] PROGMEM = "application/json";
|
||||||
const char HDR_CTYPE_STREAM[] PROGMEM = "application/octet-stream";
|
const char HDR_CTYPE_STREAM[] PROGMEM = "application/octet-stream";
|
||||||
|
|
||||||
|
const char HDR_TASMOTA_TOKEN[] PROGMEM = D_TASMOTA_TOKEN;
|
||||||
|
|
||||||
#define DNS_PORT 53
|
#define DNS_PORT 53
|
||||||
enum HttpOptions {HTTP_OFF, HTTP_USER, HTTP_ADMIN, HTTP_MANAGER};
|
enum HttpOptions {HTTP_OFF, HTTP_USER, HTTP_ADMIN, HTTP_MANAGER};
|
||||||
|
|
||||||
@ -359,7 +364,7 @@ uint8_t upload_progress_dot_count;
|
|||||||
uint8_t config_block_count = 0;
|
uint8_t config_block_count = 0;
|
||||||
uint8_t config_xor_on = 0;
|
uint8_t config_xor_on = 0;
|
||||||
uint8_t config_xor_on_set = CONFIG_FILE_XOR;
|
uint8_t config_xor_on_set = CONFIG_FILE_XOR;
|
||||||
long ajax_token = 0;
|
long ajax_token = 1;
|
||||||
|
|
||||||
// Helper function to avoid code duplication (saves 4k Flash)
|
// Helper function to avoid code duplication (saves 4k Flash)
|
||||||
static void WebGetArg(const char* arg, char* out, size_t max)
|
static void WebGetArg(const char* arg, char* out, size_t max)
|
||||||
@ -631,9 +636,15 @@ void HandleToken()
|
|||||||
{
|
{
|
||||||
char token[11];
|
char token[11];
|
||||||
|
|
||||||
ajax_token = random(0x7FFFFFFF);
|
ajax_token = random(2, 0x7FFFFFFF);
|
||||||
snprintf_P(token, sizeof(token), PSTR("%u"), ajax_token);
|
snprintf_P(token, sizeof(token), PSTR("%u"), ajax_token);
|
||||||
|
SetHeader();
|
||||||
|
WebServer->sendHeader(FPSTR(HDR_TASMOTA_TOKEN), token);
|
||||||
|
snprintf_P(token, sizeof(token), PSTR("%u"), random(0x7FFFFFFF));
|
||||||
WebServer->send(200, FPSTR(HDR_CTYPE_HTML), token);
|
WebServer->send(200, FPSTR(HDR_CTYPE_HTML), token);
|
||||||
|
|
||||||
|
const char* header_key[] = { D_TASMOTA_TOKEN };
|
||||||
|
WebServer->collectHeaders(header_key, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleAjaxStatusRefresh()
|
void HandleAjaxStatusRefresh()
|
||||||
@ -641,16 +652,13 @@ void HandleAjaxStatusRefresh()
|
|||||||
char svalue[80];
|
char svalue[80];
|
||||||
char tmp[100];
|
char tmp[100];
|
||||||
|
|
||||||
WebGetArg("t", tmp, sizeof(tmp));
|
if (WebServer->header(FPSTR(HDR_TASMOTA_TOKEN)).toInt() != ajax_token) {
|
||||||
char *p = tmp;
|
|
||||||
long ajax_token_received = strtol(p, &p, 10);
|
|
||||||
if (ajax_token_received != ajax_token) {
|
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR(D_FILE_NOT_FOUND));
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR(D_FILE_NOT_FOUND));
|
||||||
SetHeader();
|
SetHeader();
|
||||||
WebServer->send(404, FPSTR(HDR_CTYPE_PLAIN), mqtt_data);
|
WebServer->send(404, FPSTR(HDR_CTYPE_PLAIN), mqtt_data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ajax_token = 0;
|
ajax_token = 1;
|
||||||
|
|
||||||
WebGetArg("o", tmp, sizeof(tmp));
|
WebGetArg("o", tmp, sizeof(tmp));
|
||||||
if (strlen(tmp)) {
|
if (strlen(tmp)) {
|
||||||
|
@ -432,6 +432,8 @@ void RulesEvery50ms()
|
|||||||
case 2: snprintf_P(json_event, sizeof(json_event), PSTR("{\"Time\":{\"Set\":%d}}"), GetMinutesPastMidnight()); break;
|
case 2: snprintf_P(json_event, sizeof(json_event), PSTR("{\"Time\":{\"Set\":%d}}"), GetMinutesPastMidnight()); break;
|
||||||
case 3: strncpy_P(json_event, PSTR("{\"MQTT\":{\"Connected\":1}}"), sizeof(json_event)); break;
|
case 3: strncpy_P(json_event, PSTR("{\"MQTT\":{\"Connected\":1}}"), sizeof(json_event)); break;
|
||||||
case 4: strncpy_P(json_event, PSTR("{\"MQTT\":{\"Disconnected\":1}}"), sizeof(json_event)); break;
|
case 4: strncpy_P(json_event, PSTR("{\"MQTT\":{\"Disconnected\":1}}"), sizeof(json_event)); break;
|
||||||
|
case 5: strncpy_P(json_event, PSTR("{\"WIFI\":{\"Connected\":1}}"), sizeof(json_event)); break;
|
||||||
|
case 6: strncpy_P(json_event, PSTR("{\"WIFI\":{\"Disconnected\":1}}"), sizeof(json_event)); break;
|
||||||
}
|
}
|
||||||
if (json_event[0]) {
|
if (json_event[0]) {
|
||||||
RulesProcessEvent(json_event);
|
RulesProcessEvent(json_event);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user