mirror of
https://github.com/rstrouse/ESPSomfy-RTS.git
synced 2025-12-12 18:42:10 +01:00
parent
e04d7e3fc7
commit
0b985c0880
10 changed files with 272 additions and 59 deletions
217
Network.cpp
217
Network.cpp
|
|
@ -47,17 +47,101 @@ bool Network::setup() {
|
||||||
sockEmit.begin();
|
sockEmit.begin();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
conn_types_t Network::preferredConnType() {
|
||||||
|
switch(settings.connType) {
|
||||||
|
case conn_types_t::wifi:
|
||||||
|
case conn_types_t::unset:
|
||||||
|
case conn_types_t::ap:
|
||||||
|
return strlen(settings.WIFI.ssid) > 0 ? conn_types_t::wifi : conn_types_t::ap;
|
||||||
|
case conn_types_t::ethernetpref:
|
||||||
|
return strlen(settings.WIFI.ssid) > 0 && !ETH.linkUp() ? conn_types_t::wifi : conn_types_t::ethernet;
|
||||||
|
case conn_types_t::ethernet:
|
||||||
|
return ETH.linkUp() ? conn_types_t::ethernet : conn_types_t::ap;
|
||||||
|
default:
|
||||||
|
return settings.connType;
|
||||||
|
}
|
||||||
|
}
|
||||||
void Network::loop() {
|
void Network::loop() {
|
||||||
this->connect();
|
// ORDER OF OPERATIONS:
|
||||||
if(!this->connected() || this->connecting()) return;
|
// ----------------------------------------------
|
||||||
|
// 1. If we are in the middle of a connection process we need to simply bail after the connect method. The
|
||||||
|
// connect method will take care of our target connection for us.
|
||||||
|
// 2. Check to see what type of target connection we need.
|
||||||
|
// a. If this is an ethernet target then the connection needs to perform a fallback if applicable.
|
||||||
|
// b. If this is a wifi target then we need to first check to see if the SSID is available.
|
||||||
|
// c. If an SSID has not been set then we need to turn on the Soft AP.
|
||||||
|
// 3. If the Soft AP is open and the target is either wifi, ethernet, or ethernetpref then
|
||||||
|
// we need to shut it down if there are no connections and the preferred connection is available.
|
||||||
|
// a. Ethernet: Check for an active ethernet connection. We cannot rely on linkup because the PHY will
|
||||||
|
// report that the link is up when no IP address is being served.
|
||||||
|
// b. WiFi: Perform synchronous scan for APs related to the SSID. If the SSID can be found then perform
|
||||||
|
// the connection process for the WiFi connection.
|
||||||
|
// c. SoftAP: This condition retains the Soft AP because no other connection method is available.
|
||||||
|
|
||||||
|
this->connect(); // Connection timeout handled in connect function as well as the opening of the Soft AP if needed.
|
||||||
|
if(this->connecting()) return; // If we are currently attempting to connect to something then we need to bail here.
|
||||||
|
conn_types_t ctype = this->preferredConnType();
|
||||||
|
if(this->softAPOpened && WiFi.softAPgetStationNum() == 0) {
|
||||||
|
// If the Soft AP is opened and there are no clients connected then we need to scan for an AP. If
|
||||||
|
// our target exists we will exit out of the Soft AP and start that connection.
|
||||||
|
if(ctype == conn_types_t::wifi) {
|
||||||
|
// Scan for an AP.
|
||||||
|
if(!_apScanning && WiFi.scanNetworks(true, false, true, 300, 0, settings.WIFI.ssid) == -1) {
|
||||||
|
_apScanning = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(this->connected() && ctype == conn_types_t::wifi && settings.WIFI.roaming) {
|
||||||
|
// Periodically look for an AP.
|
||||||
|
if(millis() > SSID_SCAN_INTERVAL + this->lastWifiScan) {
|
||||||
|
//Serial.println("Started scan for access points");
|
||||||
|
if(!_apScanning && WiFi.scanNetworks(true, false, true, 300, 0, settings.WIFI.ssid) == -1) {
|
||||||
|
_apScanning = true;
|
||||||
|
this->lastWifiScan = millis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(_apScanning) {
|
||||||
|
if(!settings.WIFI.roaming || settings.connType != conn_types_t::wifi || (this->softAPOpened && WiFi.softAPgetStationNum() != 0)) _apScanning = false;
|
||||||
|
else {
|
||||||
|
uint16_t n = WiFi.scanComplete();
|
||||||
|
if( n > 0) {
|
||||||
|
uint8_t bssid[6];
|
||||||
|
int32_t channel = 0;
|
||||||
|
if(this->getStrongestAP(settings.WIFI.ssid, bssid, &channel)) {
|
||||||
|
if(!WiFi.BSSID() || memcmp(bssid, WiFi.BSSID(), sizeof(bssid)) != 0) {
|
||||||
|
Serial.printf("Found stronger AP %d %02X:%02X:%02X:%02X:%02X:%02X\n", channel, bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
|
||||||
|
if(this->softAPOpened) {
|
||||||
|
WiFi.softAPdisconnect(true);
|
||||||
|
WiFi.mode(WIFI_STA);
|
||||||
|
}
|
||||||
|
this->changeAP(bssid, channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_apScanning = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if(millis() - this->lastEmit > 1500) {
|
if(millis() - this->lastEmit > 1500) {
|
||||||
|
// Post our connection status if needed.
|
||||||
this->lastEmit = millis();
|
this->lastEmit = millis();
|
||||||
if(this->connected()) {
|
if(this->connected()) {
|
||||||
this->emitSockets();
|
this->emitSockets();
|
||||||
this->lastEmit = millis();
|
this->lastEmit = millis();
|
||||||
}
|
}
|
||||||
|
esp_task_wdt_reset(); // Make sure we do not reboot here.
|
||||||
}
|
}
|
||||||
sockEmit.loop();
|
sockEmit.loop();
|
||||||
|
mqtt.loop();
|
||||||
|
if(settings.ssdpBroadcast) {
|
||||||
|
if(!SSDP.isStarted) SSDP.begin();
|
||||||
|
if(SSDP.isStarted) SSDP.loop();
|
||||||
|
}
|
||||||
|
else if(!settings.ssdpBroadcast && SSDP.isStarted) SSDP.end();
|
||||||
|
|
||||||
|
/*
|
||||||
|
// ---------------------------
|
||||||
|
|
||||||
if(this->softAPOpened) {
|
if(this->softAPOpened) {
|
||||||
// If the softAP has been opened check to see if there are any clients connected. If there is not
|
// If the softAP has been opened check to see if there are any clients connected. If there is not
|
||||||
// then we need to scan for the SSID.
|
// then we need to scan for the SSID.
|
||||||
|
|
@ -66,6 +150,7 @@ void Network::loop() {
|
||||||
// then we will not start another scan.
|
// then we will not start another scan.
|
||||||
if(!_apScanning && WiFi.scanNetworks(true, false, true, 300, 0, settings.WIFI.ssid) == -1) {
|
if(!_apScanning && WiFi.scanNetworks(true, false, true, 300, 0, settings.WIFI.ssid) == -1) {
|
||||||
_apScanning = true;
|
_apScanning = true;
|
||||||
|
this->lastWifiScan = millis();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -79,10 +164,22 @@ void Network::loop() {
|
||||||
// 1. If there is currently a waiting scan don't do anything
|
// 1. If there is currently a waiting scan don't do anything
|
||||||
if(!_apScanning && WiFi.scanNetworks(true, false, true, 300, 0, settings.WIFI.ssid) == -1) {
|
if(!_apScanning && WiFi.scanNetworks(true, false, true, 300, 0, settings.WIFI.ssid) == -1) {
|
||||||
_apScanning = true;
|
_apScanning = true;
|
||||||
|
this->lastWifiScan = millis();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this->lastMDNS = millis();
|
this->lastMDNS = millis();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
//if(!this->connected() || this->connecting()) return;
|
||||||
|
if(millis() - this->lastEmit > 1500) {
|
||||||
|
this->lastEmit = millis();
|
||||||
|
if(this->connected()) {
|
||||||
|
this->emitSockets();
|
||||||
|
this->lastEmit = millis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sockEmit.loop();
|
||||||
|
}
|
||||||
if(_apScanning) {
|
if(_apScanning) {
|
||||||
if(!settings.WIFI.roaming || settings.connType != conn_types_t::wifi || (this->softAPOpened && WiFi.softAPgetStationNum() != 0)) _apScanning = false;
|
if(!settings.WIFI.roaming || settings.connType != conn_types_t::wifi || (this->softAPOpened && WiFi.softAPgetStationNum() != 0)) _apScanning = false;
|
||||||
else {
|
else {
|
||||||
|
|
@ -110,12 +207,13 @@ void Network::loop() {
|
||||||
}
|
}
|
||||||
else if(!settings.ssdpBroadcast && SSDP.isStarted) SSDP.end();
|
else if(!settings.ssdpBroadcast && SSDP.isStarted) SSDP.end();
|
||||||
mqtt.loop();
|
mqtt.loop();
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
bool Network::changeAP(const uint8_t *bssid, const int32_t channel) {
|
bool Network::changeAP(const uint8_t *bssid, const int32_t channel) {
|
||||||
esp_task_wdt_reset(); // Make sure we do not reboot here.
|
esp_task_wdt_reset(); // Make sure we do not reboot here.
|
||||||
if(SSDP.isStarted) SSDP.end();
|
if(SSDP.isStarted) SSDP.end();
|
||||||
mqtt.disconnect();
|
mqtt.disconnect();
|
||||||
sockEmit.end();
|
//sockEmit.end();
|
||||||
WiFi.disconnect(false, true);
|
WiFi.disconnect(false, true);
|
||||||
WiFi.begin(settings.WIFI.ssid, settings.WIFI.passphrase, channel, bssid);
|
WiFi.begin(settings.WIFI.ssid, settings.WIFI.passphrase, channel, bssid);
|
||||||
this->connectStart = millis();
|
this->connectStart = millis();
|
||||||
|
|
@ -340,15 +438,15 @@ bool Network::connectWired() {
|
||||||
if(ETH.linkUp()) {
|
if(ETH.linkUp()) {
|
||||||
// If the ethernet link is re-established then we need to shut down wifi.
|
// If the ethernet link is re-established then we need to shut down wifi.
|
||||||
if(WiFi.status() == WL_CONNECTED) {
|
if(WiFi.status() == WL_CONNECTED) {
|
||||||
sockEmit.end();
|
//sockEmit.end();
|
||||||
WiFi.disconnect(true);
|
WiFi.disconnect(true);
|
||||||
WiFi.mode(WIFI_OFF);
|
WiFi.mode(WIFI_OFF);
|
||||||
}
|
}
|
||||||
if(this->connType != conn_types_t::ethernet) this->setConnected(conn_types_t::ethernet);
|
if(this->connType != conn_types_t::ethernet) this->setConnected(conn_types_t::ethernet);
|
||||||
this->wifiFallback = false;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if(this->ethStarted) {
|
else if(this->ethStarted) {
|
||||||
|
// There is no wired connection so we need to fallback if appropriate.
|
||||||
if(settings.connType == conn_types_t::ethernetpref && settings.WIFI.ssid[0] != '\0')
|
if(settings.connType == conn_types_t::ethernetpref && settings.WIFI.ssid[0] != '\0')
|
||||||
return this->connectWiFi();
|
return this->connectWiFi();
|
||||||
}
|
}
|
||||||
|
|
@ -362,34 +460,34 @@ bool Network::connectWired() {
|
||||||
this->connTarget = conn_types_t::ethernet;
|
this->connTarget = conn_types_t::ethernet;
|
||||||
this->connType = conn_types_t::unset;
|
this->connType = conn_types_t::unset;
|
||||||
if(!this->ethStarted) {
|
if(!this->ethStarted) {
|
||||||
this->ethStarted = true;
|
// Currently the ethernet module will leak memory if you call begin more than once.
|
||||||
WiFi.mode(WIFI_OFF);
|
this->ethStarted = true;
|
||||||
if(settings.hostname[0] != '\0')
|
WiFi.mode(WIFI_OFF);
|
||||||
ETH.setHostname(settings.hostname);
|
if(settings.hostname[0] != '\0')
|
||||||
else
|
ETH.setHostname(settings.hostname);
|
||||||
ETH.setHostname("ESPSomfy-RTS");
|
else
|
||||||
|
ETH.setHostname("ESPSomfy-RTS");
|
||||||
Serial.print("Set hostname to:");
|
Serial.print("Set hostname to:");
|
||||||
Serial.println(ETH.getHostname());
|
Serial.println(ETH.getHostname());
|
||||||
if(!ETH.begin(settings.Ethernet.phyAddress, settings.Ethernet.PWRPin, settings.Ethernet.MDCPin, settings.Ethernet.MDIOPin, settings.Ethernet.phyType, settings.Ethernet.CLKMode)) {
|
if(!ETH.begin(settings.Ethernet.phyAddress, settings.Ethernet.PWRPin, settings.Ethernet.MDCPin, settings.Ethernet.MDIOPin, settings.Ethernet.phyType, settings.Ethernet.CLKMode)) {
|
||||||
Serial.println("Ethernet Begin failed");
|
Serial.println("Ethernet Begin failed");
|
||||||
this->ethStarted = false;
|
this->ethStarted = false;
|
||||||
if(settings.connType == conn_types_t::ethernetpref) {
|
if(settings.connType == conn_types_t::ethernetpref) {
|
||||||
this->wifiFallback = true;
|
this->wifiFallback = true;
|
||||||
return connectWiFi();
|
return connectWiFi();
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
else {
|
return false;
|
||||||
if(!settings.IP.dhcp) {
|
}
|
||||||
if(!ETH.config(settings.IP.ip, settings.IP.gateway, settings.IP.subnet, settings.IP.dns1, settings.IP.dns2)) {
|
else {
|
||||||
Serial.println("Unable to configure static IP address....");
|
if(!settings.IP.dhcp) {
|
||||||
ETH.config(INADDR_NONE, INADDR_NONE, INADDR_NONE, INADDR_NONE);
|
if(!ETH.config(settings.IP.ip, settings.IP.gateway, settings.IP.subnet, settings.IP.dns1, settings.IP.dns2)) {
|
||||||
}
|
Serial.println("Unable to configure static IP address....");
|
||||||
|
ETH.config(INADDR_NONE, INADDR_NONE, INADDR_NONE, INADDR_NONE);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
ETH.config(INADDR_NONE, INADDR_NONE, INADDR_NONE, INADDR_NONE);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
ETH.config(INADDR_NONE, INADDR_NONE, INADDR_NONE, INADDR_NONE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this->connectStart = millis();
|
this->connectStart = millis();
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -413,6 +511,8 @@ void Network::updateHostname() {
|
||||||
}
|
}
|
||||||
bool Network::connectWiFi() {
|
bool Network::connectWiFi() {
|
||||||
if(this->softAPOpened && WiFi.softAPgetStationNum() > 0) {
|
if(this->softAPOpened && WiFi.softAPgetStationNum() > 0) {
|
||||||
|
// There is a client connected to the soft AP. We do not want to close out the connection. While both the
|
||||||
|
// Soft AP and a wifi connection can coexist on ESP32 the performance is abysmal.
|
||||||
WiFi.disconnect(false);
|
WiFi.disconnect(false);
|
||||||
this->_connecting = false;
|
this->_connecting = false;
|
||||||
this->connType = conn_types_t::unset;
|
this->connType = conn_types_t::unset;
|
||||||
|
|
@ -439,10 +539,8 @@ bool Network::connectWiFi() {
|
||||||
Serial.println("dbm) ");
|
Serial.println("dbm) ");
|
||||||
}
|
}
|
||||||
else Serial.println("Connecting to AP");
|
else Serial.println("Connecting to AP");
|
||||||
// If the soft AP is currently opened then we do not want to kill it.
|
|
||||||
WiFi.setSleep(false);
|
WiFi.setSleep(false);
|
||||||
WiFi.disconnect(false);
|
WiFi.disconnect(false);
|
||||||
//WiFi.mode(WIFI_MODE_NULL);
|
|
||||||
if(!settings.IP.dhcp) {
|
if(!settings.IP.dhcp) {
|
||||||
if(!WiFi.config(settings.IP.ip, settings.IP.gateway, settings.IP.subnet, settings.IP.dns1, settings.IP.dns2))
|
if(!WiFi.config(settings.IP.ip, settings.IP.gateway, settings.IP.subnet, settings.IP.dns1, settings.IP.dns2))
|
||||||
WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE, INADDR_NONE);
|
WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE, INADDR_NONE);
|
||||||
|
|
@ -454,7 +552,6 @@ bool Network::connectWiFi() {
|
||||||
if(settings.hostname[0] != '\0') WiFi.setHostname(settings.hostname);
|
if(settings.hostname[0] != '\0') WiFi.setHostname(settings.hostname);
|
||||||
Serial.print("Set hostname to:");
|
Serial.print("Set hostname to:");
|
||||||
Serial.println(WiFi.getHostname());
|
Serial.println(WiFi.getHostname());
|
||||||
//WiFi.mode(WIFI_STA);
|
|
||||||
WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN);
|
WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN);
|
||||||
WiFi.setSortMethod(WIFI_CONNECT_AP_BY_SIGNAL);
|
WiFi.setSortMethod(WIFI_CONNECT_AP_BY_SIGNAL);
|
||||||
uint8_t bssid[6];
|
uint8_t bssid[6];
|
||||||
|
|
@ -470,42 +567,55 @@ bool Network::connectWiFi() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool Network::connect() {
|
bool Network::connect() {
|
||||||
|
esp_task_wdt_reset();
|
||||||
if(this->connecting()) {
|
if(this->connecting()) {
|
||||||
// We are currently connecting and this flag is triggered while there is an attempt
|
// CHECK FOR CONNECTION TIMEOUT
|
||||||
// to connect to the network. If the connection type is set then we need to
|
// -------------------------------------
|
||||||
// finish the connection. If it is not then we need to fall back to AP or in
|
// We are currently connecting and this flag is triggered while there is an attempt to connect to the network.
|
||||||
// the case where the target was originally ethernet then we need to open the softAP.
|
// If the connection type is set then we need to finish the connection. If it is not then we need to fall back to AP or in
|
||||||
|
// the case where the target was originally ethernetpref then we need to open the Soft AP.
|
||||||
if(this->connType == conn_types_t::unset) {
|
if(this->connType == conn_types_t::unset) {
|
||||||
// If we reached our timeout for the connection then we need to open the soft ap.
|
// If we reached our timeout for the connection then we need to fall back to wifi or open the Soft Ap.
|
||||||
if(millis() > this->connectStart + CONNECT_TIMEOUT) {
|
if(millis() > this->connectStart + CONNECT_TIMEOUT) {
|
||||||
esp_task_wdt_reset();
|
this->_connecting = false;
|
||||||
if(this->connTarget == conn_types_t::ethernet && settings.connType == conn_types_t::ethernetpref && settings.WIFI.ssid[0] != '\0')
|
if(this->connTarget == conn_types_t::ethernet &&
|
||||||
|
settings.connType == conn_types_t::ethernetpref && settings.WIFI.ssid[0] != '\0') // We timed out with the Wired connection.
|
||||||
this->connectWiFi();
|
this->connectWiFi();
|
||||||
else if(this->softAPOpened) {
|
else if(this->softAPOpened) {
|
||||||
|
// Our connection has timed out and the Soft AP is already opened. We are simply going to keep trying
|
||||||
|
// from the beginning until a connection can be made.
|
||||||
if(settings.connType == conn_types_t::ethernet || settings.connType == conn_types_t::ethernetpref)
|
if(settings.connType == conn_types_t::ethernet || settings.connType == conn_types_t::ethernetpref)
|
||||||
this->connectWired();
|
this->connectWired();
|
||||||
else if(settings.connType == conn_types_t::wifi && strlen(settings.WIFI.ssid) > 0)
|
else if(settings.connType == conn_types_t::wifi && strlen(settings.WIFI.ssid) > 0)
|
||||||
this->connectWiFi();
|
this->connectWiFi();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//Serial.println("Fell into timeout");
|
// We have exhausted all attempts to connect. Fall back to the Soft AP
|
||||||
this->openSoftAP();
|
this->openSoftAP();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
// A connection has been established and we need to now set up the rest of our connectivity.
|
||||||
this->setConnected(this->connTarget);
|
this->setConnected(this->connTarget);
|
||||||
}
|
}
|
||||||
|
else if(this->softAPOpened) {
|
||||||
|
// If the Soft AP is currently open then we will let the passive scanning or Ethernet link layer
|
||||||
|
// do its thing to connect or reconnect.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
else if(settings.connType == conn_types_t::ethernet || settings.connType == conn_types_t::ethernetpref)
|
else if(settings.connType == conn_types_t::ethernet || settings.connType == conn_types_t::ethernetpref)
|
||||||
this->connectWired();
|
this->connectWired();
|
||||||
else if(settings.connType == conn_types_t::wifi && strlen(settings.WIFI.ssid) > 0)
|
else if(settings.connType == conn_types_t::wifi && strlen(settings.WIFI.ssid) > 0)
|
||||||
this->connectWiFi();
|
this->connectWiFi();
|
||||||
else
|
else
|
||||||
|
// We do not currently have a connection method set.
|
||||||
this->openSoftAP();
|
this->openSoftAP();
|
||||||
if(this->softAPOpened && this->connected() && WiFi.softAPgetStationNum() == 0) {
|
if(this->softAPOpened && this->connected() && WiFi.softAPgetStationNum() == 0) {
|
||||||
Serial.println("Closing uneeded SoftAP");
|
// We have a connnection and the AP is still open. Kill it.
|
||||||
WiFi.softAPdisconnect(true);
|
Serial.println("Closing uneeded SoftAP");
|
||||||
if(this->connType == conn_types_t::wifi) WiFi.mode(WIFI_STA);
|
WiFi.softAPdisconnect(true);
|
||||||
|
if(this->connType == conn_types_t::wifi) WiFi.mode(WIFI_STA);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -517,7 +627,6 @@ uint32_t Network::getChipId() {
|
||||||
}
|
}
|
||||||
return chipId;
|
return chipId;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Network::getStrongestAP(const char *ssid, uint8_t *bssid, int32_t *channel) {
|
bool Network::getStrongestAP(const char *ssid, uint8_t *bssid, int32_t *channel) {
|
||||||
// The new AP must be at least 10dbm greater.
|
// The new AP must be at least 10dbm greater.
|
||||||
int32_t strength = this->connected() ? WiFi.RSSI() + 10 : -127;
|
int32_t strength = this->connected() ? WiFi.RSSI() + 10 : -127;
|
||||||
|
|
@ -558,13 +667,14 @@ bool Network::connected() {
|
||||||
else return this->connType != conn_types_t::unset;
|
else return this->connType != conn_types_t::unset;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool Network::connecting() {
|
bool Network::connecting() { return this->_connecting; }
|
||||||
return this->_connecting;
|
|
||||||
}
|
|
||||||
void Network::networkEvent(WiFiEvent_t event) {
|
void Network::networkEvent(WiFiEvent_t event) {
|
||||||
switch(event) {
|
switch(event) {
|
||||||
case ARDUINO_EVENT_WIFI_READY: Serial.println("(evt) WiFi interface ready"); break;
|
case ARDUINO_EVENT_WIFI_READY: Serial.println("(evt) WiFi interface ready"); break;
|
||||||
case ARDUINO_EVENT_WIFI_SCAN_DONE: Serial.println("(evt) Completed scan for access points"); break;
|
case ARDUINO_EVENT_WIFI_SCAN_DONE:
|
||||||
|
Serial.println("(evt) Completed scan for access points");
|
||||||
|
net.lastWifiScan = millis();
|
||||||
|
break;
|
||||||
case ARDUINO_EVENT_WIFI_STA_START:
|
case ARDUINO_EVENT_WIFI_STA_START:
|
||||||
Serial.println("WiFi station mode started");
|
Serial.println("WiFi station mode started");
|
||||||
if(settings.hostname[0] != '\0') WiFi.setHostname(settings.hostname);
|
if(settings.hostname[0] != '\0') WiFi.setHostname(settings.hostname);
|
||||||
|
|
@ -587,6 +697,13 @@ void Network::networkEvent(WiFiEvent_t event) {
|
||||||
Serial.println(ETH.localIP());
|
Serial.println(ETH.localIP());
|
||||||
net.connectTime = millis();
|
net.connectTime = millis();
|
||||||
net.connType = conn_types_t::ethernet;
|
net.connType = conn_types_t::ethernet;
|
||||||
|
if(settings.IP.dhcp) {
|
||||||
|
settings.IP.ip = ETH.localIP();
|
||||||
|
settings.IP.subnet = ETH.subnetMask();
|
||||||
|
settings.IP.gateway = ETH.gatewayIP();
|
||||||
|
settings.IP.dns1 = ETH.dnsIP(0);
|
||||||
|
settings.IP.dns2 = ETH.dnsIP(1);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ARDUINO_EVENT_ETH_CONNECTED:
|
case ARDUINO_EVENT_ETH_CONNECTED:
|
||||||
Serial.print("(evt) Ethernet Connected ");
|
Serial.print("(evt) Ethernet Connected ");
|
||||||
|
|
@ -611,7 +728,7 @@ void Network::networkEvent(WiFiEvent_t event) {
|
||||||
net.softAPOpened = true;
|
net.softAPOpened = true;
|
||||||
break;
|
break;
|
||||||
case ARDUINO_EVENT_WIFI_AP_STOP:
|
case ARDUINO_EVENT_WIFI_AP_STOP:
|
||||||
Serial.println("(evt) WiFi SoftAP Stopped");
|
if(!net.openingSoftAP) Serial.println("(evt) WiFi SoftAP Stopped");
|
||||||
//if(net.softAPOpened) net.openingSoftAP = false;
|
//if(net.softAPOpened) net.openingSoftAP = false;
|
||||||
net.softAPOpened = false;
|
net.softAPOpened = false;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
//enum class conn_types_t : byte;
|
//enum class conn_types_t : byte;
|
||||||
|
|
||||||
#define CONNECT_TIMEOUT 20000
|
#define CONNECT_TIMEOUT 20000
|
||||||
|
#define SSID_SCAN_INTERVAL 60000
|
||||||
class Network {
|
class Network {
|
||||||
protected:
|
protected:
|
||||||
unsigned long lastEmit = 0;
|
unsigned long lastEmit = 0;
|
||||||
|
|
@ -15,6 +16,7 @@ class Network {
|
||||||
int linkSpeed = 0;
|
int linkSpeed = 0;
|
||||||
bool _connecting = false;
|
bool _connecting = false;
|
||||||
public:
|
public:
|
||||||
|
unsigned long lastWifiScan = 0;
|
||||||
bool ethStarted = false;
|
bool ethStarted = false;
|
||||||
bool wifiFallback = false;
|
bool wifiFallback = false;
|
||||||
bool softAPOpened = false;
|
bool softAPOpened = false;
|
||||||
|
|
@ -24,6 +26,7 @@ class Network {
|
||||||
conn_types_t connTarget = conn_types_t::unset;
|
conn_types_t connTarget = conn_types_t::unset;
|
||||||
bool connected();
|
bool connected();
|
||||||
bool connecting();
|
bool connecting();
|
||||||
|
conn_types_t preferredConnType();
|
||||||
String ssid;
|
String ssid;
|
||||||
String mac;
|
String mac;
|
||||||
int channel;
|
int channel;
|
||||||
|
|
|
||||||
11
Sockets.cpp
11
Sockets.cpp
|
|
@ -43,6 +43,9 @@ bool room_t::leave(uint8_t num) {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
void room_t::clear() {
|
||||||
|
memset(this->clients, 255, sizeof(this->clients));
|
||||||
|
}
|
||||||
uint8_t room_t::activeClients() {
|
uint8_t room_t::activeClients() {
|
||||||
uint8_t n = 0;
|
uint8_t n = 0;
|
||||||
for(uint8_t i = 0; i < sizeof(this->clients); i++) {
|
for(uint8_t i = 0; i < sizeof(this->clients); i++) {
|
||||||
|
|
@ -77,7 +80,7 @@ void SocketEmitter::begin() {
|
||||||
sockServer.enableHeartbeat(20000, 10000, 3);
|
sockServer.enableHeartbeat(20000, 10000, 3);
|
||||||
sockServer.onEvent(this->wsEvent);
|
sockServer.onEvent(this->wsEvent);
|
||||||
Serial.println("Socket Server Started...");
|
Serial.println("Socket Server Started...");
|
||||||
settings.printAvailHeap();
|
//settings.printAvailHeap();
|
||||||
}
|
}
|
||||||
void SocketEmitter::loop() {
|
void SocketEmitter::loop() {
|
||||||
this->initClients();
|
this->initClients();
|
||||||
|
|
@ -126,7 +129,11 @@ void SocketEmitter::delayInit(uint8_t num) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void SocketEmitter::end() { sockServer.close(); }
|
void SocketEmitter::end() {
|
||||||
|
sockServer.close();
|
||||||
|
for(uint8_t i = 0; i < SOCK_MAX_ROOMS; i++)
|
||||||
|
this->rooms[i].clear();
|
||||||
|
}
|
||||||
void SocketEmitter::disconnect() { sockServer.disconnect(); }
|
void SocketEmitter::disconnect() { sockServer.disconnect(); }
|
||||||
void SocketEmitter::wsEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length) {
|
void SocketEmitter::wsEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length) {
|
||||||
switch(type) {
|
switch(type) {
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ struct room_t {
|
||||||
bool isJoined(uint8_t num);
|
bool isJoined(uint8_t num);
|
||||||
bool join(uint8_t num);
|
bool join(uint8_t num);
|
||||||
bool leave(uint8_t num);
|
bool leave(uint8_t num);
|
||||||
|
void clear();
|
||||||
};
|
};
|
||||||
class SocketEmitter {
|
class SocketEmitter {
|
||||||
protected:
|
protected:
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
71
WResp.cpp
71
WResp.cpp
|
|
@ -21,7 +21,7 @@ void JsonSockEvent::endEvent(uint8_t num) {
|
||||||
else this->server->sendTXT(num, this->buff);
|
else this->server->sendTXT(num, this->buff);
|
||||||
}
|
}
|
||||||
void JsonSockEvent::_safecat(const char *val, bool escape) {
|
void JsonSockEvent::_safecat(const char *val, bool escape) {
|
||||||
size_t len = strlen(val) + strlen(this->buff);
|
size_t len = (escape ? this->calcEscapedLength(val) : strlen(val)) + strlen(this->buff);
|
||||||
if(escape) len += 2;
|
if(escape) len += 2;
|
||||||
if(len >= this->buffSize) {
|
if(len >= this->buffSize) {
|
||||||
Serial.printf("Socket exceeded buffer size %d - %d\n", this->buffSize, len);
|
Serial.printf("Socket exceeded buffer size %d - %d\n", this->buffSize, len);
|
||||||
|
|
@ -29,7 +29,8 @@ void JsonSockEvent::_safecat(const char *val, bool escape) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(escape) strcat(this->buff, "\"");
|
if(escape) strcat(this->buff, "\"");
|
||||||
strcat(this->buff, val);
|
if(escape) this->escapeString(val, &this->buff[strlen(this->buff)]);
|
||||||
|
else strcat(this->buff, val);
|
||||||
if(escape) strcat(this->buff, "\"");
|
if(escape) strcat(this->buff, "\"");
|
||||||
}
|
}
|
||||||
void JsonResponse::beginResponse(WebServer *server, char *buff, size_t buffSize) {
|
void JsonResponse::beginResponse(WebServer *server, char *buff, size_t buffSize) {
|
||||||
|
|
@ -52,13 +53,14 @@ void JsonResponse::send() {
|
||||||
this->_headersSent = true;
|
this->_headersSent = true;
|
||||||
}
|
}
|
||||||
void JsonResponse::_safecat(const char *val, bool escape) {
|
void JsonResponse::_safecat(const char *val, bool escape) {
|
||||||
size_t len = strlen(val) + strlen(this->buff);
|
size_t len = (escape ? this->calcEscapedLength(val) : strlen(val)) + strlen(this->buff);
|
||||||
if(escape) len += 2;
|
if(escape) len += 2;
|
||||||
if(len >= this->buffSize) {
|
if(len >= this->buffSize) {
|
||||||
this->send();
|
this->send();
|
||||||
}
|
}
|
||||||
if(escape) strcat(this->buff, "\"");
|
if(escape) strcat(this->buff, "\"");
|
||||||
strcat(this->buff, val);
|
if(escape) this->escapeString(val, &this->buff[strlen(this->buff)]);
|
||||||
|
else strcat(this->buff, val);
|
||||||
if(escape) strcat(this->buff, "\"");
|
if(escape) strcat(this->buff, "\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -133,13 +135,70 @@ void JsonFormatter::addElem(const char *name, uint64_t lval) { sprintf(this->_nu
|
||||||
void JsonFormatter::addElem(const char *name, bool bval) { strcpy(this->_numbuff, bval ? "true" : "false"); this->_appendNumber(name); }
|
void JsonFormatter::addElem(const char *name, bool bval) { strcpy(this->_numbuff, bval ? "true" : "false"); this->_appendNumber(name); }
|
||||||
|
|
||||||
void JsonFormatter::_safecat(const char *val, bool escape) {
|
void JsonFormatter::_safecat(const char *val, bool escape) {
|
||||||
size_t len = strlen(val) + strlen(this->buff);
|
size_t len = (escape ? this->calcEscapedLength(val) : strlen(val)) + strlen(this->buff);
|
||||||
if(escape) len += 2;
|
if(escape) len += 2;
|
||||||
if(len >= this->buffSize) {
|
if(len >= this->buffSize) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(escape) strcat(this->buff, "\"");
|
if(escape) strcat(this->buff, "\"");
|
||||||
strcat(this->buff, val);
|
if(escape) this->escapeString(val, &this->buff[strlen(this->buff)]);
|
||||||
|
else strcat(this->buff, val);
|
||||||
if(escape) strcat(this->buff, "\"");
|
if(escape) strcat(this->buff, "\"");
|
||||||
}
|
}
|
||||||
void JsonFormatter::_appendNumber(const char *name) { this->appendElem(name); this->_safecat(this->_numbuff); }
|
void JsonFormatter::_appendNumber(const char *name) { this->appendElem(name); this->_safecat(this->_numbuff); }
|
||||||
|
uint32_t JsonFormatter::calcEscapedLength(const char *raw) {
|
||||||
|
uint32_t len = 0;
|
||||||
|
for(size_t i = strlen(raw); i > 0; i--) {
|
||||||
|
switch(raw[i]) {
|
||||||
|
case '"':
|
||||||
|
case '/':
|
||||||
|
case '\b':
|
||||||
|
case '\f':
|
||||||
|
case '\n':
|
||||||
|
case '\r':
|
||||||
|
case '\t':
|
||||||
|
case '\\':
|
||||||
|
len += 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
len++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
void JsonFormatter::escapeString(const char *raw, char *escaped) {
|
||||||
|
for(uint32_t i = 0; i < strlen(raw); i++) {
|
||||||
|
switch(raw[i]) {
|
||||||
|
case '"':
|
||||||
|
strcat(escaped, "\\\"");
|
||||||
|
break;
|
||||||
|
case '/':
|
||||||
|
strcat(escaped, "\\/");
|
||||||
|
break;
|
||||||
|
case '\b':
|
||||||
|
strcat(escaped, "\\b");
|
||||||
|
break;
|
||||||
|
case '\f':
|
||||||
|
strcat(escaped, "\\f");
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
strcat(escaped, "\\n");
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
strcat(escaped, "\\r");
|
||||||
|
break;
|
||||||
|
case '\t':
|
||||||
|
strcat(escaped, "\\t");
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
strcat(escaped, "\\\\");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
size_t len = strlen(escaped);
|
||||||
|
escaped[len] = raw[i];
|
||||||
|
escaped[len+1] = 0x00;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
2
WResp.h
2
WResp.h
|
|
@ -16,6 +16,8 @@ class JsonFormatter {
|
||||||
virtual void _safecat(const char *val, bool escape = false);
|
virtual void _safecat(const char *val, bool escape = false);
|
||||||
void _appendNumber(const char *name);
|
void _appendNumber(const char *name);
|
||||||
public:
|
public:
|
||||||
|
void escapeString(const char *raw, char *escaped);
|
||||||
|
uint32_t calcEscapedLength(const char *raw);
|
||||||
void beginObject(const char *name = nullptr);
|
void beginObject(const char *name = nullptr);
|
||||||
void endObject();
|
void endObject();
|
||||||
void beginArray(const char *name = nullptr);
|
void beginArray(const char *name = nullptr);
|
||||||
|
|
|
||||||
|
|
@ -3691,12 +3691,36 @@ class Somfy {
|
||||||
html += '<li>If the shade does not jog, press the prog button again until the shade jogs.</li>';
|
html += '<li>If the shade does not jog, press the prog button again until the shade jogs.</li>';
|
||||||
html += '</ul>';
|
html += '</ul>';
|
||||||
html += `<div class="button-container">`;
|
html += `<div class="button-container">`;
|
||||||
html += `<button id="btnSendUnpairing" type="button" style="padding-left:20px;padding-right:20px;display:inline-block;" onclick="somfy.sendCommand(${shadeId}, 'prog', 1);">Prog</button>`;
|
html += `<button id="btnSendUnpairing" type="button" style="padding-left:20px;padding-right:20px;display:inline-block;">Prog</button>`;
|
||||||
html += `<button id="btnMarkPaired" type="button" style="padding-left:20px;padding-right:20px;display:inline-block;" onclick="somfy.setPaired(${shadeId}, false);">Shade Unpaired</button>`;
|
html += `<button id="btnMarkPaired" type="button" style="padding-left:20px;padding-right:20px;display:inline-block;" onclick="somfy.setPaired(${shadeId}, false);">Shade Unpaired</button>`;
|
||||||
html += `<button id="btnStopUnpairing" type="button" style="padding-left:20px;padding-right:20px;display:inline-block" onclick="document.getElementById('divPairing').remove();">Close</button>`;
|
html += `<button id="btnStopUnpairing" type="button" style="padding-left:20px;padding-right:20px;display:inline-block" onclick="document.getElementById('divPairing').remove();">Close</button>`;
|
||||||
html += `</div>`;
|
html += `</div>`;
|
||||||
div.innerHTML = html;
|
div.innerHTML = html;
|
||||||
|
let fnRepeatProg = (err, shade) => {
|
||||||
|
if (this.btnTimer) {
|
||||||
|
clearTimeout(this.btnTimer);
|
||||||
|
this.btnTimer = null;
|
||||||
|
}
|
||||||
|
if (err) return;
|
||||||
|
if (mouseDown) {
|
||||||
|
somfy.sendCommandRepeat(shadeId, 'prog', null, fnRepeatProg);
|
||||||
|
}
|
||||||
|
}
|
||||||
document.getElementById('somfyShade').appendChild(div);
|
document.getElementById('somfyShade').appendChild(div);
|
||||||
|
let btn = document.getElementById('btnSendUnpairing');
|
||||||
|
btn.addEventListener('mousedown', (event) => {
|
||||||
|
console.log(this);
|
||||||
|
console.log(event);
|
||||||
|
console.log('mousedown');
|
||||||
|
somfy.sendCommand(shadeId, 'prog', null, (err, shade) => { fnRepeatProg(err, shade); });
|
||||||
|
}, true);
|
||||||
|
btn.addEventListener('touchstart', (event) => {
|
||||||
|
console.log(this);
|
||||||
|
console.log(event);
|
||||||
|
console.log('touchstart');
|
||||||
|
somfy.sendCommand(shadeId, 'prog', null, (err, shade) => { fnRepeatProg(err, shade); });
|
||||||
|
}, true);
|
||||||
|
|
||||||
return div;
|
return div;
|
||||||
}
|
}
|
||||||
sendCommand(shadeId, command, repeat, cb) {
|
sendCommand(shadeId, command, repeat, cb) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue