Supla 16 X relay -- esp8266 + mcp23017

elmaya
Posts: 1482
Joined: Wed Jun 27, 2018 5:48 pm
Location: El Saucejo - Sevilla

Post

Supla 16 X relay -- esp8266 + mcp23017

mcp23017 X 16_bb.png

esp8266
Gpio 5(D1) -- SCL
Gpio 4(D2) -- SDA
Gpio 0(D3) -- WiFiConfig
Gpio 2(D4) -- Led (turn on when on WiFiConfig)

Mcp23017
in VCC -- +3.3
in Gnd-a0-a1-a2 --GND
SCL -- esp Gpio 5(D1)
SDA -- esp Gpio 4(D2)
Gpio A0 -- Out 1
Gpio A1 -- Out 2
Gpio A2 -- Out 3
Gpio A3 -- Out 4
Gpio A4 -- Out 5
Gpio A5 -- Out 6
Gpio A6 -- Out 7
Gpio A7 -- Out 8
Gpio B0 -- Out 9
Gpio B1 -- Out 10
Gpio B2 -- Out 11
Gpio B3 -- Out 12
Gpio B4 -- Out 13
Gpio B5 -- Out 14
Gpio B6 -- Out 15
Gpio B7 -- Out 16

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.
*/

#include <FS.h>       // ---- esp board manager 2.5.2 --- iwip Variant V2 Lower Memory 
#include <SPI.h>
#include <SuplaDevice.h>  // SoftVer, "2.3.0"
#include <io.h>
#include <Adafruit_MCP23017.h>
#include <WiFiManager.h>
#include <ArduinoJson.h> //--------- https://github.com/bblanchon/ArduinoJson/tree/v5.13.2 ------
#include <EEPROM.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPUpdateServer.h>
#include <ESP8266TrueRandom.h>
#include <WiFiClientSecure.h>
#include <supla/network/esp_wifi.h>
Supla::ESPWifi wifi("", "");  //------ Do not change----wifimanager takes care------
extern "C"
{
#include "user_interface.h"
} 

//#define D0 16  //no internal pullup resistor
//#define D1  5
//#define D2  4
//#define D3  0  //must not be pulled low during power on/reset, toggles value during boot
//#define D4  2  //must not be pulled low during power on/reset, toggles value during boot
//#define D5 14
//#define D6 12
//#define D7 13
//#define D8 15  //must not be pulled high during power on/reset

int wificonfig_pin = 0;   //D3
int led_pin = 2;          //D4
int C_W_state = HIGH; 
int last_C_W_state = HIGH;
unsigned long time_last_C_W_change = 0; 
long C_W_delay = 5000;               // ---------------------- config delay 5 seconds ---------------------------
char Supla_server[81]=("Set server address");
char Email[81]=("set email address");
char Supla_name[51];
char Supla_status[51];
bool shouldSaveConfig = false;
bool initialConfig = false;
bool state10 = true;
bool starting = true;
int s;
char GUID[SUPLA_GUID_SIZE];
char AUTHKEY[SUPLA_AUTHKEY_SIZE];
byte uuidNumber[16]; // UUIDs in binary form are 16 bytes long
static 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>";

ESP8266WebServer httpServer(81);
ESP8266HTTPUpdateServer httpUpdater;
WiFiManager wifiManager;
Adafruit_MCP23017 mcp;

class MyMcp23017 : public Supla::Io {
  public:
    void customDigitalWrite(int channelNumber, uint8_t pin, uint8_t val) {
      if ((pin >= 100)&& (pin <= 115)){
        mcp.digitalWrite(pin - 100, val);
         if (state10 == false){ 
           EEPROM.write(pin, val);
           EEPROM.commit(); 
         }    
         return;
      }
      if (pin <= 99) {
        return ::digitalWrite(pin,val);   // ------------------------------ so that the other channels work normally
      }
   }
   
   int customDigitalRead(int channelNumber, uint8_t pin) {
      if ((pin >= 100)&& (pin <= 115)){
        return mcp.digitalRead(pin - 100);     
      }     
      if (pin <= 99){
        return ::digitalRead(pin);  // ------------------------------ so that the other channels work normally
      }
    }   
}MyMcp23017; 

