I have a water tank installed at my place which has two sensors in, one is at the bottom (LS) and one is at the top (US).
Whenever the water level goes below LS the relay to the motor turns on and as soon as the water hits the US that same relay turns off.
Until yesterday i was using US as a button in supla which turns off the relay locally and used US as action trigger to turn on the relay.
But yesterday i don't know if it was a local problem or there was a server problem i was not able to access the app,nor was i able to see any devices on supla,as i used LS as action trigger to turn on relay i was unable to turn on the relay manually and fill my water tank.
What i was wondering is ,if there is any way there can be a local version for the two gpio buttons for the same relay for which one button only turns on the relay and other only turns of the relay regardless of high/low state.
Thank you.
1 relay with two separate on and off gpio
It's just a matter of firmware. What hardware do you use? It would be easiest for you to implement something like this on Arduino.
Gpio 0 "D3" = WiFiConfig, connected to GND for at least 5 seconds.
Gpio 2 "D4" = stateLed " on = WiFiConfig, wink = connecting, off = OK.
Gpio 4 "D2" = manual on/off: toggle the state of the relay with each press.
Gpio 5 "D1" = relay.
Gpio 12 "D5" = start pin: activates the relay - while it is release, it activates the relay every 2 seconds.
Gpio 14 "D6" = stop pin: deactivates the relay - while it is pressed, it deactivates the relay every 2 seconds.
configuration as usual with WiFiconfig, connecting to the WiFi network with name: "water_level".
Gpio 2 "D4" = stateLed " on = WiFiConfig, wink = connecting, off = OK.
Gpio 4 "D2" = manual on/off: toggle the state of the relay with each press.
Gpio 5 "D1" = relay.
Gpio 12 "D5" = start pin: activates the relay - while it is release, it activates the relay every 2 seconds.
Gpio 14 "D6" = stop pin: deactivates the relay - while it is pressed, it deactivates the relay every 2 seconds.
configuration as usual with WiFiconfig, connecting to the WiFi network with name: "water_level".
Code: Select all
/*
Copyright (C) AC SOFTWARE SP. Z O.O.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define supla_lib_config_h_ // silences debug messages
#include "LittleFS.h"
#include <WiFiManager.h>
#include <ArduinoJson.h>
#include <EEPROM.h>
#include <ESP8266TrueRandom.h>
#include <SuplaDevice.h> // Supla device 2.4.1
#include <supla/control/relay.h>
#include <supla/control/button.h>
#include <supla/device/status_led.h>
#include <supla/network/esp_wifi.h>
Supla::ESPWifi wifi("SSID", "PASS"); //------ Do not change----wifimanager takes care------
extern "C"
{
#include "user_interface.h"
}
int stateLed = 2; // D4
int start_pin = 14; // D5
int stop_pin = 12; // D6
int manual_pin = 4; // D2
int button_pin = 0; // D3
int relay_pin = 5; // D1
long C_W_delay = 5000; // ---------------------- config delay 5 seconds ---------------------------
int C_W_state = HIGH;
int last_C_W_state = HIGH;
unsigned long time_last_C_W_change = 0;
char Supla_server[81] = ("svr?.supla.org");
char Email[81] = ("your@email");
char Supla_name[51] = ("water_level");
char Supla_status[51] = ("No server address");
char Router_SSID[32];
char Router_Pass[64];
bool shouldSaveConfig = false;
bool initialConfig = false;
int s;
char GUID[SUPLA_GUID_SIZE];
char AUTHKEY[SUPLA_AUTHKEY_SIZE];
byte uuidNumber[16];
const char logo[] PROGMEM = "<style>html{ background-color: #01DF3A;}</style><div class='s'><svg version='1.1' id='l' x='0' y='0' viewBox='0 0 200 200' xml:space='preserve'><path d='M59.3,2.5c18.1,0.6,31.8,8,40.2,23.5c3.1,5.7,4.3,11.9,4.1,18.3c-0.1,3.6-0.7,7.1-1.9,10.6c-0.2,0.7-0.1,1.1,0.6,1.5c12.8,7.7,25.5,15.4,38.3,23c2.9,1.7,5.8,3.4,8.7,5.3c1,0.6,1.6,0.6,2.5-0.1c4.5-3.6,9.8-5.3,15.7-5.4c12.5-0.1,22.9,7.9,25.2,19c1.9,9.2-2.9,19.2-11.8,23.9c-8.4,4.5-16.9,4.5-25.5,0.2c-0.7-0.3-1-0.2-1.5,0.3c-4.8,4.9-9.7,9.8-14.5,14.6c-5.3,5.3-10.6,10.7-15.9,16c-1.8,1.8-3.6,3.7-5.4,5.4c-0.7,0.6-0.6,1,0,1.6c3.6,3.4,5.8,7.5,6.2,12.2c0.7,7.7-2.2,14-8.8,18.5c-12.3,8.6-30.3,3.5-35-10.4c-2.8-8.4,0.6-17.7,8.6-22.8c0.9-0.6,1.1-1,0.8-2c-2-6.2-4.4-12.4-6.6-18.6c-6.3-17.6-12.7-35.1-19-52.7c-0.2-0.7-0.5-1-1.4-0.9c-12.5,0.7-23.6-2.6-33-10.4c-8-6.6-12.9-15-14.2-25c-1.5-11.5,1.7-21.9,9.6-30.7C32.5,8.9,42.2,4.2,53.7,2.7c0.7-0.1,1.5-0.2,2.2-0.2C57,2.4,58.2,2.5,59.3,2.5z M76.5,81c0,0.1,0.1,0.3,0.1,0.6c1.6,6.3,3.2,12.6,4.7,18.9c4.5,17.7,8.9,35.5,13.3,53.2c0.2,0.9,0.6,1.1,1.6,0.9c5.4-1.2,10.7-0.8,15.7,1.6c0.8,0.4,1.2,0.3,1.7-0.4c11.2-12.9,22.5-25.7,33.4-38.7c0.5-0.6,0.4-1,0-1.6c-5.6-7.9-6.1-16.1-1.3-24.5c0.5-0.8,0.3-1.1-0.5-1.6c-9.1-4.7-18.1-9.3-27.2-14c-6.8-3.5-13.5-7-20.3-10.5c-0.7-0.4-1.1-0.3-1.6,0.4c-1.3,1.8-2.7,3.5-4.3,5.1c-4.2,4.2-9.1,7.4-14.7,9.7C76.9,80.3,76.4,80.3,76.5,81z M89,42.6c0.1-2.5-0.4-5.4-1.5-8.1C83,23.1,74.2,16.9,61.7,15.8c-10-0.9-18.6,2.4-25.3,9.7c-8.4,9-9.3,22.4-2.2,32.4c6.8,9.6,19.1,14.2,31.4,11.9C79.2,67.1,89,55.9,89,42.6z M102.1,188.6c0.6,0.1,1.5-0.1,2.4-0.2c9.5-1.4,15.3-10.9,11.6-19.2c-2.6-5.9-9.4-9.6-16.8-8.6c-8.3,1.2-14.1,8.9-12.4,16.6C88.2,183.9,94.4,188.6,102.1,188.6z M167.7,88.5c-1,0-2.1,0.1-3.1,0.3c-9,1.7-14.2,10.6-10.8,18.6c2.9,6.8,11.4,10.3,19,7.8c7.1-2.3,11.1-9.1,9.6-15.9C180.9,93,174.8,88.5,167.7,88.5z'/></svg>";
WiFiManager wifiManager;
Supla::Device::StatusLed *LedS = nullptr;
void saveConfigCallback () {
Serial.println("Should save config");
shouldSaveConfig = true;
}
void ondemandwifiCallback () {
LedS->setCustomSequence(1000, 0); // void setCustomSequence(int onDurationMs, int offDurationMs);
delay (100);
wifi.setSsid("");
wifi.setPassword("");
wifiManager.setConfigPortalBlocking(true);
wifiManager.setCleanConnect(true);
wifiManager.setBreakAfterConfig(true);
wifiManager.setSaveConfigCallback(saveConfigCallback);
wifiManager.setCustomHeadElement(logo);
wifiManager.setMinimumSignalQuality(8);
wifiManager.setConfigPortalTimeout(300);
std::vector<const char *> menu = {"wifi", "wifinoscan", "sep", "update", "sep", "info", "restart"};
wifiManager.setMenu(menu);
wifiManager.setTitle("By..ElMaya");
WiFiManagerParameter custom_Supla_server("server", "supla server", Supla_server, 81, "required");
WiFiManagerParameter custom_Email("email", "Email", Email, 81, "required");
WiFiManagerParameter custom_Supla_name("name", "Supla Device Name", Supla_name, 51, "required");
WiFiManagerParameter custom_html_id21("<div><h4> - Supla State - ");
WiFiManagerParameter custom_html_id22(Supla_status);
WiFiManagerParameter custom_html_id23("</h4></div>");
wifiManager.addParameter(&custom_Supla_server);
wifiManager.addParameter(&custom_Email);
wifiManager.addParameter(&custom_Supla_name);
wifiManager.addParameter(&custom_html_id21);
wifiManager.addParameter(&custom_html_id22);
wifiManager.addParameter(&custom_html_id23);
if (!wifiManager.startConfigPortal("water_level")) {
Serial.println("Not connected to WiFi but continuing anyway.");
} else {
Serial.println("connected...yeey :)");
}
strcpy(Supla_server, custom_Supla_server.getValue());
strcpy(Email, custom_Email.getValue());
strcpy(Supla_name, custom_Supla_name.getValue());
wifiManager.getWiFiSSID().toCharArray(Router_SSID, 33);
wifiManager.getWiFiPass().toCharArray(Router_Pass, 65);
if (strcmp(Supla_server, "get_new_guid_and_authkey") == 0) {
Serial.println("new guid & authkey.");
EEPROM.write(300, 0);
EEPROM.commit();
delay(100);
ESP.reset();
}
if (shouldSaveConfig) {
DynamicJsonDocument json(1024);
json["Supla_server"] = Supla_server;
json["Email"] = Email;
json["Supla_name"] = Supla_name;
json["Router_SSID"] = Router_SSID;
json["Router_Pass"] = Router_Pass;
File configFile = LittleFS.open("/config.json", "w");
if (!configFile) {
Serial.println("failed to open config file for writing");
}
//serializeJsonPretty(json, Serial);
serializeJson(json, configFile);
configFile.close();
shouldSaveConfig = false;
initialConfig = false;
WiFi.mode(WIFI_STA);
delay(5000);
ESP.restart();
}
WiFi.softAPdisconnect(true);
if (initialConfig == true) {
shouldSaveConfig = false;
initialConfig = false;
WiFi.mode(WIFI_STA);
delay(5000);
ESP.restart();
}
LedS->setAutoSequence(); // Restores automatic LED sequence change based on device state.
}
void status_func(int status, const char *msg) { // ------------------------ Status --------------------------
if (s != status) {
s = status;
if (s != 10) {
strcpy(Supla_status, msg);
}
}
}
void guid_authkey(void) {
if (EEPROM.read(300) != 60) {
int eep_gui = 301;
ESP8266TrueRandom.uuid(uuidNumber);
String uuidString = "";
for (int i = 0; i < 16; i++) {
int topDigit = uuidNumber[i] >> 4;
int bottomDigit = uuidNumber[i] & 0x0f;
uuidString += "0123456789abcdef"[topDigit];
uuidString += "0123456789abcdef"[bottomDigit];
}
int length_uuid = uuidString.length();
for (int i = 0; i < length_uuid; ++i) {
EEPROM.put(eep_gui + i, uuidString[i]);
}
int eep_aut = 341;
ESP8266TrueRandom.uuid(uuidNumber);
String uuidString2 = "";
for (int i = 0; i < 16; i++) {
int topDigit = uuidNumber[i] >> 4;
int bottomDigit = uuidNumber[i] & 0x0f;
uuidString2 += "0123456789abcdef"[topDigit];
uuidString2 += "0123456789abcdef"[bottomDigit];
}
int length_uuid2 = uuidString2.length();
for (int i = 0; i < length_uuid2; ++i) {
EEPROM.put(eep_aut + i, uuidString2[i]);
}
EEPROM.write(300, 60);
EEPROM.commit();
delay(0);
}
read_guid();
read_authkey();
//Serial.print("GUID : ");Serial.println(read_guid());
//Serial.print("AUTHKEY : ");Serial.println(read_authkey());
}
String read_guid(void) {
String read_eeprom = "";
int i, ii = 0;
int eep_star = 301;
int end_guid = eep_star + SUPLA_GUID_SIZE;
String temp_read = "0x";
for (i = eep_star; i < end_guid + 16; i = i + 1) {
temp_read += char(EEPROM.read(i));
read_eeprom += char(EEPROM.read(i));
if ( (i % 2) == 0) {
char *_guid = strcpy((char*)malloc(temp_read.length() + 1), temp_read.c_str());
GUID[ii] = strtoul( _guid, NULL, 16);
temp_read = "0x";
ii++;
}
}
return read_eeprom;
}
String read_authkey(void) {
String read_eeprom = "";
int i, ii = 0;
int eep_star = 341;
int end_authkey = eep_star + SUPLA_AUTHKEY_SIZE;
String temp_read = "0x";
for (i = eep_star; i < end_authkey + 16; i = i + 1) {
temp_read += char(EEPROM.read(i));
read_eeprom += char(EEPROM.read(i));
if ( (i % 2) == 0) {
char *_authkey = strcpy((char*)malloc(temp_read.length() + 1), temp_read.c_str());
AUTHKEY[ii] = strtoul( _authkey, NULL, 16);
temp_read = "0x";
ii++;
}
}
return read_eeprom;
}
void setup() {
wifi_set_sleep_type(NONE_SLEEP_T);
pinMode(button_pin, INPUT_PULLUP);
Serial.begin(115200, SERIAL_8N1, SERIAL_TX_ONLY, 1);
EEPROM.begin(1024);
if (EEPROM.read(300) != 60) {
initialConfig = true;
}
guid_authkey();
if (LittleFS.begin()) { // ------------------------- wificonfig read -----------------
if (LittleFS.exists("/config.json")) {
File configFile = LittleFS.open("/config.json", "r");
if (configFile) {
DynamicJsonDocument json(1024);
DeserializationError deserializeError = deserializeJson(json, configFile);
serializeJsonPretty(json, Serial);
if (!deserializeError) {
Serial.println("\nparsed json");
if (json.containsKey("Supla_server")) strcpy(Supla_server, json["Supla_server"]);
if (json.containsKey("Email")) strcpy(Email, json["Email"]);
if (json.containsKey("Supla_name")) strcpy(Supla_name, json["Supla_name"]);
if (json.containsKey("Router_SSID")) strcpy(Router_SSID, json["Router_SSID"]);
if (json.containsKey("Router_Pass")) strcpy(Router_Pass, json["Router_Pass"]);
} else {
initialConfig = true;
}
configFile.close();
}
}
} else {
Serial.println("failed to mount FS");
}
wifi_station_set_hostname(Supla_name);
WiFi.mode(WIFI_STA);
auto relay_0 = new Supla::Control::Relay(relay_pin, true, 32);
relay_0->getChannel()->setDefault(SUPLA_CHANNELFNC_POWERSWITCH);
auto button_1 = new Supla::Control::Button(start_pin, true, false);
auto button_2 = new Supla::Control::Button(stop_pin, true, true);
auto button_3 = new Supla::Control::Button(manual_pin, true, true);
button_1->setHoldTime(500);
button_2->setHoldTime(500);
button_1->repeatOnHoldEvery(2000);
button_2->repeatOnHoldEvery(2000);
button_1->addAction(Supla::TURN_ON, relay_0, Supla::ON_PRESS);
button_1->addAction(Supla::TURN_ON, relay_0, Supla::ON_HOLD);
button_2->addAction(Supla::TURN_OFF, relay_0, Supla::ON_PRESS);
button_2->addAction(Supla::TURN_OFF, relay_0, Supla::ON_HOLD);
button_3->addAction(Supla::TOGGLE, relay_0, Supla::ON_PRESS);
LedS = new Supla::Device::StatusLed(stateLed, true);
LedS->setMode(Supla::LED_OFF_WHEN_CONNECTED);
SuplaDevice.setName(Supla_name);
wifi.setSsid(Router_SSID);
wifi.setPassword(Router_Pass);
SuplaDevice.setStatusFuncImpl(&status_func);
wifi.enableSSL(false);
if (initialConfig) {
ondemandwifiCallback();
}
SuplaDevice.begin(GUID, Supla_server, Email, AUTHKEY);
}
void loop() {
int C_W_read = digitalRead(button_pin); {
if (C_W_read != last_C_W_state) {
time_last_C_W_change = millis();
}
if ((millis() - time_last_C_W_change) > C_W_delay) {
if (C_W_read != C_W_state) {
C_W_state = C_W_read;
if (C_W_state == LOW) {
ondemandwifiCallback () ;
}
}
}
last_C_W_state = C_W_read;
}
SuplaDevice.iterate();
delay(20);
}