Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem manually handling WiFi reconnect #2735

Closed
eketjall opened this issue Dec 4, 2016 · 16 comments
Closed

Problem manually handling WiFi reconnect #2735

eketjall opened this issue Dec 4, 2016 · 16 comments
Labels
waiting for feedback Waiting on additional info. If it's not received, the issue may be closed.

Comments

@eketjall
Copy link

eketjall commented Dec 4, 2016

I'm trying to handle WiFi auto/reconnects in WIFI-STA mode but having troubles.

Setting WiFi.setAutoConnect ( true ) to auto connect on power up works just fine.

Setting WiFi.setAutoReconnect ( false ) on the other hand have issues.
This setting dosen't have any effect if an initial connection is not established.
ie if there is no auto-connect and WiFi.begin(ssid,password) is called the ESP will try to reconnect ever 1s even if WiFi.setAutoReconnect ( false ) is called beforehand.
If an initial connection is established the WiFi.setAutoReconnect ( false ) will work as expected.
Only way I have found to disable auto reconnect after a WiFi.begin is to call WiFi.disconnect() if WiFi.status() not return 3 - WL_CONNECTED
This on the other hand will disable the possibility to manually reconnect later with WiFi.reconnect();
And calling WiFi.begin a second time causes a wdt reset

Soft WDT reset

ctx: sys 
sp: 3ffffd20 end: 3fffffb0 offset: 01b0

>>>stack>>>
3ffffed0:  3fff0acc 40202f8c 00000064 4020113b  
3ffffee0:  40203160 3ffe8350 3ffeef00 4020316e  
3ffffef0:  027e08b8 3ffe8350 3ffeef00 4020235b  
3fffff00:  3ffe8518 0000000b 3ffee980 40206068  
3fffff10:  3ffef0b0 0000000f 3fffff60 40202080  
3fffff20:  4021e4d6 3ffeef00 00000000 027e08b8  
3fffff30:  4021f323 00000000 3fffff60 4010068c  
3fffff40:  3fff0acc 40202f8c 3fffff60 60000600  
3fffff50:  027e08b8 00000000 3ffeef00 4020243d  
3fffff60:  00000000 00000000 00000000 027e08b8  
3fffff70:  60000600 3ffee3b0 3fff0a8c 4021d2bd  
3fffff80:  4021d302 3fffdab0 00000000 3fffdcb0  
3fffff90:  3ffee3d8 3fffdad0 3ffef194 40206bc7  
3fffffa0:  40000f49 40000f49 3fffdab0 40000f49  
<<<stack<<<

If an initial connection is established but later the AP which the ESP is connected to is not available any more the WiFi.status() is still returning 3 - WL_CONNECTED.
An event 1 - WIFI_EVENT_STAMODE_DISCONNECTED is triggered though.

This is my Sketch:

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <ip_addr.h>
#include <Ticker.h>

Ticker      sensors;
Ticker      wifiReconnect;

const char* hostnamePrefix = "sensorhub_";

const char* ssidWiFi = "***";
const char* passwordWiFi = "***";


/********************************************************
/*  Debug Print                                         *
/********************************************************/
void dbg_printf ( const char *format, ... )
{

    static char sbuf[1400];                                                     // For debug lines
    va_list varArgs;                                                            // For variable number of params

    va_start ( varArgs, format );                                               // Prepare parameters
    vsnprintf ( sbuf, sizeof ( sbuf ), format, varArgs );                       // Format the message
    va_end ( varArgs );                                                         // End of using parameters

    Serial.print ( sbuf );

}