void saveConfigCallback () {          
  Serial.println("Should save config");
  shouldSaveConfig = true;
}
void ondemandwifiCallback () {
   digitalWrite(led_pin, LOW);
   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_Supla_status("status", "Supla Last State", Supla_status, 51,"readonly");
   
   wifiManager.setBreakAfterConfig(true);
   wifiManager.setSaveConfigCallback(saveConfigCallback);
  
   wifiManager.addParameter(&custom_Supla_server);
   wifiManager.addParameter(&custom_Email);
   wifiManager.addParameter(&custom_Supla_name);
   wifiManager.addParameter(&custom_Supla_status);

   wifiManager.setCustomHeadElement(logo);
   wifiManager.setMinimumSignalQuality(8);
   //wifiManager.setShowStaticFields(true); // force show static ip fields
   //wifiManager.setShowDnsFields(true);    // force show dns field always
   wifiManager.setConfigPortalTimeout(300);

   if (!wifiManager.startConfigPortal("Supla_16X")) { 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());
    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(); 
    }  
    WiFi.softAPdisconnect(true);   //  close AP
}
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 = 321;
    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 = 321;
  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);
  Serial.begin(115200);
  delay(10);
  Serial.println(" ");
  Serial.println(" ");
  pinMode(wificonfig_pin, INPUT_PULLUP);
  pinMode(led_pin,OUTPUT);   
  digitalWrite(led_pin, HIGH);
  EEPROM.begin(1024);
  if (EEPROM.read(300) != 60){initialConfig = true;} 
  guid_authkey();
  
  if (WiFi.SSID()==""){ initialConfig = true;} 

  mcp.begin();      // use default address 0
  mcp.pinMode(0, OUTPUT);
  mcp.pinMode(1, OUTPUT);
  mcp.pinMode(2, OUTPUT);
  mcp.pinMode(3, OUTPUT);
  mcp.pinMode(4, OUTPUT);
  mcp.pinMode(5, OUTPUT);
  mcp.pinMode(6, OUTPUT);
  mcp.pinMode(7, OUTPUT);
  mcp.pinMode(8, OUTPUT);
  mcp.pinMode(9, OUTPUT);
  mcp.pinMode(10, OUTPUT);
  mcp.pinMode(11, OUTPUT);
  mcp.pinMode(12, OUTPUT);
  mcp.pinMode(13, OUTPUT);
  mcp.pinMode(14, OUTPUT);
  mcp.pinMode(15, OUTPUT); 

  if (SPIFFS.begin()) {  // ------------------------- wificonfig read -----------------
    Serial.println("mounted file system");
    if (SPIFFS.exists("/config.json")) {
      Serial.println("reading config file");
      File configFile = SPIFFS.open("/config.json", "r");
      if (configFile) {
        Serial.println("opened config file");
        size_t size = configFile.size();
        std::unique_ptr<char[]> buf(new char[size]);
        configFile.readBytes(buf.get(), size);
        DynamicJsonBuffer jsonBuffer;         
        JsonObject& json = jsonBuffer.parseObject(buf.get());
        json.printTo(Serial);   //print config data to serial on startup
        if (json.success()) {Serial.println("\nparsed json");         
          strcpy(Supla_server, json["Supla_server"]);
          strcpy(Email, json["Email"]);
          strcpy(Supla_name, json["Supla_name"]);        
        } else {
          Serial.println("failed to load json config");
          initialConfig = true;
        }
      }
    }
   } else {
    Serial.println("failed to mount FS");
  }
  
   wifi_station_set_hostname(Supla_name);   
   WiFi.mode(WIFI_STA); 

      SuplaDevice.addRelay(100, false);
      SuplaDevice.addRelay(101, false); 
      SuplaDevice.addRelay(102, false); 
      SuplaDevice.addRelay(103, false); 
      SuplaDevice.addRelay(104, false); 
      SuplaDevice.addRelay(105, false); 
      SuplaDevice.addRelay(106, false);
      SuplaDevice.addRelay(107, false);
      SuplaDevice.addRelay(108, false);
      SuplaDevice.addRelay(109, false); 
      SuplaDevice.addRelay(110, false); 
      SuplaDevice.addRelay(111, false); 
      SuplaDevice.addRelay(112, false); 
      SuplaDevice.addRelay(113, false); 
      SuplaDevice.addRelay(114, false);
      SuplaDevice.addRelay(115, false); 

    SuplaDevice.setName(Supla_name);
    SuplaDevice.setStatusFuncImpl(&status_func);
  
    SuplaDevice.begin(GUID,Supla_server,Email,AUTHKEY);
    
}

