diff --git a/code/espurna/config/general.h b/code/espurna/config/general.h index 225d9c9b..bc7f9ac7 100644 --- a/code/espurna/config/general.h +++ b/code/espurna/config/general.h @@ -682,6 +682,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" diff --git a/code/espurna/relay.ino b/code/espurna/relay.ino index 2e7fd5d1..916c2f41 100644 --- a/code/espurna/relay.ino +++ b/code/espurna/relay.ino @@ -209,6 +209,8 @@ void _relayProcess(bool mode) { 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; @@ -217,11 +219,12 @@ void relayPulse(unsigned char id) { bool status = relayStatus(id); bool pulseStatus = (mode == RELAY_PULSE_ON); - if (pulseStatus == status) { - _relays[id].pulseTicker.detach(); - } else { + if (pulseStatus != status) { DEBUG_MSG_P(PSTR("[RELAY] Scheduling relay #%d back in %lums (pulse)\n"), id, ms); _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(); } } @@ -693,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++) { @@ -707,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++) { @@ -800,6 +832,11 @@ void _relayInitCommands() { DEBUG_MSG_P(PSTR("-ERROR: Wrong arguments\n")); } 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) { @@ -809,6 +846,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")); });