/********************************************************
/*  Handle WiFi events                                  *
/********************************************************/
void eventWiFi(WiFiEvent_t event) {
     
  switch(event) {
    case WIFI_EVENT_STAMODE_CONNECTED:
      dbg_printf("[WiFi] %d, Connected\n", event);
    break;
    
    case WIFI_EVENT_STAMODE_DISCONNECTED:
      dbg_printf("[WiFi] %d, Disconnected - Status %d, %s\n", event, WiFi.status(), connectionStatus( WiFi.status() ).c_str() );      
    break;
    
     case WIFI_EVENT_STAMODE_AUTHMODE_CHANGE:
      dbg_printf("[WiFi] %d, AuthMode Change\n", event);
    break;
    
    case WIFI_EVENT_STAMODE_GOT_IP:
      dbg_printf("[WiFi] %d, Got IP\n", event);
      setupOTA();
    break;
    
    case WIFI_EVENT_STAMODE_DHCP_TIMEOUT:
      dbg_printf("[WiFi] %d, DHCP Timeout\n", event);
    break;
    
    case WIFI_EVENT_SOFTAPMODE_STACONNECTED:
      dbg_printf("[AP] %d, Client Connected\n", event);
    break;
    
    case WIFI_EVENT_SOFTAPMODE_STADISCONNECTED:
      dbg_printf("[AP] %d, Client Disconnected\n", event);
    break;
    
    case WIFI_EVENT_SOFTAPMODE_PROBEREQRECVED:
//      dbg_printf("[AP] %d, Probe Request Recieved\n", event);
    break;
  }
  
}

/********************************************************
/*  WiFi Connection Status                              *
/********************************************************/
String connectionStatus ( int which )
{
    switch ( which )
    {
        case WL_CONNECTED:
            return "Connected";
            break;

        case WL_NO_SSID_AVAIL:
            return "Network not availible";
            break;

        case WL_CONNECT_FAILED:
            return "Wrong password";
            break;

        case WL_IDLE_STATUS:
            return "Idle status";
            break;

        case WL_DISCONNECTED:
            return "Disconnected";
            break;

        default:
            return "Unknown";
            break;
    }
}


/********************************************************
/*  Is the SensorHub auto connected to Wifi?            *
/********************************************************/
bool isAutoConnected () {
  int connRes = WiFi.waitForConnectResult();
  if (connRes == WL_CONNECTED) {
    dbg_printf ("[WiFi] Auto-connected to %s, IP address: " IPSTR "\n", WiFi.SSID().c_str(), IP2STR( WiFi.localIP() ) );
    return true;
  } else {
    dbg_printf ("[WiFi] Auto-connect to %s failed - Status %d, %s\n", WiFi.SSID().c_str(), WiFi.status(), connectionStatus( WiFi.status() ).c_str() );
    return false;
  }
}

/********************************************************
/*  Is the SensorHub auto connected to Wifi?            *
/********************************************************/
bool hasWifiConfigChanged() {
  if( strcmp(WiFi.SSID().c_str(),ssidWiFi) != 0 ) {
    dbg_printf ("[WiFi] Config Changed, Disconnecting...\n");
    WiFi.setAutoReconnect ( false );                                             
    WiFi.disconnect();
    return true;
  } else {
    return false;
  }
}

/********************************************************
/*  Connect WiFi                                        *
/********************************************************/
void connectWiFi () {

  dbg_printf ("[WiFi] Connecting...\n", ssidWiFi);
  WiFi.begin(ssidWiFi, passwordWiFi);
  int connRes = WiFi.waitForConnectResult();
  if (connRes != WL_CONNECTED) {
    dbg_printf ("[WiFi] Connection to %s failed - Status %d, %s, Retrying in 10s...\n", WiFi.SSID().c_str(), WiFi.status(), connectionStatus( WiFi.status() ).c_str() );
    WiFi.disconnect();
    //ESP.restart();
  } else {
    dbg_printf ("[WiFi] Connected to %s, IP address: " IPSTR "\n", WiFi.SSID().c_str(), IP2STR( WiFi.localIP() ) );
  }
  
}


/********************************************************
/*  Reconnect WiFi                                      *
/********************************************************/
void reconnectWiFi () {
  dbg_printf ("[WiFi] Status %d, %s - Reconnecting...\n", WiFi.status(), connectionStatus( WiFi.status() ).c_str() );
  if( WiFi.status() == 0 ) {
    connectWiFi();
  }
  //WiFi.reconnect();
}


