diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..89cc49c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+.pio
+.vscode/.browse.c_cpp.db*
+.vscode/c_cpp_properties.json
+.vscode/launch.json
+.vscode/ipch
diff --git a/.gitpod.Dockerfile b/.gitpod.Dockerfile
new file mode 100644
index 0000000..7fc22ba
--- /dev/null
+++ b/.gitpod.Dockerfile
@@ -0,0 +1,5 @@
+FROM gitpod/workspace-full
+
+USER gitpod
+
+RUN pip3 install -U platformio && npm install html-minifier-terser -g
\ No newline at end of file
diff --git a/.gitpod.yml b/.gitpod.yml
new file mode 100644
index 0000000..dd4cc5d
--- /dev/null
+++ b/.gitpod.yml
@@ -0,0 +1,11 @@
+vscode:
+ extensions:
+ - vscode.cpp
+
+tasks:
+ - before: platformio upgrade
+ - init: platformio test -e native
+ - command: platformio run -e lolin32
+
+image:
+ file: .gitpod.Dockerfile
diff --git a/Boot.gif b/Boot.gif
deleted file mode 100644
index 9fac7e4..0000000
Binary files a/Boot.gif and /dev/null differ
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..bb53b93
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 lolwheel
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
index 31838f1..27a331f 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,11 @@
# OwieWatcher
-A simple ESP8266 based sketch to connect to an [owie](https://github.com/lolwheel/Owie) device and pull the battery info from the status webpage for output to an OLED display. The current code configuration outputs the Voltage, BMS SOC & OVERRIDEN SOC.
+[](https://gitpod.io/#https://github.com/tonyt321/OWIE-OLED)
+
+todo
+- get gitpod working idk how to save from gitpod to here
+- use the u8g2 library better display support
+
+A simple ESP8266 based sketch to connect to an [owie](https://github.com/tonyt321/OWIE-OLED) device and pull the battery info from the status webpage for output to an OLED display. The current code configuration outputs the Voltage, BMS SOC & OVERRIDEN SOC.
## Demo
OwieWatcher bootup
diff --git a/lib/bms/desktop.ini b/lib/bms/desktop.ini
new file mode 100644
index 0000000..694dfa4
--- /dev/null
+++ b/lib/bms/desktop.ini
@@ -0,0 +1 @@
+[LocalizedFileNames]
diff --git a/owie-watcher-logo_EXAMPLE.bmp b/owie-watcher-logo_EXAMPLE.bmp
deleted file mode 100644
index 2765794..0000000
Binary files a/owie-watcher-logo_EXAMPLE.bmp and /dev/null differ
diff --git a/owie-watcher.ino b/owie-watcher.ino
deleted file mode 100644
index b8b2bb7..0000000
--- a/owie-watcher.ino
+++ /dev/null
@@ -1,192 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-#include
-
-ESP8266WiFiMulti WiFiMulti;
-
-// REPLACE WITH YOUR NETWORK CREDENTIALS
-char* ssid = "owie-ssid";
-char* password = "owie-wifi-password";
-#define OLED_RESET 0 // GPIO0
-Adafruit_SSD1306 display(OLED_RESET);
-
-//Boot Logo, change if you dont like it
-static const unsigned char PROGMEM logo16_glcd_bmp[] =
-{ 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111,
- 0b11000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000011,
- 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b01000000, 0b00000000, 0b00000000, 0b10000001, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b10000001, 0b00000000, 0b00000001,
- 0b10000110, 0b01001001, 0b01001100, 0b00010010, 0b01011101, 0b11011001, 0b01000110, 0b01010001,
- 0b10001001, 0b01010101, 0b01010010, 0b00010101, 0b01000010, 0b10100101, 0b10101001, 0b01100001,
- 0b10001001, 0b01010101, 0b01011110, 0b00010101, 0b01001110, 0b10100001, 0b00101111, 0b01000001,
- 0b10001001, 0b01010101, 0b01010000, 0b00010101, 0b01010010, 0b10100001, 0b00101000, 0b01000001,
- 0b10001001, 0b01010101, 0b01010010, 0b00010101, 0b01010010, 0b10100101, 0b00101001, 0b01000001,
- 0b10000110, 0b00100010, 0b01001100, 0b00001000, 0b10001110, 0b11011001, 0b00100110, 0b01000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00000011, 0b11000000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00001111, 0b11110000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00011100, 0b00111000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00111000, 0b00011100, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00110000, 0b00001100, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00011111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111000, 0b00000001,
- 0b10000000, 0b00001000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00010000, 0b00000001,
- 0b10000000, 0b00000100, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00100000, 0b00000001,
- 0b10000000, 0b00000011, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00110000, 0b00001100, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00111000, 0b00011100, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00011100, 0b00111000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00001111, 0b11110000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00000011, 0b11000000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
- 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
- 0b11000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000011,
- 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111 };
-
-void setup() {
-
- Serial.begin(115200);
- display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
- display.clearDisplay();
- display.drawBitmap(0, 0, logo16_glcd_bmp, 64, 48, 1);
- display.display();
- delay(2000);
- display.clearDisplay();
-
- Serial.println();
- Serial.println();
- Serial.println();
-
- for (uint8_t t = 4; t > 0; t--) {
- Serial.printf("[SETUP] WAIT %d...\n", t);
- Serial.flush();
- delay(1000);
- }
-
- WiFi.mode(WIFI_STA);
- WiFiMulti.addAP(ssid,password);
-}
-
-void loop() {
- // wait for WiFi connection
- if ((WiFiMulti.run() == WL_CONNECTED)) {
-
- WiFiClient client;
- HTTPClient http;
-
- display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
- display.setTextSize(1);
- display.setTextColor(WHITE,BLACK);
-
- display.setCursor(0, 0);
- Serial.print("[HTTP] begin...\n");
-
- http.begin(client, "http://192.168.4.1");
-
- Serial.print("[HTTP] GET...\n");
- int httpCode = http.GET();
- if (httpCode > 0) {
- Serial.printf("[HTTP] GET... code: %d\n", httpCode);
-
- if (httpCode == HTTP_CODE_OK) {
- int len = http.getSize();
-
-#if 0
- // with API
- Serial.println(http.getString());
-#else
- WiFiClient* stream = &client;
-
- while (http.connected() && (len > 0 || len == -1)) {
- char vbuff[5] = {0};
- char socbuff[4] = {0};
- char ovrbuff[4] = {0};
- display.setCursor(0, 0);
- stream->find("Voltage");
- while(stream->find("TOTAL_VOLTAGE\">")){
- stream->readBytesUntil('<',vbuff,5);
- Serial.print(vbuff);
- display.print("VOL:");
- display.print(vbuff);
- display.print("v");
- display.println();
- display.display();
- stream->find("BMS_SOC\">");
- stream->readBytesUntil('<',socbuff,4);
- display.println();
- display.print("BMS:");
- Serial.println();
- Serial.print(socbuff);
- display.print(socbuff);
- display.println();
- display.display();
- stream->find("OVERRIDDEN_SOC\">");
- stream->readBytesUntil('<',ovrbuff,4);
- Serial.println();
- Serial.print(ovrbuff);
- display.println();
- display.print("OVR:");
- display.print(ovrbuff);
- display.println();
- display.display();
- display.print(" ");
- display.display();
- display.setCursor(0, 41);
- delay(5 * 1000);
- display.print("REFRESH");
- display.display();
- Serial.print("REFRESH");
- delay(1 * 1000);
- display.print(".");
- Serial.print(".");
- display.display();
- delay(1 * 1000);
- display.print(".");
- Serial.print(".");
- display.display();
- delay(1 * 1000);
- display.print(".");
- Serial.print(".");
- display.display();
- delay(1 * 1000);
- return;
- }
- }
-#endif
- Serial.println();
- Serial.print("[HTTP] connection closed or file end.\n");
- }
- } else {
- Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
- }
-
- http.end();
- }
-
- Serial.print("RETRYING...");
- display.setCursor(0, 41);
- display.print("RETRYING ");
- display.display();
- delay(30 * 1000);
-}
diff --git a/pio_tools/gen_data.py b/pio_tools/gen_data.py
new file mode 100644
index 0000000..5e55c4b
--- /dev/null
+++ b/pio_tools/gen_data.py
@@ -0,0 +1,74 @@
+Import("env")
+import os
+import subprocess
+
+from SCons.Script import COMMAND_LINE_TARGETS
+
+if "idedata" in COMMAND_LINE_TARGETS:
+ env.Exit(0)
+
+
+def ReadAndMaybeMinifyFiles(fullPath):
+ _, extension = os.path.splitext(fullPath)
+ if not extension in ['.html', '.js', '.css']:
+ with open(fullPath, "rb") as f:
+ return f.read()
+ originalSize = os.stat(fullPath).st_size
+ result = subprocess.run(['html-minifier-terser',
+ '--collapse-whitespace',
+ '--remove-comments',
+ '--minify-js',
+ 'true',
+ '--minify-css',
+ 'true',
+ fullPath], stdout=subprocess.PIPE)
+ minifiedContent = result.stdout
+ print("Minified '%s' with from %d to %d bytes" % (fullPath, originalSize, len(minifiedContent)))
+ return minifiedContent
+
+
+def GenData():
+ dataDir = os.path.join(env["PROJECT_DIR"], "data")
+ print("dataDir = %s" % dataDir)
+ genDir = os.path.join(env.subst("$BUILD_DIR"), 'inline_data')
+ print("genDir = %s" % genDir)
+ if not os.path.exists(dataDir):
+ return
+ if not os.path.exists(genDir):
+ os.mkdir(genDir)
+ env.Append(CPPPATH=[genDir])
+
+ files = sorted(file for file in os.listdir(dataDir)
+ if os.path.isfile(os.path.join(dataDir, file)))
+
+ out = "// WARNING: Autogenerated by pio_tools/gen_data.py, don't edit manually.\n"
+ out += "#ifndef OWIE_GENERATED_DATA_H\n"
+ out +="#define OWIE_GENERATED_DATA_H\n\n"
+ for name in files:
+ varName = name.upper().replace(".", "_")
+ sizeName = varName + "_SIZE"
+ storageArrayName = varName + "_PROGMEM_ARRAY"
+ out += (
+ "static const unsigned char %s[] PROGMEM = {\n " % storageArrayName)
+ firstByte = True
+ fileContent = ReadAndMaybeMinifyFiles(os.path.join(dataDir, name))
+ column = 0
+ for b in fileContent:
+ if not firstByte:
+ out += ","
+ else:
+ firstByte = False
+ column = column + 1
+ if column > 20:
+ column = 0
+ out += "\n "
+ out += str(b)
+ out += "};\n"
+ out += "#define %s FPSTR(%s)\n" % (varName, storageArrayName)
+ out += "#define %s sizeof(%s)\n\n" % (sizeName, storageArrayName)
+ out += "\n#endif // OWIE_GENERATED_DATA_H\n"
+ with open(os.path.join(genDir, "data.h"), 'w') as f:
+ f.write(out)
+ print("Wrote data.h\n")
+
+GenData()
diff --git a/pio_tools/platformio_upload.py b/pio_tools/platformio_upload.py
new file mode 100644
index 0000000..02e735d
--- /dev/null
+++ b/pio_tools/platformio_upload.py
@@ -0,0 +1,53 @@
+# Allows PlatformIO to upload directly to AsyncElegantOTA
+#
+# To use:
+# - copy this script into the same folder as your platformio.ini
+# - set the following for your project in platformio.ini:
+#
+# extra_scripts = platformio_upload.py
+# upload_protocol = custom
+# upload_url =
+#
+# An example of an upload URL:
+# upload_URL = http://192.168.1.123/update
+
+import requests
+import hashlib
+Import('env')
+
+try:
+ from requests_toolbelt import MultipartEncoder, MultipartEncoderMonitor
+ from tqdm import tqdm
+except ImportError:
+ env.Execute("$PYTHONEXE -m pip install requests_toolbelt")
+ env.Execute("$PYTHONEXE -m pip install tqdm")
+ from requests_toolbelt import MultipartEncoder, MultipartEncoderMonitor
+ from tqdm import tqdm
+
+def on_upload(source, target, env):
+ firmware_path = str(source[0])
+ upload_url = env.GetProjectOption('upload_url')
+
+ with open(firmware_path, 'rb') as firmware:
+ md5 = hashlib.md5(firmware.read()).hexdigest()
+ firmware.seek(0)
+ encoder = MultipartEncoder(fields={
+ 'MD5': md5,
+ 'firmware': ('firmware', firmware, 'application/octet-stream')}
+ )
+
+ bar = tqdm(desc='Upload Progress',
+ total=encoder.len,
+ dynamic_ncols=True,
+ unit='B',
+ unit_scale=True,
+ unit_divisor=1024
+ )
+
+ monitor = MultipartEncoderMonitor(encoder, lambda monitor: bar.update(monitor.bytes_read - bar.n))
+
+ response = requests.post(upload_url, data=monitor, headers={'Content-Type': monitor.content_type})
+ bar.close()
+ print(response,response.text)
+
+env.Replace(UPLOADCMD=on_upload)
\ No newline at end of file
diff --git a/platformio.ini b/platformio.ini
new file mode 100644
index 0000000..f4bd7a5
--- /dev/null
+++ b/platformio.ini
@@ -0,0 +1,92 @@
+[platformio]
+; point data_dir to nonexistent directory so that PIO doesn't bother building SPIFFS
+data_dir = nonexistent
+
+[env:d1_mini_lite_clone]
+platform = espressif8266
+upload_speed = 524288
+monitor_speed = 115200
+board = d1_mini
+# Following is necessary for cheap Wemos D1 Lite clones.
+# Without this line, flashing succeeds but programs simply don't run on the chip.
+board_build.flash_mode = dout
+framework = arduino
+board_build.ldscript = eagle.flash.1m.ld
+
+custom_nanopb_protos =
+ +
+custom_nanopb_options =
+ --error-on-unmatched
+
+extra_scripts =
+ pre:pio_tools/gen_data.py
+
+build_flags =
+ ; Disable global instances to save space
+ -DNO_GLOBAL_INSTANCES
+ ;-DDEBUG_ESP_PORT=Serial
+ ;-DDEBUG_EEPROM_ROTATE_PORT=Serial
+ ;-DDEBUG_ESP_CORE
+ ;-DDEBUG_ESP_WIFI
+ ;-DDEBUG_ESP_UPDATER
+ ;-DDEBUG_ESP_PORT=Serial
+ ;-DDEBUG_UPDATER=Serial
+
+
+lib_deps =
+ xoseperez/EEPROM_Rotate@^0.9.2
+ ottowinter/ESPAsyncWebServer-esphome@^2.1.0
+ nanopb/Nanopb@^0.4.6
+ bblanchon/ArduinoJson@^6.19.4
+
+[env:ota]
+extends = env:d1_mini_lite_clone
+extra_scripts =
+ pre:pio_tools/gen_data.py
+ pio_tools/platformio_upload.py
+upload_url = http://owie-c024.lan/update
+upload_protocol = custom
+;board_build.gzip_fw = true
+
+[env:native]
+platform = native
+debug_test = test_bms_relay
+
+
+
+[env:lolin32]
+platform = espressif32
+upload_speed = 524288
+monitor_speed = 115200
+board = lolin32
+# Following is necessary for cheap Wemos D1 Lite clones.
+# Without this line, flashing succeeds but programs simply don't run on the chip.
+board_build.flash_mode = dout
+framework = arduino
+#board_build.ldscript = eagle.flash.1m.ld
+
+#custom_nanopb_protos =
+# +
+#custom_nanopb_options =
+# --error-on-unmatched
+
+extra_scripts =
+ pre:pio_tools/gen_data.py
+
+build_flags =
+ ; Disable global instances to save space
+ ;-DNO_GLOBAL_INSTANCES #enable this to disable serial port
+ ;-DDEBUG_ESP_PORT=Serial
+ ;-DDEBUG_EEPROM_ROTATE_PORT=Serial
+ ;-DDEBUG_ESP_CORE
+ ;-DDEBUG_ESP_WIFI
+ ;-DDEBUG_ESP_UPDATER
+ ;-DDEBUG_ESP_PORT=Serial
+ ;-DDEBUG_UPDATER=Serial
+
+
+#lib_deps =
+# xoseperez/EEPROM_Rotate@^0.9.2
+# ottowinter/ESPAsyncWebServer-esphome@^2.1.0
+# nanopb/Nanopb@^0.4.6
+# bblanchon/ArduinoJson@^6.19.4
\ No newline at end of file
diff --git a/src/owie-watcher.ino b/src/owie-watcher.ino
new file mode 100644
index 0000000..b757cfd
--- /dev/null
+++ b/src/owie-watcher.ino
@@ -0,0 +1,48 @@
+
+#include
+#include "time.h"
+
+const char* ssid = "YOUR_SSID";
+const char* password = "YOUR_PASS";
+
+const char* ntpServer = "pool.ntp.org";
+const long gmtOffset_sec = 3600;
+const int daylightOffset_sec = 3600;
+
+void printLocalTime()
+{
+ struct tm timeinfo;
+ if(!getLocalTime(&timeinfo)){
+ // Serial.println("Failed to obtain time");
+ return;
+ }
+ // Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
+}
+
+void setup()
+{
+ Serial.begin(115200);
+
+ //connect to WiFi
+ //Serial.printf("Connecting to %s ", ssid);
+ WiFi.begin(ssid, password);
+ while (WiFi.status() != WL_CONNECTED) {
+ delay(500);
+ // Serial.print(".");
+ }
+ //Serial.println(" CONNECTED");
+
+ //init and get the time
+ configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
+ printLocalTime();
+
+ //disconnect WiFi as it's no longer needed
+ WiFi.disconnect(true);
+ WiFi.mode(WIFI_OFF);
+}
+
+void loop()
+{
+ delay(1000);
+ printLocalTime();
+}
\ No newline at end of file