void loop() {
  if (initialConfig == true){ondemandwifiCallback();}

  int C_W_read = digitalRead(wificonfig_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;            
   }
      
  if (shouldSaveConfig == true) { // ------------------------ wificonfig save --------------
    Serial.println("saving config");
    DynamicJsonBuffer jsonBuffer;
    JsonObject& json = jsonBuffer.createObject();
    json["Supla_server"] = Supla_server;
    json["Email"] = Email;
    json["Supla_name"] = Supla_name;
    File configFile = SPIFFS.open("/config.json", "w");
    if (!configFile) {Serial.println("failed to open config file for writing"); }   
    json.prettyPrintTo(Serial);
    json.printTo(configFile);
    configFile.close();
    Serial.println("config saved");    
    shouldSaveConfig = false;
    initialConfig = false; 
    WiFi.mode(WIFI_STA);   
    delay(5000);
    ESP.restart(); 
  }
  
  SuplaDevice.iterate();
   delay(75);

     if (WiFi.status() == WL_CONNECTED){
    if (starting){
      httpUpdater.setup(&httpServer, "/update", "admin", "pass");
      httpServer.begin(); 
      starting = false;         
     }
     httpServer.handleClient();
   }

   switch (s) { 
    case 17:      // -----     STATUS_REGISTERED_AND_READY
     if (state10 == true){ 
      for (int i = 0; i < 16; i++) {
       if (EEPROM.read(i +100)> 0){
         SuplaDevice.channelValueChanged(i,1);
         }
        }            
      state10 = false;   
     }  
     break;     
    case 10:      // --------------------- REGISTER_IN_PROGRESS  ----------------------
     state10 = true;
     break;  
  }
}
To enter or change the settings:
To enter the WiFi configuration mode, press and hold the button for at least 5 seconds.
When in Wi-Fi configuration mode, the device enters Wi-Fi access point mode and the status LED turns on.
- Log in to https://cloud.supla.org (registration is free) and Activate registration for new device.
- Connect to the WiFi called "Supla_16X" from any device with wireless network and an Internet browser.
- Open the Page: http://192.168.4.1
- Tap Configure WiFi.
- On the configuration page
- Select the Wi-Fi network at the top by pressing the appropriate one and then enter the password.
- enter the data to:
suplaServer (svrX.supla.org),
Email (registration email in supla),
Supla Device Name (name with which it will be seen in the cloud),
- To finish click on Save to save the configuration data.

Firmware update through the OTA web browser - http: // XX: 81 / update
xx = Device IP. For example http://192.168.1.22:81/update
User: admin
Password: pass

Supla_16X_DOUT_16Mbit.rar
You do not have the required permissions to view the files attached to this post.
User avatar
lesny8
Posts: 2915
Joined: Mon Dec 11, 2017 9:43 pm

Post

You must use the develop version of the library.
SOP 2023 :heavy_check_mark:
SOP 2024 :heavy_check_mark:
Czekam na kolejne Supla Offline Party :upside_down_face:
piotrekk
Posts: 134
Joined: Thu Sep 19, 2019 7:12 am

Post

ok works
Last edited by piotrekk on Fri Feb 07, 2020 10:10 am, edited 1 time in total.
elmaya
Posts: 1482
Joined: Wed Jun 27, 2018 5:48 pm
Location: El Saucejo - Sevilla

Post

in English please :)
meliwal
Posts: 16
Joined: Fri Oct 26, 2018 4:47 pm

Post

interesting,I did everything you posted, and it works the first time, can you add buttons at least 8 to activate relays (not touch buttons thisway allow me to use rf receiver to swith relays) and ds18b20 sensor to this projects? thanks a lot
elmaya
Posts: 1482
Joined: Wed Jun 27, 2018 5:48 pm
Location: El Saucejo - Sevilla

Post

My intention is to add a second Mcp23017 for 16 buttons. :)
meliwal
Posts: 16
Joined: Fri Oct 26, 2018 4:47 pm

Post