/********************************************************
/*  Setup OTA                                           *
/********************************************************/
void setupOTA () {
  // Port defaults to 8266
  // ArduinoOTA.setPort(8266);

  char otaHost[18];
  uint8_t wifiMac[6];
  WiFi.macAddress(wifiMac);
  sprintf(otaHost,"%s%02x%02x%02x%02x%02x%02x", hostnamePrefix, MAC2STR ( wifiMac ) );
  ArduinoOTA.setHostname(otaHost);

  // No authentication by default
  // ArduinoOTA.setPassword((const char *)"123");

  ArduinoOTA.onStart([]() {
    sensors.detach();                   // disable sensors during OTA
    dbg_printf ("[OTA] Start\n");
  });
  ArduinoOTA.onEnd([]() {
    dbg_printf ("\n[OTA] End\n");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
     dbg_printf ("[OTA] Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    dbg_printf ("\n[OTA] Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) dbg_printf ("Auth Failed\n");
    else if (error == OTA_BEGIN_ERROR) dbg_printf ("Begin Failed\n");
    else if (error == OTA_CONNECT_ERROR) dbg_printf ("Connect Failed\n");
    else if (error == OTA_RECEIVE_ERROR) dbg_printf ("Receive Failed\n");
    else if (error == OTA_END_ERROR) dbg_printf ("End Failed\n");
  });
  ArduinoOTA.begin();
  dbg_printf ("[OTA] Ready, Host: %s, IP address: " IPSTR "\n", ArduinoOTA.getHostname().c_str(), IP2STR( WiFi.localIP() ) );

}


/********************************************************
/*  Read sensors                                        *
/********************************************************/
void readSensors () {
  dbg_printf ("[Sensors] Read...\n");
}

/********************************************************
/*  Main Setup                                          *
/********************************************************/
void setup() {
  Serial.begin(115200);
  delay(1);
  
  dbg_printf ("\n\n--- Sensor Hub ---\n");

  WiFi.setAutoConnect ( true );                                             // Autoconnect to last known Wifi on startup
  WiFi.setAutoReconnect ( false );                                             
  WiFi.onEvent(eventWiFi);                                                    // Handle WiFi event
  WiFi.mode(WIFI_STA);                                                        // Station mode

  if ( !isAutoConnected() || hasWifiConfigChanged() ) {                       // If no aout-connection or if config has changed
    connectWiFi();                                                            // connect to Wifi.
  }

  wifiReconnect.attach(10.0,reconnectWiFi);   // Try to reconnect in 10s

  readSensors();                                                              // Do a first sensor read
  sensors.attach(10.0, readSensors);                                          // Read sesors every 10s;
}

/********************************************************
/*  Main Loop                                           *
/********************************************************/
void loop() {
  ArduinoOTA.handle();

}

@kendo55
Copy link

kendo55 commented Dec 4, 2016

i had that problem too !!!

FIX FOR USING 2.3.0 CORE (only .begin if not connected)!!!!!!!

if (WiFi.status() != WL_CONNECTED) { // FIX FOR USING 2.3.0 CORE (only .begin if not connected)
    WiFi.begin(ssid, password); // connect to the network
}
while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
}

