diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index ce288ac..506ba6a 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -7,7 +7,7 @@ on: env: ARDUINO_BOARD_MANAGER_ADDITIONAL_URLS: "https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json" ARDUINO_CLI_VERSION: "0.x" - ARDUINO_ESP32_VERSION: "2.0.16" + ARDUINO_ESP32_VERSION: "2.0.17" ARDUINO_JSON_VERSION: "6.21.5" ESPTOOL_VERSION: "4.7" LITTLEFS_VERSION: "v2.5.1" @@ -30,17 +30,17 @@ jobs: GITHUB_TOKEN: ${{ github.token }} - name: Check out code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Checkout mklittlefs - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: earlephilhower/mklittlefs path: mklittlefs ref: ${{ env.MKLITTLEFS_VERSION }} - name: Checkout LittleFS - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: littlefs-project/littlefs path: mklittlefs/littlefs @@ -55,14 +55,14 @@ jobs: ./mklittlefs/mklittlefs --create data --size 1441792 SomfyController.littlefs.bin - name: Upload binaries - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: LittleFS path: SomfyController.littlefs.bin retention-days: 5 - name: Upload LittleFS - uses: shogo82148/actions-upload-release-asset@v1.7.2 + uses: shogo82148/actions-upload-release-asset@v1.7.5 with: github_token: ${{ github.token }} upload_url: ${{ steps.get_release.outputs.upload_url }} @@ -120,12 +120,12 @@ jobs: GITHUB_TOKEN: ${{ github.token }} - name: Check out code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: path: SomfyController - name: Get LittleFS - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: LittleFS @@ -175,7 +175,7 @@ jobs: 0x290000 SomfyController.littlefs.bin - name: Upload Firmware ${{ matrix.name }} - uses: shogo82148/actions-upload-release-asset@v1.7.2 + uses: shogo82148/actions-upload-release-asset@v1.7.5 with: github_token: ${{ github.token }} upload_url: ${{ steps.get_release.outputs.upload_url }} @@ -187,7 +187,7 @@ jobs: zip ${{ matrix.obname }}.zip ./${{ matrix.obname }} - name: Upload Onboard ${{ matrix.name }} - uses: shogo82148/actions-upload-release-asset@v1.7.2 + uses: shogo82148/actions-upload-release-asset@v1.7.5 # env: # GITHUB_TOKEN: ${{ github.token }} with: diff --git a/ConfigSettings.h b/ConfigSettings.h index d5af040..660a8ed 100644 --- a/ConfigSettings.h +++ b/ConfigSettings.h @@ -3,7 +3,7 @@ #ifndef configsettings_h #define configsettings_h #include "WResp.h" -#define FW_VERSION "v2.4.3" +#define FW_VERSION "v2.4.4" enum DeviceStatus { DS_OK = 0, DS_ERROR = 1, diff --git a/GitOTA.cpp b/GitOTA.cpp index 763d387..6dda09e 100644 --- a/GitOTA.cpp +++ b/GitOTA.cpp @@ -10,6 +10,8 @@ #include "Somfy.h" #include "Web.h" #include "WResp.h" +#include "Network.h" + @@ -18,6 +20,7 @@ extern SocketEmitter sockEmit; extern SomfyShadeController somfy; extern rebootDelay_t rebootDelay; extern Web webServer; +extern Network net; @@ -251,7 +254,7 @@ void GitRepo::toJSON(JsonResponse &json) { void GitUpdater::loop() { if(this->status == GIT_STATUS_READY) { if(settings.checkForUpdate && - (millis() > 60000) && // Wait a minute before checking after boot. + (millis() > net.connectTime + 60000) && // Wait a minute before checking after connection. (this->lastCheck + 86400000 < millis() || this->lastCheck == 0) && !rebootDelay.reboot) { // 1 day this->checkForUpdate(); } @@ -356,7 +359,9 @@ int GitUpdater::checkInternet() { if(https.begin(sclient, "https://github.com/rstrouse/ESPSomfy-RTS")) { https.setFollowRedirects(HTTPC_FORCE_FOLLOW_REDIRECTS); https.setTimeout(3000); + esp_task_wdt_reset(); int httpCode = https.sendRequest("HEAD"); + esp_task_wdt_reset(); if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY || httpCode == HTTP_CODE_FOUND) { err = 0; Serial.printf("Internet is Available: %ldms\n", millis() - t); diff --git a/MQTT.cpp b/MQTT.cpp index 6ade1da..62e7d0b 100644 --- a/MQTT.cpp +++ b/MQTT.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "MQTT.h" #include "ConfigSettings.h" #include "Somfy.h" @@ -195,6 +196,7 @@ bool MQTTClass::connect() { char lwtTopic[128] = "status"; if(strlen(settings.MQTT.rootTopic) > 0) snprintf(lwtTopic, sizeof(lwtTopic), "%s/status", settings.MQTT.rootTopic); + esp_task_wdt_reset(); if(mqttClient.connect(this->clientId, settings.MQTT.username, settings.MQTT.password, lwtTopic, 0, true, "offline")) { Serial.print("Successfully connected MQTT client "); Serial.println(this->clientId); @@ -219,8 +221,9 @@ bool MQTTClass::connect() { this->subscribe("groups/+/sunFlag/set"); this->subscribe("groups/+/sunny/set"); this->subscribe("groups/+/windy/set"); - mqttClient.setCallback(MQTTClass::receive); + Serial.println("MQTT Startup Completed"); + esp_task_wdt_reset(); this->lastConnect = millis(); return true; } diff --git a/Network.cpp b/Network.cpp index fcc9698..67ac7fd 100644 --- a/Network.cpp +++ b/Network.cpp @@ -10,6 +10,8 @@ #include "SSDP.h" #include "MQTT.h" +int testFallback = 5; + extern ConfigSettings settings; extern Web webServer; extern SocketEmitter sockEmit; @@ -18,7 +20,6 @@ extern rebootDelay_t rebootDelay; extern Network net; extern SomfyShadeController somfy; - static bool _apScanning = false; static uint32_t _lastMaxHeap = 0; static uint32_t _lastHeap = 0; @@ -41,9 +42,9 @@ bool Network::setup() { Serial.print("WiFi Mode: "); Serial.println(WiFi.getMode()); WiFi.mode(WIFI_STA); - settings.WIFI.printNetworks(); + //settings.WIFI.printNetworks(); } - //if(!this->connect()) this->openSoftAP(); + sockEmit.begin(); return true; } void Network::loop() { @@ -51,11 +52,9 @@ void Network::loop() { if(!this->connected() || this->connecting()) return; if(millis() - this->lastEmit > 1500) { this->lastEmit = millis(); - if(!this->softAPOpened) { - if(this->connected()) { - this->emitSockets(); - this->lastEmit = millis(); - } + if(this->connected()) { + this->emitSockets(); + this->lastEmit = millis(); } } sockEmit.loop(); @@ -224,7 +223,7 @@ void Network::setConnected(conn_types connType) { this->connectTime = millis(); connectRetries = 0; if(this->connType == conn_types::wifi) { - if(this->softAPOpened) { + if(this->softAPOpened && WiFi.softAPgetStationNum() == 0) { WiFi.softAPdisconnect(true); WiFi.mode(WIFI_STA); } @@ -233,6 +232,7 @@ void Network::setConnected(conn_types connType) { this->mac = WiFi.BSSIDstr(); this->strength = WiFi.RSSI(); this->channel = WiFi.channel(); + this->connectAttempts++; } else if(this->connType == conn_types::ethernet) { if(this->softAPOpened) { @@ -240,10 +240,12 @@ void Network::setConnected(conn_types connType) { WiFi.softAPdisconnect(true); WiFi.mode(WIFI_OFF); } + this->connectAttempts++; this->_connecting = false; this->wifiFallback = false; } - sockEmit.begin(); + // NET: Begin this in the startup. + //sockEmit.begin(); if(this->connectAttempts == 1) { Serial.println(); if(this->connType == conn_types::wifi) { @@ -283,11 +285,6 @@ void Network::setConnected(conn_types connType) { json->addElem("fullduplex", ETH.fullDuplex()); json->endObject(); sockEmit.endEmit(); - /* - char buf[128]; - snprintf(buf, sizeof(buf), "{\"connected\":true,\"speed\":%d,\"fullduplex\":%s}", ETH.linkSpeed(), ETH.fullDuplex() ? "true" : "false"); - sockEmit.sendToClients("ethernet", buf); - */ } } else { @@ -379,8 +376,6 @@ bool Network::connectWired() { } else Serial.println("Connecting to Wired Ethernet"); - - this->connectAttempts++; this->_connecting = true; this->connTarget = conn_types::ethernet; this->connType = conn_types::unset; @@ -441,6 +436,10 @@ bool Network::connectWiFi() { this->disconnected = 0; return true; } + if(this->softAPOpened) Serial.printf("connectWiFi: %d\n", WiFi.softAPgetStationNum()); + this->_connecting = true; + this->connTarget = conn_types::wifi; + this->connType = conn_types::unset; if(this->connectAttempts > 0) { Serial.print("Connection Lost..."); Serial.print(this->mac); @@ -451,13 +450,9 @@ bool Network::connectWiFi() { Serial.println("dbm) "); } else Serial.println("Connecting to AP"); - this->connectAttempts++; - this->_connecting = true; - this->connTarget = conn_types::wifi; - this->connType = conn_types::unset; - + // If the soft AP is currently opened then we do not want to kill it. WiFi.setSleep(false); - WiFi.mode(WIFI_MODE_NULL); + //WiFi.mode(WIFI_MODE_NULL); if(!settings.IP.dhcp) { 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); @@ -469,9 +464,10 @@ bool Network::connectWiFi() { if(settings.hostname[0] != '\0') WiFi.setHostname(settings.hostname); Serial.print("Set hostname to:"); Serial.println(WiFi.getHostname()); - WiFi.mode(WIFI_STA); + //WiFi.mode(WIFI_STA); WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN); WiFi.setSortMethod(WIFI_CONNECT_AP_BY_SIGNAL); + this->connectAttempts++; uint8_t bssid[6]; int32_t channel = 0; if(this->getStrongestAP(settings.WIFI.ssid, bssid, &channel)) { @@ -480,21 +476,31 @@ bool Network::connectWiFi() { } else WiFi.begin(settings.WIFI.ssid, settings.WIFI.passphrase); - this->connectStart = millis(); } + this->connectStart = millis(); return true; } bool Network::connect() { if(this->connecting()) { + // We are currently connecting and this flag is triggered while there is an attempt + // 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 + // the case where the target was originally ethernet then we need to open the softAP. if(this->connType == conn_types::unset) { // If we reached our timeout for the connection then we need to open the soft ap. if(millis() > this->connectStart + CONNECT_TIMEOUT) { + esp_task_wdt_reset(); if(this->connTarget == conn_types::ethernet && settings.connType == conn_types::ethernetpref && settings.WIFI.ssid[0] != '\0') this->connectWiFi(); + else if(this->softAPOpened) { + if(settings.connType == conn_types::ethernet || settings.connType == conn_types::ethernetpref) + this->connectWired(); + else if(settings.connType == conn_types::wifi && strlen(settings.WIFI.ssid) > 0) + this->connectWiFi(); + } else { - Serial.println("Fell into timeout"); + //Serial.println("Fell into timeout"); this->openSoftAP(); - } } } @@ -507,6 +513,11 @@ bool Network::connect() { this->connectWiFi(); else this->openSoftAP(); + if(this->softAPOpened && this->connected() && WiFi.softAPgetStationNum() == 0) { + Serial.println("Closing uneeded SoftAP"); + WiFi.softAPdisconnect(true); + if(this->connType == conn_types::wifi) WiFi.mode(WIFI_STA); + } return true; } uint32_t Network::getChipId() { @@ -539,69 +550,14 @@ bool Network::getStrongestAP(const char *ssid, uint8_t *bssid, int32_t *channel) return chan > 0; } bool Network::openSoftAP() { + if(this->softAPOpened || this->openingSoftAP) return true; + this->openingSoftAP = true; Serial.println(); Serial.println("Turning the HotSpot On"); - WiFi.disconnect(true); - WiFi.hostname("ESPSomfy RTS"); - WiFi.mode(WIFI_AP_STA); - this->_connecting = false; - delay(100); + esp_task_wdt_reset(); // Make sure we do not reboot here. WiFi.softAP("ESPSomfy RTS", ""); Serial.println("Initializing AP for credentials modification"); - Serial.println(); - Serial.print("SoftAP IP: "); - Serial.println(WiFi.softAPIP()); - //pinMode(D0, INPUT_PULLUP); - long startTime = millis(); - int c = 0; - sockEmit.begin(); - while (!this->connected()) - { - int clients = WiFi.softAPgetStationNum(); - somfy.loop(); - webServer.loop(); - if(millis() - this->lastEmit > 1500) { - //if(this->connect()) {} - this->lastEmit = millis(); - this->emitSockets(); - if(clients > 0) - Serial.print(clients); - else - Serial.print("."); - c++; - } - sockEmit.loop(); - if(rebootDelay.reboot && millis() > rebootDelay.rebootTime) { - this->end(); - ESP.restart(); - break; - } - - // If no clients have connected in 3 minutes from starting this server reboot this pig. This will - // force a reboot cycle until we have some response. That is unless the SSID has been cleared. - if(clients == 0 && this->connType != conn_types::unset) { - Serial.println(); - Serial.println("Connection Established Stopping AP Mode"); - this->setConnected(this->connType); - return false; - } - else if(clients == 0 && - (strlen(settings.WIFI.ssid) > 0 || settings.connType == conn_types::ethernet || settings.connType == conn_types::ethernetpref) && - millis() - startTime > 3 * 60000) { - Serial.println(); - Serial.println("Stopping AP Mode"); - WiFi.softAPdisconnect(true); - - return false; - } - - if(c == 100) { - Serial.println(); - c = 0; - } - esp_task_wdt_reset(); - yield(); - } + delay(200); return true; } bool Network::connected() { @@ -617,20 +573,21 @@ bool Network::connecting() { } void Network::networkEvent(WiFiEvent_t event) { switch(event) { - case ARDUINO_EVENT_WIFI_READY: Serial.println("WiFi interface ready"); break; - case ARDUINO_EVENT_WIFI_SCAN_DONE: Serial.println("Completed scan for access points"); 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_STA_START: Serial.println("WiFi station mode started"); if(settings.hostname[0] != '\0') WiFi.setHostname(settings.hostname); break; - case ARDUINO_EVENT_WIFI_STA_STOP: Serial.println("WiFi clients stopped"); break; - case ARDUINO_EVENT_WIFI_STA_CONNECTED: Serial.println("Connected to access point"); break; - case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: Serial.println("Disconnected from WiFi access point"); break; - case ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE: Serial.println("Authentication mode of access point has changed"); break; + case ARDUINO_EVENT_WIFI_STA_STOP: Serial.println("(evt) WiFi clients stopped"); break; + case ARDUINO_EVENT_WIFI_STA_CONNECTED: Serial.println("(evt) Connected to access point"); break; + case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: Serial.println("(evt) Disconnected from WiFi access point"); break; + case ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE: Serial.println("(evt) Authentication mode of access point has changed"); break; case ARDUINO_EVENT_WIFI_STA_GOT_IP: Serial.print("Got WiFi IP: "); Serial.println(WiFi.localIP()); net.connType = conn_types::wifi; + net.connectTime = millis(); break; case ARDUINO_EVENT_WIFI_STA_LOST_IP: Serial.println("Lost IP address and IP address is reset to 0"); break; case ARDUINO_EVENT_ETH_GOT_IP: @@ -638,38 +595,39 @@ void Network::networkEvent(WiFiEvent_t event) { if(WiFi.status() == WL_CONNECTED) WiFi.disconnect(true); Serial.print("Got Ethernet IP "); Serial.println(ETH.localIP()); + net.connectTime = millis(); net.connType = conn_types::ethernet; break; case ARDUINO_EVENT_ETH_CONNECTED: - Serial.print("Ethernet Connected "); - // We don't want to call setConnected if we do not have an IP address yet - //if(ETH.localIP() != INADDR_NONE) - // net.setConnected(conn_types::ethernet); + Serial.print("(evt) Ethernet Connected "); break; case ARDUINO_EVENT_ETH_DISCONNECTED: - Serial.println("Ethernet Disconnected"); + Serial.println("(evt) Ethernet Disconnected"); net.connType = conn_types::unset; break; case ARDUINO_EVENT_ETH_START: - Serial.println("Ethernet Started"); + Serial.println("(evt) Ethernet Started"); net.ethStarted = true; break; case ARDUINO_EVENT_ETH_STOP: - Serial.println("Ethernet Stopped"); + Serial.println("(evt) Ethernet Stopped"); net.connType = conn_types::unset; net.ethStarted = false; break; case ARDUINO_EVENT_WIFI_AP_START: - Serial.println("WiFi AP Started"); + Serial.print("(evt) WiFi SoftAP Started IP:"); + Serial.println(WiFi.softAPIP()); + net.openingSoftAP = false; net.softAPOpened = true; break; case ARDUINO_EVENT_WIFI_AP_STOP: - Serial.println("WiFi AP Stopped"); + Serial.println("(evt) WiFi SoftAP Stopped"); + //if(net.softAPOpened) net.openingSoftAP = false; net.softAPOpened = false; break; default: if(event > ARDUINO_EVENT_ETH_START) - Serial.printf("Unknown Ethernet Event %d\n", event); + Serial.printf("(evt) Unknown Ethernet Event %d\n", event); break; } } diff --git a/Network.h b/Network.h index d05d664..0d90256 100644 --- a/Network.h +++ b/Network.h @@ -16,6 +16,7 @@ class Network { bool ethStarted = false; bool wifiFallback = false; bool softAPOpened = false; + bool openingSoftAP = false; bool needsBroadcast = true; conn_types connType = conn_types::unset; conn_types connTarget = conn_types::unset; diff --git a/Sockets.cpp b/Sockets.cpp index 97c26e0..6d098a8 100644 --- a/Sockets.cpp +++ b/Sockets.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "Sockets.h" #include "ConfigSettings.h" #include "Somfy.h" @@ -105,10 +106,12 @@ void SocketEmitter::initClients() { if(num != 255) { if(sockServer.clientIsConnected(num)) { Serial.printf("Initializing Socket Client %u\n", num); + esp_task_wdt_reset(); settings.emitSockets(num); somfy.emitState(num); git.emitUpdateCheck(num); net.emitSockets(num); + esp_task_wdt_reset(); } this->newClients[i] = 255; } diff --git a/Somfy.cpp b/Somfy.cpp index f28aeb4..1cae433 100644 --- a/Somfy.cpp +++ b/Somfy.cpp @@ -4613,6 +4613,7 @@ void Transceiver::clearReceived(void) { //packet_received = false; //memset(receive_buffer, 0x00, sizeof(receive_buffer)); if(this->config.enabled) + //attachInterrupt(interruptPin, handleReceive, FALLING); attachInterrupt(interruptPin, handleReceive, CHANGE); } void Transceiver::enableReceive(void) { @@ -4623,6 +4624,7 @@ void Transceiver::enableReceive(void) { pinMode(this->config.RXPin, INPUT); interruptPin = digitalPinToInterrupt(this->config.RXPin); ELECHOUSE_cc1101.SetRx(); + //attachInterrupt(interruptPin, handleReceive, FALLING); attachInterrupt(interruptPin, handleReceive, CHANGE); Serial.printf("Enabled receive on Pin #%d Timing: %ld\n", this->config.RXPin, millis() - timing); } diff --git a/SomfyController.ino b/SomfyController.ino index 3702b5d..46dfc8d 100644 --- a/SomfyController.ino +++ b/SomfyController.ino @@ -56,16 +56,24 @@ void loop() { net.loop(); if(millis() - timing > 100) Serial.printf("Timing Net: %ldms\n", millis() - timing); timing = millis(); + esp_task_wdt_reset(); somfy.loop(); if(millis() - timing > 100) Serial.printf("Timing Somfy: %ldms\n", millis() - timing); timing = millis(); - if(net.connected()) { - if(!rebootDelay.reboot) git.loop(); + esp_task_wdt_reset(); + if(net.connected() || net.softAPOpened) { + if(!rebootDelay.reboot && net.connected() && !net.softAPOpened) { + git.loop(); + esp_task_wdt_reset(); + } webServer.loop(); - if(millis() - timing > 200) Serial.printf("Timing WebServer: %ldms\n", millis() - timing); + esp_task_wdt_reset(); + if(millis() - timing > 100) Serial.printf("Timing WebServer: %ldms\n", millis() - timing); + esp_task_wdt_reset(); timing = millis(); sockEmit.loop(); if(millis() - timing > 100) Serial.printf("Timing Socket: %ldms\n", millis() - timing); + esp_task_wdt_reset(); timing = millis(); } if(rebootDelay.reboot && millis() > rebootDelay.rebootTime) { @@ -73,14 +81,4 @@ void loop() { ESP.restart(); } esp_task_wdt_reset(); - - /* - if(heap < oldheap) { - Serial.print("Heap: "); - Serial.print(oldheap); - Serial.print(" -> "); - Serial.println(heap); - } - oldheap = heap; - */ } diff --git a/SomfyController.ino.esp32.bin b/SomfyController.ino.esp32.bin index c2fc5d9..9812796 100644 Binary files a/SomfyController.ino.esp32.bin and b/SomfyController.ino.esp32.bin differ diff --git a/SomfyController.ino.esp32s3.bin b/SomfyController.ino.esp32s3.bin index 1e8b11b..b24c51f 100644 Binary files a/SomfyController.ino.esp32s3.bin and b/SomfyController.ino.esp32s3.bin differ diff --git a/SomfyController.littlefs.bin b/SomfyController.littlefs.bin index fb06c91..a20cf66 100644 Binary files a/SomfyController.littlefs.bin and b/SomfyController.littlefs.bin differ diff --git a/Web.cpp b/Web.cpp index efa2efb..10faf68 100644 --- a/Web.cpp +++ b/Web.cpp @@ -215,7 +215,7 @@ void Web::handleStreamFile(WebServer &server, const char *filename, const char * } webServer.sendCORSHeaders(server); if(server.method() == HTTP_OPTIONS) { server.send(200, "OK"); return; } - + esp_task_wdt_reset(); // Load the index html page from the data directory. Serial.print("Loading file "); Serial.println(filename); @@ -225,9 +225,11 @@ void Web::handleStreamFile(WebServer &server, const char *filename, const char * Serial.println(filename); server.send(500, _encoding_text, "Error opening file"); } - esp_task_wdt_reset(); + esp_task_wdt_delete(NULL); server.streamFile(file, encoding); file.close(); + esp_task_wdt_add(NULL); + esp_task_wdt_reset(); } void Web::handleController(WebServer &server) { webServer.sendCORSHeaders(server); diff --git a/data/appversion b/data/appversion index 6550da6..ab6d278 100644 --- a/data/appversion +++ b/data/appversion @@ -1 +1 @@ -2.4.3 \ No newline at end of file +2.4.4 \ No newline at end of file diff --git a/data/index.js b/data/index.js index 227b9fe..399002d 100644 --- a/data/index.js +++ b/data/index.js @@ -1270,7 +1270,7 @@ var security = new Security(); class General { initialized = false; - appVersion = 'v2.4.3'; + appVersion = 'v2.4.4'; reloadApp = false; init() { if (this.initialized) return;