it will help me.I'm waiting impatiently,thanks
elmaya
Posts: 1482
Joined: Wed Jun 27, 2018 5:48 pm
Location: El Saucejo - Sevilla

Post

Supla 16 X 16 relay

esp8266 + 2 x mcp23017
mcp23017 16 X 16_bb.png

esp8266
Gpio16(D0) -- Led (turn on when on WiFiConfig)
Gpio 5(D1) -- SCL
Gpio 4(D2) -- SDA
Gpio 0(D3) -- WiFiConfig
Gpio 2(D4) -- Mcp23017 RESET


Mcp23017 -- Relay
in VCC -- +3.3
in Gnd-a0-a1-a2 --GND
SCL -- esp Gpio 5(D1)
SDA -- esp Gpio 4(D2)
RESET -- esp Gpio 2(D4)
Gpio A0 -- Out 1
Gpio A1 -- Out 2
Gpio A2 -- Out 3
Gpio A3 -- Out 4
Gpio A4 -- Out 5
Gpio A5 -- Out 6
Gpio A6 -- Out 7
Gpio A7 -- Out 8
Gpio B0 -- Out 9
Gpio B1 -- Out 10
Gpio B2 -- Out 11
Gpio B3 -- Out 12
Gpio B4 -- Out 13
Gpio B5 -- Out 14
Gpio B6 -- Out 15
Gpio B7 -- Out 16

Mcp23017 -- button
in VCC-a0 -- +3.3
in Gnd-a1-a2 --GND
SCL -- esp Gpio 5(D1)
SDA -- esp Gpio 4(D2)
RESET -- esp Gpio 2(D4)
Gpio A0 -- button 1
Gpio A1 -- button 2
Gpio A2 -- button 3
Gpio A3 -- button 4
Gpio A4 -- button 5
Gpio A5 -- button 6
Gpio A6 -- button 7
Gpio A7 -- button 8
Gpio B0 -- button 9
Gpio B1 -- button 10
Gpio B2 -- button 11
Gpio B3 -- button 12
Gpio B4 -- button 13
Gpio B5 -- button 14
Gpio B6 -- button 15
Gpio B7 -- button 16

To enter or change the settings:
To enter the WiFi configuration mode, press and hold the button for at least 5 seconds.
When in Wi-Fi configuration mode, the device enters Wi-Fi access point mode and the status LED turns on.
- Log in to https://cloud.supla.org (registration is free) and Activate registration for new device.
- Connect to the WiFi called "Supla_16X16" from any device with wireless network and an Internet browser.
- Open the Page: http://192.168.4.1
- Tap Configure WiFi.
- On the configuration page
- Select the Wi-Fi network at the top by pressing the appropriate one and then enter the password.
- enter the data to:
suplaServer (svrX.supla.org),
Email (registration email in supla),
Supla Device Name (name with which it will be seen in the cloud),
- To finish click on Save to save the configuration data.

Firmware update through the OTA web browser - http: // XX: 81 / update
xx = Device IP. For example http://192.168.1.22:81/update
User: admin
Password: pass

Supla_16X16_DOUT_16Mbit.rar
You do not have the required permissions to view the files attached to this post.
meliwal
Posts: 16
Joined: Fri Oct 26, 2018 4:47 pm

Post

thanks elmaya, you're a genius ;)
elmaya
Posts: 1482
Joined: Wed Jun 27, 2018 5:48 pm
Location: El Saucejo - Sevilla

Post

Supla 16 x 16

added automatic delay memory for monostable channel from local push buttons.
at the moment that one of the channels is configured in the cloud as monostable (staircase timer, garage opening, etc.)
In the first activation from the App the module store the delay that has been set in the cloud.
from that moment the local button corresponding to that channel will act with the same delay.
for example:
In the Supla cloud we set channel 0 as a staircase timer with a time of 60 seconds.
Then we activate that channel once from the SuplaApp (or Supla cloud).
This saves the 60 second delay for channel 0 in the module.
if we press local button 0, channel 0 is activated for 60 seconds.

edited:
Fixed bug to return channel to delay 0 (normal operation) after having been staircase timer, garage opening, etc.

Supla_16x16_Ms_DOUT_16Mbit.rar
You do not have the required permissions to view the files attached to this post.

Return to “Ideas and concepts”