diff --git a/.vscode/settings.json b/.vscode/settings.json index 01779b03..98dc0700 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -42,7 +42,13 @@ "chrono": "cpp", "mutex": "cpp", "ratio": "cpp", - "system_error": "cpp" + "system_error": "cpp", + "cstddef": "cpp", + "unordered_set": "cpp", + "algorithm": "cpp", + "iomanip": "cpp", + "memory": "cpp", + "string": "cpp" }, "cmake.configureOnOpen": false } \ No newline at end of file diff --git a/include/Class/IoTModule.h b/include/Class/IoTModule.h index f13d91e7..1725e75b 100644 --- a/include/Class/IoTModule.h +++ b/include/Class/IoTModule.h @@ -4,10 +4,10 @@ struct ModuleInfo { - String name; - String key; - String parameters; - String type; + String name; //имя модуля + String title; //заголовок для описания модуля + String parameters; //параметры, которые может принять модуль и сущность + String type; //тип для определения сущности, которую генерирует модуль Sensor или Variable }; class IoTModule { @@ -17,4 +17,5 @@ class IoTModule { virtual void* initInstance(String parameters); virtual ModuleInfo getInfo(); + virtual void clear(); }; \ No newline at end of file diff --git a/include/Class/IoTSensor.h b/include/Class/IoTSensor.h index b41fd9bc..07fe75be 100644 --- a/include/Class/IoTSensor.h +++ b/include/Class/IoTSensor.h @@ -3,18 +3,24 @@ #include class IoTSensor { - public: - IoTSensor(); - ~IoTSensor(); + public: + IoTSensor(); + virtual ~IoTSensor(); - void loop(); - virtual void doByInterval(); - void init(unsigned long interval, String key); - void regEvent(String value, String consoleInfo); + void loop(); + virtual void doByInterval(); + void init(String key, String id, unsigned long interval); + void regEvent(String value, String consoleInfo); - unsigned long currentMillis; - unsigned long prevMillis; - unsigned long difference; - unsigned long _interval; - String _key; + String getKey(); + String getID(); + + unsigned long currentMillis; + unsigned long prevMillis; + unsigned long difference; + + protected: + String _key; + String _id; + unsigned long _interval; }; \ No newline at end of file diff --git a/include/Class/IoTVariable.h b/include/Class/IoTVariable.h new file mode 100644 index 00000000..b760572d --- /dev/null +++ b/include/Class/IoTVariable.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +class IoTVariable { + public: + IoTVariable(); + ~IoTVariable(); + + virtual String execute(String command); + virtual void loop(); + + void init(String key, String value); + void setValue(String value); + void getValue(String value); + void regEvent(String value, String consoleInfo); + + String _widgetName; //название виджета на фронтэнде для правильного отображения информации из меременной + String _key; //код переменной для идентификации событий, команд в сценариях + String _title; + + private: + String _value; //значение переменной +}; \ No newline at end of file diff --git a/include/items/vSensorSHT20.h b/include/items/vSensorSHT20.h deleted file mode 100644 index 0f79ab0b..00000000 --- a/include/items/vSensorSHT20.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifdef EnableSensorSht20 -#pragma once -#include -#include "Wire.h" -#include "SHT2x.h" - -#include "Global.h" - -extern SHT2x* sht; - -class SensorSht20; - -typedef std::vector MySensorSht20Vector; - -struct paramsSht { - String key; - unsigned long interval; - float c; -}; - -class SensorSht20 { - public: - SensorSht20(const paramsSht& paramsTmp, const paramsSht& paramsHum); - ~SensorSht20(); - - void loop(); - void read(); - - private: - paramsSht _paramsTmp; - paramsSht _paramsHum; - - unsigned long prevMillis; - unsigned long difference; -}; - -extern MySensorSht20Vector* mySensorSht20; - -extern void sht20Sensor(); -#endif \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index c7c184f2..455408f3 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,7 +9,7 @@ ; https://docs.platformio.org/page/projectconf.html [platformio] -default_envs = esp8266_4mb +default_envs = esp32_4mb data_dir = data_esp [common_env_data] diff --git a/src/BufferExecute.cpp b/src/BufferExecute.cpp index 8e847417..63464255 100644 --- a/src/BufferExecute.cpp +++ b/src/BufferExecute.cpp @@ -18,7 +18,6 @@ #include "items/vSensorDht.h" #include "items/vSensorNode.h" #include "items/vSensorPzem.h" -#include "items/vSensorSHT20.h" #include "items/vSensorUltrasonic.h" #include "items/vSensorUptime.h" @@ -122,10 +121,6 @@ void csvCmdExecute(String& cmdStr) { } else if (order == F("bme280")) { #ifdef EnableSensorBme280 sCmd.addCommand(order.c_str(), bme280Sensor); -#endif - } else if (order == F("sht20")) { -#ifdef EnableSensorSht20 - sCmd.addCommand(order.c_str(), sht20Sensor); #endif } else if (order == F("sensor")) { #ifdef EnableSensorAny @@ -170,24 +165,27 @@ void csvCmdExecute(String& cmdStr) { } sCmd.readStr(buf); - + //v3dev: инициируем экземпляр модулей в случае необходимости for (unsigned int i = 0; i < iotModules.size(); i++) { - SerialPrint("I", "Debug iotModules count", ""); - ModuleInfo moduleInfo = iotModules[i]->getInfo(); - if (moduleInfo.key == order) { - SerialPrint("I", "Debug moduleInfo.parameters", buf); - + //del SerialPrint("I", "moduleInfo.name", moduleInfo.name); + //del SerialPrint("I", "order", order); + if (moduleInfo.name == order) { //проверка вхождения имени искомого модуля в ключе элемента настройки if (moduleInfo.type == "Sensor") { myLineParsing.update(); //v3dev: пока используем мостик для совместимости версий, предполагается, что настройки сразу будут в JSON String interval = myLineParsing.gint(); + if (interval == "") interval = "50"; String pin = myLineParsing.gpin(); String index = myLineParsing.gindex(); String addr = myLineParsing.gaddr(); + String c = myLineParsing.gc(); + String id = myLineParsing.gkey(); + String key = myLineParsing.gfile(); myLineParsing.clear(); - String strTmp = "{\"addr\": \"" + addr + "\", \"int\": \"" + interval + "\", \"pin\": \"" + pin + "\", \"index\": \"" + index + "\"}"; + String strTmp = "{\"key\": \"" + key + "\", \"id\": \"" + id + "\", \"addr\": \"" + addr + "\", \"int\": \"" + interval + "\", \"pin\": \"" + pin + "\", \"index\": \"" + index + "\", \"c\": \"" + c + "\"}"; + SerialPrint("I", "Строка параметров при инициализации модуля " + moduleInfo.name + ": ", strTmp); iotSensors.push_back((IoTSensor*)iotModules[i]->initInstance(strTmp)); } else if (moduleInfo.type == "Container") { diff --git a/src/Class/IoTModule.cpp b/src/Class/IoTModule.cpp index 93afe034..9ef354b7 100644 --- a/src/Class/IoTModule.cpp +++ b/src/Class/IoTModule.cpp @@ -3,4 +3,5 @@ IoTModule::IoTModule() {}; IoTModule::~IoTModule() {}; void* IoTModule::initInstance(String parameters) {}; -ModuleInfo IoTModule::getInfo() {}; \ No newline at end of file +ModuleInfo IoTModule::getInfo() {}; +void IoTModule::clear() {}; \ No newline at end of file diff --git a/src/Class/IoTSensor.cpp b/src/Class/IoTSensor.cpp index 1229b2b0..ac493244 100644 --- a/src/Class/IoTSensor.cpp +++ b/src/Class/IoTSensor.cpp @@ -3,14 +3,23 @@ #include "Class/ScenarioClass3.h" #include "Class/IoTSensor.h" -void IoTSensor::init(unsigned long interval, String key) { +void IoTSensor::init(String key, String id, unsigned long interval) { _interval = interval * 1000; _key = key; + _id = id; } IoTSensor::IoTSensor() {} IoTSensor::~IoTSensor() {} +String IoTSensor::getKey() { + return _key; +} + +String IoTSensor::getID() { + return _id; +}; + void IoTSensor::loop() { currentMillis = millis(); difference = currentMillis - prevMillis; @@ -22,10 +31,10 @@ void IoTSensor::loop() { } void IoTSensor::regEvent(String value, String consoleInfo = "") { - eventGen2(_key, String(value)); - jsonWriteStr(configLiveJson, _key, String(value)); - publishStatus(_key, String(value)); - SerialPrint("I", "Sensor", "'" + _key + "' data: " + String(value) + "' " + consoleInfo); + eventGen2(_id, String(value)); + jsonWriteStr(configLiveJson, _id, String(value)); + publishStatus(_id, String(value)); + SerialPrint("I", "Sensor", "'" + _id + "' data: " + String(value) + "' " + consoleInfo); } void IoTSensor::doByInterval() {} \ No newline at end of file diff --git a/src/Class/IoTVariable.cpp b/src/Class/IoTVariable.cpp new file mode 100644 index 00000000..f8564ef5 --- /dev/null +++ b/src/Class/IoTVariable.cpp @@ -0,0 +1,29 @@ +#include "Utils/JsonUtils.h" +#include "Utils/SerialPrint.h" +#include "Class/ScenarioClass3.h" +#include "Class/IoTVariable.h" + +IoTVariable::IoTVariable() {} +IoTVariable::~IoTVariable() {} + +String execute(String command) {} +void IoTVariable::loop() {} + +void IoTVariable::init(String key, String value) { + +} + +void setValue(String value) { + +}; + +void getValue(String value ){ + +}; + +void IoTVariable::regEvent(String value, String consoleInfo = "") { + eventGen2(_key, String(value)); + jsonWriteStr(configLiveJson, _key, String(value)); + publishStatus(_key, String(value)); + SerialPrint("I", "Sensor", "'" + _key + "' data: " + String(value) + "' " + consoleInfo); +} \ No newline at end of file diff --git a/src/Init.cpp b/src/Init.cpp index 8bbad937..b37643dc 100644 --- a/src/Init.cpp +++ b/src/Init.cpp @@ -18,10 +18,16 @@ #include "items/vSensorDht.h" #include "items/vSensorNode.h" #include "items/vSensorPzem.h" -#include "items/vSensorSHT20.h" #include "items/vSensorUltrasonic.h" #include "items/vSensorUptime.h" +#include +#include "Class/IoTSensor.h" +#include "Class/IoTModule.h" + +extern std::vector iotModules; //v3dev: вектор ссылок базового класса IoTModule - интерфейсы для общения со всеми поддерживаемыми системой модулями +extern std::vector iotSensors; //v3dev: вектор ссылок базового класса IoTSensor - список всех запущенных сенсоров + void loadConfig() { configSetupJson = readFile("config.json", 4096); configSetupJson.replace("\r\n", ""); @@ -110,6 +116,21 @@ void handle_uptime() { } void clearVectors() { + +//v3dev: очищаем вектора с сенсорами... +for (unsigned int i = 0; i < iotSensors.size(); i++) { + IoTSensor* tmpptr = iotSensors[i]; //временно сохраняем указатель на сенсор, т.к. его преждевременное удаление оставит поломаную запись в векторе, к которой может обратиться ядро и вызвать исключение + iotSensors.erase(iotSensors.begin() + i); //сначала удаляем элемент вектора, + delete tmpptr; //а далее уже удаляем объект сенсора +} +//...и переменными +//... +//заставляем модули прибраться за собой +for (unsigned int i = 0; i < iotModules.size(); i++) { + iotModules[i]->clear(); +} + + #ifdef EnableLogging if (myLogging != nullptr) { myLogging->clear(); @@ -181,11 +202,6 @@ void clearVectors() { mySensorBme280->clear(); } #endif -#ifdef EnableSensorSht20 - if (mySensorSht20 != nullptr) { - mySensorSht20->clear(); - } -#endif #ifdef EnableSensorBmp280 if (mySensorBmp280 != nullptr) { mySensorBmp280->clear(); diff --git a/src/Modules/Sensors/IoTSensorDallasTemp.cpp b/src/Modules/Sensors/IoTSensorDallasTemp.cpp index 1b84f40a..b6978de3 100644 --- a/src/Modules/Sensors/IoTSensorDallasTemp.cpp +++ b/src/Modules/Sensors/IoTSensorDallasTemp.cpp @@ -10,7 +10,6 @@ #include extern std::vector iotModules; //v3dev: вектор ссылок базового класса IoTModule - интерфейсы для общения со всеми поддерживаемыми системой модулями -#define IOTDALLASTEMPKEY "dallas-temp" //глобальные списки необходимы для хранения объектов об активных линиях 1-wire используемых разными датчиками из модуля. Ключ - номер пина std::map oneWireTemperatureArray; @@ -31,7 +30,8 @@ class IoTSensorDallas: public IoTSensor { public: //аналог setup() из Arduino IoTSensorDallas(String parameters) { - init(jsonReadInt(parameters, "int"), IOTDALLASTEMPKEY); //передаем часть базовых параметров в конструктор базового класса для обеспечения работы его методов + //передаем часть базовых параметров в конструктор базового класса для обеспечения работы его методов + init(jsonReadStr(parameters, "key"), jsonReadStr(parameters, "id"), jsonReadInt(parameters, "int")); _pin = jsonReadInt(parameters, "pin"); _index = jsonReadInt(parameters, "index"); _addr = jsonReadStr(parameters, "addr"); @@ -84,12 +84,22 @@ class IoTModuleDallasTemp: public IoTModule { return new IoTSensorDallas(parameters); }; + //обязательный к заполнению метод, если модуль использует свои глобальные переменные. Необходимо сбросить и очистить используемую память. + void clear() { + for (unsigned int i = 0; i < sensorsTemperatureArray.size(); i++) { + delete oneWireTemperatureArray[i]; + } + for (unsigned int i = 0; i < oneWireTemperatureArray.size(); i++) { + delete oneWireTemperatureArray[i]; + } + } + //обязательный метод для отправки информации о модуле, ModuleInfo getInfo() { ModuleInfo MI; - MI.key = IOTDALLASTEMPKEY; - MI.name = "Датчик температуры Ds18b20"; - MI.parameters = "{\"addr\": \"\", \"int\": \"10\", \"pin\": \"18\", \"index\": \"0\"}"; + MI.name = "dallas-temp"; + MI.title = "Датчик температуры Ds18b20"; + MI.parameters = "{\"key\": \"dallas-temp\", \"id\": \"tmp\", \"addr\": \"\", \"int\": \"10\", \"pin\": \"18\", \"index\": \"0\"}"; MI.type = "Sensor"; return MI; }; diff --git a/src/Modules/Sensors/IoTSensorSHT20.cpp b/src/Modules/Sensors/IoTSensorSHT20.cpp new file mode 100644 index 00000000..fe41fd45 --- /dev/null +++ b/src/Modules/Sensors/IoTSensorSHT20.cpp @@ -0,0 +1,81 @@ +#include "Utils/JsonUtils.h" +#include "Utils/SerialPrint.h" +#include "Utils/StringUtils.h" +#include "Class/IoTSensor.h" +#include "Class/IoTModule.h" + + +#include "Wire.h" +#include "SHT2x.h" + +extern std::vector iotModules; //v3dev: вектор ссылок базового класса IoTModule - интерфейсы для общения со всеми поддерживаемыми системой модулями + +SHT2x* sht = nullptr; + +class IoTSensorSHT20: public IoTSensor { + private: + //описание переменных экземпляра датчика - аналог глобальных переменных из Arduino + + //описание параметров передаваемых из настроек датчика из веба + float _c; + + public: + //аналог setup() из Arduino + IoTSensorSHT20(String parameters) { + //передаем часть базовых параметров в конструктор базового класса для обеспечения работы его методов + init(jsonReadStr(parameters, "key"), jsonReadStr(parameters, "id"), jsonReadInt(parameters, "int")); + _c = jsonReadFloat(parameters, "c"); + + if (!sht) { + sht = new SHT2x; + sht->begin(); + } + } + + ~IoTSensorSHT20() {} + + //аналог loop() из Arduino но квотируемый по времени параметром interval + void doByInterval() { + //запускаем опрос измерений + float value; + if (getKey() == "anydataTemp") { + value = sht->getTemperature(); + } else { + value = sht->getHumidity(); + } + value = _c * value; + + regEvent((String)value, ""); //обязательный вызов для отправки результата измерений + } +}; + +//технический класс для взаимодействия с ядром, меняются только названия +class IoTModuleSHT20: public IoTModule { + //обязательный метод для инициализации экземпляра датчика, вызывается при чтении конфигурации. Нужно учитывать, что некоторые датчики могут обеспечивать + //несколько измерений, для каждого будет отдельный вызов. + void* initInstance(String parameters) { + return new IoTSensorSHT20(parameters); + }; + + //обязательный к заполнению метод, если модуль использует свои глобальные переменные. Необходимо сбросить и очистить используемую память. + void clear() { + + } + + //обязательный метод для отправки информации о модуле, + ModuleInfo getInfo() { + ModuleInfo MI; + MI.name = "sht20"; + MI.title = "Датчик температуры и влажности SHT2x, HTU2x and Si70xx"; + //v3dev: key - это внутренний маркер-ключ определяющий значение для измерений, на этапе апробации на ver3 установлено значение = типу виджета, т.к. в таблице настройки отсутствует парамтер key в этой интерпретации + MI.parameters = "{\"key\": \"anydataTemp\", \"id\": \"SHT20\", \"int\": \"10\", \"c\": \"1\"}, {\"key\": \"anydataHum\", \"id\": \"SHT20\", \"int\": \"10\", \"c\": \"1\"}"; + MI.type = "Sensor"; + return MI; + }; +}; + +//точка входа в модуль для заполнения вектора, требуется только изменить имя и прописать в файле api.cpp +void getApiIoTSensorSHT20() { + iotModules.push_back(new IoTModuleSHT20()); + return; +} \ No newline at end of file diff --git a/src/Modules/api.cpp b/src/Modules/api.cpp index 978f172e..8eeb56a8 100644 --- a/src/Modules/api.cpp +++ b/src/Modules/api.cpp @@ -1,9 +1,11 @@ #include "Utils/SerialPrint.h" //объявляем функцию для добавления модуля в вектор void getApiIoTSensorDallasTemp(); +void getApiIoTSensorSHT20(); //формируем вектор модулей путем вызова из каждого модуля специальной функции //в дальнейшем предполагается отключать вызов, если модуль не участвует в сборке void InitModulesApi() { getApiIoTSensorDallasTemp(); + getApiIoTSensorSHT20(); } \ No newline at end of file diff --git a/src/items/vSensorSHT20.cpp b/src/items/vSensorSHT20.cpp deleted file mode 100644 index 8293dcfa..00000000 --- a/src/items/vSensorSHT20.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include "Consts.h" -#ifdef EnableSensorSht20 -#include "items/vSensorSHT20.h" - -#include - -#include "BufferExecute.h" -#include "Class/LineParsing.h" -#include "Global.h" - -#include "Wire.h" -#include "SHT2x.h" -SHT2x* sht = nullptr; - -SensorSht20::SensorSht20(const paramsSht& paramsTmp, const paramsSht& paramsHum) { - _paramsTmp = paramsSht(paramsTmp); - _paramsHum = paramsSht(paramsHum); - - if (!sht) { - sht = new SHT2x; - } - - sht->begin(); - - uint8_t stat = sht->getStatus(); - Serial.print(stat, HEX); - Serial.println(); -} - -SensorSht20::~SensorSht20() {} - -void SensorSht20::loop() { - difference = millis() - prevMillis; - if (difference >= _paramsHum.interval) { - prevMillis = millis(); - read(); - } -} - -void SensorSht20::read() { - sht->read(); - - float tmp = sht->getTemperature(); - float hum = sht->getHumidity(); - - tmp = tmp * _paramsTmp.c; - hum = hum * _paramsHum.c; - - eventGen2(_paramsTmp.key, String(tmp)); - jsonWriteStr(configLiveJson, _paramsTmp.key, String(tmp)); - publishStatus(_paramsTmp.key, String(tmp)); - String path = mqttRootDevice + "/" +_paramsTmp.key + "/status"; - String json = "{}"; - jsonWriteStr(json, "status", String(tmp)); - String MyJson = json; - jsonWriteStr(MyJson, "topic", path); - ws.textAll(MyJson); - - SerialPrint("I", "Sensor", "'" + _paramsTmp.key + "' data: " + String(tmp)); - - eventGen2(_paramsHum.key, String(hum)); - jsonWriteStr(configLiveJson, _paramsHum.key, String(hum)); - publishStatus(_paramsHum.key, String(hum)); - path = mqttRootDevice + "/" +_paramsHum.key + "/status"; - json = "{}"; - jsonWriteStr(json, "status", String(hum)); - MyJson = json; - jsonWriteStr(MyJson, "topic", path); - ws.textAll(MyJson); - SerialPrint("I", "Sensor", "'" + _paramsHum.key + "' data: " + String(hum)); -} - -MySensorSht20Vector* mySensorSht20 = nullptr; - -void sht20Sensor() { - myLineParsing.update(); - String key = myLineParsing.gkey(); - String interval = myLineParsing.gint(); - String c = myLineParsing.gc(); - myLineParsing.clear(); - - static int enterCnt = -1; - enterCnt++; - - static paramsSht paramsTmp; - static paramsSht paramsHum; - - if (enterCnt == 0) { - paramsTmp.key = key; - paramsTmp.c = c.toFloat(); - } - - if (enterCnt == 1) { - paramsHum.key = key; - paramsHum.c = c.toFloat(); - paramsHum.interval = interval.toInt() * 1000; - - static bool firstTime = true; - if (firstTime) mySensorSht20 = new MySensorSht20Vector(); - firstTime = false; - mySensorSht20->push_back(SensorSht20(paramsTmp, paramsHum)); - } -} -#endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index c017cd1c..b2759499 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -31,7 +31,6 @@ #include "items/vSensorDht.h" #include "items/vSensorNode.h" #include "items/vSensorPzem.h" -#include "items/vSensorSHT20.h" #include "items/vSensorUltrasonic.h" #include "items/vSensorUptime.h" //#include "WebServer.h" @@ -190,13 +189,6 @@ void loop() { } } #endif -#ifdef EnableSensorSht20 - if (mySensorSht20 != nullptr) { - for (unsigned int i = 0; i < mySensorSht20->size(); i++) { - mySensorSht20->at(i).loop(); - } - } -#endif #ifdef EnableSensorAny if (mySensorAny != nullptr) { for (unsigned int i = 0; i < mySensorAny->size(); i++) {