Fix rules induced LWT message

Fix rules induced LWT message
This commit is contained in:
Theo Arends 2018-06-25 18:00:20 +02:00
parent 9331cab55c
commit e818f0da55
6 changed files with 70 additions and 18 deletions

View File

@ -12,6 +12,7 @@
* Change default CFG_HOLDER from 0x20161209 to 4617 (=0x1209) - no impact on default upgrades
* Fix Pzem004T checksum error
* Fix KNX bug when doing reply of sensors values
* Fix rules induced LWT message
*
* 5.14.0b
* Add Console Commands to send KNX Commands

View File

@ -318,6 +318,29 @@ struct XDRVMAILBOX {
char *data;
} XdrvMailbox;
#define MAX_RULES_FLAG 5 // Number of bits used in RulesBitfield (tricky I know...)
typedef union { // Restricted by MISRA-C Rule 18.4 but so usefull...
uint16_t data; // Allow bit manipulation
struct {
uint16_t system_boot : 1;
uint16_t time_init : 1;
uint16_t time_set : 1;
uint16_t mqtt_connected : 1;
uint16_t mqtt_disconnected : 1;
uint16_t spare05 : 1;
uint16_t spare06 : 1;
uint16_t spare07 : 1;
uint16_t spare08 : 1;
uint16_t spare09 : 1;
uint16_t spare10 : 1;
uint16_t spare11 : 1;
uint16_t spare12 : 1;
uint16_t spare13 : 1;
uint16_t spare14 : 1;
uint16_t spare15 : 1;
};
} RulesBitfield;
// See issue https://github.com/esp8266/Arduino/issues/2913
#ifdef USE_ADC_VCC
ADC_MODE(ADC_VCC); // Set ADC input for Power Supply Voltage usage

View File

@ -181,6 +181,7 @@ uint8_t light_type = 0; // Light types
bool pwm_present = false; // Any PWM channel configured with SetOption15 0
boolean mdns_begun = false;
uint8_t ntp_force_sync = 0; // Force NTP sync
RulesBitfield rules_flag;
char my_version[33]; // Composed version string
char my_hostname[33]; // Composed Wifi hostname

View File

@ -1754,11 +1754,10 @@ void RtcSecond()
GetTime(0).c_str(), GetTime(2).c_str(), GetTime(3).c_str());
AddLog(LOG_LEVEL_DEBUG);
if (local_time < 1451602800) { // 2016-01-01
strncpy_P(mqtt_data, PSTR("{\"Time\":{\"Initialized\":1}}"), sizeof(mqtt_data));
rules_flag.time_init = 1;
} else {
strncpy_P(mqtt_data, PSTR("{\"Time\":{\"Set\":1}}"), sizeof(mqtt_data));
rules_flag.time_set = 1;
}
XdrvRulesProcess();
} else {
ntp_sync_minute++; // Try again in next minute
}

View File

@ -315,8 +315,7 @@ void MqttDisconnected(int state)
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MQTT D_CONNECT_FAILED_TO " %s:%d, rc %d. " D_RETRY_IN " %d " D_UNIT_SECOND),
Settings.mqtt_host, Settings.mqtt_port, state, mqtt_retry_counter);
AddLog(LOG_LEVEL_INFO);
strncpy_P(mqtt_data, PSTR("{\"MQTT\":{\"Disconnected\":1}}"), sizeof(mqtt_data));
XdrvRulesProcess();
rules_flag.mqtt_disconnected = 1;
}
void MqttConnected()
@ -368,13 +367,11 @@ void MqttConnected()
tele_period = Settings.tele_period -9;
}
status_update_timer = 2;
strncpy_P(mqtt_data, PSTR("{\"System\":{\"Boot\":1}}"), sizeof(mqtt_data));
XdrvRulesProcess();
rules_flag.system_boot = 1;
XdrvCall(FUNC_MQTT_INIT);
}
mqtt_initial_connection_state = 0;
strncpy_P(mqtt_data, PSTR("{\"MQTT\":{\"Connected\":1}}"), sizeof(mqtt_data));
XdrvRulesProcess();
rules_flag.mqtt_connected = 1;
}
#ifdef USE_MQTT_TLS

