From 092bec7dde523b8878806801da5d924c6ccbc2d6 Mon Sep 17 00:00:00 2001 From: Yuri Trikoz Date: Mon, 22 Jun 2020 03:11:02 +0300 Subject: [PATCH] 32 broken --- include/Clock.h | 7 ++ include/CommonTypes.h | 22 ++++ include/Errors.h | 14 +-- include/Global.h | 20 +-- include/Module/CharBuffer.h | 72 +++++++++++ include/Module/CircularBuffer.h | 86 +++++++++++++ include/Module/CommandShell.h | 45 +++++++ include/Module/EditLine.h | 68 +++++++++++ include/Module/Module.h | 84 +++++++++++++ include/Module/Runner.h | 8 ++ include/Module/Telnet.h | 50 ++++++++ include/Module/Terminal.h | 183 ++++++++++++++++++++++++++++ include/UptimeInterval.h | 4 +- include/Utils/FileHelper.h | 55 +++++++++ include/Utils/FileUtils.h | 1 + include/Utils/PrintMessage.h | 32 +++++ include/Utils/StringUtils.h | 2 + include/Utils/TimeUtils.h | 12 +- include/Utils/WiFiUtils.h | 10 ++ src/Clock.cpp | 54 +++++++++ src/Cmd.cpp | 1 + src/Errors.cpp | 25 ---- src/Global.cpp | 1 + src/Init.cpp | 12 +- src/Module/Telnet.cpp | 84 +++++++++++++ src/Mqtt.cpp | 10 +- src/Upgrade.cpp | 2 +- src/Utils/FileUtils.cpp | 11 +- src/Utils/StringUtils.cpp | 28 ++++- src/Utils/TimeUtils.cpp | 207 ++++++++++++++++++++++++-------- src/Utils/WiFiUtils.cpp | 108 +++++++++++++++++ src/WiFiUtils.cpp | 113 ----------------- src/iot_firmware.cpp | 87 -------------- src/main.cpp | 131 ++++++++++++++++++-- 34 files changed, 1308 insertions(+), 341 deletions(-) create mode 100644 include/Clock.h create mode 100644 include/CommonTypes.h create mode 100644 include/Module/CharBuffer.h create mode 100644 include/Module/CircularBuffer.h create mode 100644 include/Module/CommandShell.h create mode 100644 include/Module/EditLine.h create mode 100644 include/Module/Module.h create mode 100644 include/Module/Runner.h create mode 100644 include/Module/Telnet.h create mode 100644 include/Module/Terminal.h create mode 100644 include/Utils/FileHelper.h create mode 100644 include/Utils/PrintMessage.h create mode 100644 include/Utils/WiFiUtils.h create mode 100644 src/Clock.cpp delete mode 100644 src/Errors.cpp create mode 100644 src/Module/Telnet.cpp create mode 100644 src/Utils/WiFiUtils.cpp delete mode 100644 src/WiFiUtils.cpp delete mode 100644 src/iot_firmware.cpp diff --git a/include/Clock.h b/include/Clock.h new file mode 100644 index 00000000..6c6efd84 --- /dev/null +++ b/include/Clock.h @@ -0,0 +1,7 @@ +#pragma once + +#include "Global.h" + +void startTimeSync(); + +void reconfigTime(); \ No newline at end of file diff --git a/include/CommonTypes.h b/include/CommonTypes.h new file mode 100644 index 00000000..a609f050 --- /dev/null +++ b/include/CommonTypes.h @@ -0,0 +1,22 @@ +#pragma once + +enum ErrorType_t { + ET_NONE, + ET_FUNCTION, + ET_MODULE, + ET_SYSTEM +}; + +enum ErrorLevel_t { + EL_NONE, + EL_INFO, + EL_WARNING, + EL_ERROR +}; + +enum LedStatus_t { + LED_OFF, + LED_ON, + LED_SLOW, + LED_FAST +}; diff --git a/include/Errors.h b/include/Errors.h index 6a92623a..047f0af2 100644 --- a/include/Errors.h +++ b/include/Errors.h @@ -2,19 +2,7 @@ #include -enum ErrorType_t { - ET_NONE, - ET_FUNCTION, - ET_MODULE, - ET_SYSTEM -}; - -enum ErrorLevel_t { - EL_NONE, - EL_INFO, - EL_WARNING, - EL_ERROR -}; +#include "CommonTypes.h" String getErrorLevelStr(ErrorLevel_t level); diff --git a/include/Global.h b/include/Global.h index 78e771c0..e4fe7f82 100644 --- a/include/Global.h +++ b/include/Global.h @@ -10,14 +10,18 @@ #include "ESP8266.h" // #include "Consts.h" +#include "CommonTypes.h" #include "Errors.h" #include "GyverFilters.h" #include "UptimeInterval.h" +#include "Clock.h" #include "Utils\FileUtils.h" #include "Utils\JsonUtils.h" #include "Utils\StringUtils.h" #include "Utils\SysUtils.h" #include "Utils\TimeUtils.h" +#include "Utils\PrintMessage.h" +#include "Utils\WiFiUtils.h" //=========ПОДКЛЮЧЕНИЕ ОБЩИХ БИБЛИОТЕК=============== #include @@ -60,7 +64,7 @@ extern DallasTemperature sensors; * Global vars */ -enum { ROUTER_SEARCHING, +enum { WIFI_SCAN, WIFI_MQTT_CONNECTION_CHECK, SENSORS, STEPPER1, @@ -188,7 +192,7 @@ extern String getURL(const String &urls); extern void servo_(); -extern void led_blink(String satus); +extern void setLedStatus(LedStatus_t); // Mqtt extern void MQTT_init(); @@ -200,12 +204,6 @@ extern void sendCONTROL(String id, String topik, String state); extern void do_mqtt_connection(); extern void handleMQTT(); -// WiFiUtils -extern void WIFI_init(); -extern void All_init(); -extern bool StartAPMode(); -extern void ROUTER_Connecting(); - //Scenario extern void eventGen(String event_name, String number); extern String add_set(String param_name); @@ -259,7 +257,7 @@ extern void delTimer(String number); extern int readTimer(int number); //Upgrade -extern void initUpgrade(); +extern void init_updater(); // widget extern void createWidget(String widget_name, String page_name, String page_number, String file, String topic); @@ -290,4 +288,6 @@ extern void do_upgrade(); extern void uptime_init(); // Web -extern void web_init(); \ No newline at end of file +extern void web_init(); + +extern void telemetry_init(); \ No newline at end of file diff --git a/include/Module/CharBuffer.h b/include/Module/CharBuffer.h new file mode 100644 index 00000000..74fd922d --- /dev/null +++ b/include/Module/CharBuffer.h @@ -0,0 +1,72 @@ +#pragma once + +#include + +class CharBuffer : Print { + public: + CharBuffer(size_t size) : _capacity(size < 2 ? 2 : size), _write(0), _read(0) { + _pool = new char[_capacity + 1]; + memset(_pool, 0, _capacity + 1); + } + + CharBuffer(const CharBuffer &src) { + _capacity = src._capacity; + _write = src._write; + memcpy(_pool, src._pool, src._write); + } + + CharBuffer(const char *str) : CharBuffer(strlen(str) + 1) { + write((const uint8_t *)str, strlen(str)); + } + + ~CharBuffer() { + delete _pool; + } + + void clear() { + memset(_pool, 0, _capacity); + _write = 0; + _read = 0; + } + + size_t size() const { return _capacity; } + + size_t free() const { return _capacity - _write - 2; } + + size_t available() const { return _write; } + + const char *c_str() { + if (_pool[_write] != '\x00') + _pool[_write] = '\x00'; + return _pool; + } + + size_t write(char ch) { + return write((uint8_t)ch); + }; + + size_t write(const uint8_t ch) { + size_t n = 0; + if (_write < (_capacity - 2)) { + _pool[_write++] = ch; + n = 1; + } + return n; + } + + size_t write(const uint8_t *ptr, const size_t size) { + size_t n = 0; + while (n < size) { + uint8_t ch = ptr[n++]; + if (!write(ch)) + break; + } + return n; + } + + protected: + char *_pool; + size_t _capacity; + size_t _write; + size_t _read; +}; diff --git a/include/Module/CircularBuffer.h b/include/Module/CircularBuffer.h new file mode 100644 index 00000000..5c197652 --- /dev/null +++ b/include/Module/CircularBuffer.h @@ -0,0 +1,86 @@ +#pragma once + +#include + +template +class CircularBuffer { + public: + CircularBuffer() : _head{0}, _tail{0}, _full{false} {} + + ~CircularBuffer() {} + + void reset() { + _head = _tail = _full = 0; + } + + bool empty() const { + return _head == _tail && !_full; + } + + bool full() const { + return _full; + } + + size_t size() const { + size_t res = 0; + if (!_full) { + if (_head < _tail) + res = BUFFER_SIZE + _head - _tail; + else + res = _head - _tail; + } else { + res = BUFFER_SIZE; + } + return res; + } + + void push(const T &item) { + if (_full) { + _tail++; + if (_tail == BUFFER_SIZE) + _tail = 0; + } + _pool[_head++] = item; + if (_head == BUFFER_SIZE) + _head = 0; + if (_head == _tail) + _full = true; + } + + bool pop(T &item) { + bool res = false; + if (!empty()) { + item = _pool[_tail++]; + if (_tail == BUFFER_SIZE) _tail = 0; + _full = false; + res = true; + } + return res; + } + + bool pop_back(T &item) { + bool res = false; + if (!empty()) { + item = _pool[--_head]; + _full = false; + res = true; + } + return res; + } + + bool peek(T &item) const { + bool res = false; + if (!empty()) { + item = _pool[_tail]; + + res = true; + } + return res; + } + + private: + T _pool[BUFFER_SIZE]; + size_t _head; + size_t _tail; + bool _full; +}; \ No newline at end of file diff --git a/include/Module/CommandShell.h b/include/Module/CommandShell.h new file mode 100644 index 00000000..6a986639 --- /dev/null +++ b/include/Module/CommandShell.h @@ -0,0 +1,45 @@ +#pragma once + +#include + +#include "Module/Terminal.h" +#include "Module/CircularBuffer.h" +#include "Module/Runner.h" + +class CommandShell { + public: + CommandShell(Runner *runner); + + void setTerm(Terminal *term); + Terminal *term(); + + void showGreetings(bool = true); + void showFarewell(bool = true); + + void clearHistory(); + void addHistory(const char *); + bool getHistoryInput(String &); + void setEditLine(const String &); + bool active(); + void loop(); + + private: + size_t printGreetings(Print *); + size_t printFarewell(Print *); + size_t printPrompt(Print *); + + void onOpen(Print *out); + void onClose(Print *out); + void onData(const char *); + void onHistory(Print *out); + bool getLastInput(String &); + + private: + CircularBuffer _history; + Terminal *_term; + Runner *_runner; + String _path; + bool _active; + bool _greetings; + bool _farewell; +}; diff --git a/include/Module/EditLine.h b/include/Module/EditLine.h new file mode 100644 index 00000000..4368fb7f --- /dev/null +++ b/include/Module/EditLine.h @@ -0,0 +1,68 @@ +#pragma once + +#include "Module/CharBuffer.h" + +class EditLine : public CharBuffer { + public: + EditLine(size_t size) : CharBuffer(size){}; + + char &operator[](size_t i) { return _pool[i]; } + + char operator[](size_t i) const { return _pool[i]; } + + EditLine &operator=(const EditLine &src) { + delete[] _pool; + _pool = new char[src._capacity]; + memcpy(_pool, src._pool, src._capacity); + _read = src._read; + _write = src._write; + return *this; + } + + void del() { + size_t i; + for (i = _write; i < _capacity; ++i) + _pool[i] = _pool[i + 1]; + _pool[i] = '\x00'; + } + + bool backspace() { + bool res = false; + if (prev()) { + del(); + res = true; + } + return res; + } + + bool next() { + bool res = false; + if (_write < _capacity - 1) { + _write++; + res = true; + } + return res; + } + + bool prev() { + bool res = false; + if (_write > 0) { + _write--; + res = true; + } + return res; + } + + size_t home() { + size_t res = _write; + _write = 0; + return res; + } + + size_t end() { + size_t n; + for (n = 0; n < _capacity - 1; ++n) + if (_pool[n] == '\x00') break; + return n; + } +}; diff --git a/include/Module/Module.h b/include/Module/Module.h new file mode 100644 index 00000000..800d5919 --- /dev/null +++ b/include/Module/Module.h @@ -0,0 +1,84 @@ +#pragma once + +#include + +enum ModuleState_t { + MOD_INIT, + MOD_INIT_FAILED, + MOD_INIT_COMPLETE, + MOD_START_FAILED, + MOD_ACTIVE +}; + +class Module { + protected: + virtual bool onInit() { return true; }; + virtual void onEnd(){}; + virtual bool onStart() { return true; } + virtual void onStop(){}; + virtual void onLoop() = 0; + + protected: + Print *_out; + + public: + Module() : _state{MOD_INIT} {} + + bool init(bool force = false) { + if (_state > MOD_INIT_COMPLETE) { + return true; + } + if (_state == MOD_INIT_FAILED && !force) { + return false; + } + + _state = onInit() ? MOD_INIT_COMPLETE : MOD_INIT_FAILED; + + return _state == MOD_INIT_COMPLETE; + } + + bool start(bool force = false) { + if (_state == MOD_ACTIVE) { + return true; + } + if (_state == MOD_START_FAILED && !force) { + return false; + } + if (_state < MOD_INIT_COMPLETE) { + if (!init(force)) { + return false; + } + } + _state = onStart() ? MOD_ACTIVE : MOD_START_FAILED; + return _state == MOD_ACTIVE; + } + + void stop() { + if (_state < MOD_ACTIVE) { + return; + } + onStop(); + _state = MOD_INIT_COMPLETE; + }; + + void end() { + if (_state < MOD_INIT_FAILED) { + return; + } + onEnd(); + _state = MOD_INIT; + }; + + void loop() { + if (_state == MOD_ACTIVE || start()) onLoop(); + }; + + void setOutput(Print *p) { _out = p; } + + ModuleState_t getState() { + return _state; + } + + private: + ModuleState_t _state; +}; diff --git a/include/Module/Runner.h b/include/Module/Runner.h new file mode 100644 index 00000000..2fcc2b6e --- /dev/null +++ b/include/Module/Runner.h @@ -0,0 +1,8 @@ +#pragma once + +#include + +class Runner { + public: + virtual void run(const char*, Print*); +}; diff --git a/include/Module/Telnet.h b/include/Module/Telnet.h new file mode 100644 index 00000000..38ec2a91 --- /dev/null +++ b/include/Module/Telnet.h @@ -0,0 +1,50 @@ +#pragma once + +#include "Global.h" + +#include "Module/Module.h" +#include "Module/Terminal.h" +#include "Module/CommandShell.h" + +#include + +enum TelnetEvent_t { + TE_CONNECTED, + TE_DISCONNECTED +}; + +typedef std::function TelnetEventHandler; + +class Telnet : public Module { + public: + Telnet(uint16_t port) : _port{port}, _lastConnected{false} {}; + + public: + void setEventHandler(TelnetEventHandler); + void sendData(const String&); + bool hasClient(); + bool isShellActive(); + + protected: + bool onInit() override; + void onEnd() override; + bool onStart() override; + void onStop() override; + void onLoop() override; + + private: + void onConnect(); + void onDisconnect(); + void onData(); + void onOpen(); + void onClose(); + + private: + TelnetEventHandler _eventHandler; + uint16_t _port; + bool _lastConnected; + WiFiClient _client; + WiFiServer* _server; + Terminal* _term; + CommandShell* _shell; +}; diff --git a/include/Module/Terminal.h b/include/Module/Terminal.h new file mode 100644 index 00000000..859f227d --- /dev/null +++ b/include/Module/Terminal.h @@ -0,0 +1,183 @@ +#pragma once + +#include "Module/EditLine.h" + +#define A_NORMAL 0x0000 // normal +#define A_UNDERLINE 0x0001 // underline +#define A_REVERSE 0x0002 // reverse +#define A_BLINK 0x0004 // blink +#define A_BOLD 0x0008 // bold +#define A_DIM 0x0010 // dim +#define A_STANDOUT A_BOLD // standout (same as bold) + +#define F_BLACK 0x0100 // foreground black +#define F_RED 0x0200 // foreground red +#define F_GREEN 0x0300 // foreground green +#define F_BROWN 0x0400 // foreground brown +#define F_BLUE 0x0500 // foreground blue +#define F_MAGENTA 0x0600 // foreground magenta +#define F_CYAN 0x0700 // foreground cyan +#define F_WHITE 0x0800 // foreground white +#define F_YELLOW F_BROWN // some terminals show brown as yellow (with A_BOLD) +#define F_COLOR 0x0F00 // foreground mask + +#define B_BLACK 0x1000 // background black +#define B_RED 0x2000 // background red +#define B_GREEN 0x3000 // background green +#define B_BROWN 0x4000 // background brown +#define B_BLUE 0x5000 // background blue +#define B_MAGENTA 0x6000 // background magenta +#define B_CYAN 0x7000 // background cyan +#define B_WHITE 0x8000 // background white +#define B_YELLOW B_BROWN // some terminals show brown as yellow (with A_BOLD) +#define B_COLOR 0xF000 // background mask + +#define CHAR_NULL 0x00 +#define CHAR_BEL 0x07 +#define CHAR_BS 0x08 +#define CHAR_SPACE 0x20 +#define CHAR_TAB 0x09 +#define CHAR_LF 0x0a +#define CHAR_CR 0x0d +#define CHR_ZERO 0x30 + +#define KEY_DEL 0x7f +#define KEY_DOWN 0x80 +#define KEY_UP 0x81 +#define KEY_LEFT 0x82 +#define KEY_RIGHT 0x83 +#define KEY_HOME 0x84 +#define KEY_INS 0x86 +#define KEY_PAGE_DOWN 0x87 +#define KEY_PAGE_UP 0x88 +#define KEY_END 0x89 +#define CHAR_LT 0x8b +#define CHAR_CSI 0x9b +#define CHAR_ESC 0x1b +#define CHAR_BIN 0xFF + +#define ESC_CURSOR_HOME "\x1b[H" +#define ESC_SAVE_CURSOR "\x1b[s" +#define ESC_UNSAVE_CURSOR "\x1b[u" +#define ESC_SAVE_CURSOR_AND_ATTRS "\x1b[7" +#define ESC_RESTORE_CURSOR_AND_ATTRS "\x1b[8" + +#define ESC_CLEAR "\x1b[2J" +#define ESC_CLEAR_BOTTOM "\x1b[J" +#define ESC_CLEAR_EOL "\x1b[0K" + +#define ESC_CURSOR_UP "\x1b[1A" +#define ESC_CURSOR_DOWN "\x1b[1B" +#define ESC_CURSOR_FORWARD "\x1b[1C" +#define ESC_CURSOR_BACKWARD "\x1b[1D" + +#define SEQ_CSI PSTR("\033[") // code introducer +#define SEQ_LOAD_G1 PSTR("\033)0") // load G1 character set +#define SEQ_CLEAR PSTR("\033[2J") // clear screen +#define SEQ_ATTRSET PSTR("\033[0") // set attributes, e.g. "\033[0;7;1m" + +#define SEQ_ATTRSET_BOLD PSTR(";1") // bold +#define SEQ_ATTRSET_DIM PSTR(";2") // dim +#define SEQ_ATTRSET_FCOLOR PSTR(";3") // forground color +#define SEQ_ATTRSET_UNDERLINE PSTR(";4") // underline +#define SEQ_ATTRSET_BCOLOR PSTR(";4") // background color +#define SEQ_ATTRSET_BLINK PSTR(";5") // blink +#define SEQ_ATTRSET_REVERSE PSTR(";7") // reverse + +enum TerminalEventEnum { + EVENT_OPEN, + EVENT_CLOSE, + EVENT_TAB +}; + +enum SpecialKeyEnum { SPEC_KEY_UP, + SPEC_KEY_TAB, + SPEC_KEY_ENTER, + SPEC_KEY_ESC }; + +typedef std::function SpecialKeyPressedEvent; + +typedef std::function TerminalEventHandler; + +typedef std::function TerminalInputEventHandler; + +enum EOLType_t { CRLF, + LFCR, + LF, + CR }; + +enum State { ST_INACTIVE, + ST_NORMAL, + ST_ESC_SEQ, + ST_CTRL_SEQ }; + +class Terminal : public Print { + public: + Terminal(Stream *stream = nullptr); + ~Terminal(); + void setStream(Stream *stream); + void setEOL(EOLType_t code); + void enableControlCodes(bool enabled = true); + void enableEcho(bool enabled = true); + void enableColors(bool enabled = true); + void setOnEvent(TerminalEventHandler); + void setOnSpecKeyPress(SpecialKeyPressedEvent); + void setOnReadLine(TerminalInputEventHandler); + + bool setLine(const uint8_t *bytes, size_t size); + CharBuffer &getLine(); + + void backsp(); + void clear(); + void clear_line(); + size_t println(const char *str); + size_t println(void); + size_t write_P(PGM_P str); + size_t write(uint8_t c); + size_t write(const uint8_t *buf, size_t size); + void writeByDigit(uint8_t i); + bool available(); + void loop(); + void start(); + void quit(); + void initscr(); + void attrset(uint16_t attr); + + private: + void move(uint8_t y, uint8_t x); + TerminalEventHandler eventHandler_; + TerminalInputEventHandler inputHandler_; + + uint8_t attr = 0xff; + uint8_t curY = 0xff; + uint8_t curX = 0xff; + + unsigned long lastReceived = 0; + State state = ST_INACTIVE; + Stream *_stream; + EditLine _line; + char cc_buf[32] = {0}; + size_t cc_pos = 0; + bool _color = false; + bool _controlCodes = false; + bool _echo = false; + EOLType_t _eol = CRLF; + + struct ControlCode { + const char *cc; + const char ch; + }; + + ControlCode keyMap[10] = { + {"G", KEY_HOME}, // 71 Home key + {"H", KEY_UP}, // 72 Up arrow + {"I", KEY_PAGE_UP}, // 73 PageUp + {"K", KEY_LEFT}, // 75 Left arrow + {"M", KEY_RIGHT}, // 77 Right arrow + {"O", KEY_END}, // 79 End key + {"P", KEY_DOWN}, // 80 Down arrow + {"Q", KEY_PAGE_DOWN}, // 81 PageDown + {"R", KEY_INS}, // 82 Insert + {"S", KEY_DEL}, // 83 Delete + }; +}; diff --git a/include/UptimeInterval.h b/include/UptimeInterval.h index 0037d3d0..1e90ec47 100644 --- a/include/UptimeInterval.h +++ b/include/UptimeInterval.h @@ -4,7 +4,7 @@ class UptimeInterval { public: - UptimeInterval(unsigned long interval, boolean postpone = true) : _interval{interval} { + UptimeInterval(unsigned long interval, boolean postpone = true) : _next{0}, _interval{interval} { reset(postpone); } @@ -28,5 +28,5 @@ class UptimeInterval { static unsigned long _uptime_seconds; private: - unsigned long _interval, _next; + unsigned long _next, _interval; }; diff --git a/include/Utils/FileHelper.h b/include/Utils/FileHelper.h new file mode 100644 index 00000000..daa9186c --- /dev/null +++ b/include/Utils/FileHelper.h @@ -0,0 +1,55 @@ +#pragma once + +#include + +#include "FS.h" + +#ifdef ESP32 +#include "LITTLEFS.h" +#define LittleFS LITTLEFS +#endif +#ifdef ESP8266 +#include +#endif + +class FileHelper { + public: + FileHelper(const String filename); + /* + * Проверить существование + */ + void exists(); + /* + * Удалить файл + */ + void remove(); + /* + * Открыть файл установить позицию @position + */ + File seek(size_t position = 0); + + /* + * Чтение строки с содержащей @substr + */ + String readFileString(const String substr); + + /* + * Добовление строки @str в файл + */ + String appendStr(const String str); + + /* + * Запись строки + */ + String writeStr(const String); + + /* + * Чтение в строку + */ + String readStr(size_t); + + /* + * Размер в байтах + */ + size_t getSize(); +}; \ No newline at end of file diff --git a/include/Utils/FileUtils.h b/include/Utils/FileUtils.h index c5f4e5a3..39fef037 100644 --- a/include/Utils/FileUtils.h +++ b/include/Utils/FileUtils.h @@ -11,6 +11,7 @@ #ifdef ESP8266 #include #endif + /* * Инициализация ФС */ diff --git a/include/Utils/PrintMessage.h b/include/Utils/PrintMessage.h new file mode 100644 index 00000000..1434907a --- /dev/null +++ b/include/Utils/PrintMessage.h @@ -0,0 +1,32 @@ +#pragma once + +#include "Arduino.h" +#include "CommonTypes.h" +#include "Utils\StringUtils.h" +#include "Utils\TimeUtils.h" +#include "Errors.h" + +#define pm PrintMessage(MODULE) + +class PrintMessage { + public: + PrintMessage(const char* module) { + _module = module; + } + + void error(const String str) { + print(EL_ERROR, str); + } + + void info(const String str) { + print(EL_INFO, str); + } + + private: + void print(const ErrorLevel_t level, const String& str) { + Serial.printf("%s [%s] [%s] %s\n", prettyMillis().c_str(), getErrorLevelStr(level).c_str(), _module, str.c_str()); + } + + private: + const char* _module; +}; diff --git a/include/Utils/StringUtils.h b/include/Utils/StringUtils.h index 1347b1ba..355cf262 100644 --- a/include/Utils/StringUtils.h +++ b/include/Utils/StringUtils.h @@ -2,6 +2,8 @@ #include +#include "CommonTypes.h" + uint8_t hexStringToUint8(String hex); uint16_t hexStringToUint16(String hex); diff --git a/include/Utils/TimeUtils.h b/include/Utils/TimeUtils.h index 5e3a37d3..f5af3064 100644 --- a/include/Utils/TimeUtils.h +++ b/include/Utils/TimeUtils.h @@ -7,10 +7,6 @@ void Time_Init(); -void time_check(); - -void reconfigTime(); - /* * Получение текущего времени */ @@ -22,7 +18,7 @@ String getTimeUnix(); /* * Параметр время -* Результат выполнения +* @result результат */ boolean getUnixTimeStr(String&); @@ -38,3 +34,9 @@ String getDateDigitalFormated(); int timeToMin(String Time); const String prettyMillis(unsigned long time_ms = millis()); + +int timeZoneInSeconds(const byte timeZone); + +bool hasTimeSynced(); + +int getBiasInSeconds(); \ No newline at end of file diff --git a/include/Utils/WiFiUtils.h b/include/Utils/WiFiUtils.h new file mode 100644 index 00000000..4fd68ad2 --- /dev/null +++ b/include/Utils/WiFiUtils.h @@ -0,0 +1,10 @@ +#pragma once + +#include "Global.h" + +boolean scanWiFi(String ssid); + +void startSTAMode(); + +bool startAPMode(); + diff --git a/src/Clock.cpp b/src/Clock.cpp new file mode 100644 index 00000000..bfc0e005 --- /dev/null +++ b/src/Clock.cpp @@ -0,0 +1,54 @@ +#include "Clock.h" + +#include "Utils/TimeUtils.h" + +static const char* MODULE = "Clock"; + +void startTimeSync() { + if (!hasTimeSynced()) { + pm.info("Start syncing"); + reconfigTime(); + } +} + +void setupSntp() { + int tzs = getBiasInSeconds(); + int tzh = tzs / 3600; + tzs -= tzh * 3600; + int tzm = tzs / 60; + tzs -= tzm * 60; + + String ntp = jsonReadStr(configSetupJson, "ntp"); + pm.info("Setup ntp: " + ntp); + char tzstr[64]; + snprintf(tzstr, sizeof tzstr, "ESPUSER<%+d:%02d:%02d>", tzh, tzm, tzs); + return configTime(tzstr, ntp.c_str(), "pool.ntp.org", "time.nist.gov"); +} + +void reconfigTime() { +#ifdef ESP32 + uint8_t i = 0; + struct tm timeinfo; + while (!getLocalTime(&timeinfo) && i <= 4) { + Serial.print("."); + i++; + delay(1000); + } +#endif + +#ifdef ESP8266 + setupSntp(); + uint8_t i = 0; + while (!hasTimeSynced() && i < 4) { + Serial.print("."); + i++; + delay(300); + } +#endif + + if (getTimeUnix() != "failed") { + pm.info("Time synced " + getDateDigitalFormated() + " " + getTime()); + } else { + pm.error("Failed to obtain"); + } +} diff --git a/src/Cmd.cpp b/src/Cmd.cpp index 93ec23cc..005c35d5 100644 --- a/src/Cmd.cpp +++ b/src/Cmd.cpp @@ -549,6 +549,7 @@ void firmwareVersion() { choose_widget_and_create(widget_name, page_name, page_number, "any-data", "firmver"); } + //============================================================================================================================== //============================выполнение команд (в лупе) по очереди из строки order============================================= void handleCMD_loop() { diff --git a/src/Errors.cpp b/src/Errors.cpp deleted file mode 100644 index b0099e4f..00000000 --- a/src/Errors.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "Errors.h" - -static const char *str_info = "Info"; -static const char *str_warn = "Warn"; -static const char *str_error = "Error"; -static const char *str_unknown = "Unknown"; - -String getErrorLevelStr(ErrorLevel_t level) { - const char *ptr; - switch (level) { - case EL_INFO: - ptr = str_info; - break; - case EL_WARNING: - ptr = str_warn; - break; - case EL_ERROR: - ptr = str_error; - break; - default: - ptr = str_unknown; - break; - } - return String(ptr); -} \ No newline at end of file diff --git a/src/Global.cpp b/src/Global.cpp index 1aff5ed0..d4b9b154 100644 --- a/src/Global.cpp +++ b/src/Global.cpp @@ -9,6 +9,7 @@ AsyncWebSocket ws; //AsyncEventSource events; #endif + TickerScheduler ts(TEST + 1); WiFiClient espClient; diff --git a/src/Init.cpp b/src/Init.cpp index 592340ca..48f9d69e 100644 --- a/src/Init.cpp +++ b/src/Init.cpp @@ -1,14 +1,10 @@ #include "Global.h" -unsigned long UptimeInterval::_uptime_seconds; - -UptimeInterval myUptime(10); - void handle_uptime(); void handle_statistics(); +void telemetry_init(); void loadConfig() { - configSetupJson = readFile("config.json", 4096); configSetupJson.replace(" ", ""); configSetupJson.replace("\r\n", ""); @@ -81,7 +77,9 @@ void uptime_init() { handle_uptime(); }, nullptr, true); +} +void telemetry_init() { if (TELEMETRY_UPDATE_INTERVAL) { ts.add( STATISTICS, TELEMETRY_UPDATE_INTERVAL, [&](void*) { @@ -92,9 +90,7 @@ void uptime_init() { } void handle_uptime() { - if (myUptime.check()) { - jsonWriteStr(configSetupJson, "uptime", prettyMillis()); - } + jsonWriteStr(configSetupJson, "uptime", prettyMillis()); } void handle_statistics() { diff --git a/src/Module/Telnet.cpp b/src/Module/Telnet.cpp new file mode 100644 index 00000000..0c2681ee --- /dev/null +++ b/src/Module/Telnet.cpp @@ -0,0 +1,84 @@ +#include "Module/Telnet.h" + +bool Telnet::onInit() { + _server = new WiFiServer(_port); + _term = new Terminal(); + _term->enableControlCodes(); + _term->enableEcho(false); + _term->setStream(&_client); + + // _shell = new CommandShell(Cli::get()); + _shell->setTerm(_term); + return true; +} + +void Telnet::onEnd() { + delete _server; +} + +bool Telnet::onStart() { + _server->begin(); + _server->setNoDelay(true); + return _server->status() != CLOSED; +} + +void Telnet::onStop() { + if (hasClient()) { + _client.stop(); + } + _server->stop(); +} + +bool Telnet::hasClient() { return _client.connected(); } + +void Telnet::sendData(const String& data) { + if (hasClient()) { + _client.write(data.c_str()); + } +} + +void Telnet::setEventHandler(TelnetEventHandler h) { _eventHandler = h; } + +void Telnet::onLoop() { + if (_server->hasClient()) { + if (!_client) { + _client = _server->available(); + } else { + if (!_client.connected()) { + _server->stop(); + _client = _server->available(); + } else { + WiFiClient rejected; + rejected = _server->available(); + rejected.stop(); + } + } + } + + if (_lastConnected != hasClient()) { + _lastConnected = hasClient(); + if (_lastConnected) { + onConnect(); + } else { + onDisconnect(); + } + } + + if (hasClient() && _shell != nullptr) _shell->loop(); +} + +bool Telnet::isShellActive() { + return _shell->active(); +} + +void Telnet::onConnect() { + if (_eventHandler) { + _eventHandler(TE_CONNECTED, &_client); + } +} + +void Telnet::onDisconnect() { + if (_eventHandler) { + _eventHandler(TE_DISCONNECTED, nullptr); + } +} diff --git a/src/Mqtt.cpp b/src/Mqtt.cpp index 0af3e13a..907f801f 100644 --- a/src/Mqtt.cpp +++ b/src/Mqtt.cpp @@ -22,7 +22,7 @@ void MQTT_init() { Serial.println("[VV] WiFi-ok"); if (client_mqtt.connected()) { Serial.println("[VV] MQTT-ok"); - led_blink("off"); + setLedStatus(LED_OFF); } else { MQTT_Connecting(); if (!just_load) mqtt_lost_error++; @@ -31,7 +31,7 @@ void MQTT_init() { Serial.println("[E] Lost WiFi connection"); wifi_lost_error++; ts.remove(WIFI_MQTT_CONNECTION_CHECK); - StartAPMode(); + startAPMode(); } }, nullptr, true); @@ -58,14 +58,14 @@ boolean MQTT_Connecting() { String mqtt_server = jsonReadStr(configSetupJson, "mqttServer"); if ((mqtt_server != "")) { Serial.println("[E] Lost MQTT connection, start reconnecting"); - led_blink("fast"); + setLedStatus(LED_FAST); client_mqtt.setServer(mqtt_server.c_str(), jsonReadInt(configSetupJson, "mqttPort")); if (WiFi.status() == WL_CONNECTED) { if (!client_mqtt.connected()) { Serial.println("[V] Connecting to MQTT server commenced"); if (client_mqtt.connect(chipId.c_str(), jsonReadStr(configSetupJson, "mqttUser").c_str(), jsonReadStr(configSetupJson, "mqttPass").c_str())) { Serial.println("[VV] MQTT connected"); - led_blink("off"); + setLedStatus(LED_OFF); client_mqtt.setCallback(callback); client_mqtt.subscribe(jsonReadStr(configSetupJson, "mqttPrefix").c_str()); // Для приема получения HELLOW и подтверждения связи client_mqtt.subscribe((jsonReadStr(configSetupJson, "mqttPrefix") + "/" + chipId + "/+/control").c_str()); // Подписываемся на топики control @@ -77,7 +77,7 @@ boolean MQTT_Connecting() { res = true; } else { Serial.println("[E] try again in " + String(MQTT_RECONNECT_INTERVAL / 1000) + " sec"); - led_blink("fast"); + setLedStatus(LED_FAST); } } } diff --git a/src/Upgrade.cpp b/src/Upgrade.cpp index 5cc21f2d..4f9877b2 100644 --- a/src/Upgrade.cpp +++ b/src/Upgrade.cpp @@ -1,5 +1,5 @@ #include "Global.h" -void initUpgrade() { +void init_updater() { #ifdef ESP8266 if (WiFi.status() == WL_CONNECTED) last_version = getURL("http://91.204.228.124:1100/update/esp8266/version.txt"); #endif diff --git a/src/Utils/FileUtils.cpp b/src/Utils/FileUtils.cpp index f27418a1..429eacda 100644 --- a/src/Utils/FileUtils.cpp +++ b/src/Utils/FileUtils.cpp @@ -1,18 +1,15 @@ #include "Utils/FileUtils.h" +#include "Utils/PrintMessage.h" static const char* MODULE = "FS"; -void printError(const String str) { - Serial.printf("[E] [%s] %s\n", MODULE, str.c_str()); -} - const String filepath(const String& filename) { return filename.startsWith("/") ? filename : "/" + filename; } bool fileSystemInit() { if (!LittleFS.begin()) { - printError("init"); + pm.error("init"); return false; } return true; @@ -20,14 +17,14 @@ bool fileSystemInit() { void removeFile(const String filename) { if (!LittleFS.remove(filepath(filename))) { - printError("remove " + filename); + pm.error("remove " + filename); } } File seekFile(const String filename, size_t position) { auto file = LittleFS.open(filepath(filename), "r"); if (!file) { - printError("open " + filename); + pm.error("open " + filename); } // поставим курсор в начало файла file.seek(position, SeekSet); diff --git a/src/Utils/StringUtils.cpp b/src/Utils/StringUtils.cpp index f4515fe3..48df7eba 100644 --- a/src/Utils/StringUtils.cpp +++ b/src/Utils/StringUtils.cpp @@ -61,7 +61,7 @@ uint16_t hexStringToUint16(String hex) { } } -size_t itemsCount(String str, const String& separator) { +size_t itemsCount(String str, const String &separator) { // если строки поиск нет сразу выход if (str.indexOf(separator) == -1) { return 0; @@ -77,7 +77,7 @@ size_t itemsCount(String str, const String& separator) { return cnt; } -boolean isDigitStr(const String& str) { +boolean isDigitStr(const String &str) { for (size_t i = 0; i < str.length(); i++) { if (!isDigit(str.charAt(i))) { return false; @@ -96,3 +96,27 @@ String prettyBytes(size_t size) { else return String(size / 1024.0 / 1024.0 / 1024.0) + "GB"; } + +static const char *str_info = "I"; +static const char *str_warn = "W"; +static const char *str_error = "E"; +static const char *str_unknown = "?"; + +String getErrorLevelStr(ErrorLevel_t level) { + const char *ptr; + switch (level) { + case EL_INFO: + ptr = str_info; + break; + case EL_WARNING: + ptr = str_warn; + break; + case EL_ERROR: + ptr = str_error; + break; + default: + ptr = str_unknown; + break; + } + return String(ptr); +} \ No newline at end of file diff --git a/src/Utils/TimeUtils.cpp b/src/Utils/TimeUtils.cpp index fbbcb00c..b52d9cd9 100644 --- a/src/Utils/TimeUtils.cpp +++ b/src/Utils/TimeUtils.cpp @@ -3,54 +3,33 @@ #include "Global.h" #include "Utils\StringUtils.h" -void Time_Init() { - ts.add( - TIME_SYNC, 30000, [&](void*) { - time_check(); - }, - nullptr, true); +#define ONE_MINUTE_s 60 +#define ONE_HOUR_s 60 * ONE_MINUTE_s + +int getBiasInSeconds() { + return 3600 * jsonReadStr(configSetupJson, "timezone").toInt(); } -void time_check() { - if (getTimeUnix() == "failed") { - Serial.println("[I] Trying to obtain time"); - reconfigTime(); - } +int getBiasInMinutes() { + return getBiasInSeconds() / 60; } -void reconfigTime() { - if (WiFi.status() == WL_CONNECTED) { - String ntp = jsonReadStr(configSetupJson, "ntp"); - configTime(0, 0, ntp.c_str()); - Serial.println("[I] Time sync"); -#ifdef ESP32 - uint8_t i = 0; - struct tm timeinfo; - while (!getLocalTime(&timeinfo) && i <= 4) { - Serial.print("."); - i++; - delay(1000); - } -#endif -#ifdef ESP8266 - //uint8_t i = 0; - //while (!time(nullptr) && i < 4) { - // Serial.print("."); - // i++; - delay(2000); - //} -#endif - if (getTimeUnix() != "failed") { - Serial.print("[V] Got time = "); - Serial.print(getDateDigitalFormated()); - Serial.print(' '); - Serial.println(getTime()); - } else { - Serial.println("[E] Failed to obtain time, retry in 30 sec"); - } - } else { - Serial.println("[E] Unable to obtain time"); - } +const timezone getTimeZone() { + return timezone{getBiasInMinutes(), 0}; +} + +time_t getSystemTime() { + timeval tv{0, 0}; + timezone tz = getTimeZone(); + time_t epoch = 0; + if (gettimeofday(&tv, &tz) != -1) + epoch = tv.tv_sec; + return epoch; +} + +bool hasTimeSynced() { + time_t now = time(nullptr); + return now > millis(); } String getTimeUnix() { @@ -69,7 +48,7 @@ boolean getUnixTimeStr(String& res) { } String getTime() { - time_t now = time(nullptr); // получаем время с помощью библиотеки time.h + time_t now = time(nullptr); int zone = 3600 * jsonReadStr(configSetupJson, "timezone").toInt(); now = now + zone; String Time = ""; // Строка для результатов времени @@ -80,7 +59,7 @@ String getTime() { } String getTimeWOsec() { - time_t now = time(nullptr); // получаем время с помощью библиотеки time.h + time_t now = time(nullptr); int zone = 3600 * jsonReadStr(configSetupJson, "timezone").toInt(); now = now + zone; String Time = ""; // Строка для результатов времени @@ -91,7 +70,7 @@ String getTimeWOsec() { } String getDate() { - time_t now = time(nullptr); // получаем время с помощью библиотеки time.h + time_t now = time(nullptr); int zone = 3600 * jsonReadStr(configSetupJson, "timezone").toInt(); now = now + zone; String Data = ""; // Строка для результатов времени @@ -142,11 +121,11 @@ int timeToMin(String Time) { return min; } -static const char* TIME_FORMAT PROGMEM = "%2d:%2d:%2d"; -static const char* TIME_FORMAT_WITH_DAYS PROGMEM = "%dd %2d:%2d"; +static const char* TIME_FORMAT PROGMEM = "%02d:%02d:%02d"; +static const char* TIME_FORMAT_WITH_DAYS PROGMEM = "%dd %02d:%02d"; const String prettyMillis(unsigned long time_ms) { - unsigned long tmp = time_ms; + unsigned long tmp = time_ms / 1000; unsigned long seconds; unsigned long minutes; unsigned long hours; @@ -156,15 +135,137 @@ const String prettyMillis(unsigned long time_ms) { minutes = tmp % 60; tmp = tmp / 60; + hours = tmp % 24; days = tmp / 24; - char buf[16]; + char buf[32]; if (days) { - sprintf_P(buf, TIME_FORMAT, hours, minutes, seconds); + sprintf_P(buf, TIME_FORMAT_WITH_DAYS, days, hours, minutes, seconds); } else { - sprintf_P(buf, TIME_FORMAT_WITH_DAYS, days, hours, minutes); + sprintf_P(buf, TIME_FORMAT, hours, minutes, seconds); } return String(buf); } + +int timeZoneInSeconds(const byte timeZone) { + int res = 0; + switch (constrain(timeZone, 1, 38)) { + case 1: + res = -12 * ONE_HOUR_s; + break; + case 2: + res = -11 * ONE_HOUR_s; + break; + case 3: + res = -10 * ONE_HOUR_s; + break; + case 4: + res = -9 * ONE_HOUR_s - 30 * ONE_MINUTE_s; + break; + case 5: + res = -9 * ONE_HOUR_s; + break; + case 6: + res = -8 * ONE_HOUR_s; + break; + case 7: + res = -7 * ONE_HOUR_s; + break; + case 8: + res = -6 * ONE_HOUR_s; + break; + case 9: + res = -5 * ONE_HOUR_s; + break; + case 10: + res = -4 * ONE_HOUR_s; + break; + case 11: + res = -3 * ONE_HOUR_s - 30 * ONE_MINUTE_s; + break; + case 12: + res = -3 * ONE_HOUR_s; + break; + case 13: + res = -2 * ONE_HOUR_s; + break; + case 14: + res = -1 * ONE_HOUR_s; + break; + case 15: + res = 0; + break; + case 16: + res = 1 * ONE_HOUR_s; + break; + case 17: + res = 2 * ONE_HOUR_s; + break; + case 18: + res = 3 * ONE_HOUR_s; + break; + case 19: + res = 3 * ONE_HOUR_s + 30 * ONE_MINUTE_s; + break; + case 20: + res = 4 * ONE_HOUR_s; + break; + case 21: + res = 4 * ONE_HOUR_s + 30 * ONE_MINUTE_s; + break; + case 22: + res = 5 * ONE_HOUR_s; + break; + case 23: + res = 5 * ONE_HOUR_s + 30 * ONE_MINUTE_s; + break; + case 24: + res = 5 * ONE_HOUR_s + 45 * ONE_MINUTE_s; + break; + case 25: + res = 6 * ONE_HOUR_s; + break; + case 26: + res = 6 * ONE_HOUR_s + 30 * ONE_MINUTE_s; + break; + case 27: + res = 7 * ONE_HOUR_s; + break; + case 28: + res = 8 * ONE_HOUR_s; + break; + case 29: + res = 8 * ONE_HOUR_s + 45 * ONE_MINUTE_s; + break; + case 30: + res = 9 * ONE_HOUR_s; + break; + case 31: + res = 9 * ONE_HOUR_s + 30 * ONE_MINUTE_s; + break; + case 32: + res = 10 * ONE_HOUR_s; + break; + case 33: + res = 10 * ONE_HOUR_s + 30 * ONE_MINUTE_s; + break; + case 34: + res = 11 * ONE_HOUR_s; + break; + case 35: + res = 12 * ONE_HOUR_s; + break; + case 36: + res = 12 * ONE_HOUR_s + 45 * ONE_MINUTE_s; + break; + case 37: + res = 13 * ONE_HOUR_s; + break; + case 38: + res = 14 * ONE_HOUR_s; + break; + } + return res; +} \ No newline at end of file diff --git a/src/Utils/WiFiUtils.cpp b/src/Utils/WiFiUtils.cpp new file mode 100644 index 00000000..ca1ac77a --- /dev/null +++ b/src/Utils/WiFiUtils.cpp @@ -0,0 +1,108 @@ +#include "Utils/WiFiUtils.h" + +static const char* MODULE = "WiFi"; + +void startSTAMode() { + setLedStatus(LED_SLOW); + pm.info("STA Mode"); + + String ssid = jsonReadStr(configSetupJson, "routerssid"); + String passwd = jsonReadStr(configSetupJson, "routerpass"); + + WiFi.mode(WIFI_STA); + if (ssid == "" && passwd == "") { + WiFi.begin(); + } else { + if (WiFi.begin(ssid.c_str(), passwd.c_str()) == WL_CONNECT_FAILED) { + pm.error("failed on start"); + } + } + + bool keepConnecting = true; + uint8_t tries = 20; + do { + sint8_t connRes = WiFi.waitForConnectResult(1000); + switch (connRes) { + case WL_NO_SSID_AVAIL: { + pm.error("No ssid available"); + keepConnecting = false; + } break; + case WL_CONNECTED: { + String hostIpStr = WiFi.localIP().toString(); + pm.info("http://" + hostIpStr); + jsonWriteStr(configSetupJson, "ip", hostIpStr); + keepConnecting = false; + } break; + case WL_CONNECT_FAILED: { + pm.error("Check credentials"); + jsonWriteInt(configOptionJson, "pass_status", 1); + keepConnecting = false; + } break; + default: + break; + } + } while (keepConnecting && tries--); + + if (WiFi.status() == WL_CONNECTED) { + MQTT_init(); + setLedStatus(LED_OFF); + } else { + startAPMode(); + }; +} + +bool startAPMode() { + setLedStatus(LED_ON); + pm.info("AP Mode"); + + String ssid = jsonReadStr(configSetupJson, "apssid"); + String passwd = jsonReadStr(configSetupJson, "appass"); + + WiFi.mode(WIFI_AP); + + WiFi.softAP(ssid.c_str(), passwd.c_str()); + String hostIpStr = WiFi.softAPIP().toString(); + pm.info("Host IP: " + hostIpStr); + jsonWriteStr(configSetupJson, "ip", hostIpStr); + + ts.add( + WIFI_SCAN, 10 * 1000, + [&](void*) { + String sta_ssid = jsonReadStr(configSetupJson, "routerssid"); + pm.info("scanning for " + sta_ssid); + if (scanWiFi(sta_ssid)) { + ts.remove(WIFI_SCAN); + startSTAMode(); + } + }, + nullptr, true); + + return true; +} + +boolean scanWiFi(String ssid) { + bool res = false; + int8_t n = WiFi.scanComplete(); + pm.info("scan result: " + String(n, DEC)); + if (n == -2) { + // не было запущено, запускаем + pm.info("start scanning"); + // async, show_hidden + WiFi.scanNetworks(true, false); + } else if (n == -1) { + // все еще выполняется + pm.info("scanning in progress"); + } else if (n == 0) { + // не найдена ни одна сеть + pm.info("no networks found"); + WiFi.scanNetworks(true, false); + } else if (n > 0) { + for (int8_t i = 0; i < n; i++) { + if (WiFi.SSID(i) == ssid) { + res = true; + } + pm.info((res ? "*" : "") + String(i, DEC) + ") " + WiFi.SSID(i)); + } + } + return res; +} \ No newline at end of file diff --git a/src/WiFiUtils.cpp b/src/WiFiUtils.cpp deleted file mode 100644 index 2e31d19f..00000000 --- a/src/WiFiUtils.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include "Global.h" - -boolean RouterFind(String ssid); - -void ROUTER_Connecting() { - led_blink("slow"); - - WiFi.mode(WIFI_STA); - - byte tries = 20; - String _ssid = jsonReadStr(configSetupJson, "routerssid"); - String _password = jsonReadStr(configSetupJson, "routerpass"); - //WiFi.persistent(false); - - if (_ssid == "" && _password == "") { - WiFi.begin(); - } else { - WiFi.begin(_ssid.c_str(), _password.c_str()); - Serial.print("ssid: "); - Serial.println(_ssid); - } - // Делаем проверку подключения до тех пор пока счетчик tries - // не станет равен нулю или не получим подключение - while (--tries && WiFi.status() != WL_CONNECTED) { - if (WiFi.status() == WL_CONNECT_FAILED) { - Serial.println("[E] password is not correct"); - tries = 1; - jsonWriteInt(configOptionJson, "pass_status", 1); - } - Serial.print("."); - delay(1000); - } - - if (WiFi.status() != WL_CONNECTED) { - // Если не удалось подключиться запускаем в режиме AP - Serial.println(""); - // WiFi.disconnect(true); - StartAPMode(); - - } else { - // Иначе удалось подключиться отправляем сообщение - // о подключении и выводим адрес IP - Serial.println(""); - Serial.println("[V] WiFi connected"); - Serial.print("[V] IP address: http://"); - Serial.print(WiFi.localIP()); - Serial.println(""); - jsonWriteStr(configSetupJson, "ip", WiFi.localIP().toString()); - led_blink("off"); - //add_dev_in_list("dev.txt", chipID, WiFi.localIP().toString()); - MQTT_init(); - } -} - -bool StartAPMode() { - Serial.println("[I] WiFi AP"); - WiFi.disconnect(); - - WiFi.mode(WIFI_AP); - - String _ssidAP = jsonReadStr(configSetupJson, "apssid"); - String _passwordAP = jsonReadStr(configSetupJson, "appass"); - WiFi.softAP(_ssidAP.c_str(), _passwordAP.c_str()); - IPAddress myIP = WiFi.softAPIP(); - led_blink("on"); - Serial.printf("[I] AP IP: %s\n", myIP.toString().c_str()); - jsonWriteStr(configSetupJson, "ip", myIP.toString()); - - //if (jsonReadInt(configOptionJson, "pass_status") != 1) { - ts.add( - ROUTER_SEARCHING, 10 * 1000, [&](void*) { - Serial.println("[I] searching ssid"); - if (RouterFind(jsonReadStr(configSetupJson, "routerssid"))) { - ts.remove(ROUTER_SEARCHING); - WiFi.scanDelete(); - ROUTER_Connecting(); - } - }, - nullptr, true); - //} - return true; -} - -boolean RouterFind(String ssid) { - bool res = false; - - int8_t n = WiFi.scanComplete(); - Serial.printf("[I][WIFI] scan result = %d\n", n); - if (n == -2) { - // не было запущено, запускаем - Serial.println("[I][WIFI] start scanning"); - // async, show_hidden - WiFi.scanNetworks(true, false); - } else if (n == -1) { - // все еще выполняется - Serial.println("[I][WIFI] scanning in progress"); - } else if (n == 0) { - // не найдена ни одна сеть - Serial.println("[I][WIFI] no wifi stations, start scanning"); - WiFi.scanNetworks(true, false); - } else if (n > 0) { - for (int8_t i = 0; i < n; i++) { - if (WiFi.SSID(i) == ssid) { - WiFi.scanDelete(); - res = true; - } else { - Serial.printf("%d) %s;\n", i, WiFi.SSID(i).c_str()); - } - } - WiFi.scanDelete(); - } - return res; -} \ No newline at end of file diff --git a/src/iot_firmware.cpp b/src/iot_firmware.cpp deleted file mode 100644 index ceb5bea6..00000000 --- a/src/iot_firmware.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#include "Global.h" - -void not_async_actions(); - -void setup() { - Serial.begin(115200); - Serial.println(); - Serial.println("--------------started----------------"); - - setChipId(); - - fileSystemInit(); - - loadConfig(); - - CMD_init(); - Serial.println("[V] Commands"); - - sensors_init(); - Serial.println("[V] Sensors"); - - All_init(); - Serial.println("[V] All"); - - ROUTER_Connecting(); - Serial.println("[V] ROUTER_Connecting"); - - uptime_init(); - Serial.println("[V] statistics_init"); - - initUpgrade(); - Serial.println("[V] initUpgrade"); - - Web_server_init(); - Serial.println("[V] Web_server_init"); - - web_init(); - Serial.println("[V] web_init"); - - Time_Init(); - Serial.println("[V] Time_Init"); - -#ifdef UDP_ENABLED - UDP_init(); - Serial.println("[V] UDP_init"); -#endif - - ts.add( - TEST, 10000, [&](void*) { - printMemoryStatus("[I] sysinfo "); - }, - nullptr, true); - - just_load = false; -} - -void loop() { -#ifdef OTA_UPDATES_ENABLED - ArduinoOTA.handle(); -#endif - -#ifdef WS_enable - ws.cleanupClients(); -#endif - - not_async_actions(); - - handleMQTT(); - handleCMD_loop(); - handleButton(); - handleScenario(); -#ifdef UDP_ENABLED - handleUdp(); -#endif - ts.update(); -} - -void not_async_actions() { - do_mqtt_connection(); - do_upgrade_url(); - do_upgrade(); -#ifdef UDP_ENABLED - do_udp_data_parse(); - do_mqtt_send_settings_to_udp(); -#endif - do_i2c_scanning(); -} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 7777bdee..2bc15218 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,9 +1,111 @@ #include "Global.h" +void not_async_actions(); + +static const char* MODULE = "Main"; + +void setup() { + WiFi.setAutoConnect(false); + WiFi.persistent(false); + + Serial.begin(115200); + Serial.flush(); + Serial.println(); + Serial.println("--------------started----------------"); + + setChipId(); + + pm.info("FS"); + fileSystemInit(); + + pm.info("Config"); + loadConfig(); + + pm.info("Commands"); + CMD_init(); + + pm.info("Sensors"); + sensors_init(); + + pm.info("Init"); + All_init(); + + pm.info("Network"); + startSTAMode(); + + pm.info("Uptime"); + uptime_init(); + + pm.info("Telemery: " + !TELEMETRY_UPDATE_INTERVAL ? "Disabled" : "Enabled"); + telemetry_init(); + + pm.info("Updater"); + init_updater(); + + pm.info("WebServer"); + Web_server_init(); + + pm.info("WebAdmin"); + web_init(); + + pm.info("TimeSync"); + ts.add( + TIME_SYNC, 30000, [&](void*) { + startTimeSync(); + }, + nullptr, true); + +#ifdef UDP_ENABLED + UDP_init(); + pm.info("Broadcast"); +#endif + ts.add( + TEST, 10000, [&](void*) { + printMemoryStatus(); + }, + nullptr, true); + + just_load = false; +} + void saveConfig() { writeFile("config.json", configSetupJson); } +void loop() { +#ifdef OTA_UPDATES_ENABLED + ArduinoOTA.handle(); +#endif + +#ifdef WS_enable + ws.cleanupClients(); +#endif + + not_async_actions(); + + handleMQTT(); + handleCMD_loop(); + handleButton(); + handleScenario(); +#ifdef UDP_ENABLED + handleUdp(); +#endif + ts.update(); +} + +void not_async_actions() { + do_mqtt_connection(); + do_upgrade_url(); + do_upgrade(); + +#ifdef UDP_ENABLED + do_udp_data_parse(); + do_mqtt_send_settings_to_udp(); +#endif + + do_i2c_scanning(); +} + String getURL(const String& urls) { String res = ""; HTTPClient http; @@ -54,18 +156,27 @@ void setChipId() { #ifdef ESP8266 #ifdef LED_PIN -void led_blink(String satus) { + +void setLedStatus(LedStatus_t status) { pinMode(LED_PIN, OUTPUT); - if (satus == "off") { - noTone(LED_PIN); - digitalWrite(LED_PIN, HIGH); + switch (status) { + case LED_OFF: + noTone(LED_PIN); + digitalWrite(LED_PIN, HIGH); + break; + case LED_ON: + noTone(LED_PIN); + digitalWrite(LED_PIN, LOW); + break; + case LED_SLOW: + tone(LED_PIN, 1); + break; + case LED_FAST: + tone(LED_PIN, 20); + break; + default: + break; } - if (satus == "on") { - noTone(LED_PIN); - digitalWrite(LED_PIN, LOW); - } - if (satus == "slow") tone(LED_PIN, 1); - if (satus == "fast") tone(LED_PIN, 20); } #endif #endif