diff --git a/code/espurna/button.ino b/code/espurna/button.ino index 81720806..a9806d3e 100644 --- a/code/espurna/button.ino +++ b/code/espurna/button.ino @@ -106,6 +106,12 @@ void buttonSetup() { _buttons.push_back({new DebounceEvent(BUTTON4_PIN), BUTTON4_RELAY}); #endif + #ifdef LED_PULSE + pinMode(LED_PULSE, OUTPUT); + byte relayPulseMode = getSetting("relayPulseMode", String(RELAY_PULSE_MODE)).toInt(); + digitalWrite(LED_PULSE, relayPulseMode != RELAY_PULSE_NONE); + #endif + DEBUG_MSG("[BUTTON] Number of buttons: %d\n", _buttons.size()); } @@ -114,20 +120,32 @@ void buttonLoop() { for (unsigned int i=0; i < _buttons.size(); i++) { if (_buttons[i].button->loop()) { + uint8_t event = _buttons[i].button->getEvent(); DEBUG_MSG("[BUTTON] Pressed #%d, event: %d\n", i, event); + #ifdef MQTT_BUTTON_TOPIC buttonMQTT(i); #endif + if (i == 0) { if (event == EVENT_DOUBLE_CLICK) createAP(); if (event == EVENT_LONG_CLICK) ESP.reset(); } + + #ifdef ITEAD_1CH_INCHING + if (i == 1) { + relayPulseToggle(); + continue; + } + #endif + if (event == EVENT_SINGLE_CLICK) { if (_buttons[i].relayID > 0) { relayToggle(_buttons[i].relayID - 1); } } + } } diff --git a/code/espurna/config/general.h b/code/espurna/config/general.h index ebea1ec5..3d78446c 100644 --- a/code/espurna/config/general.h +++ b/code/espurna/config/general.h @@ -20,12 +20,22 @@ #define RELAY_SYNC_ONE 2 #define RELAY_SYNC_SAME 3 +#define RELAY_PULSE_NONE 0 +#define RELAY_PULSE_OFF 1 +#define RELAY_PULSE_ON 2 + +// Pulse time in seconds +#define RELAY_PULSE_TIME 1 + // 0 means OFF, 1 ON and 2 whatever was before #define RELAY_MODE RELAY_MODE_OFF // 0 means ANY, 1 zero or one and 2 one and only one #define RELAY_SYNC RELAY_SYNC_ANY +// 0 means no pulses, 1 means normally off, 2 normally on +#define RELAY_PULSE_MODE RELAY_PULSE_NONE + //-------------------------------------------------------------------------------- // LED //-------------------------------------------------------------------------------- diff --git a/code/espurna/config/hardware.h b/code/espurna/config/hardware.h index 5dead08f..2d0dd5f2 100644 --- a/code/espurna/config/hardware.h +++ b/code/espurna/config/hardware.h @@ -137,6 +137,24 @@ #define LED1_PIN 13 #define LED1_PIN_INVERSE 1 +#elif defined(ITEAD_1CH_INCHING) + + // Note: definitions for this board are based on third party data + // and have not been fully tested yet. If you have the chance to + // test them, please report back. Thank you. + + #define MANUFACTURER "ITEAD" + #define DEVICE "1CH_INCHING" + #define BUTTON1_PIN 0 + #define BUTTON1_RELAY 1 + #define BUTTON2_PIN 15 + #define BUTTON2_RELAY 0 + #define RELAY1_PIN 12 + #define RELAY1_PIN_INVERSE 0 + #define LED1_PIN 13 + #define LED1_PIN_INVERSE 0 + #define LED_PULSE 14 + // ----------------------------------------------------------------------------- // Electrodragon boards // ----------------------------------------------------------------------------- diff --git a/code/espurna/data/index.html.gz b/code/espurna/data/index.html.gz index 4e662552..ef0a84a5 100644 Binary files a/code/espurna/data/index.html.gz and b/code/espurna/data/index.html.gz differ diff --git a/code/espurna/relay.ino b/code/espurna/relay.ino index ff185a22..68a5c760 100644 --- a/code/espurna/relay.ino +++ b/code/espurna/relay.ino @@ -7,6 +7,7 @@ Copyright (C) 2016-2017 by Xose PĂ©rez */ #include +#include #include #include #include @@ -20,6 +21,7 @@ std::vector _relays; #ifdef SONOFF_DUAL unsigned char dualRelayStatus = 0; #endif +Ticker pulseTicker; bool recursive = false; @@ -50,6 +52,71 @@ bool relayStatus(unsigned char id) { #endif } +void relayPulseBack(unsigned char id) { + relayToggle(id); + pulseTicker.detach(); +} + +void relayPulse(unsigned char id) { + + byte relayPulseMode = getSetting("relayPulseMode", RELAY_PULSE_MODE).toInt(); + if (relayPulseMode == RELAY_PULSE_NONE) return; + + bool status = relayStatus(id); + bool pulseStatus = (relayPulseMode == RELAY_PULSE_ON); + if (pulseStatus == status) { + pulseTicker.detach(); + return; + } + + pulseTicker.attach( + getSetting("relayPulseTime", RELAY_PULSE_TIME).toInt(), + relayPulseBack, + id + ); + +} + +unsigned int relayPulseMode() { + unsigned int value = getSetting("relayPulseMode", RELAY_PULSE_MODE).toInt(); + return value; +} + +void relayPulseMode(unsigned int value, bool report) { + + setSetting("relayPulseMode", value); + + /* + if (report) { + String mqttGetter = getSetting("mqttGetter", MQTT_USE_GETTER); + char topic[strlen(MQTT_RELAY_TOPIC) + mqttGetter.length() + 10]; + sprintf(topic, "%s/pulse%s", MQTT_RELAY_TOPIC, mqttGetter.c_str()); + char value[2]; + sprintf(value, "%d", value); + mqttSend(topic, value); + } + */ + + char message[20]; + sprintf(message, "{\"relayPulseMode\": %d}", value); + wsSend(message); + + #ifdef LED_PULSE + digitalWrite(LED_PULSE, value != RELAY_PULSE_NONE); + #endif + +} + +void relayPulseMode(unsigned int value) { + relayPulseMode(value, true); +} + +void relayPulseToggle() { + unsigned int value = relayPulseMode(); + value = (value == RELAY_PULSE_NONE) ? RELAY_PULSE_OFF : RELAY_PULSE_NONE; + relayPulseMode(value); +} + bool relayStatus(unsigned char id, bool status, bool report) { if (id >= _relays.size()) return false; @@ -77,6 +144,7 @@ bool relayStatus(unsigned char id, bool status, bool report) { if (report) relayMQTT(id); if (!recursive) { + relayPulse(id); relaySync(id); relaySave(); relayWS(); @@ -93,7 +161,6 @@ bool relayStatus(unsigned char id, bool status, bool report) { } bool relayStatus(unsigned char id, bool status) { - if (id >= _relays.size()) return false; return relayStatus(id, status, true); } @@ -300,10 +367,16 @@ void relayMQTTCallback(unsigned int type, const char * topic, const char * paylo bool sameSetGet = mqttGetter.compareTo(mqttSetter) == 0; if (type == MQTT_CONNECT_EVENT) { + relayMQTT(); - char buffer[strlen(MQTT_RELAY_TOPIC) + mqttSetter.length() + 3]; + char buffer[strlen(MQTT_RELAY_TOPIC) + mqttSetter.length() + 10]; + sprintf(buffer, "%s/+%s", MQTT_RELAY_TOPIC, mqttSetter.c_str()); mqttSubscribe(buffer); + + sprintf(buffer, "%s/pulse%s", MQTT_RELAY_TOPIC, mqttSetter.c_str()); + mqttSubscribe(buffer); + } if (type == MQTT_MESSAGE_EVENT) { @@ -313,6 +386,15 @@ void relayMQTTCallback(unsigned int type, const char * topic, const char * paylo if (!t.startsWith(MQTT_RELAY_TOPIC)) return; if (!t.endsWith(mqttSetter)) return; + // Get value + unsigned int value = (char)payload[0] - '0'; + + // Pulse topic + if (t.indexOf("pulse") > 0) { + relayPulseMode(value, !sameSetGet); + return; + } + // Get relay ID unsigned int relayID = topic[strlen(topic) - mqttSetter.length() - 1] - '0'; if (relayID >= relayCount()) { @@ -321,7 +403,6 @@ void relayMQTTCallback(unsigned int type, const char * topic, const char * paylo } // Action to perform - unsigned int value = (char)payload[0] - '0'; if (value == 2) { relayToggle(relayID); } else { diff --git a/code/espurna/web.ino b/code/espurna/web.ino index 0c00e78f..d6d23355 100644 --- a/code/espurna/web.ino +++ b/code/espurna/web.ino @@ -264,6 +264,11 @@ void _wsParse(uint32_t client_id, uint8_t * payload, size_t length) { setCurrentRatio(getSetting("emonRatio").toFloat()); #endif + #if ITEAD_1CH_INCHING + byte relayPulseMode = getSetting("relayPulseMode", String(RELAY_PULSE_MODE)).toInt(); + digitalWrite(LED_PULSE, relayPulseMode != RELAY_PULSE_NONE); + #endif + // Check if we should reconfigure MQTT connection if (changedMQTT) { mqttDisconnect(); @@ -313,6 +318,8 @@ void _wsStart(uint32_t client_id) { relay.add(relayStatus(relayID)); } root["relayMode"] = getSetting("relayMode", RELAY_MODE); + root["relayPulseMode"] = getSetting("relayPulseMode", RELAY_PULSE_MODE); + root["relayPulseTime"] = getSetting("relayPulseTime", RELAY_PULSE_TIME); if (relayCount() > 1) { root["multirelayVisible"] = 1; root["relaySync"] = getSetting("relaySync", RELAY_SYNC); diff --git a/code/html/index.html b/code/html/index.html index 4aecb410..51556ae8 100644 --- a/code/html/index.html +++ b/code/html/index.html @@ -197,7 +197,7 @@
-