View File

@ -339,11 +339,11 @@ bool RuleSetProcess(byte rule_set, String &event_saved)
/*******************************************************************************************/
bool RulesProcess()
bool RulesProcessEvent(char *json_event)
{
bool serviced = false;
String event_saved = mqtt_data;
String event_saved = json_event;
event_saved.toUpperCase();
for (byte i = 0; i < MAX_RULE_SETS; i++) {
@ -354,8 +354,14 @@ bool RulesProcess()
return serviced;
}
bool RulesProcess()
{
return RulesProcessEvent(mqtt_data);
}
void RulesInit()
{
rules_flag.data = 0;
for (byte i = 0; i < MAX_RULE_SETS; i++) {
if (Settings.rules[i][0] == '\0') {
bitWrite(Settings.rule_enabled, i, 0);
@ -368,19 +374,21 @@ void RulesInit()
void RulesEvery50ms()
{
if (Settings.rule_enabled) { // Any rule enabled
char json_event[120];
if (rules_new_power != rules_old_power) {
if (rules_old_power != -1) {
for (byte i = 0; i < devices_present; i++) {
uint8_t new_state = (rules_new_power >> i) &1;
if (new_state != ((rules_old_power >> i) &1)) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"Power%d\":{\"State\":%d}}"), i +1, new_state);
RulesProcess();
snprintf_P(json_event, sizeof(json_event), PSTR("{\"Power%d\":{\"State\":%d}}"), i +1, new_state);
RulesProcessEvent(json_event);
}
}
}
rules_old_power = rules_new_power;
}
else if(event_data[0]) {
else if (event_data[0]) {
char *event;
char *parameter;
event = strtok_r(event_data, "=", &parameter); // event_data = fanspeed=10
@ -391,13 +399,34 @@ void RulesEvery50ms()
} else {
parameter = event + strlen(event); // '\0'
}
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"Event\":{\"%s\":\"%s\"}}"), event, parameter);
snprintf_P(json_event, sizeof(json_event), PSTR("{\"Event\":{\"%s\":\"%s\"}}"), event, parameter);
event_data[0] ='\0';
RulesProcess();
RulesProcessEvent(json_event);
} else {
event_data[0] ='\0';
}
}
else if (rules_flag.data) {
uint16_t mask = 1;
for (byte i = 0; i < MAX_RULES_FLAG; i++) {
if (rules_flag.data & mask) {
rules_flag.data ^= mask;
json_event[0] = '\0';
switch (i) {
case 0: strncpy_P(json_event, PSTR("{\"System\":{\"Boot\":1}}"), sizeof(json_event)); break;
case 1: strncpy_P(json_event, PSTR("{\"Time\":{\"Initialized\":1}}"), sizeof(json_event)); break;
case 2: strncpy_P(json_event, PSTR("{\"Time\":{\"Set\":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;
}
if (json_event[0]) {
RulesProcessEvent(json_event);
break; // Only service one event within 50mS
}
}
mask <<= 1;
}
}
else {
rules_quota++;
if (rules_quota &1) { // Every 100 ms
@ -419,12 +448,14 @@ void RulesEvery50ms()
void RulesEverySecond()
{
if (Settings.rule_enabled) { // Any rule enabled
char json_event[120];
for (byte i = 0; i < MAX_RULE_TIMERS; i++) {
if (rules_timer[i] != 0L) { // Timer active?
if (TimeReached(rules_timer[i])) { // Timer finished?
rules_timer[i] = 0L; // Turn off this timer
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"Rules\":{\"Timer\":%d}}"), i +1);
RulesProcess();
snprintf_P(json_event, sizeof(json_event), PSTR("{\"Rules\":{\"Timer\":%d}}"), i +1);
RulesProcessEvent(json_event);
}
}
}