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..f4fb061c 100644 --- a/include/Class/IoTSensor.h +++ b/include/Class/IoTSensor.h @@ -3,18 +3,24 @@ #include class IoTSensor { - public: - IoTSensor(); - ~IoTSensor(); + public: + IoTSensor(); + ~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..244f8f0d --- /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 selfExec(); + virtual void loop(); + + void init(String key, String id); + void regEvent(String value, String consoleInfo); + + String getKey(); + String getID(); + + protected: + String _key; //имя переменной, для идентификации при работе с несколькими переменными в одном модуле + String _id; //код переменной для идентификации событий, команд в сценариях и логах + +}; \ No newline at end of file diff --git a/include/Class/LineParsing.h b/include/Class/LineParsing.h index ff8a3965..c1519edb 100644 --- a/include/Class/LineParsing.h +++ b/include/Class/LineParsing.h @@ -210,6 +210,9 @@ class LineParsing { String gtm2() { return _tm2; } + String gdb() { + return _db; + } int getPinErrors() { return pinErrors; diff --git a/include/items/ButtonInClass.h b/include/items/ButtonInClass.h deleted file mode 100644 index e9719874..00000000 --- a/include/items/ButtonInClass.h +++ /dev/null @@ -1,65 +0,0 @@ - -#ifdef EnableButtonIn -#pragma once -#include -#include -#include "Class/LineParsing.h" -#include "Global.h" - -extern boolean but[NUM_BUTTONS]; -extern Bounce* buttons; - -class ButtonInClass : public LineParsing { - protected: - int numberEntering = 0; - int state = _state.toInt(); - - public: - ButtonInClass() : LineParsing(){}; - - void init() { - if (_pin != "") { - int number = numberEntering++; - buttons[number].attach(_pin.toInt(), INPUT); - buttons[number].interval(_db.toInt()); - but[number] = true; - jsonWriteStr(configOptionJson, "switch_num_" + String(number), _key); - } - } - - void loop() { - static uint8_t switch_number = 1; - if (but[switch_number]) { - buttons[switch_number].update(); - if (buttons[switch_number].fell()) { - String key = jsonReadStr(configOptionJson, "switch_num_" + String(switch_number)); - state = 1; - switchChangeVirtual(key, String(state)); - } - if (buttons[switch_number].rose()) { - String key = jsonReadStr(configOptionJson, "switch_num_" + String(switch_number)); - state = 0; - switchChangeVirtual(key, String(state)); - } - } - switch_number++; - if (switch_number == NUM_BUTTONS) { - switch_number = 0; - } - } - - void switchStateSetDefault() { - if (_state != "") { - switchChangeVirtual(_key, _state); - } - } - - void switchChangeVirtual(String key, String state) { - eventGen2(key, state); - jsonWriteInt(configLiveJson, key, state.toInt()); - publishStatus(key, state); - } -}; - -extern ButtonInClass myButtonIn; -#endif \ 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..8b851184 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" @@ -27,9 +26,11 @@ #include "Class/IoTModule.h" #include "Class/IoTSensor.h" +#include "Class/IoTVariable.h" extern std::vector iotModules; //v3dev: вектор ссылок базового класса IoTModule - интерфейсы для общения со всеми поддерживаемыми системой модулями extern std::vector iotSensors; //v3dev: вектор ссылок базового класса IoTSensor - список всех запущенных сенсоров +extern std::vector iotVariables; //v3dev: вектор ссылок базового класса IoTVariable - список всех подготовленных переменных void loopCmdAdd(const String& cmdStr) { if (cmdStr.endsWith(",")) { @@ -89,10 +90,6 @@ void csvCmdExecute(String& cmdStr) { } else if (order == F("pwm-out")) { #ifdef EnablePwmOut sCmd.addCommand(order.c_str(), pwmOut); -#endif - } else if (order == F("button-in")) { -#ifdef EnableButtonIn - sCmd.addCommand(order.c_str(), buttonIn); #endif } else if (order == F("input-value")) { #ifdef EnableInput @@ -122,10 +119,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,28 +163,31 @@ 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) { //проверка вхождения имени искомого модуля в ключе элемента настройки + 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(); + String db = myLineParsing.gdb(); + myLineParsing.clear(); + String strTmp = "{\"key\": \"" + key + "\", \"id\": \"" + id + "\", \"addr\": \"" + addr + "\", \"int\": \"" + interval + "\", \"pin\": \"" + pin + "\", \"index\": \"" + index + "\", \"c\": \"" + c + "\", \"db\": \"" + db + "\"}"; + SerialPrint("I", "Строка параметров при инициализации модуля " + moduleInfo.name + ": ", strTmp); if (moduleInfo.type == "Sensor") { - myLineParsing.update(); //v3dev: пока используем мостик для совместимости версий, предполагается, что настройки сразу будут в JSON - String interval = myLineParsing.gint(); - String pin = myLineParsing.gpin(); - String index = myLineParsing.gindex(); - String addr = myLineParsing.gaddr(); - myLineParsing.clear(); - String strTmp = "{\"addr\": \"" + addr + "\", \"int\": \"" + interval + "\", \"pin\": \"" + pin + "\", \"index\": \"" + index + "\"}"; - iotSensors.push_back((IoTSensor*)iotModules[i]->initInstance(strTmp)); - } else if (moduleInfo.type == "Container") - { - //iot.push_back((IoTSensor*)iotModules[i]->initInstance(moduleInfo.parameters)); + } else if (moduleInfo.type == "Variable") { + iotVariables.push_back((IoTVariable*)iotModules[i]->initInstance(strTmp)); } } } 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..13e95914 100644 --- a/src/Class/IoTSensor.cpp +++ b/src/Class/IoTSensor.cpp @@ -3,29 +3,37 @@ #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; if (difference >= _interval) { prevMillis = millis(); - SerialPrint("I", "Sensor", "Вызывается loop"); this->doByInterval(); } } 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..31545ff3 --- /dev/null +++ b/src/Class/IoTVariable.cpp @@ -0,0 +1,31 @@ +#include "Utils/JsonUtils.h" +#include "Utils/SerialPrint.h" +#include "Class/ScenarioClass3.h" +#include "Class/IoTVariable.h" + +IoTVariable::IoTVariable() {} +IoTVariable::~IoTVariable() {} + +String IoTVariable::execute(String command) { return "";} +void IoTVariable::selfExec() {} +void IoTVariable::loop() {} + +void IoTVariable::init(String key, String id) { + _key = key; + _id = id; +} + +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); +} + +String IoTVariable::getKey() { + return _key; +} + +String IoTVariable::getID() { + return _id; +}; \ 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/IoTSensorButtonIn.cpp b/src/Modules/Sensors/IoTSensorButtonIn.cpp new file mode 100644 index 00000000..0ed6d95e --- /dev/null +++ b/src/Modules/Sensors/IoTSensorButtonIn.cpp @@ -0,0 +1,79 @@ +#include "Utils/JsonUtils.h" +#include "Utils/SerialPrint.h" +#include "Utils/StringUtils.h" +#include "Class/IoTSensor.h" +#include "Class/IoTModule.h" + +#include + +class IoTSensorButtonIn: public IoTSensor { + private: + //описание переменных экземпляра датчика - аналог глобальных переменных из Arduino + //для работы библиотеки с несколькими линиями необходимо обеспечить каждый экземпляр класса ссылками на объекты настроенные на эти линии + Bounce* bButton; + boolean status; + + //описание параметров передаваемых из настроек датчика из веба + unsigned int _pin; + unsigned int _db; + + public: + //аналог setup() из Arduino + IoTSensorButtonIn(String parameters) { + //передаем часть базовых параметров в конструктор базового класса для обеспечения работы его методов + init(jsonReadStr(parameters, "key"), jsonReadStr(parameters, "id"), 0); + _pin = jsonReadInt(parameters, "pin"); + _db = jsonReadInt(parameters, "db"); + + bButton = new Bounce(); + bButton->attach(_pin, INPUT); + bButton->interval(_db); + status = true; + } + + ~IoTSensorButtonIn() { + delete bButton; + } + + //аналог loop() из Arduino, но квотируемый по времени параметром interval + void doByInterval() { + bButton->update(); + if (bButton->fell()) { + status = 1; + regEvent((String)status, ""); //обязательный вызов для отправки результата работы + } + if (bButton->rose()) { + status = 0; + regEvent((String)status, ""); //обязательный вызов для отправки результата работы + } + } +}; + +//технический класс для взаимодействия с ядром, меняются только названия +class IoTModuleButtonIn: public IoTModule { + //обязательный метод для инициализации экземпляра датчика, вызывается при чтении конфигурации. Нужно учитывать, что некоторые датчики могут обеспечивать + //несколько измерений, для каждого будет отдельный вызов. + void* initInstance(String parameters) { + return new IoTSensorButtonIn(parameters); + }; + + //обязательный к заполнению метод, если модуль использует свои глобальные переменные. Необходимо сбросить и очистить используемую память. + void clear() { + //и так чисто + } + + //обязательный метод для отправки информации о модуле, + ModuleInfo getInfo() { + ModuleInfo MI; + MI.name = "button-in"; + MI.title = "Кнопка физическая, чтение состояния пина (подключается проводами к устройству)"; + MI.parameters = "{\"key\": \"button-in\", \"id\": \"btn\", \"pin\": \"2\", \"db\": \"20\"}"; + MI.type = "Sensor"; + return MI; + }; +}; + +//точка входа в модуль для заполнения вектора, требуется только изменить имя и прописать в файле api.cpp +void* getApiIoTSensorButtonIn() { + return new IoTModuleButtonIn(); +} \ No newline at end of file diff --git a/src/Modules/Sensors/IoTSensorDallasTemp.cpp b/src/Modules/Sensors/IoTSensorDallasTemp.cpp index 1b84f40a..6615ad59 100644 --- a/src/Modules/Sensors/IoTSensorDallasTemp.cpp +++ b/src/Modules/Sensors/IoTSensorDallasTemp.cpp @@ -9,8 +9,6 @@ #include #include -extern std::vector iotModules; //v3dev: вектор ссылок базового класса IoTModule - интерфейсы для общения со всеми поддерживаемыми системой модулями -#define IOTDALLASTEMPKEY "dallas-temp" //глобальные списки необходимы для хранения объектов об активных линиях 1-wire используемых разными датчиками из модуля. Ключ - номер пина std::map oneWireTemperatureArray; @@ -31,7 +29,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,19 +83,35 @@ class IoTModuleDallasTemp: public IoTModule { return new IoTSensorDallas(parameters); }; + //обязательный к заполнению метод, если модуль использует свои глобальные переменные. Необходимо сбросить и очистить используемую память. + void clear() { + // for (auto it = sensorsTemperatureArray.cbegin(), next_it = it; it != sensorsTemperatureArray.cend(); it = next_it) { + // ++next_it; + // DallasTemperature* tmpptr = it->second; //временно сохраняем указатель на сенсор, т.к. его преждевременное удаление оставит поломаную запись в векторе, к которой может обратиться ядро и вызвать исключение + // sensorsTemperatureArray.erase(it); + // delete tmpptr; //а далее уже удаляем объект сенсора + // } + + // for (auto it = oneWireTemperatureArray.cbegin(), next_it = it; it != oneWireTemperatureArray.cend(); it = next_it) { + // ++next_it; + // OneWire* tmpptr = it->second; //временно сохраняем указатель на сенсор, т.к. его преждевременное удаление оставит поломаную запись в векторе, к которой может обратиться ядро и вызвать исключение + // oneWireTemperatureArray.erase(it); + // delete tmpptr; //а далее уже удаляем объект сенсора + // } + } + //обязательный метод для отправки информации о модуле, 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; }; }; //точка входа в модуль для заполнения вектора, требуется только изменить имя и прописать в файле api.cpp -void getApiIoTSensorDallasTemp() { - iotModules.push_back(new IoTModuleDallasTemp()); - return; +void* getApiIoTSensorDallasTemp() { + return new IoTModuleDallasTemp(); } \ No newline at end of file diff --git a/src/Modules/Sensors/IoTSensorSHT20.cpp b/src/Modules/Sensors/IoTSensorSHT20.cpp new file mode 100644 index 00000000..2d641dcd --- /dev/null +++ b/src/Modules/Sensors/IoTSensorSHT20.cpp @@ -0,0 +1,80 @@ +#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" + + +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() { + //запускаем опрос измерений + sht->read(); + 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() { + return new IoTModuleSHT20(); +} \ No newline at end of file diff --git a/src/Modules/Variables/IoTVariableVirtual.cpp b/src/Modules/Variables/IoTVariableVirtual.cpp new file mode 100644 index 00000000..9b9a558d --- /dev/null +++ b/src/Modules/Variables/IoTVariableVirtual.cpp @@ -0,0 +1,69 @@ +#include "Utils/JsonUtils.h" +#include "Utils/SerialPrint.h" +#include "Utils/StringUtils.h" + +#include "Class/IoTVariable.h" +#include "Class/IoTModule.h" + + +class IoTVariableVirtual: public IoTVariable { + private: + //описание переменных экземпляра Variable - аналог глобальных переменных из Arduino + String value; + + //описание параметров передаваемых из настроек переменной из веба + + public: + //аналог setup() из Arduino + IoTVariableVirtual(String parameters) { + //передаем часть базовых параметров в конструктор базового класса для обеспечения работы его методов + init(jsonReadStr(parameters, "key"), jsonReadStr(parameters, "id")); + + } + + ~IoTVariableVirtual() {} + + //аналог loop() из Arduino + void loop() { + + } + + //вызывается при выполнении команды связанной с конкретным экземпляром переменной + String execute(String command) { + + return ""; + } + + //вызывается при любом изменении переменной + void selfExec() { + + } +}; + +//технический класс для взаимодействия с ядром, меняются только названия +class IoTModuleVariable: public IoTModule { + //обязательный метод для инициализации экземпляра переменной, вызывается при чтении конфигурации. + void* initInstance(String parameters) { + return new IoTVariableVirtual(parameters); + }; + + //обязательный к заполнению метод, если модуль использует свои глобальные переменные. Необходимо сбросить и очистить используемую память. + void clear() { + //и так чисто + } + + //обязательный метод для отправки информации о модуле, + ModuleInfo getInfo() { + ModuleInfo MI; + MI.name = "variable"; + MI.title = "Переменная для хранения значений пользователя"; + MI.parameters = "{\"key\": \"variable\", \"id\": \"var\"}"; + MI.type = "Variable"; + return MI; + }; +}; + +//точка входа в модуль для заполнения вектора, требуется только изменить имя и прописать в файле api.cpp + void* getApiIoTVariableVirtual() { + return new IoTModuleVariable(); +} \ No newline at end of file diff --git a/src/Modules/api.cpp b/src/Modules/api.cpp index 978f172e..7c1f9b69 100644 --- a/src/Modules/api.cpp +++ b/src/Modules/api.cpp @@ -1,9 +1,23 @@ #include "Utils/SerialPrint.h" +#include "Class/IoTSensor.h" +#include "Class/IoTModule.h" +#include "Class/IoTVariable.h" + +extern std::vector iotModules; //v3dev: вектор ссылок базового класса IoTModule - интерфейсы для общения со всеми поддерживаемыми системой модулями + //объявляем функцию для добавления модуля в вектор -void getApiIoTSensorDallasTemp(); +void* getApiIoTSensorDallasTemp(); +void* getApiIoTSensorSHT20(); +void* getApiIoTSensorButtonIn(); + +void* getApiIoTVariableVirtual(); //формируем вектор модулей путем вызова из каждого модуля специальной функции //в дальнейшем предполагается отключать вызов, если модуль не участвует в сборке void InitModulesApi() { - getApiIoTSensorDallasTemp(); + iotModules.push_back((IoTModule*) getApiIoTSensorDallasTemp()); + iotModules.push_back((IoTModule*) getApiIoTSensorSHT20()); + iotModules.push_back((IoTModule*) getApiIoTSensorButtonIn()); + + iotModules.push_back((IoTModule*) getApiIoTVariableVirtual()); } \ No newline at end of file diff --git a/src/items/ButtonInClass.cpp b/src/items/ButtonInClass.cpp deleted file mode 100644 index 7e64aaec..00000000 --- a/src/items/ButtonInClass.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "Consts.h" -#ifdef EnableButtonIn -#include "BufferExecute.h" -#include "items/ButtonInClass.h" -//==========================================Модуль физических кнопок======================================== -//button-in switch1 toggle Кнопки Свет 1 pin[2] db[20] -//========================================================================================================== - -boolean but[NUM_BUTTONS]; -Bounce *buttons = new Bounce[NUM_BUTTONS]; - -ButtonInClass myButtonIn; -void buttonIn() { - myButtonIn.update(); - String key = myButtonIn.gkey(); - String pin = myButtonIn.gpin(); - sCmd.addCommand(key.c_str(), buttonInSet); - myButtonIn.init(); - myButtonIn.switchStateSetDefault(); - myButtonIn.clear(); -} - -void buttonInSet() { - String key = sCmd.order(); - String state = sCmd.next(); - myButtonIn.switchChangeVirtual(key, state); -} -#endif \ 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..09690911 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -19,7 +19,6 @@ #include "Utils/statUtils.h" #include "Utils/Timings.h" #include "Utils/WebUtils.h" -#include "items/ButtonInClass.h" #include "items/vCountDown.h" #include "items/vImpulsOut.h" #include "items/vLogging.h" @@ -31,7 +30,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" @@ -39,10 +37,12 @@ #include #include "Class/IoTSensor.h" #include "Class/IoTModule.h" +#include "Class/IoTVariable.h" std::vector iotModules; //v3dev: вектор ссылок базового класса IoTModule - интерфейсы для общения со всеми поддерживаемыми системой модулями std::vector iotSensors; //v3dev: вектор ссылок базового класса IoTSensor - список всех запущенных сенсоров +std::vector iotVariables; //v3dev: вектор ссылок базового класса IoTVariable - список всех подготовленных переменных void InitModulesApi(); //v3dev: инициализация модуля при первом вызове . @@ -190,13 +190,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++) { @@ -239,9 +232,7 @@ void loop() { } } #endif -#ifdef EnableButtonIn - myButtonIn.loop(); -#endif +