Merge branch 'mqtt-dynamic-pulse' of https://github.com/mcspr/espurna into mcspr-mqtt-dynamic-pulse

This commit is contained in:
Xose Pérez
2018-06-12 21:43:30 +02:00
6 changed files with 2368 additions and 2339 deletions

View File

@@ -4,9 +4,9 @@ ESPurna ("spark" in Catalan) is a custom firmware for ESP8285/ESP8266 based smar
It uses the Arduino Core for ESP8266 framework and a number of 3rd party libraries.
[![version](https://img.shields.io/badge/version-1.13.0c-brightgreen.svg)](CHANGELOG.md)
[![branch](https://img.shields.io/badge/branch-dev-orange.svg)](https://github.org/xoseperez/espurna/tree/dev/)
[![travis](https://travis-ci.org/xoseperez/espurna.svg?branch=dev)](https://travis-ci.org/xoseperez/espurna)
[![codacy](https://img.shields.io/codacy/grade/c9496e25cf07434cba786b462cb15f49/dev.svg)](https://www.codacy.com/app/xoseperez/espurna/dashboard)
[![branch](https://img.shields.io/badge/branch-mcspr-mqtt-dynamic-pulse-orange.svg)](https://github.org/xoseperez/espurna/tree/mcspr-mqtt-dynamic-pulse/)
[![travis](https://travis-ci.org/xoseperez/espurna.svg?branch=mcspr-mqtt-dynamic-pulse)](https://travis-ci.org/xoseperez/espurna)
[![codacy](https://img.shields.io/codacy/grade/c9496e25cf07434cba786b462cb15f49/mcspr-mqtt-dynamic-pulse.svg)](https://www.codacy.com/app/xoseperez/espurna/dashboard)
[![license](https://img.shields.io/github/license/xoseperez/espurna.svg)](LICENSE)
<br />
[![donate](https://img.shields.io/badge/donate-PayPal-blue.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=xose%2eperez%40gmail%2ecom&lc=US&no_note=0&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHostedGuest)

View File

@@ -684,6 +684,7 @@
#define MQTT_TOPIC_UARTOUT "uartout"
#define MQTT_TOPIC_LOADAVG "loadavg"
#define MQTT_TOPIC_BOARD "board"
#define MQTT_TOPIC_PULSE "pulse"
// Light module
#define MQTT_TOPIC_CHANNEL "channel"

Binary file not shown.

View File

@@ -23,7 +23,6 @@ typedef struct {
unsigned long delay_off; // Delay to turn relay OFF
unsigned char pulse; // RELAY_PULSE_NONE, RELAY_PULSE_OFF or RELAY_PULSE_ON
unsigned long pulse_ms; // Pulse length in millis
unsigned long pulse_start; // Current pulse start (millis), 0 means no pulse
// Status variables
@@ -35,6 +34,10 @@ typedef struct {
bool report; // Whether to report to own topic
bool group_report; // Whether to report to group topic
// Helping objects
Ticker pulseTicker; // Holds the pulse back timer
} relay_t;
std::vector<relay_t> _relays;
bool _relayRecursive = false;
@@ -200,27 +203,14 @@ void _relayProcess(bool mode) {
}
/**
* Walks the relay vector check if any relay has to pulse back
*/
void _relayPulseCheck() {
unsigned long current_time = millis();
for (unsigned char id = 0; id < _relays.size(); id++) {
if (_relays[id].pulse_start > 0) {
if (current_time - _relays[id].pulse_start > _relays[id].pulse_ms) {
_relays[id].pulse_start = 0;
relayToggle(id);
}
}
}
}
// -----------------------------------------------------------------------------
// RELAY
// -----------------------------------------------------------------------------
void relayPulse(unsigned char id) {
_relays[id].pulseTicker.detach();
byte mode = _relays[id].pulse;
if (mode == RELAY_PULSE_NONE) return;
unsigned long ms = _relays[id].pulse_ms;
@@ -229,11 +219,12 @@ void relayPulse(unsigned char id) {
bool status = relayStatus(id);
bool pulseStatus = (mode == RELAY_PULSE_ON);
if (pulseStatus == status) {
_relays[id].pulse_start = 0;
} else {
if (pulseStatus != status) {
DEBUG_MSG_P(PSTR("[RELAY] Scheduling relay #%d back in %lums (pulse)\n"), id, ms);
_relays[id].pulse_start = millis();
_relays[id].pulseTicker.once_ms(ms, relayToggle, id);
// Reconfigure after dynamic pulse
_relays[id].pulse = getSetting("relayPulse", id, RELAY_PULSE_MODE).toInt();
_relays[id].pulse_ms = 1000 * getSetting("relayTime", id, RELAY_PULSE_MODE).toFloat();
}
}
@@ -476,7 +467,6 @@ void _relayBoot() {
}
_relays[i].current_status = !status;
_relays[i].target_status = status;
_relays[i].pulse_start = 0;
#if RELAY_PROVIDER == RELAY_PROVIDER_STM
_relays[i].change_time = millis() + 3000 + 1000 * i;
#else
@@ -706,9 +696,14 @@ void relayMQTTCallback(unsigned int type, const char * topic, const char * paylo
#endif
// Subscribe to own /set topic
char buffer[strlen(MQTT_TOPIC_RELAY) + 3];
snprintf_P(buffer, sizeof(buffer), PSTR("%s/+"), MQTT_TOPIC_RELAY);
mqttSubscribe(buffer);
char relay_topic[strlen(MQTT_TOPIC_RELAY) + 3];
snprintf_P(relay_topic, sizeof(relay_topic), PSTR("%s/+"), MQTT_TOPIC_RELAY);
mqttSubscribe(relay_topic);
// Subscribe to pulse topic
char pulse_topic[strlen(MQTT_TOPIC_RELAY) + strlen(MQTT_TOPIC_PULSE) + 4];
snprintf_P(pulse_topic, sizeof(pulse_topic), PSTR("%s/+/%s"), MQTT_TOPIC_RELAY, MQTT_TOPIC_PULSE);
mqttSubscribe(pulse_topic);
// Subscribe to group topics
for (unsigned int i=0; i < _relays.size(); i++) {
@@ -720,26 +715,50 @@ void relayMQTTCallback(unsigned int type, const char * topic, const char * paylo
if (type == MQTT_MESSAGE_EVENT) {
// Check relay topic
String t = mqttMagnitude((char *) topic);
if (t.startsWith(MQTT_TOPIC_RELAY)) {
// Get value
unsigned char value = relayParsePayload(payload);
if (value == 0xFF) return;
// magnitude is relay/#/pulse
if (t.startsWith(MQTT_TOPIC_RELAY) && t.endsWith(MQTT_TOPIC_PULSE)) {
unsigned int id = t.substring(t.indexOf("/"), t.lastIndexOf("/")).toInt();
if (id >= relayCount()) {
DEBUG_MSG_P(PSTR("[RELAY] Wrong relayID (%d)\n"), id);
return;
}
unsigned long pulse = 1000 * String(payload).toFloat();
if (pulse == 0) return;
if (_relays[id].pulse != RELAY_PULSE_NONE) {
DEBUG_MSG_P(PSTR("[RELAY] Overriding relay #%d pulse settings\n"), id);
}
_relays[id].pulse_ms = pulse;
_relays[id].pulse = relayStatus(id) ? RELAY_PULSE_ON : RELAY_PULSE_OFF;
relayToggle(id, true, false);
return;
}
// magnitude is relay/#
if (t.startsWith(MQTT_TOPIC_RELAY)) {
// Get relay ID
unsigned int id = t.substring(strlen(MQTT_TOPIC_RELAY)+1).toInt();
if (id >= relayCount()) {
DEBUG_MSG_P(PSTR("[RELAY] Wrong relayID (%d)\n"), id);
} else {
relayStatusWrap(id, value, false);
return;
}
return;
// Get value
unsigned char value = relayParsePayload(payload);
if (value == 0xFF) return;
relayStatusWrap(id, value, false);
return;
}
// Check group topics
for (unsigned int i=0; i < _relays.size(); i++) {
@@ -814,6 +833,11 @@ void _relayInitCommands() {
return;
}
int id = String(e->argv[1]).toInt();
if (id >= relayCount()) {
DEBUG_MSG_P(PSTR("-ERROR: Wrong relayID (%d)\n"), id);
return;
}
if (e->argc > 2) {
int value = String(e->argv[2]).toInt();
if (value == 2) {
@@ -823,6 +847,11 @@ void _relayInitCommands() {
}
}
DEBUG_MSG_P(PSTR("Status: %s\n"), _relays[id].target_status ? "true" : "false");
if (_relays[id].pulse != RELAY_PULSE_NONE) {
DEBUG_MSG_P(PSTR("Pulse: %s\n"), (_relays[id].pulse == RELAY_PULSE_ON) ? "ON" : "OFF");
DEBUG_MSG_P(PSTR("Pulse time: %d\n"), _relays[id].pulse_ms);
}
DEBUG_MSG_P(PSTR("+OK\n"));
});
@@ -835,7 +864,6 @@ void _relayInitCommands() {
//------------------------------------------------------------------------------
void _relayLoop() {
_relayPulseCheck();
_relayProcess(false);
_relayProcess(true);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1336,7 +1336,7 @@
</div>
<div class="pure-g">
<div class="pure-u-1 pure-u-lg-1-4"><label>Pulse time (s)</label></div>
<div class="pure-u-1 pure-u-lg-1-4"><input name="relayTime" class="pure-u-1" type="number" min="0" step="0.1" max="86400" /></div>
<div class="pure-u-1 pure-u-lg-1-4"><input name="relayTime" class="pure-u-1" type="number" min="0" step="0.1" max="3600" /></div>
</div>
<div class="pure-g module module-mqtt">
<div class="pure-u-1 pure-u-lg-1-4"><label>MQTT group</label></div>