mirror of https://github.com/arendst/Tasmota.git
Add two more rule sets
5.14.0b * Increase rule storage space to 3 rule sets of 512 characters using commands rule1, rule2 and rule3
This commit is contained in:
parent
be895fdcc0
commit
ca08b77aad
|
@ -13,7 +13,7 @@ If you like **Sonoff-Tasmota**, give it a star, or fork it and contribute!
|
||||||
### Development
|
### Development
|
||||||
[![Build Status](https://img.shields.io/travis/arendst/Sonoff-Tasmota.svg)](https://travis-ci.org/arendst/Sonoff-Tasmota)
|
[![Build Status](https://img.shields.io/travis/arendst/Sonoff-Tasmota.svg)](https://travis-ci.org/arendst/Sonoff-Tasmota)
|
||||||
|
|
||||||
Current version is **5.14.0a** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information.
|
Current version is **5.14.0b** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information.
|
||||||
|
|
||||||
### Quick install
|
### Quick install
|
||||||
Download one of the released binaries from https://github.com/arendst/Sonoff-Tasmota/releases and flash it to your hardware as documented in the wiki.
|
Download one of the released binaries from https://github.com/arendst/Sonoff-Tasmota/releases and flash it to your hardware as documented in the wiki.
|
||||||
|
@ -22,7 +22,7 @@ Download one of the released binaries from https://github.com/arendst/Sonoff-Tas
|
||||||
If you want to compile Sonoff-Tasmota yourself keep in mind the following:
|
If you want to compile Sonoff-Tasmota yourself keep in mind the following:
|
||||||
|
|
||||||
- Only Flash Mode **DOUT** is supported. Do not use Flash Mode DIO / QIO / QOUT as it might seem to brick your device. See [Wiki](https://github.com/arendst/Sonoff-Tasmota/wiki/Theo's-Tasmota-Tips) for background information.
|
- Only Flash Mode **DOUT** is supported. Do not use Flash Mode DIO / QIO / QOUT as it might seem to brick your device. See [Wiki](https://github.com/arendst/Sonoff-Tasmota/wiki/Theo's-Tasmota-Tips) for background information.
|
||||||
- Sonoff-Tasmota uses a 1M linker script WITHOUT spiffs for optimal code space. If you compile using ESP/Arduino library 2.3.0 then download the provided new linker script to your Arduino IDE or Platformio base folder. Later version of ESP/Arduino library already contain the correct linker script. See [Wiki > Prerequisite](https://github.com/arendst/Sonoff-Tasmota/wiki/Prerequisite).
|
- Sonoff-Tasmota uses a 1M linker script WITHOUT spiffs **1M (no SPIFFS)** for optimal code space. If you compile using ESP/Arduino library 2.3.0 then download the provided new linker script to your Arduino IDE or Platformio base folder. Later version of ESP/Arduino library already contain the correct linker script. See [Wiki > Prerequisite](https://github.com/arendst/Sonoff-Tasmota/wiki/Prerequisite).
|
||||||
- To make compile time changes to Sonoff-Tasmota it can use the ``user_config_override.h`` file. It assures keeping your settings when you download and compile a new version. To use ``user_config.override.h`` you will have to make a copy of the provided ``user_config.override_sample.h`` file and add your setting overrides. To enable the override file you will need to use a compile define as documented in the ``user_config_override_sample.h`` file.
|
- To make compile time changes to Sonoff-Tasmota it can use the ``user_config_override.h`` file. It assures keeping your settings when you download and compile a new version. To use ``user_config.override.h`` you will have to make a copy of the provided ``user_config.override_sample.h`` file and add your setting overrides. To enable the override file you will need to use a compile define as documented in the ``user_config_override_sample.h`` file.
|
||||||
|
|
||||||
### Version Information
|
### Version Information
|
||||||
|
|
|
@ -57,9 +57,6 @@ build_flags =
|
||||||
-DPIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH
|
-DPIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH
|
||||||
; -DUSE_CONFIG_OVERRIDE
|
; -DUSE_CONFIG_OVERRIDE
|
||||||
|
|
||||||
; *** Fix Esp/Arduino core 2.4.x induced Tasmota unused floating point includes
|
|
||||||
extra_scripts = pio/strip-floats.py
|
|
||||||
|
|
||||||
; *** Serial Monitor options
|
; *** Serial Monitor options
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
|
|
||||||
|
@ -68,6 +65,8 @@ monitor_speed = 115200
|
||||||
upload_speed = 512000
|
upload_speed = 512000
|
||||||
upload_resetmethod = nodemcu
|
upload_resetmethod = nodemcu
|
||||||
upload_port = COM5
|
upload_port = COM5
|
||||||
|
; *** Fix Esp/Arduino core 2.4.x induced Tasmota unused floating point includes
|
||||||
|
extra_scripts = pio/strip-floats.py
|
||||||
|
|
||||||
; *** Upload file to OTA server using SCP
|
; *** Upload file to OTA server using SCP
|
||||||
;upload_port = user@host:/path
|
;upload_port = user@host:/path
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
/* 5.14.0a
|
/* 5.14.0b
|
||||||
|
* Increase rule storage space to 3 rule sets of 512 characters using commands rule1, rule2 and rule3
|
||||||
|
*
|
||||||
|
* 5.14.0a
|
||||||
* Add feature information to Status 4
|
* Add feature information to Status 4
|
||||||
* Add tools folder with python script decode-status.py for decoding some status fields like SetOption and Features
|
* Add tools folder with python script decode-status.py for decoding some status fields like SetOption and Features
|
||||||
* Add Eastron SDM630 energy meter by Gennaro Tortone (#2735)
|
* Add Eastron SDM630 energy meter by Gennaro Tortone (#2735)
|
||||||
|
@ -7,7 +10,7 @@
|
||||||
* Add python script fw-server.py in tools folder to create a simple OTA server by Gennaro Tortone (#2759)
|
* Add python script fw-server.py in tools folder to create a simple OTA server by Gennaro Tortone (#2759)
|
||||||
* Add rules %mem1% to %mem5% variable names storing data in flash (#2780)
|
* Add rules %mem1% to %mem5% variable names storing data in flash (#2780)
|
||||||
* Add rules test on %varx% or %memx% (#2780)
|
* Add rules test on %varx% or %memx% (#2780)
|
||||||
* Add optional token %id% substituting the unique MAC address for topic names by Michael Graf (#2794)
|
* Add optional token %id% substituting the unique MAC address to fulltopic by Michael Graf (#2794)
|
||||||
* Fix display selection of un-available GPIO options in Module Configuration webpage (#2718)
|
* Fix display selection of un-available GPIO options in Module Configuration webpage (#2718)
|
||||||
* Fix timer re-trigger within one minute after restart (#2744)
|
* Fix timer re-trigger within one minute after restart (#2744)
|
||||||
* Fix IRSend not accepting data value of 0 by David Conran (#2751)
|
* Fix IRSend not accepting data value of 0 by David Conran (#2751)
|
||||||
|
|
|
@ -48,8 +48,8 @@ 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)
|
uint32_t rules_enabled : 1; // bit 23 (v5.12.0j) - free since v5.14.0b
|
||||||
uint32_t rules_once : 1; // bit 24 (v5.12.0k)
|
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)
|
||||||
uint32_t knx_enable_enhancement : 1; // bit 27 (v5.14.0a) KNX
|
uint32_t knx_enable_enhancement : 1; // bit 27 (v5.14.0a) KNX
|
||||||
|
@ -232,9 +232,8 @@ struct SYSCFG {
|
||||||
uint8_t light_color[5]; // 498
|
uint8_t light_color[5]; // 498
|
||||||
uint8_t light_correction; // 49D
|
uint8_t light_correction; // 49D
|
||||||
uint8_t light_dimmer; // 49E
|
uint8_t light_dimmer; // 49E
|
||||||
|
uint8_t rule_enabled; // 49F
|
||||||
byte free_49F[2]; // 49F
|
uint8_t rule_once; // 4A0
|
||||||
|
|
||||||
uint8_t light_fade; // 4A1
|
uint8_t light_fade; // 4A1
|
||||||
uint8_t light_speed; // 4A2
|
uint8_t light_speed; // 4A2
|
||||||
uint8_t light_scheme; // 4A3
|
uint8_t light_scheme; // 4A3
|
||||||
|
@ -274,9 +273,11 @@ struct SYSCFG {
|
||||||
byte free_6f6[216]; // 6F6
|
byte free_6f6[216]; // 6F6
|
||||||
|
|
||||||
char mems[RULES_MAX_MEMS][10]; // 7CE
|
char mems[RULES_MAX_MEMS][10]; // 7CE
|
||||||
char rules[MAX_RULE_SIZE]; // 800 uses 512 bytes in v5.12.0m
|
// 800 Full - no more free locations
|
||||||
|
|
||||||
// A00 - FFF free locations
|
char rules[MAX_RULE_SETS][MAX_RULE_SIZE]; // 800 uses 512 bytes in v5.12.0m, 3 x 512 bytes in v5.14.0b
|
||||||
|
|
||||||
|
// E00 - FFF free locations
|
||||||
} Settings;
|
} Settings;
|
||||||
|
|
||||||
struct RTCMEM {
|
struct RTCMEM {
|
||||||
|
|
|
@ -143,6 +143,7 @@ extern "C" uint32_t _SPIFFS_end;
|
||||||
|
|
||||||
uint32_t settings_hash = 0;
|
uint32_t settings_hash = 0;
|
||||||
uint32_t settings_location = SETTINGS_LOCATION;
|
uint32_t settings_location = SETTINGS_LOCATION;
|
||||||
|
uint8_t *settings_buffer = NULL;
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
/*
|
/*
|
||||||
|
@ -167,6 +168,24 @@ void SetFlashModeDout()
|
||||||
delete[] _buffer;
|
delete[] _buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SettingsBufferFree()
|
||||||
|
{
|
||||||
|
if (settings_buffer != NULL) {
|
||||||
|
free(settings_buffer);
|
||||||
|
settings_buffer = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SettingsBufferAlloc()
|
||||||
|
{
|
||||||
|
SettingsBufferFree();
|
||||||
|
if (!(settings_buffer = (uint8_t *)malloc(sizeof(Settings)))) {
|
||||||
|
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_UPLOAD_ERR_2)); // Not enough (memory) space
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t GetSettingsHash()
|
uint32_t GetSettingsHash()
|
||||||
{
|
{
|
||||||
uint32_t hash = 0;
|
uint32_t hash = 0;
|
||||||
|
@ -870,7 +889,8 @@ void SettingsDelta()
|
||||||
Settings.longitude = (int)((double)LONGITUDE * 1000000);
|
Settings.longitude = (int)((double)LONGITUDE * 1000000);
|
||||||
}
|
}
|
||||||
if (Settings.version < 0x050C000B) {
|
if (Settings.version < 0x050C000B) {
|
||||||
memset(&Settings.rules, 0x00, sizeof(Settings.rules));
|
// memset(&Settings.rules, 0x00, sizeof(Settings.rules));
|
||||||
|
Settings.rules[0][0] = '\0';
|
||||||
}
|
}
|
||||||
if (Settings.version < 0x050C000D) {
|
if (Settings.version < 0x050C000D) {
|
||||||
memmove(Settings.rules, Settings.rules -256, sizeof(Settings.rules)); // move rules up by 256 bytes
|
memmove(Settings.rules, Settings.rules -256, sizeof(Settings.rules)); // move rules up by 256 bytes
|
||||||
|
@ -887,6 +907,13 @@ void SettingsDelta()
|
||||||
if (Settings.version < 0x050D0103) {
|
if (Settings.version < 0x050D0103) {
|
||||||
SettingsDefaultSet_5_13_1c();
|
SettingsDefaultSet_5_13_1c();
|
||||||
}
|
}
|
||||||
|
if (Settings.version < 0x050E0002) {
|
||||||
|
for (byte i = 1; i < MAX_RULE_SETS -1; i++) {
|
||||||
|
Settings.rules[i][0] = '\0';
|
||||||
|
}
|
||||||
|
Settings.rule_enabled = Settings.flag.rules_enabled;
|
||||||
|
Settings.rule_once = Settings.flag.rules_once;
|
||||||
|
}
|
||||||
|
|
||||||
Settings.version = VERSION;
|
Settings.version = VERSION;
|
||||||
SettingsSave(1);
|
SettingsSave(1);
|
||||||
|
|
|
@ -51,6 +51,7 @@ typedef unsigned long power_t; // Power (Relay) type
|
||||||
#define MAX_KNX_GA 10 // Max number of KNX Group Addresses to read that can be set
|
#define MAX_KNX_GA 10 // Max number of KNX Group Addresses to read that can be set
|
||||||
#define MAX_KNX_CB 10 // Max number of KNX Group Addresses to write that can be set
|
#define MAX_KNX_CB 10 // Max number of KNX Group Addresses to write that can be set
|
||||||
#define RULES_MAX_MEMS 5 // Max number of saved vars
|
#define RULES_MAX_MEMS 5 // Max number of saved vars
|
||||||
|
#define MAX_RULE_SETS 3 // Max number of rule sets of size 512 characters
|
||||||
#define MAX_RULE_SIZE 512 // Max number of characters in rules
|
#define MAX_RULE_SIZE 512 // Max number of characters in rules
|
||||||
|
|
||||||
#define MQTT_TOKEN_PREFIX "%prefix%" // To be substituted by mqtt_prefix[x]
|
#define MQTT_TOKEN_PREFIX "%prefix%" // To be substituted by mqtt_prefix[x]
|
||||||
|
@ -88,7 +89,7 @@ typedef unsigned long power_t; // Power (Relay) type
|
||||||
#define SERIALLOG_TIMER 600 // Seconds to disable SerialLog
|
#define SERIALLOG_TIMER 600 // Seconds to disable SerialLog
|
||||||
#define OTA_ATTEMPTS 5 // Number of times to try fetching the new firmware
|
#define OTA_ATTEMPTS 5 // Number of times to try fetching the new firmware
|
||||||
|
|
||||||
#define INPUT_BUFFER_SIZE 512 // Max number of characters in (serial and http) command buffer
|
#define INPUT_BUFFER_SIZE 520 // Max number of characters in (serial and http) command buffer
|
||||||
#define CMDSZ 24 // Max number of characters in command
|
#define CMDSZ 24 // Max number of characters in command
|
||||||
#define TOPSZ 100 // Max number of characters in topic string
|
#define TOPSZ 100 // Max number of characters in topic string
|
||||||
#define LOGSZ 512 // Max number of characters in log
|
#define LOGSZ 512 // Max number of characters in log
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
- Select IDE Tools - Flash Size: "1M (no SPIFFS)"
|
- Select IDE Tools - Flash Size: "1M (no SPIFFS)"
|
||||||
====================================================*/
|
====================================================*/
|
||||||
|
|
||||||
#define VERSION 0x050E0001 // 5.14.0a
|
#define VERSION 0x050E0002 // 5.14.0b
|
||||||
|
|
||||||
// Location specific includes
|
// Location specific includes
|
||||||
#include <core_version.h> // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_3_0)
|
#include <core_version.h> // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_3_0)
|
||||||
|
|
|
@ -328,7 +328,6 @@ 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;
|
||||||
uint8_t *settings_new = NULL;
|
|
||||||
|
|
||||||
// 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)
|
||||||
|
@ -915,25 +914,36 @@ void HandleBackupConfiguration()
|
||||||
if (HttpUser()) { return; }
|
if (HttpUser()) { return; }
|
||||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_BACKUP_CONFIGURATION));
|
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_BACKUP_CONFIGURATION));
|
||||||
|
|
||||||
uint8_t buffer[sizeof(Settings)];
|
if (!SettingsBufferAlloc()) { return; }
|
||||||
|
|
||||||
WiFiClient myClient = WebServer->client();
|
WiFiClient myClient = WebServer->client();
|
||||||
WebServer->setContentLength(sizeof(buffer));
|
WebServer->setContentLength(sizeof(Settings));
|
||||||
|
|
||||||
char attachment[100];
|
char attachment[100];
|
||||||
char friendlyname[sizeof(Settings.friendlyname[0])];
|
char friendlyname[sizeof(Settings.friendlyname[0])];
|
||||||
snprintf_P(attachment, sizeof(attachment), PSTR("attachment; filename=Config_%s_%s.dmp"), NoAlNumToUnderscore(friendlyname, Settings.friendlyname[0]), my_version);
|
snprintf_P(attachment, sizeof(attachment), PSTR("attachment; filename=Config_%s_%s.dmp"), NoAlNumToUnderscore(friendlyname, Settings.friendlyname[0]), my_version);
|
||||||
WebServer->sendHeader(F("Content-Disposition"), attachment);
|
WebServer->sendHeader(F("Content-Disposition"), attachment);
|
||||||
|
|
||||||
WebServer->send(200, FPSTR(HDR_CTYPE_STREAM), "");
|
WebServer->send(200, FPSTR(HDR_CTYPE_STREAM), "");
|
||||||
memcpy(buffer, &Settings, sizeof(buffer));
|
memcpy(settings_buffer, &Settings, sizeof(Settings));
|
||||||
buffer[0] = CONFIG_FILE_SIGN;
|
settings_buffer[0] = CONFIG_FILE_SIGN;
|
||||||
buffer[1] = (!config_xor_on_set) ? 0 : 1;
|
settings_buffer[1] = (!config_xor_on_set) ? 0 : 1;
|
||||||
if (buffer[1]) {
|
if (settings_buffer[1]) {
|
||||||
for (uint16_t i = 2; i < sizeof(buffer); i++) {
|
for (uint16_t i = 2; i < sizeof(Settings); i++) {
|
||||||
buffer[i] ^= (config_xor_on_set +i);
|
settings_buffer[i] ^= (config_xor_on_set +i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
myClient.write((const char*)buffer, sizeof(buffer));
|
|
||||||
|
#ifdef ARDUINO_ESP8266_RELEASE_2_3_0
|
||||||
|
size_t written = myClient.write((const char*)settings_buffer, sizeof(Settings));
|
||||||
|
if (written < sizeof(Settings)) { // https://github.com/esp8266/Arduino/issues/3218
|
||||||
|
myClient.write((const char*)settings_buffer +written, sizeof(Settings) -written);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
myClient.write((const char*)settings_buffer, sizeof(Settings));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SettingsBufferFree();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleSaveSettings()
|
void HandleSaveSettings()
|
||||||
|
@ -1186,14 +1196,6 @@ void HandleUpgradeFirmwareStart()
|
||||||
ExecuteCommand(svalue);
|
ExecuteCommand(svalue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsNewFree()
|
|
||||||
{
|
|
||||||
if (settings_new != NULL) {
|
|
||||||
free(settings_new);
|
|
||||||
settings_new = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandleUploadDone()
|
void HandleUploadDone()
|
||||||
{
|
{
|
||||||
if (HttpUser()) { return; }
|
if (HttpUser()) { return; }
|
||||||
|
@ -1233,7 +1235,7 @@ void HandleUploadDone()
|
||||||
page += FPSTR(HTTP_MSG_RSTRT);
|
page += FPSTR(HTTP_MSG_RSTRT);
|
||||||
restart_flag = 2;
|
restart_flag = 2;
|
||||||
}
|
}
|
||||||
SettingsNewFree();
|
SettingsBufferFree();
|
||||||
page += F("</div><br/>");
|
page += F("</div><br/>");
|
||||||
page += FPSTR(HTTP_BTN_MAIN);
|
page += FPSTR(HTTP_BTN_MAIN);
|
||||||
ShowPage(page);
|
ShowPage(page);
|
||||||
|
@ -1262,8 +1264,7 @@ void HandleUploadLoop()
|
||||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_UPLOAD D_FILE " %s ..."), upload.filename.c_str());
|
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_UPLOAD D_FILE " %s ..."), upload.filename.c_str());
|
||||||
AddLog(LOG_LEVEL_INFO);
|
AddLog(LOG_LEVEL_INFO);
|
||||||
if (upload_file_type) {
|
if (upload_file_type) {
|
||||||
SettingsNewFree();
|
if (!SettingsBufferAlloc()) {
|
||||||
if (!(settings_new = (uint8_t *)malloc(sizeof(Settings)))) {
|
|
||||||
upload_error = 2;
|
upload_error = 2;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1311,7 +1312,7 @@ void HandleUploadLoop()
|
||||||
upload_error = 9;
|
upload_error = 9;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy(settings_new + (config_block_count * HTTP_UPLOAD_BUFLEN), upload.buf, upload.currentSize);
|
memcpy(settings_buffer + (config_block_count * HTTP_UPLOAD_BUFLEN), upload.buf, upload.currentSize);
|
||||||
config_block_count++;
|
config_block_count++;
|
||||||
}
|
}
|
||||||
} else { // firmware
|
} else { // firmware
|
||||||
|
@ -1332,13 +1333,13 @@ void HandleUploadLoop()
|
||||||
if (upload_file_type) {
|
if (upload_file_type) {
|
||||||
if (config_xor_on) {
|
if (config_xor_on) {
|
||||||
for (uint16_t i = 2; i < sizeof(Settings); i++) {
|
for (uint16_t i = 2; i < sizeof(Settings); i++) {
|
||||||
settings_new[i] ^= (config_xor_on_set +i);
|
settings_buffer[i] ^= (config_xor_on_set +i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SettingsDefaultSet2();
|
SettingsDefaultSet2();
|
||||||
memcpy((char*)&Settings +16, settings_new +16, sizeof(Settings) -16);
|
memcpy((char*)&Settings +16, settings_buffer +16, sizeof(Settings) -16);
|
||||||
memcpy((char*)&Settings +8, settings_new +8, 4); // Restore version and auto upgrade
|
memcpy((char*)&Settings +8, settings_buffer +8, 4); // Restore version and auto upgrade
|
||||||
SettingsNewFree();
|
SettingsBufferFree();
|
||||||
} else {
|
} else {
|
||||||
if (!Update.end(true)) { // true to set the size to the current progress
|
if (!Update.end(true)) { // true to set the size to the current progress
|
||||||
if (_serialoutput) { Update.printError(Serial); }
|
if (_serialoutput) { Update.printError(Serial); }
|
||||||
|
|
|
@ -80,14 +80,16 @@
|
||||||
enum RulesCommands { CMND_RULE, CMND_RULETIMER, CMND_EVENT, CMND_VAR, CMND_MEM };
|
enum RulesCommands { CMND_RULE, CMND_RULETIMER, CMND_EVENT, CMND_VAR, CMND_MEM };
|
||||||
const char kRulesCommands[] PROGMEM = D_CMND_RULE "|" D_CMND_RULETIMER "|" D_CMND_EVENT "|" D_CMND_VAR "|" D_CMND_MEM ;
|
const char kRulesCommands[] PROGMEM = D_CMND_RULE "|" D_CMND_RULETIMER "|" D_CMND_EVENT "|" D_CMND_VAR "|" D_CMND_MEM ;
|
||||||
|
|
||||||
|
char rules[MAX_RULE_SIZE];
|
||||||
|
|
||||||
String rules_event_value;
|
String rules_event_value;
|
||||||
unsigned long rules_timer[MAX_RULE_TIMERS] = { 0 };
|
unsigned long rules_timer[MAX_RULE_TIMERS] = { 0 };
|
||||||
uint8_t rules_quota = 0;
|
uint8_t rules_quota = 0;
|
||||||
long rules_new_power = -1;
|
long rules_new_power = -1;
|
||||||
long rules_old_power = -1;
|
long rules_old_power = -1;
|
||||||
|
|
||||||
uint32_t rules_triggers = 0;
|
uint32_t rules_triggers[MAX_RULE_SETS] = { 0 };
|
||||||
uint8_t rules_trigger_count = 0;
|
uint8_t rules_trigger_count[MAX_RULE_SETS] = { 0 };
|
||||||
uint8_t rules_teleperiod = 0;
|
uint8_t rules_teleperiod = 0;
|
||||||
|
|
||||||
char vars[RULES_MAX_VARS][10] = { 0 };
|
char vars[RULES_MAX_VARS][10] = { 0 };
|
||||||
|
@ -141,7 +143,7 @@ bool TimeReached(unsigned long timer)
|
||||||
|
|
||||||
/*******************************************************************************************/
|
/*******************************************************************************************/
|
||||||
|
|
||||||
bool RulesRuleMatch(String &event, String &rule)
|
bool RulesRuleMatch(byte rule_set, String &event, String &rule)
|
||||||
{
|
{
|
||||||
// event = {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}}
|
// event = {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}}
|
||||||
// event = {"System":{"Boot":1}}
|
// event = {"System":{"Boot":1}}
|
||||||
|
@ -218,7 +220,7 @@ bool RulesRuleMatch(String &event, String &rule)
|
||||||
const char* str_value = root[rule_task][rule_name];
|
const char* str_value = root[rule_task][rule_name];
|
||||||
|
|
||||||
//snprintf_P(log_data, sizeof(log_data), PSTR("RUL: Task %s, Name %s, Value |%s|, TrigCnt %d, TrigSt %d, Source %s, Json %s"),
|
//snprintf_P(log_data, sizeof(log_data), PSTR("RUL: Task %s, Name %s, Value |%s|, TrigCnt %d, TrigSt %d, Source %s, Json %s"),
|
||||||
// rule_task.c_str(), rule_name.c_str(), tmp_value, rules_trigger_count, bitRead(rules_triggers, rules_trigger_count), event.c_str(), (str_value) ? str_value : "none");
|
// rule_task.c_str(), rule_name.c_str(), tmp_value, rules_trigger_count[rule_set], bitRead(rules_triggers[rule_set], rules_trigger_count[rule_set]), event.c_str(), (str_value) ? str_value : "none");
|
||||||
//AddLog(LOG_LEVEL_DEBUG);
|
//AddLog(LOG_LEVEL_DEBUG);
|
||||||
|
|
||||||
if (!root[rule_task][rule_name].success()) { return false; }
|
if (!root[rule_task][rule_name].success()) { return false; }
|
||||||
|
@ -247,13 +249,13 @@ bool RulesRuleMatch(String &event, String &rule)
|
||||||
|
|
||||||
if (Settings.flag.rules_once) {
|
if (Settings.flag.rules_once) {
|
||||||
if (match) { // Only allow match state changes
|
if (match) { // Only allow match state changes
|
||||||
if (!bitRead(rules_triggers, rules_trigger_count)) {
|
if (!bitRead(rules_triggers[rule_set], rules_trigger_count[rule_set])) {
|
||||||
bitSet(rules_triggers, rules_trigger_count);
|
bitSet(rules_triggers[rule_set], rules_trigger_count[rule_set]);
|
||||||
} else {
|
} else {
|
||||||
match = false;
|
match = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bitClear(rules_triggers, rules_trigger_count);
|
bitClear(rules_triggers[rule_set], rules_trigger_count[rule_set]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,24 +264,19 @@ bool RulesRuleMatch(String &event, String &rule)
|
||||||
|
|
||||||
/*******************************************************************************************/
|
/*******************************************************************************************/
|
||||||
|
|
||||||
bool RulesProcess()
|
bool RuleSetProcess(byte rule_set, String &event_saved)
|
||||||
{
|
{
|
||||||
bool serviced = false;
|
bool serviced = false;
|
||||||
char stemp[10];
|
char stemp[10];
|
||||||
|
|
||||||
delay(0); // Prohibit possible loop software watchdog
|
delay(0); // Prohibit possible loop software watchdog
|
||||||
|
|
||||||
//snprintf_P(log_data, sizeof(log_data), PSTR("RUL: Event = %s, Rule = %s"), mqtt_data, Settings.rules);
|
//snprintf_P(log_data, sizeof(log_data), PSTR("RUL: Event = %s, Rule = %s"), event_saved.c_str(), Settings.rules[rule_set]);
|
||||||
//AddLog(LOG_LEVEL_DEBUG);
|
//AddLog(LOG_LEVEL_DEBUG);
|
||||||
|
|
||||||
if (!Settings.flag.rules_enabled) { return serviced; } // Not enabled
|
String rules = Settings.rules[rule_set];
|
||||||
if (!strlen(Settings.rules)) { return serviced; } // No rules
|
|
||||||
|
|
||||||
String event_saved = mqtt_data;
|
rules_trigger_count[rule_set] = 0;
|
||||||
event_saved.toUpperCase();
|
|
||||||
String rules = Settings.rules;
|
|
||||||
|
|
||||||
rules_trigger_count = 0;
|
|
||||||
int plen = 0;
|
int plen = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
rules = rules.substring(plen); // Select relative to last rule
|
rules = rules.substring(plen); // Select relative to last rule
|
||||||
|
@ -304,7 +301,7 @@ bool RulesProcess()
|
||||||
//snprintf_P(log_data, sizeof(log_data), PSTR("RUL: Event |%s|, Rule |%s|, Command(s) |%s|"), event.c_str(), event_trigger.c_str(), commands.c_str());
|
//snprintf_P(log_data, sizeof(log_data), PSTR("RUL: Event |%s|, Rule |%s|, Command(s) |%s|"), event.c_str(), event_trigger.c_str(), commands.c_str());
|
||||||
//AddLog(LOG_LEVEL_DEBUG);
|
//AddLog(LOG_LEVEL_DEBUG);
|
||||||
|
|
||||||
if (RulesRuleMatch(event, event_trigger)) {
|
if (RulesRuleMatch(rule_set, event, event_trigger)) {
|
||||||
commands.trim();
|
commands.trim();
|
||||||
String ucommand = commands;
|
String ucommand = commands;
|
||||||
ucommand.toUpperCase();
|
ucommand.toUpperCase();
|
||||||
|
@ -331,25 +328,42 @@ bool RulesProcess()
|
||||||
ExecuteCommand(command);
|
ExecuteCommand(command);
|
||||||
serviced = true;
|
serviced = true;
|
||||||
}
|
}
|
||||||
rules_trigger_count++;
|
rules_trigger_count[rule_set]++;
|
||||||
}
|
}
|
||||||
return serviced;
|
return serviced;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************************/
|
/*******************************************************************************************/
|
||||||
|
|
||||||
|
bool RulesProcess()
|
||||||
|
{
|
||||||
|
bool serviced = false;
|
||||||
|
|
||||||
|
String event_saved = mqtt_data;
|
||||||
|
event_saved.toUpperCase();
|
||||||
|
|
||||||
|
for (byte i = 0; i < MAX_RULE_SETS; i++) {
|
||||||
|
if (strlen(Settings.rules[i]) && bitRead(Settings.rule_enabled, i)) {
|
||||||
|
if (RuleSetProcess(i, event_saved)) { serviced = true; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return serviced;
|
||||||
|
}
|
||||||
|
|
||||||
void RulesInit()
|
void RulesInit()
|
||||||
{
|
{
|
||||||
if (Settings.rules[0] == '\0') {
|
for (byte i = 0; i < MAX_RULE_SETS; i++) {
|
||||||
Settings.flag.rules_enabled = 0;
|
if (Settings.rules[i][0] == '\0') {
|
||||||
Settings.flag.rules_once = 0;
|
bitWrite(Settings.rule_enabled, i, 0);
|
||||||
|
bitWrite(Settings.rule_once, i, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rules_teleperiod = 0;
|
rules_teleperiod = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RulesEvery50ms()
|
void RulesEvery50ms()
|
||||||
{
|
{
|
||||||
if (Settings.flag.rules_enabled) {
|
if (Settings.rule_enabled) { // Any rule enabled
|
||||||
if (rules_new_power != rules_old_power) {
|
if (rules_new_power != rules_old_power) {
|
||||||
if (rules_old_power != -1) {
|
if (rules_old_power != -1) {
|
||||||
for (byte i = 0; i < devices_present; i++) {
|
for (byte i = 0; i < devices_present; i++) {
|
||||||
|
@ -381,7 +395,7 @@ void RulesEvery50ms()
|
||||||
|
|
||||||
void RulesEverySecond()
|
void RulesEverySecond()
|
||||||
{
|
{
|
||||||
if (Settings.flag.rules_enabled) {
|
if (Settings.rule_enabled) { // Any rule enabled
|
||||||
for (byte i = 0; i < MAX_RULE_TIMERS; i++) {
|
for (byte i = 0; i < MAX_RULE_TIMERS; i++) {
|
||||||
if (rules_timer[i] != 0L) { // Timer active?
|
if (rules_timer[i] != 0L) { // Timer active?
|
||||||
if (TimeReached(rules_timer[i])) { // Timer finished?
|
if (TimeReached(rules_timer[i])) { // Timer finished?
|
||||||
|
@ -416,39 +430,36 @@ boolean RulesCommand()
|
||||||
if (-1 == command_code) {
|
if (-1 == command_code) {
|
||||||
serviced = false; // Unknown command
|
serviced = false; // Unknown command
|
||||||
}
|
}
|
||||||
else if (CMND_RULE == command_code) {
|
else if ((CMND_RULE == command_code) && (index > 0) && (index <= MAX_RULE_SETS)) {
|
||||||
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.rules))) {
|
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.rules[index -1]))) {
|
||||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 6)) {
|
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 6)) {
|
||||||
switch (XdrvMailbox.payload) {
|
switch (XdrvMailbox.payload) {
|
||||||
case 0: // Off
|
case 0: // Off
|
||||||
case 1: // On
|
case 1: // On
|
||||||
Settings.flag.rules_enabled = XdrvMailbox.payload;
|
// Settings.flag.rules_enabled = XdrvMailbox.payload;
|
||||||
|
bitWrite(Settings.rule_enabled, index -1, XdrvMailbox.payload);
|
||||||
break;
|
break;
|
||||||
case 2: // Toggle
|
case 2: // Toggle
|
||||||
Settings.flag.rules_enabled ^= 1;
|
// Settings.flag.rules_enabled ^= 1;
|
||||||
|
bitWrite(Settings.rule_enabled, index -1, bitRead(Settings.rule_enabled, index -1) ^1);
|
||||||
break;
|
break;
|
||||||
case 4: // Off
|
case 4: // Off
|
||||||
case 5: // On
|
case 5: // On
|
||||||
Settings.flag.rules_once = XdrvMailbox.payload &1;
|
// Settings.flag.rules_once = XdrvMailbox.payload &1;
|
||||||
|
bitWrite(Settings.rule_once, index -1, XdrvMailbox.payload &1);
|
||||||
break;
|
break;
|
||||||
case 6: // Toggle
|
case 6: // Toggle
|
||||||
Settings.flag.rules_once ^= 1;
|
// Settings.flag.rules_once ^= 1;
|
||||||
|
bitWrite(Settings.rule_once, index -1, bitRead(Settings.rule_once, index -1) ^1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
strlcpy(Settings.rules[index -1], ('"' == XdrvMailbox.data[0]) ? "" : XdrvMailbox.data, sizeof(Settings.rules[index -1]));
|
||||||
String uc_data = XdrvMailbox.data; // Do not allow Rule to be used within a rule
|
|
||||||
uc_data.toUpperCase();
|
|
||||||
String uc_command = command;
|
|
||||||
uc_command += " "; // Distuingish from RuleTimer
|
|
||||||
uc_command.toUpperCase();
|
|
||||||
if (!uc_data.indexOf(uc_command)) { strlcpy(Settings.rules, XdrvMailbox.data, sizeof(Settings.rules)); }
|
|
||||||
*/
|
|
||||||
strlcpy(Settings.rules, XdrvMailbox.data, sizeof(Settings.rules));
|
|
||||||
}
|
}
|
||||||
rules_triggers = 0; // Reset once flag
|
rules_triggers[index -1] = 0; // Reset once flag
|
||||||
}
|
}
|
||||||
snprintf_P (mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":\"%s\",\"Once\":\"%s\",\"Rules\":\"%s\"}"), command, GetStateText(Settings.flag.rules_enabled), GetStateText(Settings.flag.rules_once), Settings.rules);
|
snprintf_P (mqtt_data, sizeof(mqtt_data), PSTR("{\"%s%d\":\"%s\",\"Once\":\"%s\",\"Free\":%d,\"Rules\":\"%s\"}"),
|
||||||
|
command, index, GetStateText(bitRead(Settings.rule_enabled, index -1)), GetStateText(bitRead(Settings.rule_once, index -1)), sizeof(Settings.rules[index -1]) - strlen(Settings.rules[index -1]) -1, Settings.rules[index -1]);
|
||||||
}
|
}
|
||||||
else if ((CMND_RULETIMER == command_code) && (index > 0) && (index <= MAX_RULE_TIMERS)) {
|
else if ((CMND_RULETIMER == command_code) && (index > 0) && (index <= MAX_RULE_TIMERS)) {
|
||||||
if (XdrvMailbox.data_len > 0) {
|
if (XdrvMailbox.data_len > 0) {
|
||||||
|
|
Loading…
Reference in New Issue