mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-26 22:22:16 +03:00
start version
This commit is contained in:
56
include/Bus/BusScanner.h
Normal file
56
include/Bus/BusScanner.h
Normal file
@@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
class BusScanner {
|
||||
public:
|
||||
BusScanner(const char* tag, String& out, size_t tries) : _found{0},
|
||||
_tries{tries},
|
||||
_out{&out} {
|
||||
_tag = new char(strlen(tag) + 1);
|
||||
strcpy(_tag, tag);
|
||||
}
|
||||
|
||||
void scan() {
|
||||
init();
|
||||
bool res;
|
||||
do {
|
||||
res = syncScan();
|
||||
} while (!res && --_tries);
|
||||
|
||||
if (!_found) {
|
||||
addResult("не найдено");
|
||||
}
|
||||
}
|
||||
|
||||
const char* tag() {
|
||||
return _tag;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void init(){};
|
||||
|
||||
virtual boolean syncScan() = 0;
|
||||
|
||||
protected:
|
||||
void addResult(const String& str) {
|
||||
_out->concat(str);
|
||||
}
|
||||
|
||||
void addResult(uint8_t addr, boolean last = true) {
|
||||
_found++;
|
||||
String str = "0x";
|
||||
if (addr < 16) {
|
||||
str += "0";
|
||||
}
|
||||
str += String(addr, HEX);
|
||||
str += !last ? ", " : ", ";
|
||||
addResult(str);
|
||||
};
|
||||
|
||||
private:
|
||||
char* _tag;
|
||||
size_t _found;
|
||||
size_t _tries;
|
||||
String* _out;
|
||||
};
|
||||
23
include/Bus/BusScannerFactory.h
Normal file
23
include/Bus/BusScannerFactory.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "Bus/BusScanner.h"
|
||||
#include "Bus/I2CScanner.h"
|
||||
#include "Bus/OneWireScanner.h"
|
||||
#include "Consts.h"
|
||||
#include "Utils/JsonUtils.h"
|
||||
|
||||
class BusScannerFactory {
|
||||
public:
|
||||
static BusScanner* get(String& config, BusScanner_t type, String& str) {
|
||||
switch (type) {
|
||||
case BS_I2C:
|
||||
return new I2CScanner(str);
|
||||
case BS_ONE_WIRE: {
|
||||
uint8_t pin = jsonReadInt(config, TAG_ONE_WIRE_PIN);
|
||||
return new OneWireScanner(str, pin);
|
||||
}
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
12
include/Bus/I2CScanner.h
Normal file
12
include/Bus/I2CScanner.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "Bus/BusScanner.h"
|
||||
|
||||
class I2CScanner : public BusScanner {
|
||||
public:
|
||||
I2CScanner(String& out);
|
||||
|
||||
protected:
|
||||
virtual void init() override;
|
||||
virtual boolean syncScan() override;
|
||||
};
|
||||
21
include/Bus/OneWireBus.h
Normal file
21
include/Bus/OneWireBus.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <OneWire.h>
|
||||
|
||||
struct OneWireBus_t {
|
||||
OneWire *bus;
|
||||
uint8_t pin;
|
||||
};
|
||||
|
||||
class OneWireBus {
|
||||
public:
|
||||
OneWireBus();
|
||||
OneWire *get(uint8_t pin);
|
||||
size_t count();
|
||||
|
||||
private:
|
||||
std::vector<OneWireBus_t> _items;
|
||||
};
|
||||
|
||||
extern OneWireBus oneWireBus;
|
||||
15
include/Bus/OneWireScanner.h
Normal file
15
include/Bus/OneWireScanner.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "BusScanner.h"
|
||||
#include "OneWireBus.h"
|
||||
|
||||
class OneWireScanner : public BusScanner {
|
||||
public:
|
||||
OneWireScanner(String& out, uint8_t pin);
|
||||
|
||||
protected:
|
||||
virtual boolean syncScan() override;
|
||||
|
||||
private:
|
||||
OneWire* _bus;
|
||||
};
|
||||
165
include/Clock.h
Normal file
165
include/Clock.h
Normal file
@@ -0,0 +1,165 @@
|
||||
#pragma once
|
||||
|
||||
#include "Utils/TimeUtils.h"
|
||||
#include "Utils/PrintMessage.h"
|
||||
|
||||
#ifdef ESP8266
|
||||
#include "sntp.h"
|
||||
#endif
|
||||
|
||||
class Clock {
|
||||
const char* MODULE = "Clock";
|
||||
|
||||
private:
|
||||
Time_t _time_local;
|
||||
Time_t _time_utc;
|
||||
unsigned long _uptime;
|
||||
unsigned long _unixtime;
|
||||
int _timezone;
|
||||
String _ntp;
|
||||
bool _hasSynced;
|
||||
bool _configured;
|
||||
|
||||
public:
|
||||
Clock() : _uptime{0}, _timezone{0}, _ntp{""}, _hasSynced{false}, _configured{false} {};
|
||||
|
||||
void loop() {
|
||||
unsigned long passed = millis_since(_uptime);
|
||||
if (passed < ONE_SECOND_ms) {
|
||||
return;
|
||||
}
|
||||
_uptime += passed;
|
||||
|
||||
// world time
|
||||
time_t now = getSystemTime();
|
||||
time_t estimated = _unixtime + (passed / ONE_SECOND_ms);
|
||||
double drift = difftime(now, estimated);
|
||||
if (drift > 1) {
|
||||
// Обработать ситуации c дрифтом времени на значительные величины
|
||||
}
|
||||
// TODO сохранять время на флеше
|
||||
|
||||
_unixtime = now;
|
||||
|
||||
breakEpochToTime(_unixtime, _time_utc);
|
||||
|
||||
breakEpochToTime(_unixtime + getOffsetInSeconds(_timezone), _time_local);
|
||||
}
|
||||
|
||||
bool hasSync() {
|
||||
if (!_hasSynced) {
|
||||
startSync();
|
||||
}
|
||||
return _hasSynced;
|
||||
}
|
||||
|
||||
void setNtpPool(String ntp) {
|
||||
if (!_ntp.equals(ntp)) {
|
||||
_ntp = ntp;
|
||||
_configured = false;
|
||||
}
|
||||
}
|
||||
|
||||
void setTimezone(int timezone) {
|
||||
if (_timezone != timezone) {
|
||||
_timezone = timezone;
|
||||
_configured = false;
|
||||
}
|
||||
}
|
||||
|
||||
void startSync() {
|
||||
if (!_configured) {
|
||||
pm.info("sync to: " + _ntp + " timezone: " + String(_timezone));
|
||||
setupSntp();
|
||||
_configured = true;
|
||||
// лучше не ждать, проверим в следующий раз
|
||||
return;
|
||||
}
|
||||
_hasSynced = hasTimeSynced();
|
||||
if (_hasSynced) {
|
||||
pm.info("synced " + getDateDotFormated() + " " + getTime());
|
||||
} else {
|
||||
pm.error("failed to obtain");
|
||||
}
|
||||
}
|
||||
|
||||
void setupSntp() {
|
||||
#ifdef ESP2866
|
||||
sntp_setservername(0, _ntp.c_str());
|
||||
sntp_setservername(1, "ru.pool.ntp.org");
|
||||
sntp_setservername(2, "pool.ntp.org");
|
||||
sntp_stop();
|
||||
sntp_set_timezone(0); // UTC time
|
||||
sntp_init();
|
||||
#else
|
||||
configTime(0, 0, _ntp.c_str(), "ru.pool.ntp.org", "pool.ntp.org");
|
||||
#endif
|
||||
}
|
||||
|
||||
bool hasTimeSynced() const {
|
||||
return _unixtime > MIN_DATETIME;
|
||||
}
|
||||
|
||||
time_t getSystemTime() const {
|
||||
timeval tv{0, 0};
|
||||
timezone tz = timezone{0, 0};
|
||||
time_t epoch = 0;
|
||||
if (gettimeofday(&tv, &tz) != -1) {
|
||||
epoch = tv.tv_sec;
|
||||
}
|
||||
return epoch;
|
||||
}
|
||||
|
||||
const String getTimeUnix() {
|
||||
return String(_unixtime);
|
||||
}
|
||||
|
||||
/*
|
||||
* Локальное время "дд.ММ.гг"
|
||||
*/
|
||||
const String getDateDotFormated() {
|
||||
char buf[32];
|
||||
sprintf(buf, "%02d.%02d.%02d", _time_local.day_of_month, _time_local.month, _time_local.year);
|
||||
return String(buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Локальное дата время "дд.ММ.гг чч.мм.cc"
|
||||
*/
|
||||
const String getDateTimeDotFormated() {
|
||||
char buf[32];
|
||||
sprintf(buf, "%02d.%02d.%02d %02d:%02d:%02d", _time_local.day_of_month, _time_local.month, _time_local.year, _time_local.hour, _time_local.minute, _time_local.second);
|
||||
return String(buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Локальное время "чч:мм:cc"
|
||||
*/
|
||||
const String getTime() {
|
||||
char buf[32];
|
||||
sprintf(buf, "%02d:%02d:%02d", _time_local.hour, _time_local.minute, _time_local.second);
|
||||
return String(buf);
|
||||
}
|
||||
|
||||
const String getTimeJson() {
|
||||
char buf[32];
|
||||
sprintf(buf, "%02d-%02d-%02d", _time_local.hour, _time_local.minute, _time_local.second);
|
||||
return String(buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Локальное время "чч:мм"
|
||||
*/
|
||||
const String getTimeWOsec() {
|
||||
char buf[32];
|
||||
sprintf(buf, "%02d:%02d", _time_local.hour, _time_local.minute);
|
||||
return String(buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Время с момента запуска "чч:мм:cc" далее "дд чч:мм"
|
||||
*/
|
||||
const String getUptime() {
|
||||
return prettyMillis(_uptime);
|
||||
}
|
||||
};
|
||||
116
include/Consts.h
Normal file
116
include/Consts.h
Normal file
@@ -0,0 +1,116 @@
|
||||
#pragma once
|
||||
/*
|
||||
* Main consts
|
||||
*/
|
||||
#define FIRMWARE_VERSION "2.3.5"
|
||||
#define NUM_BUTTONS 6
|
||||
#define LED_PIN 2
|
||||
#define FLASH_4MB true
|
||||
#define MQTT_RECONNECT_INTERVAL 20000
|
||||
// 1000 * 60 * 60 * 2
|
||||
#define TELEMETRY_UPDATE_INTERVAL 0
|
||||
|
||||
#define DEVICE_CONFIG_FILE "dev_conf.txt"
|
||||
#define DEVICE_SCENARIO_FILE "dev_scen.txt"
|
||||
#define DEFAULT_PRESET 100
|
||||
#define DEFAULT_SCENARIO 100
|
||||
|
||||
#define TAG_ONE_WIRE "oneWire"
|
||||
#define TAG_I2C "i2c"
|
||||
#define TAG_ONE_WIRE_PIN "oneWirePin"
|
||||
|
||||
/*
|
||||
* Optional
|
||||
*/
|
||||
//#define OTA_UPDATES_ENABLED
|
||||
//#define MDNS_ENABLED
|
||||
//#define WEBSOCKET_ENABLED
|
||||
//#define LAYOUT_IN_RAM
|
||||
#define UDP_ENABLED
|
||||
|
||||
/*
|
||||
* Sensor
|
||||
*/
|
||||
#define TANK_LEVEL_SAMPLES 10
|
||||
#define LEVEL_ENABLED
|
||||
#define ANALOG_ENABLED
|
||||
#define DALLAS_ENABLED
|
||||
#define DHT_ENABLED
|
||||
#define BMP_ENABLED
|
||||
#define BME_ENABLED
|
||||
|
||||
/*
|
||||
* Gears
|
||||
*/
|
||||
#define STEPPER_ENABLED
|
||||
#define SERVO_ENABLED
|
||||
|
||||
/*
|
||||
* Other
|
||||
*/
|
||||
#define LOGGING_ENABLED
|
||||
#define SERIAL_ENABLED
|
||||
#define PUSH_ENABLED
|
||||
|
||||
struct Time_t {
|
||||
uint8_t second;
|
||||
uint8_t minute;
|
||||
uint8_t hour;
|
||||
uint8_t day_of_week;
|
||||
uint8_t day_of_month;
|
||||
uint8_t month;
|
||||
uint16_t day_of_year;
|
||||
uint16_t year;
|
||||
unsigned long days;
|
||||
unsigned long valid;
|
||||
};
|
||||
|
||||
enum TimerTask_t { WIFI_SCAN,
|
||||
WIFI_MQTT_CONNECTION_CHECK,
|
||||
SENSORS,
|
||||
STEPPER1,
|
||||
STEPPER2,
|
||||
LOG1,
|
||||
LOG2,
|
||||
LOG3,
|
||||
LOG4,
|
||||
LOG5,
|
||||
TIMER_COUNTDOWN,
|
||||
TIME,
|
||||
TIME_SYNC,
|
||||
STATISTICS,
|
||||
UPTIME,
|
||||
UDP,
|
||||
UDP_DB,
|
||||
TEST };
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
enum ConfigType_t {
|
||||
CT_CONFIG,
|
||||
CT_SCENARIO
|
||||
};
|
||||
|
||||
enum BusScanner_t {
|
||||
BS_I2C,
|
||||
BS_ONE_WIRE
|
||||
};
|
||||
26
include/ESP32.h
Normal file
26
include/ESP32.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef ESP32
|
||||
// don't change order
|
||||
#include "WiFi.h"
|
||||
//
|
||||
|
||||
#include "ESPAsyncWebServer.h"
|
||||
#include "SPIFFSEditor.h"
|
||||
// don't change order
|
||||
#include <AsyncUDP.h>
|
||||
#include <ESP32Servo.h>
|
||||
#include <HTTPClient.h>
|
||||
#include <HTTPUpdate.h>
|
||||
|
||||
//
|
||||
#include <WiFi.h>
|
||||
#include <analogWrite.h>
|
||||
|
||||
#ifdef MDNS_ENABLED
|
||||
#include <ESPmDNS.h>
|
||||
#endif
|
||||
|
||||
extern AsyncUDP udp;
|
||||
|
||||
#endif
|
||||
19
include/ESP8266.h
Normal file
19
include/ESP8266.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef ESP8266
|
||||
#include <ESP8266WebServer.h>
|
||||
#include <ESP8266HTTPUpdate.h>
|
||||
#include "ESPAsyncTCP.h"
|
||||
#include "ESPAsyncWebServer.h"
|
||||
#include <LittleFS.h>
|
||||
#include <SPIFFSEditor.h>
|
||||
#include <Servo.h>
|
||||
#include <WiFiUdp.h>
|
||||
#include <SoftwareSerial.h>
|
||||
#ifdef MDNS_ENABLED
|
||||
#include <ESP8266mDNS.h>
|
||||
#endif
|
||||
|
||||
extern WiFiUDP udp;
|
||||
|
||||
#endif
|
||||
52
include/Errors.h
Normal file
52
include/Errors.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
String getErrorLevelStr(ErrorLevel_t level);
|
||||
|
||||
class Error : public Printable {
|
||||
public:
|
||||
static Error OK() {
|
||||
return Error();
|
||||
}
|
||||
|
||||
static Error InfoMessage(const char *message) {
|
||||
return Error(EL_INFO, message);
|
||||
}
|
||||
|
||||
static Error ErrorMessage(const char *message) {
|
||||
return Error(EL_ERROR, message);
|
||||
}
|
||||
|
||||
public:
|
||||
Error() : _type{ET_NONE}, _level{EL_NONE} {};
|
||||
|
||||
Error(const ErrorLevel_t level, const char *message) : Error(ET_FUNCTION, level, message){};
|
||||
|
||||
Error(const ErrorType_t type, const ErrorLevel_t level, const char *message) : _type{type}, _level{level} {
|
||||
strncpy(_message, message, sizeof(_message));
|
||||
};
|
||||
|
||||
const ErrorLevel_t level() const { return _level; }
|
||||
|
||||
const ErrorType_t type() const { return _type; }
|
||||
|
||||
const char *message() const { return _message; }
|
||||
|
||||
operator bool() const { return _level != EL_NONE; }
|
||||
|
||||
const String toString() const {
|
||||
char buf[128];
|
||||
sprintf(buf, "[%s] %s", getErrorLevelStr(_level).c_str(), _message);
|
||||
return String(buf);
|
||||
}
|
||||
|
||||
virtual size_t printTo(Print &p) const {
|
||||
return p.println(toString().c_str());
|
||||
}
|
||||
|
||||
private:
|
||||
char _message[128];
|
||||
ErrorType_t _type;
|
||||
ErrorLevel_t _level;
|
||||
};
|
||||
272
include/Global.h
Normal file
272
include/Global.h
Normal file
@@ -0,0 +1,272 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
* Libraries
|
||||
*/
|
||||
#include <Arduino.h>
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
#include "ESP32.h"
|
||||
#include "ESP8266.h"
|
||||
//
|
||||
#include "Consts.h"
|
||||
#include "Errors.h"
|
||||
#include "GyverFilters.h"
|
||||
#include "Upgrade.h"
|
||||
#include "Clock.h"
|
||||
|
||||
#include "MqttClient.h"
|
||||
#include "Utils\FileUtils.h"
|
||||
#include "Utils\JsonUtils.h"
|
||||
#include "Utils\StringUtils.h"
|
||||
#include "Utils\SysUtils.h"
|
||||
#include "Utils\PrintMessage.h"
|
||||
#include "Utils\WiFiUtils.h"
|
||||
|
||||
//=========ПОДКЛЮЧЕНИЕ ОБЩИХ БИБЛИОТЕК===============
|
||||
|
||||
#include <Adafruit_BME280.h>
|
||||
#include <Adafruit_BMP280.h>
|
||||
#include <Bounce2.h>
|
||||
#include <DHTesp.h>
|
||||
#include <DallasTemperature.h>
|
||||
#include <OneWire.h>
|
||||
#include <PubSubClient.h>
|
||||
#include <StringCommand.h>
|
||||
#include <TickerScheduler.h>
|
||||
#include <Wire.h>
|
||||
#include <time.h>
|
||||
#include <ArduinoOTA.h>
|
||||
|
||||
#ifdef WEBSOCKET_ENABLED
|
||||
extern AsyncWebSocket ws;
|
||||
//extern AsyncEventSource events;
|
||||
#endif
|
||||
|
||||
extern Clock* timeNow;
|
||||
|
||||
extern TickerScheduler ts;
|
||||
|
||||
extern WiFiClient espClient;
|
||||
|
||||
extern PubSubClient mqtt;
|
||||
|
||||
extern StringCommand sCmd;
|
||||
|
||||
extern AsyncWebServer server;
|
||||
|
||||
extern DallasTemperature sensors;
|
||||
|
||||
extern boolean but[NUM_BUTTONS];
|
||||
|
||||
extern Bounce* buttons;
|
||||
|
||||
/*
|
||||
* Global vars
|
||||
*/
|
||||
|
||||
extern boolean just_load;
|
||||
|
||||
extern String configSetupJson; //все настройки
|
||||
extern String configLiveJson; //все данные с датчиков (связан с mqtt)
|
||||
extern String configOptionJson; //для трансфера
|
||||
|
||||
extern String chipId;
|
||||
extern String prex;
|
||||
extern String all_widgets;
|
||||
extern String scenario;
|
||||
extern String order_loop;
|
||||
|
||||
extern String analog_value_names_list;
|
||||
extern int enter_to_analog_counter;
|
||||
|
||||
extern String dallas_value_name;
|
||||
extern int enter_to_dallas_counter;
|
||||
|
||||
extern String levelPr_value_name;
|
||||
extern String ultrasonicCm_value_name;
|
||||
|
||||
extern String dhtT_value_name;
|
||||
extern String dhtH_value_name;
|
||||
|
||||
extern String bmp280T_value_name;
|
||||
extern String bmp280P_value_name;
|
||||
|
||||
extern String bme280T_value_name;
|
||||
extern String bme280P_value_name;
|
||||
extern String bme280H_value_name;
|
||||
extern String bme280A_value_name;
|
||||
|
||||
extern String logging_value_names_list;
|
||||
extern int enter_to_logging_counter;
|
||||
|
||||
extern int scenario_line_status[40];
|
||||
|
||||
extern String lastVersion;
|
||||
|
||||
extern boolean checkUpdatesFlag;
|
||||
extern boolean updateFlag;
|
||||
extern boolean mqttParamsChanged;
|
||||
extern boolean udp_data_parse;
|
||||
extern boolean mqtt_send_settings_to_udp;
|
||||
|
||||
/*
|
||||
* Запрос на скарнирование шины
|
||||
*/
|
||||
extern boolean busScanFlag;
|
||||
/*
|
||||
* Запрос на сканирование шины, указание какую
|
||||
*/
|
||||
extern BusScanner_t busToScan;
|
||||
|
||||
extern boolean fsCheckFlag;
|
||||
|
||||
extern int sensors_reading_map[15];
|
||||
|
||||
/*
|
||||
* Global functions
|
||||
*/
|
||||
|
||||
// Cmd
|
||||
extern void cmd_init();
|
||||
extern void button();
|
||||
extern void buttonSet();
|
||||
extern void buttonChange();
|
||||
extern void pinSet();
|
||||
extern void pinChange();
|
||||
extern void handle_time_init();
|
||||
extern void pwm();
|
||||
extern void switch_();
|
||||
extern void pwmSet();
|
||||
extern void stepper();
|
||||
extern void stepperSet();
|
||||
extern void servo_();
|
||||
extern void servoSet();
|
||||
extern void serialBegin();
|
||||
extern void serialWrite();
|
||||
extern void logging();
|
||||
extern void inputDigit();
|
||||
extern void digitSet();
|
||||
extern void inputTime();
|
||||
extern void button();
|
||||
extern void timeSet();
|
||||
extern void text();
|
||||
extern void textSet();
|
||||
extern void mqttOrderSend();
|
||||
extern void httpOrderSend();
|
||||
extern void firmwareVersion();
|
||||
extern void firmwareUpdate();
|
||||
extern void loadScenario();
|
||||
|
||||
extern void fileExecute(const String& filename);
|
||||
extern void stringExecute(String& cmdStr);
|
||||
// Init
|
||||
extern void loadConfig();
|
||||
extern void all_init();
|
||||
extern void statistics_init();
|
||||
extern void loadScenario();
|
||||
extern void Device_init();
|
||||
extern void prsets_init();
|
||||
|
||||
// Logging
|
||||
extern void logging();
|
||||
extern void deleteOldDate(String filename, size_t max_lines, String date_to_add);
|
||||
extern void clean_log_date();
|
||||
extern void choose_log_date_and_send();
|
||||
|
||||
// Main
|
||||
extern void setChipId();
|
||||
extern void saveConfig();
|
||||
extern void setConfigParam(const char* param, const String& value);
|
||||
|
||||
extern String getURL(const String& urls);
|
||||
extern void do_fscheck();
|
||||
extern void do_scan_bus();
|
||||
extern void servo_();
|
||||
extern void clock_init();
|
||||
|
||||
extern void setLedStatus(LedStatus_t);
|
||||
|
||||
//Scenario
|
||||
extern void eventGen(String event_name, String number);
|
||||
extern String add_set(String param_name);
|
||||
|
||||
//Sensors
|
||||
extern void sensors_init();
|
||||
|
||||
extern void levelPr();
|
||||
extern void ultrasonicCm();
|
||||
extern void ultrasonic_reading();
|
||||
|
||||
extern void analog();
|
||||
extern void analog_reading1();
|
||||
extern void analog_reading2();
|
||||
extern void dallas_reading();
|
||||
extern void dhtT_reading();
|
||||
|
||||
extern void dallas();
|
||||
|
||||
extern void bmp280T();
|
||||
extern void bmp280P();
|
||||
extern void bmp280T_reading();
|
||||
extern void bmp280P_reading();
|
||||
|
||||
extern void bme280T();
|
||||
extern void bme280P();
|
||||
extern void bme280H();
|
||||
extern void bme280A();
|
||||
|
||||
extern void bme280T_reading();
|
||||
extern void bme280P_reading();
|
||||
extern void bme280H_reading();
|
||||
extern void bme280A_reading();
|
||||
|
||||
extern void dhtT();
|
||||
extern void dhtH();
|
||||
extern void dhtP();
|
||||
extern void dhtC();
|
||||
extern void dhtD();
|
||||
extern void dhtH_reading();
|
||||
extern void dhtP_reading();
|
||||
extern void dhtC_reading();
|
||||
extern void dhtD_reading();
|
||||
|
||||
//Timers
|
||||
extern void Timer_countdown_init();
|
||||
extern void timerStart_();
|
||||
extern void addTimer(String number, String time);
|
||||
extern void timerStop_();
|
||||
extern void delTimer(String number);
|
||||
extern int readTimer(int number);
|
||||
|
||||
extern void initUpdater();
|
||||
|
||||
// widget
|
||||
extern void createWidgetByType(String widget_name, String page_name, String page_number, String file, String topic);
|
||||
extern void createWidgetParam(String widget_name, String page_name, String page_number, String file, String topic, String name1, String param1, String name2, String param2, String name3, String param3);
|
||||
extern void createWidget(String widget_name, String page_name, String page_number, String type, String topik);
|
||||
extern void createChart(String widget_name, String page_name, String page_number, String file, String topic, String maxCount);
|
||||
|
||||
// PushingBox
|
||||
extern void pushControl();
|
||||
|
||||
// UDP
|
||||
extern void udp_init();
|
||||
extern void do_udp_data_parse();
|
||||
extern void do_mqtt_send_settings_to_udp();
|
||||
|
||||
extern void addCommandLoop(const String& cmdStr);
|
||||
extern void loopSerial();
|
||||
extern void loopCmd();
|
||||
extern void loopButton();
|
||||
extern void loopScenario();
|
||||
extern void loopUdp();
|
||||
|
||||
extern void do_update();
|
||||
|
||||
// Init
|
||||
extern void uptime_init();
|
||||
|
||||
// Web
|
||||
extern void web_init();
|
||||
extern void telemetry_init();
|
||||
9
include/HttpServer.h
Normal file
9
include/HttpServer.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "Global.h"
|
||||
|
||||
namespace HttpServer {
|
||||
|
||||
void init();
|
||||
|
||||
} // namespace HttpServer
|
||||
72
include/Module/CharBuffer.h
Normal file
72
include/Module/CharBuffer.h
Normal file
@@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
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;
|
||||
};
|
||||
86
include/Module/CircularBuffer.h
Normal file
86
include/Module/CircularBuffer.h
Normal file
@@ -0,0 +1,86 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
template <typename T, size_t BUFFER_SIZE>
|
||||
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;
|
||||
};
|
||||
45
include/Module/CommandShell.h
Normal file
45
include/Module/CommandShell.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#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<String, 4> _history;
|
||||
Terminal *_term;
|
||||
Runner *_runner;
|
||||
String _path;
|
||||
bool _active;
|
||||
bool _greetings;
|
||||
bool _farewell;
|
||||
};
|
||||
68
include/Module/EditLine.h
Normal file
68
include/Module/EditLine.h
Normal file
@@ -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;
|
||||
}
|
||||
};
|
||||
84
include/Module/Module.h
Normal file
84
include/Module/Module.h
Normal file
@@ -0,0 +1,84 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
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;
|
||||
};
|
||||
16
include/Module/Runner.h
Normal file
16
include/Module/Runner.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <Print.h>
|
||||
|
||||
class Runner {
|
||||
public:
|
||||
virtual void run(const char*, Print*);
|
||||
};
|
||||
|
||||
class CmdRunner : public Runner {
|
||||
public:
|
||||
void run(const char* cmd, Print* out) override {
|
||||
String cmdStr{cmd};
|
||||
stringExecute(cmdStr);
|
||||
}
|
||||
};
|
||||
51
include/Module/Telnet.h
Normal file
51
include/Module/Telnet.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include "Global.h"
|
||||
|
||||
#include "Module/Module.h"
|
||||
#include "Module/Terminal.h"
|
||||
#include "Module/CommandShell.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
enum TelnetEvent_t {
|
||||
TE_CONNECTED,
|
||||
TE_DISCONNECTED
|
||||
};
|
||||
|
||||
typedef std::function<void(TelnetEvent_t, WiFiClient*)> 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();
|
||||
void setCommandShell(CommandShell*);
|
||||
|
||||
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;
|
||||
};
|
||||
186
include/Module/Terminal.h
Normal file
186
include/Module/Terminal.h
Normal file
@@ -0,0 +1,186 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "Module/EditLine.h"
|
||||
#include <functional>
|
||||
|
||||
#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<bool(SpecialKeyEnum key)> SpecialKeyPressedEvent;
|
||||
|
||||
typedef std::function<void(TerminalEventEnum, Stream *)> TerminalEventHandler;
|
||||
|
||||
typedef std::function<void(const char *)> 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);
|
||||
|
||||
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;
|
||||
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
|
||||
};
|
||||
};
|
||||
27
include/MqttClient.h
Normal file
27
include/MqttClient.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
namespace MqttClient {
|
||||
|
||||
void init();
|
||||
boolean connect();
|
||||
void reconnect();
|
||||
void loop();
|
||||
|
||||
void subscribe();
|
||||
|
||||
boolean publish(const String& topic, const String& data);
|
||||
boolean publishData(const String& topic, const String& data);
|
||||
boolean publishChart(const String& topic, const String& data);
|
||||
boolean publishControl(String id, String topic, String state);
|
||||
boolean publishChart_test(const String& topic, const String& data);
|
||||
boolean publishStatus(const String& topic, const String& data);
|
||||
|
||||
void publishWidgets();
|
||||
void publishState();
|
||||
|
||||
void handleSubscribedUpdates(char* topic, uint8_t* payload, size_t length);
|
||||
const String getStateStr();
|
||||
|
||||
} // namespace MqttClient
|
||||
8
include/MqttDiscovery.h
Normal file
8
include/MqttDiscovery.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "Utils/SysUtils.h"
|
||||
|
||||
namespace Discovery {
|
||||
|
||||
|
||||
}
|
||||
25
include/Servo/Servos.h
Normal file
25
include/Servo/Servos.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Servo.h>
|
||||
|
||||
struct Servo_t {
|
||||
uint8_t num;
|
||||
uint8_t pin;
|
||||
Servo* obj;
|
||||
Servo_t(uint8_t num, uint8_t pin) : num{num}, pin{pin}, obj{nullptr} {};
|
||||
};
|
||||
|
||||
class Servos {
|
||||
public:
|
||||
Servos();
|
||||
Servo* get(uint8_t num);
|
||||
Servo* create(uint8_t num, uint8_t pin);
|
||||
|
||||
size_t count();
|
||||
|
||||
private:
|
||||
std::vector<Servo_t> _items;
|
||||
};
|
||||
|
||||
extern Servos myServo;
|
||||
139
include/Strings_.h
Normal file
139
include/Strings_.h
Normal file
@@ -0,0 +1,139 @@
|
||||
#pragma once
|
||||
|
||||
//Strings
|
||||
// #include <stdafx.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
class char_array {
|
||||
private:
|
||||
char *p_stringarray; //initial input array
|
||||
char *p_inputstring; //holds actual length data
|
||||
//char **pp_database_string; //allocate data database.cpp
|
||||
int stringsize; //holds array size to allocate memory
|
||||
int charinput; //holds array input size
|
||||
|
||||
public:
|
||||
inline char_array(); //inline so other functions can call on it
|
||||
inline ~char_array();
|
||||
inline void getinput(char *&); //retrieves user input
|
||||
inline void grabline(char *&); //retrieve line with whitespace included NOT COMPLETE, may not need
|
||||
inline int sortline(char **&, char *&); //sorts line into an array of strings and returns number of separate strings
|
||||
inline int arraysize(); //returns size of string array
|
||||
inline void printinput(); //print input string
|
||||
inline void changedefaultsize(); //change default input size NOT COMPLETE
|
||||
};
|
||||
|
||||
inline char_array::char_array() //constructor
|
||||
{
|
||||
stringsize = 0;
|
||||
charinput = 64;
|
||||
p_stringarray = new char[charinput];
|
||||
}
|
||||
|
||||
inline char_array::~char_array() //destructor
|
||||
{
|
||||
delete[] p_inputstring;
|
||||
delete[] p_stringarray;
|
||||
}
|
||||
|
||||
inline void char_array::getinput(char *&p_stringin) {
|
||||
stringsize = 0;
|
||||
|
||||
scanf("%63s", p_stringarray); //get input string
|
||||
|
||||
while (p_stringarray[stringsize] != 0) //finding out the size of string array
|
||||
{
|
||||
stringsize++;
|
||||
}
|
||||
stringsize++;
|
||||
|
||||
p_inputstring = new char[stringsize]; //reallocate memory block and set array inside
|
||||
for (int i = 0; i < stringsize; i++) {
|
||||
p_inputstring[i] = p_stringarray[i];
|
||||
}
|
||||
|
||||
p_inputstring[stringsize - 1] = '\x00';
|
||||
|
||||
p_stringin = new char[stringsize]; //set pp_stringin
|
||||
|
||||
p_stringin = p_inputstring;
|
||||
}
|
||||
|
||||
inline void char_array::grabline(char *&p_stringin) {
|
||||
stringsize = 0;
|
||||
std::cin.getline(p_stringarray, charinput);
|
||||
while (p_stringarray[stringsize] != 0) {
|
||||
stringsize++;
|
||||
}
|
||||
stringsize++;
|
||||
p_inputstring = new char[stringsize];
|
||||
|
||||
for (int i = 0; i < stringsize; i++) {
|
||||
p_inputstring[i] = p_stringarray[i];
|
||||
}
|
||||
|
||||
p_stringin = new char[stringsize];
|
||||
p_stringin = p_inputstring;
|
||||
}
|
||||
|
||||
inline int char_array::sortline(char **&pp_stringin, char *&p_string) {
|
||||
int position = 0; //position in string
|
||||
int charcount = 1; //how many characters there are
|
||||
int wordnum; //which word is being processed
|
||||
int wordcount = 1; //number of words in string
|
||||
int bookmark = 0; //holds last known position
|
||||
|
||||
while (p_string[position] == ' ') {
|
||||
position++;
|
||||
}
|
||||
|
||||
wordnum = position; //borrow wordnum to hold position value
|
||||
while (p_string[position] != '\x00') //find total inputted string word length
|
||||
{
|
||||
if ((p_string[position] == ' ') && ((p_string[position + 1] != ' ') || (p_string[position + 1] != '\x00'))) {
|
||||
wordcount++;
|
||||
}
|
||||
position++;
|
||||
}
|
||||
position = wordnum; //set position to original value
|
||||
for (wordnum = 0; wordnum < wordcount; wordnum++) {
|
||||
charcount = 1;
|
||||
while (p_string[position] == ' ') {
|
||||
position++;
|
||||
}
|
||||
while ((p_string[position] != ' ') && (p_string[position] != '\x00')) {
|
||||
position++;
|
||||
charcount++;
|
||||
}
|
||||
pp_stringin[wordnum] = new char[charcount];
|
||||
|
||||
for (int i = 0; i < charcount; i++) {
|
||||
pp_stringin[wordnum][i] = p_string[i + bookmark];
|
||||
}
|
||||
pp_stringin[wordnum][charcount - 1] = '\x00';
|
||||
bookmark = position + 1;
|
||||
}
|
||||
|
||||
return wordcount;
|
||||
}
|
||||
|
||||
inline int char_array::arraysize() {
|
||||
if (stringsize != 0) {
|
||||
return stringsize;
|
||||
} else {
|
||||
printf("Array size is set at 0\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline void char_array::printinput() {
|
||||
printf("%s", p_inputstring);
|
||||
}
|
||||
|
||||
inline void char_array::changedefaultsize() {
|
||||
printf("Input new default input string size: ");
|
||||
scanf("%i", charinput);
|
||||
}
|
||||
5
include/Upgrade.h
Normal file
5
include/Upgrade.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
void getLastVersion();
|
||||
|
||||
void do_update();
|
||||
55
include/Utils/FileHelper.h
Normal file
55
include/Utils/FileHelper.h
Normal file
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "FS.h"
|
||||
|
||||
#ifdef ESP32
|
||||
#include "LITTLEFS.h"
|
||||
#define LittleFS LITTLEFS
|
||||
#endif
|
||||
#ifdef ESP8266
|
||||
#include <LittleFS.h>
|
||||
#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();
|
||||
};
|
||||
62
include/Utils/FileUtils.h
Normal file
62
include/Utils/FileUtils.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "Consts.h"
|
||||
|
||||
#include "FS.h"
|
||||
|
||||
#ifdef ESP32
|
||||
#include "LITTLEFS.h"
|
||||
#define LittleFS LITTLEFS
|
||||
#endif
|
||||
#ifdef ESP8266
|
||||
#include <LittleFS.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Инициализация ФС
|
||||
*/
|
||||
bool fileSystemInit();
|
||||
|
||||
/*
|
||||
* Удалить файл
|
||||
*/
|
||||
void removeFile(const String& filename);
|
||||
|
||||
/*
|
||||
* Открыть файл на позиции
|
||||
*/
|
||||
File seekFile(const String& filename, size_t position = 0);
|
||||
|
||||
/*
|
||||
* Чтение строки из файла
|
||||
* возвращает стоку из файла в которой есть искомое слово found
|
||||
*/
|
||||
const String readFileString(const String& filename, const String& to_find);
|
||||
|
||||
/*
|
||||
* Добовление строки в файл
|
||||
*/
|
||||
const String addFile(const String& filename, const String& str);
|
||||
|
||||
/*
|
||||
* Запись строки в файл
|
||||
*/
|
||||
const String writeFile(const String& filename, const String& str);
|
||||
|
||||
/*
|
||||
* Чтение файла в строку
|
||||
*/
|
||||
const String readFile(const String& filename, size_t max_size);
|
||||
|
||||
/*
|
||||
* Размер файла
|
||||
*/
|
||||
const String getFileSize(const String& filename);
|
||||
|
||||
bool copyFile(const String& src, const String& dst, bool overwrite = true);
|
||||
|
||||
const String getFSSizeInfo();
|
||||
|
||||
const String getConfigFile(uint8_t preset, ConfigType_t type);
|
||||
17
include/Utils/JsonUtils.h
Normal file
17
include/Utils/JsonUtils.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
String jsonReadStr(String& json, String name);
|
||||
|
||||
int jsonReadInt(String& json, String name);
|
||||
|
||||
boolean jsonReadBool(String& json, String name);
|
||||
|
||||
String jsonWriteStr(String& json, String name, String value);
|
||||
|
||||
String jsonWriteInt(String& json, String name, int value);
|
||||
|
||||
String jsonWriteFloat(String& json, String name, float value);
|
||||
|
||||
String jsonWriteBool(String& json, String name, boolean value);
|
||||
31
include/Utils/PrintMessage.h
Normal file
31
include/Utils/PrintMessage.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include "Arduino.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(millis()).c_str(), getErrorLevelStr(level).c_str(), _module, str.c_str());
|
||||
}
|
||||
|
||||
private:
|
||||
const char* _module;
|
||||
};
|
||||
25
include/Utils/StringUtils.h
Normal file
25
include/Utils/StringUtils.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
uint8_t hexStringToUint8(String hex);
|
||||
|
||||
uint16_t hexStringToUint16(String hex);
|
||||
|
||||
String selectToMarkerLast(String str, String found);
|
||||
|
||||
String selectToMarker(String str, String found);
|
||||
|
||||
String deleteAfterDelimiter(String str, String found);
|
||||
|
||||
String deleteBeforeDelimiter(String str, String found);
|
||||
|
||||
String deleteBeforeDelimiterTo(String str, String found);
|
||||
|
||||
String selectFromMarkerToMarker(String str, String found, int number);
|
||||
|
||||
size_t itemsCount(String str, const String& separator);
|
||||
|
||||
boolean isDigitStr(const String&);
|
||||
|
||||
String prettyBytes(size_t size);
|
||||
13
include/Utils/SysUtils.h
Normal file
13
include/Utils/SysUtils.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
const String getChipId();
|
||||
|
||||
const String getUniqueId(const String& name);
|
||||
|
||||
const String printMemoryStatus();
|
||||
|
||||
const String getHeapStats();
|
||||
|
||||
const String getMacAddress();
|
||||
51
include/Utils/TimeUtils.h
Normal file
51
include/Utils/TimeUtils.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "Consts.h"
|
||||
|
||||
#define ONE_MINUTE_s 60
|
||||
#define ONE_HOUR_m 60
|
||||
#define ONE_HOUR_s 60 * ONE_MINUTE_s
|
||||
#define LEAP_YEAR(Y) (((1970 + Y) > 0) && !((1970 + Y) % 4) && (((1970 + Y) % 100) || !((1970 + Y) % 400)))
|
||||
#define MIN_DATETIME 1575158400
|
||||
#define ONE_SECOND_ms 1000
|
||||
|
||||
/*
|
||||
* Время (мс) прошедщее с @since
|
||||
*/
|
||||
unsigned long millis_since(unsigned long sinse);
|
||||
|
||||
/*
|
||||
* Интерввал времени (мс) между @start и @finish
|
||||
*/
|
||||
unsigned long millis_passed(unsigned long start, unsigned long finish);
|
||||
|
||||
/*
|
||||
* Форматиронное время интервала (мс)
|
||||
* "чч:мм:cc",
|
||||
* "дд чч:мм", если > 24 часов
|
||||
*/
|
||||
const String prettyMillis(unsigned long time_ms = millis());
|
||||
|
||||
/*
|
||||
* Форматиронное время интервала (c)
|
||||
* "чч:мм:cc",
|
||||
* "дд чч:мм", если > 24 часов
|
||||
*/
|
||||
const String prettySeconds(unsigned long time_s);
|
||||
|
||||
/*
|
||||
* Тайм зона в секундах
|
||||
*/
|
||||
int getOffsetInSeconds(int timezone);
|
||||
|
||||
/*
|
||||
* Тайм зона в минутах
|
||||
*/
|
||||
int getOffsetInMinutes(int timezone);
|
||||
|
||||
/*
|
||||
* Разбивает время на составляющие
|
||||
*/
|
||||
void breakEpochToTime(unsigned long epoch, Time_t& tm);
|
||||
71
include/Utils/Timings.h
Normal file
71
include/Utils/Timings.h
Normal file
@@ -0,0 +1,71 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
enum Timings_t { MT_ONE,
|
||||
MT_TWO,
|
||||
NUM_TIMINGS };
|
||||
|
||||
struct Timing {
|
||||
unsigned long _total_mu;
|
||||
unsigned long _min_mu;
|
||||
unsigned long _max_mu;
|
||||
|
||||
Timing() : _total_mu{0}, _min_mu{999999}, _max_mu{0} {};
|
||||
|
||||
void reset() {
|
||||
_total_mu = 0;
|
||||
_min_mu = 999999;
|
||||
_max_mu = 0;
|
||||
}
|
||||
|
||||
void add(unsigned long time_mu) {
|
||||
if (time_mu == 0) return;
|
||||
|
||||
_total_mu += time_mu;
|
||||
|
||||
if (_min_mu > time_mu) {
|
||||
_min_mu = time_mu;
|
||||
}
|
||||
|
||||
if (_max_mu < time_mu) {
|
||||
_max_mu = time_mu;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const char* module_name[NUM_TIMINGS] = {"strings", "boolean"};
|
||||
|
||||
struct Timings {
|
||||
Timing mu[NUM_TIMINGS];
|
||||
|
||||
unsigned long _counter;
|
||||
unsigned long _start;
|
||||
unsigned long long _total;
|
||||
|
||||
Timings() : _counter{0}, _start{0} {};
|
||||
|
||||
void add(size_t module, unsigned long now = micros()) {
|
||||
unsigned long time = now - _start;
|
||||
_total += time;
|
||||
mu[module].add(time);
|
||||
_start = now;
|
||||
}
|
||||
|
||||
void count() {
|
||||
_counter++;
|
||||
_start = micros();
|
||||
}
|
||||
|
||||
void print() {
|
||||
if (!_counter) {
|
||||
return;
|
||||
};
|
||||
Serial.printf("lp/ms: %llu ", _counter / _total);
|
||||
for (size_t i = 0; i < NUM_TIMINGS; i++) {
|
||||
Serial.printf("%s: %.2f%% ", module_name[i], ((float)mu[i]._total_mu / _total) * 100);
|
||||
mu[i].reset();
|
||||
}
|
||||
Serial.println();
|
||||
_counter = 0;
|
||||
_total = 0;
|
||||
};
|
||||
};
|
||||
73
include/Utils/WebUtils.h
Normal file
73
include/Utils/WebUtils.h
Normal file
@@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
|
||||
#include "ESPAsyncWebServer.h"
|
||||
|
||||
const String getMethodName(AsyncWebServerRequest* request) {
|
||||
String res = F("UNKNOWN");
|
||||
if (request->method() == HTTP_GET)
|
||||
res = F("GET");
|
||||
else if (request->method() == HTTP_POST)
|
||||
res = F("POST");
|
||||
else if (request->method() == HTTP_DELETE)
|
||||
res = F("DELETE");
|
||||
else if (request->method() == HTTP_PUT)
|
||||
res = F("PUT");
|
||||
else if (request->method() == HTTP_PATCH)
|
||||
res = F("PATCH");
|
||||
else if (request->method() == HTTP_HEAD)
|
||||
res = F("HEAD");
|
||||
else if (request->method() == HTTP_OPTIONS)
|
||||
res = F("OPTIONS");
|
||||
return res;
|
||||
}
|
||||
|
||||
const String getRequestInfo(AsyncWebServerRequest* request) {
|
||||
String res = getMethodName(request);
|
||||
res += ' ';
|
||||
res += "http://";
|
||||
res += request->host();
|
||||
res += request->url();
|
||||
res += '\n';
|
||||
if (request->contentLength()) {
|
||||
res += "content-type: ";
|
||||
res += request->contentType();
|
||||
res += " content-lenght: ";
|
||||
res += prettyBytes(request->contentLength());
|
||||
res += '\n';
|
||||
}
|
||||
|
||||
if (request->headers()) {
|
||||
res += "headers:\n";
|
||||
for (size_t i = 0; i < request->headers(); i++) {
|
||||
AsyncWebHeader* h = request->getHeader(i);
|
||||
res += h->name();
|
||||
res += '=';
|
||||
res += h->value();
|
||||
res += '\n';
|
||||
}
|
||||
}
|
||||
|
||||
if (request->params()) {
|
||||
res += "params:\n";
|
||||
for (size_t i = 0; i < request->params(); i++) {
|
||||
AsyncWebParameter* p = request->getParam(i);
|
||||
if (p->isFile()) {
|
||||
res += "FILE";
|
||||
} else if (p->isPost()) {
|
||||
res += "POST";
|
||||
} else {
|
||||
res += "GET";
|
||||
}
|
||||
res += ' ';
|
||||
res += p->name();
|
||||
res += ':';
|
||||
res += p->value();
|
||||
if (p->isFile()) {
|
||||
res += " size:";
|
||||
res += p->size();
|
||||
}
|
||||
res += '\n';
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
12
include/Utils/WiFiUtils.h
Normal file
12
include/Utils/WiFiUtils.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "Global.h"
|
||||
|
||||
boolean isNetworkActive();
|
||||
|
||||
void startSTAMode();
|
||||
|
||||
bool startAPMode();
|
||||
|
||||
boolean scanWiFi(String ssid);
|
||||
|
||||
Reference in New Issue
Block a user