see:
(#2186)
and:
(#2594)

@eketjall
Copy link
Author

eketjall commented Dec 4, 2016

I never call WiFi.begin() while already connected.
The problem with that was actually that I called it from inside a Ticker.

So remaining issues is the way autoreconnect(false) don't work intuitively before a first connection actually has been established.

And second, that WiFi.status() return WL_CONNECTED also when the current AP connected to becomes unavailable. In this case it actually works to call WiFi.begin even if WiFi.status is WL_CONNECTED

@kentaylor
Copy link

I didn't understand what you are trying to do but in general there is nothing you can do to make the ESP8266 more likely to connect to WiFi. If you have called WiFi.begin(SSID,password) ever and you don't want to change SSID or password you never need to call WiFi.begin again. The module will do the best it can to acquire and maintain a WiFi connection and during boot up will commence connecting to WIFi before user code starts.

@eketjall
Copy link
Author

eketjall commented Dec 9, 2016

Yes, but that is exactly what I want to avoid.
I would like the ESP to autoconnect on start-up, but if that fails for some reason I want to handle reconnects manually. Why? Because the auto reconnect tries to reconnect every 1s. And I would rather try like every 10s in my application.
I have it working now, but with one small problem.
I have to call disconnect() to stop the auto reconnect.
This is not a problem in it self, but with that I also lose the auto connect credentials. This makes the time for connection on next boot longer.

To clarify what I would like to do;

Power up ESP
Auto connect WiFi
If auto connect fails, try to connect manually (WiFi.begin)
If still no connection could be made, try again in 10s, repeat maximum n times.
If connected, do stuff.
Power down.

The power up/down is handled by external hardware.

@eketjall
Copy link
Author

eketjall commented Dec 9, 2016

Just realized that autoconnect dosen't work with static wifi configuration.
If the esp is configured and connected with static ip and then powered off it auto connects with dhcp to the same AP on the next power up.

@kentaylor
Copy link

kentaylor commented Dec 9, 2016

It seems needlessly complex to

rather try like every 10s in my application

If power saving is the goal, better to let it do its best for a while then go to deep sleep while not trying to connect. See long but comprehensive discussion of time it takes to connect.

However, if the desire is to disable WiFi connectivity and re-enable it later then call wifi.persistent(false) then wifi.disconnect(true) which will turn off radio but not wipe WiFi credentials from flash then wifi.begin() to try connecting to WiFi again later.

To learn how to connect with a static IP also see this discussion.

The @eketjall statement

And second, that WiFi.status() return WL_CONNECTED also when the current AP connected to becomes unavailable. In this case it actually works to call WiFi.begin even if WiFi.status is WL_CONNECTED

seems unlikely. How could it be known calling WiFi.begin caused the WiFi connection to be established when the ESP will already be trying to reestablish the WiFi connection anyway?

@eketjall
Copy link
Author

eketjall commented Dec 9, 2016

Power consumption is one thing, and what you suggest is probably what I will end upp with. ie let the ESP do it's thing and have a timeout.
But as far as static IP, the discussion you linked you come to the same conclusion, that it's not saved for auto connect, WiFi.config() and WiFi.begin() has to be called.

The ESP is not trying to do anything "by it self" if WiFi.setAutoConnect ( false ) and WiFi.setAutoReconnect ( false );

If using Wifi.onEvent() you get event WIFI_EVENT_STAMODE_DISCONNECTED when the AP becomes unavailable. If checking WiFi.status() when the event WIFI_EVENT_STAMODE_DISCONNECTED occur it reports WL_CONNECTED.
Feature or bug is the question. It is actually, as far as i can tell, the only way to determine if the connection was closed unintentionally or not.
If you close the connection by calling WiFi.disconnect() the event is still WIFI_EVENT_STAMODE_DISCONNECTED byt then WiFi.status report WL_DISCONNECTED

@kentaylor
Copy link

@eketjall says

But as far as static IP, ..... WiFi.config() and WiFi.begin() has to be called.

Not correct. WiFi.config(ip,gw,subnet, dns) has to be called but not WiFi.begin() . Autoconnect state is remembered across boots and as long as autoconnect was not set to false you never need WiFi.begin().

I would consider

If checking WiFi.status() when the event WIFI_EVENT_STAMODE_DISCONNECTED occur it reports WL_CONNECTED

to be a bug but are you sure it was not connected again by the time you checked the state? If you tried to use the WiFi I expect it would report failure and if it succeeded then you are connected.

@eketjall
Copy link
Author

eketjall commented Dec 9, 2016

Ok, wasn't aware that WiFi.begin wasn't needed.
The autoconnect can be a little trap, because it only has effect on the NEXT boot.
Also autoreconnect is a little tricky because it only has effect after a connection has been established.

As far as the WIFI_EVENT_STAMODE_DISCONNECTED and WL_CONNECTED I am sure. Both autoconnect and autoreconnect is set to false when it happens.
Easy to replicate, just check WiFi.status inside the event function.

@kentaylor
Copy link

kentaylor commented Dec 9, 2016

The WiFi connection process starts long before a sketch starts. A sketch will be launched about 300ms after the clock starts which is already a while after boot.

Where @eketjall says

As far as the WIFI_EVENT_STAMODE_DISCONNECTED and WL_CONNECTED I am sure.

then I'd consider that a bug. From memory wifi.begin() will set autoreconnect true but I didn't check so I'm not sure.

@eketjall
Copy link
Author

I've went for the solution to let the ESP do it's thing and just have a time out instead.

But in doing so I found out that there is a differens in connection times depending on how you connect and how you restart/reset/repower the ESP.

If you just do a ESP.reset() the connection times for a static configuration (call WiFi.config) is low (under 700ms) even without calling WiFi.begin() (and just letting the ESP use saved configuration)
But if you do a ESP.restart() the connection times is much longer (in my case around 2000-2500ms).
If I call both WiFi.config() and WiFi.begin() with all parameters (channel don't seem to matter, any channel gives the same result) I get the same <700ms even with ESP.restart().

ESP.restart() and a power cycle seems to give similar results in connection times.
I haven't tried deep sleep though because I'm using a ESP-01.

Here is the code that gives me consistent connections times under 700ms:
(I left out the non important parts, but I'm just setting up a Ticker for timeout and read WiFi configuration from a file.)

/********************************************************
/*  Main Setup                                          *
/********************************************************/
void setup() {
  t_setup = millis();
  wifiConnectTimeout.once ( 10, connectWiFiFail );                                            // Set WiFi connection time out
  Serial.begin ( 115200 );
  delay ( 1 );
  //Serial.setDebugOutput ( true );                                                           // Print Wifi debug info
  if ( !SPIFFS.begin() ) {                                                                    // Mount file system
    dbg_printf ( "Error mounting file system\n" );
  } else {
    if ( loadWiFiConfig() ) {
      t_configfile = millis();
      if ( wifiStatic ) {
        WiFi.config ( wifiIP, wifiGateway, wifiNetmask, wifiGateway ) ;
      }
      WiFi.begin ( wifiSSID, wifiPassword, wifiChannel, wifiBSSID, true );
    }
  }
  while ( WiFi.status() != WL_CONNECTED ) {                                                   // Wait for connection
    if ( connectWiFiFail ) {                                                                  // If connection times out
      WiFi.disconnect ( false );
      break;
    }
    delay ( 1 );
  }
  t_connection = millis();
  WiFi.setAutoConnect ( true );                                                               // Make sure auto connect is set for next boot;                                           
  WiFi.setAutoReconnect ( true );                                                             // Make sure auto reconnect is set for next boot;    
}

/********************************************************
/*  Main Loop                                           *
/********************************************************/
void loop() {
  dbg_printf ( "\n     setup: %lu \n", t_setup );
  dbg_printf ( "configfile: %lu \n", t_configfile );
  dbg_printf ( "connection: %lu ", t_connection );
  if ( f_connectWiFiFail ) dbg_printf ( " failed" );
  dbg_printf ( "\n" );
  delay(10000);
  ESP.restart();
 }

@kentaylor
Copy link

kentaylor commented Dec 12, 2016

The results reported by @eketjall look unlikely. The line
WiFi.begin ( wifiSSID, wifiPassword, wifiChannel, wifiBSSID, true );
doesn't do anything if wifiSSID and wifiPassword is the same as the values already stored, so there ought to be the same results whether it is used or not.

These lines could be left out
WiFi.setAutoConnect ( true );
WiFi.setAutoReconnect ( true );
and
WiFi.begin ( wifiSSID, wifiPassword, wifiChannel, wifiBSSID, true );
could be reduced to:-
WiFi.begin ( wifiSSID, wifiPassword);

I'd be curious to see what time you get with this sketch. If you remove this line nothing changes. Also you have to do it a few times to be definitive as connection times have a random element as well,.

@eketjall
Copy link
Author

We are drifting away from the original issue about contradictory event and status codes when a network becomes unavailable. (And autoconnect/autoreconnect which need a little more documentation to be crystal clear)

Connection times is a can of worms never the less.

With "your" sketch (the actual sketch below), testing now with a Nexus 5x as AP, which is probably not the best, gives some "interesting" results.
I have tested 3 different scenarios for WiFi.begin
[A] omitting WiFi.begin
[B] WiFi.begin(ssid,pass)
[C] WiFi.begin(ssid,pass,ch,bssid)

I have also tested 4 different boot/restart/powerup methods.
[1] ESP.restart() at end of loop
[2] ESP.reset() at end of loop
[3] Disable an re-enable the ESP via CH_PD (done by jumper and may have issues with not a clean on/off)
[4] Power off an on. (done by jumper and may have issues with not a clean on/off)

The reported times is "Program Time" averaged over 20 measurement.

  |   A  |   B  |   C
--|------|------|------
1 | 2186 | 2291 |  182
--|------|------|------
2 | 1310 | 2635 | 1180
--|------|------|------
3 | 5455 | 6686 | 2360
--|------|------|------
4 | 5432 | 5044 | 2667

For boot/reset method 3 & 4 I got quit a lot of variations in the results which indicates that the way of doing it manually by a jumper have some issues with the contact not being clean.
For case C3 and C4 most of the times were long, but a few was actually close to the C1 times.

Signal strength variations and interference from other networks will also most certainly be significant in this setup I have at the moment. I will try to do the test again with a better AP, and a "automated" hardware setup where I can control power on/off, CH_PD and also hardware Reset from an Arduino.

But it seems clear that WiFi.begin(ssid,pass,ch,bssid) is preferred to get the fastest connection times.
Note that WiFi.printDiag(Serial) reports the same for all samples, except "BSSID set" which reports 1 for case [C], which is logical.

Mode: STA
PHY mode: N
Channel: 6
AP id: 0
Status: 5
Auto connect: 1
SSID (5): ------
Passphrase (14): --------------
BSSID set: 0

The "Start millis" is around 250ms in all cases but for restart method 3 (CH_PD) where it is ~50ms.
What is even more interesting is that for method 1 and 2 the "Start millis" depends on how the first run of the sketch is initialized. If its done by a power off/on all the following restarts/resets will have ~250ms start time, but if the first run is initialized via CH_PD low to high all the following restarts/resets will have ~50ms start time.

Sketch used:

#include <ESP8266WiFi.h>
#ifdef ESP8266
extern "C" {
#include "user_interface.h"
}
#endif
int start;
int now;
int codeTime;
const char* ssid = "------";
const char* pass = "--------------";
IPAddress ip = IPAddress(192,168,43,163);
IPAddress gw = IPAddress(192,168,43,1);
IPAddress subnet = IPAddress(255,255,255,0);
IPAddress dns = IPAddress(192,168,43,1);
const int ch = 6;
const byte bssid[6] = {0x78,0xF8,0x82,0xED,0xFE,0xB3};
static struct station_config conf;
char mac[18] = { 0 };
void setup() {
  start = millis();
  WiFi.config(ip,gw,subnet,dns); 
  //WiFi.begin(ssid,pass);       // case [B]     
  //WiFi.begin(ssid,pass,ch,bssid);    // case [C]    
  while (WiFi.status() != WL_CONNECTED) {
        delay(1);
    }
  now = millis();
  codeTime = now - start;
  wifi_station_get_config(&conf);
  Serial.begin(115200);
  delay(1);
}

void loop() {
  printf("\n\nSDK version:%s\n", system_get_sdk_version());
  Serial.print("Start millis = "); 
  Serial.println(start); 
  Serial.print("Now millis = "); 
  Serial.println(now);
  Serial.print("Program Time = "); 
  Serial.println(codeTime);
  sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X", conf.bssid[0], conf.bssid[1], conf.bssid[2], conf.bssid[3], conf.bssid[4], conf.bssid[5]);
  Serial.println(mac);
  WiFi.printDiag(Serial);
  delay(5000); 

  //ESP.restart(); // method 1
  //ESP.reset();   // method 2   

}

@mlord
Copy link

mlord commented Feb 27, 2017

My wifi issues all vanished when I switched to using Static IP configs instead of DHCP. The built-in DHCP seems to have issues, particularly as the distance between the esp8266 and the AP increases, suggesting perhaps inadequate internal timeouts or problems with retransmissions perhaps.

@devyte
Copy link
Collaborator

devyte commented Oct 6, 2017

@eketjall is this issue still valid with latest git? Also, what about #3215 ?

@devyte devyte added the waiting for feedback Waiting on additional info. If it's not received, the issue may be closed. label Oct 6, 2017
@devyte
Copy link
Collaborator

devyte commented Jan 29, 2018

Closing due to lack of feedback and age.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
waiting for feedback Waiting on additional info. If it's not received, the issue may be closed.
Projects
None yet
Development

No branches or pull requests

5 participants