mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-27 06:32:19 +03:00
Убираем нумерацию папок модулей
This commit is contained in:
100
src/modules/sensors/Ads1115/Ads1115.cpp
Normal file
100
src/modules/sensors/Ads1115/Ads1115.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
/******************************************************************
|
||||
Used Adafruit ADS1X15 Driver (16-bit Differential or Single-Ended ADCs with PGA and Comparator)
|
||||
Support for ADS1015/1115
|
||||
https://github.com/adafruit/Adafruit_ADS1X15
|
||||
|
||||
adapted for version 4 @Serghei63
|
||||
******************************************************************/
|
||||
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
|
||||
#include "Wire.h"
|
||||
#include <Adafruit_ADS1X15.h> // Библиотека для работы с модулями ADS1115 и ADS1015
|
||||
|
||||
// to do убрать глобальный экземпляр
|
||||
Adafruit_ADS1115 ads;
|
||||
|
||||
class Ads1115 : public IoTItem {
|
||||
int _pin;
|
||||
bool _isRaw;
|
||||
bool _isInited = false;
|
||||
|
||||
public:
|
||||
Ads1115(String parameters) : IoTItem(parameters) {
|
||||
String tmp;
|
||||
jsonRead(parameters, "pin", tmp);
|
||||
_pin = tmp.toInt();
|
||||
|
||||
jsonRead(parameters, "mode", tmp);
|
||||
_isRaw = tmp == "raw";
|
||||
|
||||
if (!ads.begin()) {
|
||||
Serial.println("Failed to initialize ADS.");
|
||||
_isInited = false;
|
||||
} else
|
||||
_isInited = true;
|
||||
|
||||
String gain;
|
||||
jsonRead(parameters, "gain", gain);
|
||||
if (gain == "1x")
|
||||
ads.setGain(GAIN_ONE);
|
||||
else if (gain == "2x")
|
||||
ads.setGain(GAIN_TWO);
|
||||
else if (gain == "4x")
|
||||
ads.setGain(GAIN_FOUR);
|
||||
else if (gain == "8x")
|
||||
ads.setGain(GAIN_EIGHT);
|
||||
else if (gain == "16x")
|
||||
ads.setGain(GAIN_SIXTEEN);
|
||||
else
|
||||
ads.setGain(GAIN_TWOTHIRDS);
|
||||
// ВОЗМОЖНЫЕ ВАРИАНТЫ УСТАНОВКИ КУ:
|
||||
// ads.setGain(GAIN_TWOTHIRDS); //| 2/3х | +/-6.144V | 1bit = 0.1875mV |
|
||||
// ads.setGain(GAIN_ONE); //| 1х | +/-4.096V | 1bit = 0.125mV |
|
||||
// ads.setGain(GAIN_TWO); //| 2х | +/-2.048V | 1bit = 0.0625mV |
|
||||
// ads.setGain(GAIN_FOUR); //| 4х | +/-1.024V | 1bit = 0.03125mV |
|
||||
// ads.setGain(GAIN_EIGHT); //| 8х | +/-0.512V | 1bit = 0.015625mV |
|
||||
// ads.setGain(GAIN_SIXTEEN); //| 16х | +/-0.256V | 1bit = 0.0078125mV |
|
||||
}
|
||||
|
||||
void doByInterval() {
|
||||
if (_isInited) {
|
||||
if (_isRaw)
|
||||
value.valD = ads.readADC_SingleEnded(_pin); // Чтение АЦП нулевого канала(rawdata)
|
||||
else
|
||||
value.valD = ads.computeVolts(ads.readADC_SingleEnded(_pin)); // Чтение АЦП нулевого канала (Вольты)
|
||||
regEvent(value.valD, "ADC1115");
|
||||
}
|
||||
}
|
||||
|
||||
~Ads1115(){};
|
||||
};
|
||||
|
||||
void *getAPI_Ads1115(String subtype, String param) {
|
||||
if (subtype == F("Ads1115")) {
|
||||
return new Ads1115(param);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// {
|
||||
// "name": "26. Датчик напряжения ADS1115",
|
||||
// "num": 26,
|
||||
// "type": "Reading",
|
||||
// "subtype": "Ads1115",
|
||||
// "id": "Ads3",
|
||||
// "widget": "anydataVlt",
|
||||
// "page": "Сенсоры",
|
||||
// "descr": "ADS_3",
|
||||
|
||||
// "pin": "0",
|
||||
// "mode": "volt",
|
||||
// "gain": "3/4x",
|
||||
|
||||
// "plus": 0,
|
||||
// "multiply": 1,
|
||||
// "round": 100,
|
||||
// "int": 10
|
||||
// }
|
||||
49
src/modules/sensors/Ads1115/modinfo.json
Normal file
49
src/modules/sensors/Ads1115/modinfo.json
Normal file
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"menuSection": "Сенсоры",
|
||||
|
||||
"configItem": [{
|
||||
"name": "Датчик напряжения ADS1115",
|
||||
"type": "Reading",
|
||||
"subtype": "Ads1115",
|
||||
"id": "Ads3",
|
||||
"widget": "anydataVlt",
|
||||
"page": "Сенсоры",
|
||||
"descr": "ADS_3",
|
||||
|
||||
"pin": "0",
|
||||
"mode": "volt",
|
||||
"gain": "3/4x",
|
||||
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 2,
|
||||
"int": 10
|
||||
}],
|
||||
|
||||
"about": {
|
||||
"authorName": "Serghei Crasnicov",
|
||||
"authorContact": "https://t.me/Serghei63",
|
||||
"authorGit": "https://github.com/Serghei63",
|
||||
"specialThanks": "",
|
||||
"moduleName": "Ads1115",
|
||||
"moduleVersion": "1.0",
|
||||
"moduleDesc": "Позволяет получить относительную величину напряжения на понижающем трансформаторе.",
|
||||
"propInfo": {
|
||||
"pin": "GPIO номер, к которому подключен датчик.",
|
||||
"mode": "",
|
||||
"gain": "",
|
||||
"int": "Количество секунд между опросами датчика."
|
||||
}
|
||||
},
|
||||
|
||||
"defActive": false,
|
||||
|
||||
"devices": {
|
||||
"esp32_4mb": [
|
||||
"adafruit/Adafruit ADS1X15 @ ^2.3.0"
|
||||
],
|
||||
"esp8266_4mb": [
|
||||
"adafruit/Adafruit ADS1X15 @ ^2.3.0"
|
||||
]
|
||||
}
|
||||
}
|
||||
61
src/modules/sensors/Aht20/Aht20.cpp
Normal file
61
src/modules/sensors/Aht20/Aht20.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
/******************************************************************
|
||||
Used Adafruit AHT20 Driver (temperature and humidity sensor)
|
||||
Support for AHT20
|
||||
https://github.com/adafruit/Adafruit_AHTX0
|
||||
|
||||
adapted for version 4 @Serghei63
|
||||
******************************************************************/
|
||||
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
|
||||
#include "Adafruit_AHTX0.h"
|
||||
#include <map>
|
||||
|
||||
// to do убрать глобальный экземпляр
|
||||
Adafruit_AHTX0 aht;
|
||||
sensors_event_t temp, humidity;
|
||||
|
||||
class Aht20t : public IoTItem {
|
||||
public:
|
||||
Aht20t(String parameters) : IoTItem(parameters) {}
|
||||
|
||||
void doByInterval() {
|
||||
value.valD = temp.temperature;
|
||||
if (value.valD != -200)
|
||||
regEvent(value.valD, "Aht20t"); // TODO: найти способ понимания ошибки получения данных
|
||||
else
|
||||
SerialPrint("E", "Sensor AHTt", "Error");
|
||||
}
|
||||
|
||||
~Aht20t(){};
|
||||
};
|
||||
|
||||
class Aht20h : public IoTItem {
|
||||
public:
|
||||
Aht20h(String parameters) : IoTItem(parameters) {}
|
||||
|
||||
void doByInterval() {
|
||||
value.valD = humidity.relative_humidity;
|
||||
if (value.valD != -200)
|
||||
regEvent(value.valD, "Aht20h"); // TODO: найти способ понимания ошибки получения данных
|
||||
else
|
||||
SerialPrint("E", "Sensor AHTt", "Error");
|
||||
}
|
||||
|
||||
~Aht20h(){};
|
||||
};
|
||||
|
||||
void* getAPI_Aht20(String subtype, String param) {
|
||||
if (subtype == F("Aht20t")) {
|
||||
aht.begin();
|
||||
aht.getEvent(&humidity, &temp); // populate temp and humidity objects with fresh data
|
||||
return new Aht20t(param);
|
||||
} else if (subtype == F("Aht20h")) {
|
||||
aht.begin();
|
||||
aht.getEvent(&humidity, &temp); // populate temp and humidity objects with fresh data
|
||||
return new Aht20h(param);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
54
src/modules/sensors/Aht20/modinfo.json
Normal file
54
src/modules/sensors/Aht20/modinfo.json
Normal file
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"menuSection": "Сенсоры",
|
||||
|
||||
"configItem": [{
|
||||
"name": "Cенсор температуры AHT20",
|
||||
"type": "Reading",
|
||||
"subtype": "Aht20t",
|
||||
"id": "Temp20",
|
||||
"widget": "anydataTmp",
|
||||
"page": "Сенсоры",
|
||||
"descr": "AHT20 Температура",
|
||||
"int": 15,
|
||||
"addr": "0x38",
|
||||
"round": 1
|
||||
},
|
||||
{
|
||||
"name": "Cенсор влажности AHT20",
|
||||
"type": "Reading",
|
||||
"subtype": "Aht20h",
|
||||
"id": "Hum20",
|
||||
"widget": "anydataHum",
|
||||
"page": "Сенсоры",
|
||||
"descr": "AHT20 Влажность",
|
||||
"int": 15,
|
||||
"addr": "0x38",
|
||||
"round": 1
|
||||
}],
|
||||
|
||||
"about": {
|
||||
"authorName": "Serghei Crasnicov",
|
||||
"authorContact": "https://t.me/Serghei63",
|
||||
"authorGit": "https://github.com/Serghei63",
|
||||
"specialThanks": "",
|
||||
"moduleName": "Aht20",
|
||||
"moduleVersion": "1.0",
|
||||
"moduleDesc": "Позволяет получить температуру и влажность с Aht20.",
|
||||
"propInfo": {
|
||||
"pin": "GPIO номер, к которому подключен датчик.",
|
||||
"addr": "Адрес датчика на шине, обычно 0x38.",
|
||||
"int": "Количество секунд между опросами датчика."
|
||||
}
|
||||
},
|
||||
|
||||
"defActive": true,
|
||||
|
||||
"devices": {
|
||||
"esp32_4mb": [
|
||||
"Adafruit AHTX0"
|
||||
],
|
||||
"esp8266_4mb": [
|
||||
"Adafruit AHTX0"
|
||||
]
|
||||
}
|
||||
}
|
||||
84
src/modules/sensors/AnalogAdc/AnalogAdc.cpp
Normal file
84
src/modules/sensors/AnalogAdc/AnalogAdc.cpp
Normal file
@@ -0,0 +1,84 @@
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
|
||||
extern IoTGpio IoTgpio;
|
||||
|
||||
// Это файл сенсора, в нем осуществляется чтение сенсора.
|
||||
// для добавления сенсора вам нужно скопировать этот файл и заменить в нем текст AnalogAdc на название вашего сенсора
|
||||
// Название должно быть уникальным, коротким и отражать суть сенсора.
|
||||
|
||||
class AnalogAdc : public IoTItem {
|
||||
private:
|
||||
//=======================================================================================================
|
||||
// Секция переменных.
|
||||
// Это секция где Вы можете объявлять переменные и объекты arduino библиотек, что бы
|
||||
// впоследствии использовать их в loop и setup
|
||||
unsigned int _pin;
|
||||
unsigned int _avgSteps, _avgCount;
|
||||
unsigned long _avgSumm;
|
||||
|
||||
public:
|
||||
//=======================================================================================================
|
||||
// setup()
|
||||
// это аналог setup из arduino. Здесь вы можете выполнять методы инициализации сенсора.
|
||||
// Такие как ...begin и подставлять в них параметры полученные из web интерфейса.
|
||||
// Все параметры хранятся в перемененной parameters, вы можете прочитать любой параметр используя jsonRead функции:
|
||||
// jsonReadStr, jsonReadBool, jsonReadInt
|
||||
AnalogAdc(String parameters): IoTItem(parameters) {
|
||||
_pin = jsonReadInt(parameters, "pin");
|
||||
_avgSteps = jsonReadInt(parameters, "avgSteps");
|
||||
_avgSumm = 0;
|
||||
_avgCount = 0;
|
||||
}
|
||||
|
||||
//=======================================================================================================
|
||||
// doByInterval()
|
||||
// это аналог loop из arduino, но вызываемый каждые int секунд, заданные в настройках. Здесь вы должны выполнить чтение вашего сенсора
|
||||
// а затем выполнить regEvent - это регистрация произошедшего события чтения
|
||||
// здесь так же доступны все переменные из секции переменных, и полученные в setup
|
||||
// если у сенсора несколько величин то делайте несколько regEvent
|
||||
// не используйте delay - помните, что данный loop общий для всех модулей. Если у вас планируется длительная операция, постарайтесь разбить ее на порции
|
||||
// и выполнить за несколько тактов
|
||||
void doByInterval() {
|
||||
if (_avgSteps <= 1) value.valD = IoTgpio.analogRead(_pin);
|
||||
regEvent(value.valD, "AnalogAdc"); //обязательный вызов хотяб один
|
||||
}
|
||||
|
||||
//=======================================================================================================
|
||||
// loop()
|
||||
// полный аналог loop() из arduino. Нужно помнить, что все модули имеют равный поочередный доступ к центральному loop(), поэтому, необходимо следить
|
||||
// за задержками в алгоритме и не создавать пауз. Кроме того, данная версия перегружает родительскую, поэтому doByInterval() отключается, если
|
||||
// не повторить механизм расчета интервалов.
|
||||
void loop() {
|
||||
if (_avgSteps > 1) {
|
||||
if (_avgCount > _avgSteps) {
|
||||
value.valD = _avgSumm / _avgSteps;
|
||||
_avgSumm = 0;
|
||||
_avgCount = 0;
|
||||
}
|
||||
|
||||
_avgSumm = _avgSumm + IoTgpio.analogRead(_pin);
|
||||
_avgCount++;
|
||||
}
|
||||
|
||||
currentMillis = millis();
|
||||
difference = currentMillis - prevMillis;
|
||||
if (difference >= _interval) {
|
||||
prevMillis = millis();
|
||||
this->doByInterval();
|
||||
}
|
||||
}
|
||||
|
||||
~AnalogAdc() {};
|
||||
};
|
||||
|
||||
// после замены названия сенсора, на функцию можно не обращать внимания
|
||||
// если сенсор предполагает использование общего объекта библиотеки для нескольких экземпляров сенсора, то в данной функции необходимо предусмотреть
|
||||
// создание и контроль соответствующих глобальных переменных
|
||||
void* getAPI_AnalogAdc(String subtype, String param) {
|
||||
if (subtype == F("AnalogAdc")) {
|
||||
return new AnalogAdc(param);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
42
src/modules/sensors/AnalogAdc/modinfo.json
Normal file
42
src/modules/sensors/AnalogAdc/modinfo.json
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"menuSection": "Сенсоры",
|
||||
|
||||
"configItem": [{
|
||||
"name": "Аналоговый сенсор",
|
||||
"type": "Reading",
|
||||
"subtype": "AnalogAdc",
|
||||
"id": "t",
|
||||
"widget": "anydataTmp",
|
||||
"page": "Сенсоры",
|
||||
"descr": "Температура",
|
||||
"map": "1,1024,1,100",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 1,
|
||||
"pin": 0,
|
||||
"int": 15,
|
||||
"avgSteps": 1
|
||||
}],
|
||||
|
||||
"about": {
|
||||
"authorName": "Ilya Belyakov",
|
||||
"authorContact": "https://t.me/Biveraxe",
|
||||
"authorGit": "https://github.com/biveraxe",
|
||||
"specialThanks": "",
|
||||
"moduleName": "AnalogAdc",
|
||||
"moduleVersion": "1.0",
|
||||
"moduleDesc": "Позволяет получить текущее значение на аналоговом GPIO или усредненное для avgSteps измерений каждого вызова loop.",
|
||||
"propInfo": {
|
||||
"pin": "Аналоговый GPIO номер, к которому подключен датчик.",
|
||||
"avgSteps": "Количество считываний для усреднения. При <=1, считывается одно значение за каждый период опроса.",
|
||||
"int": "Количество секунд между опросами датчика."
|
||||
}
|
||||
},
|
||||
|
||||
"defActive": true,
|
||||
|
||||
"devices": {
|
||||
"esp32_4mb": [],
|
||||
"esp8266_4mb": []
|
||||
}
|
||||
}
|
||||
97
src/modules/sensors/Bme280/Bme280.cpp
Normal file
97
src/modules/sensors/Bme280/Bme280.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
/******************************************************************
|
||||
Used Adafruit BME280 Driver (Barometric Pressure Sensor)
|
||||
Support for BME280
|
||||
https://github.com/adafruit/Adafruit_BME280_Library
|
||||
******************************************************************/
|
||||
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
|
||||
#include <Adafruit_BME280.h>
|
||||
#include <map>
|
||||
|
||||
std::map<String, Adafruit_BME280*> bmes;
|
||||
|
||||
class Bme280t : public IoTItem {
|
||||
private:
|
||||
Adafruit_BME280* _bme;
|
||||
|
||||
public:
|
||||
Bme280t(Adafruit_BME280* bme, String parameters) : IoTItem(parameters) {
|
||||
_bme = bme;
|
||||
}
|
||||
|
||||
void doByInterval() {
|
||||
value.valD = _bme->readTemperature();
|
||||
if (value.valD < 145)
|
||||
regEvent(value.valD, "Bme280t");
|
||||
else
|
||||
SerialPrint("E", "Sensor Bme280t", "Error");
|
||||
}
|
||||
|
||||
~Bme280t() {};
|
||||
};
|
||||
|
||||
class Bme280h : public IoTItem {
|
||||
private:
|
||||
Adafruit_BME280* _bme;
|
||||
|
||||
public:
|
||||
Bme280h(Adafruit_BME280* bme, String parameters) : IoTItem(parameters) {
|
||||
_bme = bme;
|
||||
}
|
||||
|
||||
void doByInterval() {
|
||||
value.valD = _bme->readHumidity();
|
||||
if (value.valD < 100)
|
||||
regEvent(value.valD, "Bme280h");
|
||||
else
|
||||
SerialPrint("E", "Sensor Bme280h", "Error");
|
||||
}
|
||||
|
||||
~Bme280h() {};
|
||||
};
|
||||
|
||||
class Bme280p : public IoTItem {
|
||||
private:
|
||||
Adafruit_BME280* _bme;
|
||||
|
||||
public:
|
||||
Bme280p(Adafruit_BME280* bme, String parameters) : IoTItem(parameters) {
|
||||
_bme = bme;
|
||||
}
|
||||
|
||||
void doByInterval() {
|
||||
value.valD = _bme->readPressure();
|
||||
if (value.valD > 0) {
|
||||
value.valD = value.valD / 1.333224 / 100;
|
||||
regEvent(value.valD, "Bme280p");
|
||||
} else
|
||||
SerialPrint("E", "Sensor Bme280p", "Error");
|
||||
}
|
||||
|
||||
~Bme280p() {};
|
||||
};
|
||||
|
||||
|
||||
void* getAPI_Bme280(String subtype, String param) {
|
||||
if (subtype == F("Bme280t") || subtype == F("Bme280h") || subtype == F("Bme280p")) {
|
||||
String addr;
|
||||
jsonRead(param, "addr", addr);
|
||||
|
||||
if (bmes.find(addr) == bmes.end()) {
|
||||
bmes[addr] = new Adafruit_BME280();
|
||||
bmes[addr]->begin(hexStringToUint8(addr));
|
||||
}
|
||||
|
||||
if (subtype == F("Bme280t")) {
|
||||
return new Bme280t(bmes[addr], param);
|
||||
} else if (subtype == F("Bme280h")) {
|
||||
return new Bme280h(bmes[addr], param);
|
||||
} else if (subtype == F("Bme280p")) {
|
||||
return new Bme280p(bmes[addr], param);
|
||||
}
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
65
src/modules/sensors/Bme280/modinfo.json
Normal file
65
src/modules/sensors/Bme280/modinfo.json
Normal file
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"menuSection": "Сенсоры",
|
||||
|
||||
"configItem": [{
|
||||
"name": "Cенсор температуры Bme280",
|
||||
"type": "Reading",
|
||||
"subtype": "Bme280t",
|
||||
"id": "tmp3",
|
||||
"widget": "anydataTmp",
|
||||
"page": "Сенсоры",
|
||||
"descr": "Температура",
|
||||
"int": 15,
|
||||
"addr": "0x77",
|
||||
"round": 1
|
||||
},
|
||||
{
|
||||
"name": "Cенсор давления Bme280",
|
||||
"type": "Reading",
|
||||
"subtype": "Bme280p",
|
||||
"id": "Press3",
|
||||
"widget": "anydataMm",
|
||||
"page": "Сенсоры",
|
||||
"descr": "Давление",
|
||||
"int": 15,
|
||||
"addr": "0x77",
|
||||
"round": 1
|
||||
},
|
||||
{
|
||||
"name": "Cенсор влажности Bme280",
|
||||
"type": "Reading",
|
||||
"subtype": "Bme280h",
|
||||
"id": "Hum3",
|
||||
"widget": "anydataHum",
|
||||
"page": "Сенсоры",
|
||||
"descr": "Влажность",
|
||||
"int": 15,
|
||||
"addr": "0x77",
|
||||
"round": 1
|
||||
}],
|
||||
|
||||
"about": {
|
||||
"authorName": "Ilya Belyakov",
|
||||
"authorContact": "https://t.me/Biveraxe",
|
||||
"authorGit": "https://github.com/biveraxe",
|
||||
"specialThanks": "Serghei Crasnicov @Serghei63",
|
||||
"moduleName": "Bme280",
|
||||
"moduleVersion": "1.0",
|
||||
"moduleDesc": "Позволяет получить значения температуры, давления и влажности с Bme280.",
|
||||
"propInfo": {
|
||||
"addr": "Адрес датчика на шине, обычно 0x77.",
|
||||
"int": "Количество секунд между опросами датчика."
|
||||
}
|
||||
},
|
||||
|
||||
"defActive": true,
|
||||
|
||||
"devices": {
|
||||
"esp32_4mb": [
|
||||
"adafruit/Adafruit BME280 Library"
|
||||
],
|
||||
"esp8266_4mb": [
|
||||
"adafruit/Adafruit BME280 Library"
|
||||
]
|
||||
}
|
||||
}
|
||||
75
src/modules/sensors/Bmp280/Bmp280.cpp
Normal file
75
src/modules/sensors/Bmp280/Bmp280.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
/******************************************************************
|
||||
Used Adafruit BMP280 Driver (Barometric Pressure Sensor)
|
||||
Support for BMP280
|
||||
https://github.com/adafruit/Adafruit_BMP280_Library
|
||||
******************************************************************/
|
||||
|
||||
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
|
||||
#include <Adafruit_BMP280.h>
|
||||
#include <map>
|
||||
|
||||
|
||||
std::map<String, Adafruit_BMP280*> bmps;
|
||||
|
||||
class Bmp280t : public IoTItem {
|
||||
private:
|
||||
Adafruit_BMP280* _bmp;
|
||||
|
||||
public:
|
||||
Bmp280t(Adafruit_BMP280* bmp, String parameters): IoTItem(parameters) {
|
||||
_bmp = bmp;
|
||||
}
|
||||
|
||||
void doByInterval() {
|
||||
value.valD = _bmp->readTemperature();
|
||||
if (String(value.valD) != "nan") regEvent(value.valD, "Bmp280t");
|
||||
else SerialPrint("E", "Sensor DHTt", "Error");
|
||||
}
|
||||
|
||||
~Bmp280t() {};
|
||||
};
|
||||
|
||||
|
||||
class Bmp280p : public IoTItem {
|
||||
private:
|
||||
Adafruit_BMP280* _bmp;
|
||||
|
||||
public:
|
||||
Bmp280p(Adafruit_BMP280* bmp, String parameters): IoTItem(parameters) {
|
||||
_bmp = bmp;
|
||||
}
|
||||
|
||||
void doByInterval() {
|
||||
value.valD = _bmp->readPressure();
|
||||
if (String(value.valD) != "nan") {
|
||||
value.valD = value.valD / 1.333224 / 100;
|
||||
regEvent(value.valD, "Bmp280p");
|
||||
} else SerialPrint("E", "Sensor DHTh", "Error");
|
||||
}
|
||||
|
||||
~Bmp280p() {};
|
||||
};
|
||||
|
||||
|
||||
void* getAPI_Bmp280(String subtype, String param) {
|
||||
if (subtype == F("Bmp280t") || subtype == F("Bmp280p")) {
|
||||
String addr;
|
||||
jsonRead(param, "addr", addr);
|
||||
|
||||
if (bmps.find(addr) == bmps.end()) {
|
||||
bmps[addr] = new Adafruit_BMP280();
|
||||
bmps[addr]->begin(hexStringToUint8(addr));
|
||||
}
|
||||
|
||||
if (subtype == F("Bmp280t")) {
|
||||
return new Bmp280t(bmps[addr], param);
|
||||
} else if (subtype == F("Bmp280p")) {
|
||||
return new Bmp280p(bmps[addr], param);
|
||||
}
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
53
src/modules/sensors/Bmp280/modinfo.json
Normal file
53
src/modules/sensors/Bmp280/modinfo.json
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"menuSection": "Сенсоры",
|
||||
|
||||
"configItem": [{
|
||||
"name": "Cенсор температуры Bmp280",
|
||||
"type": "Reading",
|
||||
"subtype": "Bmp280t",
|
||||
"id": "tmp3",
|
||||
"widget": "anydataTmp",
|
||||
"page": "Сенсоры",
|
||||
"descr": "280 Температура",
|
||||
"int": 15,
|
||||
"addr": "0x77",
|
||||
"round": 1
|
||||
},
|
||||
{
|
||||
"name": "Cенсор давления Bmp280",
|
||||
"type": "Reading",
|
||||
"subtype": "Bmp280p",
|
||||
"id": "Press3",
|
||||
"widget": "anydataMm",
|
||||
"page": "Сенсоры",
|
||||
"descr": "280 Давление",
|
||||
"int": 15,
|
||||
"addr": "0x77",
|
||||
"round": 1
|
||||
}],
|
||||
|
||||
"about": {
|
||||
"authorName": "Ilya Belyakov",
|
||||
"authorContact": "https://t.me/Biveraxe",
|
||||
"authorGit": "https://github.com/biveraxe",
|
||||
"specialThanks": "Serghei Crasnicov @Serghei63",
|
||||
"moduleName": "Bmp280",
|
||||
"moduleVersion": "1.0",
|
||||
"moduleDesc": "Позволяет получить значения температуры и давления с Bmp280.",
|
||||
"propInfo": {
|
||||
"addr": "Адрес датчика на шине, обычно 0x77.",
|
||||
"int": "Количество секунд между опросами датчика."
|
||||
}
|
||||
},
|
||||
|
||||
"defActive": true,
|
||||
|
||||
"devices": {
|
||||
"esp32_4mb": [
|
||||
"adafruit/Adafruit BMP280 Library"
|
||||
],
|
||||
"esp8266_4mb": [
|
||||
"adafruit/Adafruit BMP280 Library"
|
||||
]
|
||||
}
|
||||
}
|
||||
80
src/modules/sensors/Dht1122/Dht1122.cpp
Normal file
80
src/modules/sensors/Dht1122/Dht1122.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
/******************************************************************
|
||||
Used DHT Temperature & Humidity Sensor library for Arduino & ESP32.
|
||||
Support for DHT11 and DHT22/AM2302/RHT03
|
||||
https://github.com/beegee-tokyo/arduino-DHTesp
|
||||
******************************************************************/
|
||||
|
||||
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
|
||||
#include "DHTesp.h"
|
||||
#include <map>
|
||||
|
||||
|
||||
std::map<int, DHTesp*> dhts;
|
||||
|
||||
class Dht1122t : public IoTItem {
|
||||
private:
|
||||
DHTesp* _dht;
|
||||
|
||||
public:
|
||||
Dht1122t(DHTesp* dht, String parameters): IoTItem(parameters) {
|
||||
_dht = dht;
|
||||
}
|
||||
|
||||
void doByInterval() {
|
||||
value.valD = _dht->getTemperature();
|
||||
if (String(value.valD) != "nan") regEvent(value.valD, "Dht1122t");
|
||||
else SerialPrint("E", "Sensor DHTt", "Error");
|
||||
}
|
||||
|
||||
~Dht1122t() {};
|
||||
};
|
||||
|
||||
|
||||
class Dht1122h : public IoTItem {
|
||||
private:
|
||||
DHTesp* _dht;
|
||||
|
||||
public:
|
||||
Dht1122h(DHTesp* dht, String parameters): IoTItem(parameters) {
|
||||
_dht = dht;
|
||||
}
|
||||
|
||||
void doByInterval() {
|
||||
value.valD = _dht->getHumidity();
|
||||
if (String(value.valD) != "nan") regEvent(value.valD, "Dht1122h");
|
||||
else SerialPrint("E", "Sensor DHTh", "Error");
|
||||
}
|
||||
|
||||
~Dht1122h() {};
|
||||
};
|
||||
|
||||
|
||||
void* getAPI_Dht1122(String subtype, String param) {
|
||||
if (subtype == F("Dht1122t") || subtype == F("Dht1122h")) {
|
||||
int pin;
|
||||
String senstype;
|
||||
jsonRead(param, "pin", pin);
|
||||
jsonRead(param, "senstype", senstype);
|
||||
|
||||
if (dhts.find(pin) == dhts.end()) {
|
||||
dhts[pin] = new DHTesp();
|
||||
|
||||
if (senstype == "dht11") {
|
||||
dhts[pin]->setup(pin, DHTesp::DHT11);
|
||||
} else if (senstype == "dht22") {
|
||||
dhts[pin]->setup(pin, DHTesp::DHT22);
|
||||
}
|
||||
}
|
||||
|
||||
if (subtype == F("Dht1122t")) {
|
||||
return new Dht1122t(dhts[pin], param);
|
||||
} else if (subtype == F("Dht1122h")) {
|
||||
return new Dht1122h(dhts[pin], param);
|
||||
}
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
53
src/modules/sensors/Dht1122/modinfo.json
Normal file
53
src/modules/sensors/Dht1122/modinfo.json
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"menuSection": "Сенсоры",
|
||||
|
||||
"configItem": [{
|
||||
"name": "Cенсор температуры dht11",
|
||||
"type": "Reading",
|
||||
"subtype": "Dht1122t",
|
||||
"id": "tmp3",
|
||||
"widget": "anydataTmp",
|
||||
"page": "Сенсоры",
|
||||
"descr": "Температура",
|
||||
"int": 15,
|
||||
"pin": 0,
|
||||
"senstype": "dht11"
|
||||
},
|
||||
{
|
||||
"name": "Cенсор влажности dht11",
|
||||
"type": "Reading",
|
||||
"subtype": "Dht1122h",
|
||||
"id": "Hum3",
|
||||
"widget": "anydataHum",
|
||||
"page": "Сенсоры",
|
||||
"descr": "Влажность",
|
||||
"int": 15,
|
||||
"pin": 0,
|
||||
"senstype": "dht11"
|
||||
}],
|
||||
|
||||
"about": {
|
||||
"authorName": "Ilya Belyakov",
|
||||
"authorContact": "https://t.me/Biveraxe",
|
||||
"authorGit": "https://github.com/biveraxe",
|
||||
"specialThanks": "Serghei Crasnicov @Serghei63",
|
||||
"moduleName": "Dht1122",
|
||||
"moduleVersion": "1.0",
|
||||
"moduleDesc": "Позволяет получить значения температуры и влажности с dht11 или dht22.",
|
||||
"propInfo": {
|
||||
"senstype": "Тип сенсора dht11 или dht22.",
|
||||
"int": "Количество секунд между опросами датчика."
|
||||
}
|
||||
},
|
||||
|
||||
"defActive": true,
|
||||
|
||||
"devices": {
|
||||
"esp32_4mb": [
|
||||
"beegee-tokyo/DHT sensor library for ESPx"
|
||||
],
|
||||
"esp8266_4mb": [
|
||||
"beegee-tokyo/DHT sensor library for ESPx"
|
||||
]
|
||||
}
|
||||
}
|
||||
96
src/modules/sensors/Ds18b20/Ds18b20.cpp
Normal file
96
src/modules/sensors/Ds18b20/Ds18b20.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
|
||||
#include "DallasTemperature.h"
|
||||
#include <OneWire.h>
|
||||
#include <map>
|
||||
|
||||
//глобальные списки необходимы для хранения объектов об активных линиях 1-wire используемых разными датчиками из модуля. Ключ - номер пина
|
||||
std::map<int, OneWire*> oneWireTemperatureArray;
|
||||
std::map<int, DallasTemperature*> sensorsTemperatureArray;
|
||||
|
||||
class Ds18b20 : public IoTItem {
|
||||
private:
|
||||
//для работы библиотеки с несколькими линиями необходимо обеспечить каждый экземпляр класса ссылками на объекты настроенные на эти линии
|
||||
OneWire* oneWire;
|
||||
DallasTemperature* sensors;
|
||||
|
||||
//описание параметров передаваемых из настроек датчика из веба
|
||||
String _addr;
|
||||
int _pin;
|
||||
int _index;
|
||||
|
||||
public:
|
||||
//=======================================================================================================
|
||||
// setup()
|
||||
//это аналог setup из arduino. Здесь вы можете выполнять методы инициализации сенсора.
|
||||
//Такие как ...begin и подставлять в них параметры полученные из web интерфейса.
|
||||
//Все параметры хранятся в перемененной parameters, вы можете прочитать любой параметр используя jsonRead функции:
|
||||
// jsonReadStr, jsonReadBool, jsonReadInt
|
||||
Ds18b20(String parameters) : IoTItem(parameters) {
|
||||
jsonRead(parameters, "pin", _pin);
|
||||
jsonRead(parameters, "index", _index, false);
|
||||
jsonRead(parameters, "addr", _addr, false);
|
||||
|
||||
//учитываем, что библиотека может работать с несколькими линиями на разных пинах, поэтому инициируем библиотеку, если линия ранее не использовалась
|
||||
if (oneWireTemperatureArray.find(_pin) == oneWireTemperatureArray.end()) {
|
||||
oneWire = new OneWire((uint8_t)_pin);
|
||||
sensors = new DallasTemperature();
|
||||
sensors->setOneWire(oneWire);
|
||||
sensors->begin();
|
||||
sensors->setResolution(12);
|
||||
|
||||
oneWireTemperatureArray[_pin] = oneWire;
|
||||
sensorsTemperatureArray[_pin] = sensors;
|
||||
} else {
|
||||
oneWire = oneWireTemperatureArray[_pin];
|
||||
sensors = sensorsTemperatureArray[_pin];
|
||||
}
|
||||
}
|
||||
//=======================================================================================================
|
||||
// doByInterval()
|
||||
//это аналог loop из arduino, но вызываемый каждые int секунд, заданные в настройках. Здесь вы должны выполнить чтение вашего сенсора
|
||||
//а затем выполнить regEvent - это регистрация произошедшего события чтения
|
||||
//здесь так же доступны все переменные из секции переменных, и полученные в setup
|
||||
//если у сенсора несколько величин то делайте несколько regEvent
|
||||
//не используйте delay - помните, что данный loop общий для всех модулей. Если у вас планируется длительная операция, постарайтесь разбить ее на порции
|
||||
//и выполнить за несколько тактов
|
||||
void doByInterval() {
|
||||
//запускаем опрос измерений у всех датчиков на линии
|
||||
sensors->requestTemperatures();
|
||||
|
||||
//Определяем адрес. Если парамтер addr не установлен, то узнаем адрес по индексу
|
||||
// TODO: понять как лучше. в текущей реализации адрес вычисляется каждый раз при опросе шины, это хорошо при отладке,
|
||||
// но при постоянном контакте и использовании правильнее генерировать адрес при инициализации модуля. Но тогда нужно перезагружать устройство при новом датчике
|
||||
DeviceAddress deviceAddress;
|
||||
if (_addr == "") {
|
||||
sensors->getAddress(deviceAddress, _index);
|
||||
} else {
|
||||
string2hex(_addr.c_str(), deviceAddress);
|
||||
}
|
||||
//получаем температуру по адресу
|
||||
value.valD = sensors->getTempC(deviceAddress);
|
||||
|
||||
char addrStr[20] = "";
|
||||
hex2string(deviceAddress, 8, addrStr);
|
||||
|
||||
if (value.valD != -127)
|
||||
regEvent(value.valD, "addr: " + String(addrStr)); //обязательный вызов для отправки результата работы
|
||||
else
|
||||
SerialPrint("E", "Sensor Ds18b20", "Error");
|
||||
}
|
||||
//=======================================================================================================
|
||||
|
||||
~Ds18b20() {};
|
||||
};
|
||||
|
||||
//после замены названия сенсора, на функцию можно не обращать внимания
|
||||
//если сенсор предполагает использование общего объекта библиотеки для нескольких экземпляров сенсора, то в данной функции необходимо предусмотреть
|
||||
//создание и контроль соответствующих глобальных переменных
|
||||
void* getAPI_Ds18b20(String subtype, String param) {
|
||||
if (subtype == F("Ds18b20")) {
|
||||
return new Ds18b20(param);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
45
src/modules/sensors/Ds18b20/modinfo.json
Normal file
45
src/modules/sensors/Ds18b20/modinfo.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"menuSection": "Сенсоры",
|
||||
|
||||
"configItem": [{
|
||||
"name": "Cенсор температуры ds18b20",
|
||||
"type": "Reading",
|
||||
"subtype": "Ds18b20",
|
||||
"id": "dstmp",
|
||||
"widget": "anydataTmp",
|
||||
"page": "Сенсоры",
|
||||
"descr": "DS Температура",
|
||||
"int": 15,
|
||||
"pin": 2,
|
||||
"index": 0,
|
||||
"addr": "",
|
||||
"round": 1
|
||||
}],
|
||||
|
||||
"about": {
|
||||
"authorName": "Ilya Belyakov",
|
||||
"authorContact": "https://t.me/Biveraxe",
|
||||
"authorGit": "https://github.com/biveraxe",
|
||||
"specialThanks": "",
|
||||
"moduleName": "Ds18b20",
|
||||
"moduleVersion": "1.0",
|
||||
"moduleDesc": "Позволяет получить значения температуры с Ds18b20.",
|
||||
"propInfo": {
|
||||
"pin": "GPIO номер, к которому подключена шина данных датчиков.",
|
||||
"index": "Порядковый номер датчика на шине.",
|
||||
"addr": "Адрес датчика на шине для точной идентификации. Можно скопировать из консоли.",
|
||||
"int": "Количество секунд между опросами датчика."
|
||||
}
|
||||
},
|
||||
|
||||
"defActive": true,
|
||||
|
||||
"devices": {
|
||||
"esp32_4mb": [
|
||||
"milesburton/DallasTemperature@^3.9.1"
|
||||
],
|
||||
"esp8266_4mb": [
|
||||
"milesburton/DallasTemperature@^3.9.1"
|
||||
]
|
||||
}
|
||||
}
|
||||
72
src/modules/sensors/Emon/Emon.cpp
Normal file
72
src/modules/sensors/Emon/Emon.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
/******************************************************************
|
||||
Used Energy Monitoring Library
|
||||
|
||||
https://github.com/openenergymonitor/EmonLib
|
||||
|
||||
adapted for version 4 @Serghei63
|
||||
******************************************************************/
|
||||
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
#include <map>
|
||||
|
||||
extern IoTGpio IoTgpio;
|
||||
|
||||
#include "EmonLib.h" // Include Emon Library
|
||||
|
||||
EnergyMonitor emon1; // Create an instance
|
||||
|
||||
|
||||
class Energy : public IoTItem {
|
||||
|
||||
private:
|
||||
unsigned int _pinI; // ток
|
||||
unsigned int _calibI; // ток
|
||||
|
||||
public:
|
||||
Energy(String parameters): IoTItem(parameters) {
|
||||
_pinI = jsonReadInt(parameters, "pin_I");
|
||||
_calibI = jsonReadInt(parameters, "calib_I");
|
||||
emon1.current(_pinI, _calibI); // Current: input pin, calibration.
|
||||
}
|
||||
|
||||
void doByInterval() {
|
||||
value.valD = emon1.calcIrms(1480); // Calculate Irms only
|
||||
regEvent(value.valD, "current");
|
||||
}
|
||||
|
||||
~Energy(){};
|
||||
};
|
||||
|
||||
|
||||
class Power : public IoTItem {
|
||||
|
||||
private:
|
||||
unsigned int _pinU; // напряжение
|
||||
unsigned int _calibU; // напряжение
|
||||
|
||||
public:
|
||||
Power(String parameters): IoTItem(parameters) {
|
||||
_pinU = jsonReadInt(parameters, "pin_U");
|
||||
_calibU = jsonReadInt(parameters, "calib_U");
|
||||
emon1.voltage(_pinU, _calibU, 1.7); // Voltage: input pin, calibration, phase_shift
|
||||
}
|
||||
|
||||
void doByInterval() {
|
||||
if (emon1.Irms > 0) emon1.calcVI(10, 1000); // Calculate all. No.of half wavelengths (crossings), time-out при условии, что ток не нулевой
|
||||
value.valD = emon1.Vrms; //extract Vrms into Variable;
|
||||
regEvent(value.valD, "voltage");
|
||||
}
|
||||
|
||||
~Power(){};
|
||||
};
|
||||
|
||||
void* getAPI_Emon(String subtype, String param) {
|
||||
if (subtype == F("I")) {
|
||||
return new Energy(param);
|
||||
} else if (subtype == F("U")) {
|
||||
return new Power(param);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
60
src/modules/sensors/Emon/modinfo.json
Normal file
60
src/modules/sensors/Emon/modinfo.json
Normal file
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"menuSection": "Сенсоры",
|
||||
|
||||
"configItem": [{
|
||||
"name": "Датчик тока",
|
||||
"type": "Reading",
|
||||
"subtype": "I",
|
||||
"id": "current",
|
||||
"widget": "anydataAmp",
|
||||
"page": "Сенсоры",
|
||||
"descr": "Датчик тока",
|
||||
"int": 10,
|
||||
"pin_I": 34,
|
||||
"calib_I": 111.1,
|
||||
"plus": 0,
|
||||
"multiply": 1
|
||||
},
|
||||
{
|
||||
"name": "Датчик напряжения",
|
||||
"type": "Reading",
|
||||
"subtype": "U",
|
||||
"id": "voltage",
|
||||
"widget": "anydataVlt",
|
||||
"page": "Сенсоры",
|
||||
"descr": "Датчик напряжения",
|
||||
"int": 10,
|
||||
"pin_U": 35,
|
||||
"calib_U": 223.1,
|
||||
"plus": 0,
|
||||
"multiply": 1
|
||||
}],
|
||||
|
||||
"about": {
|
||||
"authorName": "Serghei Crasnicov",
|
||||
"authorContact": "https://t.me/Serghei63",
|
||||
"authorGit": "https://github.com/Serghei63",
|
||||
"specialThanks": "",
|
||||
"moduleName": "Emon",
|
||||
"moduleVersion": "1.0",
|
||||
"moduleDesc": ".",
|
||||
"propInfo": {
|
||||
"pin_U": "",
|
||||
"calib_U": "",
|
||||
"pin_I": "",
|
||||
"calib_I": "",
|
||||
"int": "Количество секунд между опросами датчика."
|
||||
}
|
||||
},
|
||||
|
||||
"defActive": false,
|
||||
|
||||
"devices": {
|
||||
"esp32_4mb": [
|
||||
"openenergymonitor/EmonLib@1.1.0"
|
||||
],
|
||||
"esp8266_4mb": [
|
||||
"openenergymonitor/EmonLib@1.1.0"
|
||||
]
|
||||
}
|
||||
}
|
||||
59
src/modules/sensors/GY21/GY21.cpp
Normal file
59
src/modules/sensors/GY21/GY21.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
/******************************************************************
|
||||
Used GY21 Driver (temperature and humidity sensor)
|
||||
Support for HTY21 , SHT21 , Si7021
|
||||
https://github.com/adafruit/Adafruit_AHTX0
|
||||
|
||||
adapted for version 4 Alecs Alecs
|
||||
******************************************************************/
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
|
||||
#include "Wire.h"
|
||||
#include "GY21.h"
|
||||
|
||||
GY21* sensor = nullptr;
|
||||
|
||||
class GY21t : public IoTItem {
|
||||
public:
|
||||
GY21t(String parameters): IoTItem(parameters) { }
|
||||
|
||||
void doByInterval() {
|
||||
//wire->read();
|
||||
value.valD = sensor->GY21_Temperature();
|
||||
if (value.valD < 300) regEvent(value.valD, "GY21"); // TODO: найти способ понимания ошибки получения данных
|
||||
else SerialPrint("E", "Sensor GY21t", "Error");
|
||||
}
|
||||
|
||||
~GY21t() {};
|
||||
};
|
||||
|
||||
class GY21h : public IoTItem {
|
||||
public:
|
||||
GY21h(String parameters): IoTItem(parameters) { }
|
||||
|
||||
void doByInterval() {
|
||||
//sht->read();
|
||||
value.valD = sensor->GY21_Humidity();
|
||||
if (value.valD != 0) regEvent(value.valD, "GY21h"); // TODO: найти способ понимания ошибки получения данных
|
||||
else SerialPrint("E", "Sensor GY21h", "Error");
|
||||
}
|
||||
|
||||
~GY21h() {};
|
||||
};
|
||||
|
||||
void* getAPI_GY21(String subtype, String param) {
|
||||
if (subtype == F("GY21t") || subtype == F("GY21h")) {
|
||||
if (!sensor) {
|
||||
sensor = new GY21;
|
||||
if (sensor) Wire.begin(SDA, SCL);
|
||||
}
|
||||
|
||||
if (subtype == F("GY21t")) {
|
||||
return new GY21t(param);
|
||||
} else if (subtype == F("GY21h")) {
|
||||
return new GY21h(param);
|
||||
}
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
50
src/modules/sensors/GY21/modinfo.json
Normal file
50
src/modules/sensors/GY21/modinfo.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"menuSection": "Сенсоры",
|
||||
|
||||
"configItem": [{
|
||||
"name": "Cенсор температуры GY21",
|
||||
"type": "Reading",
|
||||
"subtype": "GY21t",
|
||||
"id": "tmp4",
|
||||
"widget": "anydataTmp",
|
||||
"page": "Сенсоры",
|
||||
"descr": "Температура",
|
||||
"round": 1,
|
||||
"int": 15
|
||||
},
|
||||
{
|
||||
"name": "Cенсор влажности GY21",
|
||||
"type": "Reading",
|
||||
"subtype": "GY21h",
|
||||
"id": "Hum4",
|
||||
"widget": "anydataHum",
|
||||
"page": "Сенсоры",
|
||||
"descr": "Влажность",
|
||||
"round": 1,
|
||||
"int": 15
|
||||
}],
|
||||
|
||||
"about": {
|
||||
"authorName": "Alecs",
|
||||
"authorContact": "https://t.me/Alecs",
|
||||
"authorGit": "",
|
||||
"specialThanks": "",
|
||||
"moduleName": "GY21",
|
||||
"moduleVersion": "1.0",
|
||||
"moduleDesc": "Позволяет получить значения температуры и влажности с GY21.",
|
||||
"propInfo": {
|
||||
"int": "Количество секунд между опросами датчика."
|
||||
}
|
||||
},
|
||||
|
||||
"defActive": true,
|
||||
|
||||
"devices": {
|
||||
"esp32_4mb": [
|
||||
"https://github.com/JonasGMorsch/GY-21.git"
|
||||
],
|
||||
"esp8266_4mb": [
|
||||
"https://github.com/JonasGMorsch/GY-21.git"
|
||||
]
|
||||
}
|
||||
}
|
||||
58
src/modules/sensors/Hdc1080/Hdc1080.cpp
Normal file
58
src/modules/sensors/Hdc1080/Hdc1080.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
/******************************************************************
|
||||
Used ClosedCube HDC1080 Driver (temperature and humidity sensor)
|
||||
Support for HDC1080
|
||||
https://github.com/closedcube/ClosedCube_HDC1080_Arduino
|
||||
|
||||
adapted for version 4 @Serghei63
|
||||
******************************************************************/
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
|
||||
#include "Wire.h"
|
||||
#include "ClosedCube_HDC1080.h"
|
||||
#include <map>
|
||||
|
||||
// to do убрать глобальный экземпляр
|
||||
ClosedCube_HDC1080 hdc1080;
|
||||
|
||||
class Hdc1080t : public IoTItem {
|
||||
public:
|
||||
Hdc1080t(String parameters) : IoTItem(parameters) {}
|
||||
|
||||
void doByInterval() {
|
||||
value.valD = hdc1080.readTemperature();
|
||||
if (value.valD < 124)
|
||||
regEvent(value.valD, "Hdc1080t");
|
||||
else
|
||||
SerialPrint("E", "Sensor Hdc1080t", "Error");
|
||||
}
|
||||
|
||||
~Hdc1080t(){};
|
||||
};
|
||||
|
||||
class Hdc1080h : public IoTItem {
|
||||
public:
|
||||
Hdc1080h(String parameters) : IoTItem(parameters) {}
|
||||
|
||||
void doByInterval() {
|
||||
value.valD = hdc1080.readHumidity();
|
||||
if (value.valD < 99)
|
||||
regEvent(value.valD, "Hdc1080h");
|
||||
else
|
||||
SerialPrint("E", "Sensor Hdc1080h", "Error");
|
||||
}
|
||||
|
||||
~Hdc1080h(){};
|
||||
};
|
||||
|
||||
void* getAPI_Hdc1080(String subtype, String param) {
|
||||
if (subtype == F("Hdc1080t")) {
|
||||
hdc1080.begin(0x40);
|
||||
return new Hdc1080t(param);
|
||||
} else if (subtype == F("Hdc1080h")) {
|
||||
hdc1080.begin(0x40);
|
||||
return new Hdc1080h(param);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
53
src/modules/sensors/Hdc1080/modinfo.json
Normal file
53
src/modules/sensors/Hdc1080/modinfo.json
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"menuSection": "Сенсоры",
|
||||
|
||||
"configItem": [{
|
||||
"name": "Cенсор температуры HDC1080",
|
||||
"type": "Reading",
|
||||
"subtype": "Hdc1080t",
|
||||
"id": "Temp1080",
|
||||
"widget": "anydataTmp",
|
||||
"page": "Сенсоры",
|
||||
"descr": "1080 Температура",
|
||||
"int": 15,
|
||||
"addr": "0x40",
|
||||
"round": 1
|
||||
},
|
||||
{
|
||||
"name": "Cенсор влажности HDC1080",
|
||||
"type": "Reading",
|
||||
"subtype": "Hdc1080h",
|
||||
"id": "Hum1080",
|
||||
"widget": "anydataHum",
|
||||
"page": "Сенсоры",
|
||||
"descr": "1080 Влажность",
|
||||
"int": 15,
|
||||
"addr": "0x40",
|
||||
"round": 1
|
||||
}],
|
||||
|
||||
"about": {
|
||||
"authorName": "Serghei Crasnicov",
|
||||
"authorContact": "https://t.me/Serghei63",
|
||||
"authorGit": "https://github.com/Serghei63",
|
||||
"specialThanks": "",
|
||||
"moduleName": "Hdc1080",
|
||||
"moduleVersion": "1.0",
|
||||
"moduleDesc": "Позволяет получить значения температуры и влажности с Hdc1080.",
|
||||
"propInfo": {
|
||||
"addr": "Адрес датчика на шине данных, обычно 0x40",
|
||||
"int": "Количество секунд между опросами датчика."
|
||||
}
|
||||
},
|
||||
|
||||
"defActive": true,
|
||||
|
||||
"devices": {
|
||||
"esp32_4mb": [
|
||||
"ClosedCube HDC1080"
|
||||
],
|
||||
"esp8266_4mb": [
|
||||
"ClosedCube HDC1080"
|
||||
]
|
||||
}
|
||||
}
|
||||
78
src/modules/sensors/IoTWiegand/IoTWiegand.cpp
Normal file
78
src/modules/sensors/IoTWiegand/IoTWiegand.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
|
||||
#include <WiegandNG.h>
|
||||
|
||||
#define PIN_D0 D5
|
||||
#define PIN_D1 D6
|
||||
|
||||
WiegandNG wg;
|
||||
|
||||
void PrintBinary(WiegandNG &tempwg) {
|
||||
volatile unsigned char *buffer=tempwg.getRawData();
|
||||
unsigned int bufferSize = tempwg.getBufferSize();
|
||||
unsigned int countedBits = tempwg.getBitCounted();
|
||||
|
||||
unsigned int countedBytes = (countedBits/8);
|
||||
if ((countedBits % 8)>0) countedBytes++;
|
||||
// unsigned int bitsUsed = countedBytes * 8;
|
||||
|
||||
for (unsigned int i=bufferSize-countedBytes; i< bufferSize;i++) {
|
||||
unsigned char bufByte=buffer[i];
|
||||
for(int x=0; x<8;x++) {
|
||||
if ( (((bufferSize-i) *8)-x) <= countedBits) {
|
||||
if((bufByte & 0x80)) {
|
||||
Serial.print("1");
|
||||
}
|
||||
else {
|
||||
Serial.print("0");
|
||||
}
|
||||
}
|
||||
bufByte<<=1;
|
||||
}
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
class IoTWiegand : public IoTItem {
|
||||
|
||||
public:
|
||||
IoTWiegand(String parameters) : IoTItem(parameters) {
|
||||
// int pinD0;
|
||||
// int pinD1;
|
||||
|
||||
// jsonRead(parameters, "pinD0", pinD0);
|
||||
// jsonRead(parameters, "pinD1", pinD1);
|
||||
|
||||
unsigned int pinD0 = D5;
|
||||
unsigned int pinD1 = D6;
|
||||
unsigned int wiegandbits = 48;
|
||||
unsigned int packetGap = 15; // 25 ms between packet
|
||||
|
||||
// if(!wg.begin(pinD0, pinD1, wiegandbits, packetGap)) {
|
||||
// Serial.println("Out of memory!");
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if(wg.available()) {
|
||||
wg.pause(); // pause Wiegand pin interrupts
|
||||
Serial.print("Bits=");
|
||||
Serial.println(wg.getBitCounted()); // display the number of bits counted
|
||||
Serial.print("RAW Binary=");
|
||||
PrintBinary(wg); // display raw data in binary form, raw data inclusive of PARITY
|
||||
wg.clear(); // compulsory to call clear() to enable interrupts for subsequent data
|
||||
}
|
||||
}
|
||||
|
||||
~IoTWiegand(){};
|
||||
};
|
||||
|
||||
void* getAPI_IoTWiegand(String subtype, String param) {
|
||||
if (subtype == F("IoTWiegand")) {
|
||||
return new IoTWiegand(param);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
42
src/modules/sensors/IoTWiegand/modinfo.json
Normal file
42
src/modules/sensors/IoTWiegand/modinfo.json
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"menuSection": "Сенсоры",
|
||||
|
||||
"configItem": [{
|
||||
"name": "Считыватель Wiegand",
|
||||
"type": "Reading",
|
||||
"subtype": "IoTWiegand",
|
||||
"id": "wg",
|
||||
"widget": "anydataTmp",
|
||||
"page": "Сенсоры",
|
||||
"descr": "Считыватель",
|
||||
"int": 0,
|
||||
"pinD0": 13,
|
||||
"pinD1": 12
|
||||
}],
|
||||
|
||||
"about": {
|
||||
"authorName": "Ilya Belyakov",
|
||||
"authorContact": "https://t.me/Biveraxe",
|
||||
"authorGit": "https://github.com/biveraxe",
|
||||
"specialThanks": "",
|
||||
"moduleName": "IoTWiegand",
|
||||
"moduleVersion": "1.0",
|
||||
"moduleDesc": "Позволяет получить коды доступа по протоколу Wiegand с различных считывателей. На данный момент модуль в РАЗРАБОТКЕ",
|
||||
"propInfo": {
|
||||
"pinD0": "GPIO шины данных",
|
||||
"pinD1": "GPIO шины данных",
|
||||
"int": "Количество секунд между опросами датчика."
|
||||
}
|
||||
},
|
||||
|
||||
"defActive": false,
|
||||
|
||||
"devices": {
|
||||
"esp32_4mb": [
|
||||
"https://github.com/jpliew/Wiegand-NG-Multi-Bit-Wiegand-Library-for-Arduino"
|
||||
],
|
||||
"esp8266_4mb": [
|
||||
"https://github.com/jpliew/Wiegand-NG-Multi-Bit-Wiegand-Library-for-Arduino"
|
||||
]
|
||||
}
|
||||
}
|
||||
45
src/modules/sensors/Max6675/Max6675.cpp
Normal file
45
src/modules/sensors/Max6675/Max6675.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
/******************************************************************
|
||||
Used MAX6675 Driver (temperature sensor)
|
||||
Support for MAX6675
|
||||
|
||||
https://github.com/adafruit/MAX6675-library
|
||||
|
||||
adapted for version 4 @Serghei63
|
||||
******************************************************************/
|
||||
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
|
||||
#include "max6675.h"
|
||||
#include <map>
|
||||
|
||||
MAX6675* thermocouple = nullptr;
|
||||
|
||||
class MAX6675t : public IoTItem {
|
||||
public:
|
||||
MAX6675t(String parameters) : IoTItem(parameters) {
|
||||
int thermoDO = jsonReadInt(parameters, "DO");
|
||||
int thermoCS = jsonReadInt(parameters, "CS");
|
||||
int thermoCLK = jsonReadInt(parameters, "CLK");
|
||||
thermocouple = new MAX6675(thermoCLK, thermoCS, thermoDO);
|
||||
}
|
||||
|
||||
void doByInterval() {
|
||||
value.valD = thermocouple->readCelsius();
|
||||
if (String(value.valD) != "nan") {
|
||||
regEvent(value.valD, "Max6675t");
|
||||
} else {
|
||||
SerialPrint("E", "Sensor Max6675t", "Error");
|
||||
}
|
||||
}
|
||||
|
||||
~MAX6675t(){};
|
||||
};
|
||||
|
||||
void* getAPI_Max6675(String subtype, String param) {
|
||||
if (subtype == F("Max6675t")) {
|
||||
return new MAX6675t(param);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
44
src/modules/sensors/Max6675/modinfo.json
Normal file
44
src/modules/sensors/Max6675/modinfo.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"menuSection": "Сенсоры",
|
||||
|
||||
"configItem": [{
|
||||
"name": "Cенсор температуры MAX6675",
|
||||
"type": "Reading",
|
||||
"subtype": "Max6675t",
|
||||
"id": "maxtmp",
|
||||
"widget": "anydataTmp",
|
||||
"page": "Сенсоры",
|
||||
"descr": "MAX Температура",
|
||||
"int": 15,
|
||||
"DO": 12,
|
||||
"CS": 13,
|
||||
"CLK": 14
|
||||
}],
|
||||
|
||||
"about": {
|
||||
"authorName": "Serghei Crasnicov",
|
||||
"authorContact": "https://t.me/Serghei63",
|
||||
"authorGit": "https://github.com/Serghei63",
|
||||
"specialThanks": "",
|
||||
"moduleName": "Max6675",
|
||||
"moduleVersion": "1.0",
|
||||
"moduleDesc": "Позволяет получить значения температуры с Max6675.",
|
||||
"propInfo": {
|
||||
"DO": "GPIO шины данных",
|
||||
"CS": "GPIO шины данных",
|
||||
"CLK": "GPIO шины данных",
|
||||
"int": "Количество секунд между опросами датчика."
|
||||
}
|
||||
},
|
||||
|
||||
"defActive": true,
|
||||
|
||||
"devices": {
|
||||
"esp32_4mb": [
|
||||
"adafruit/MAX6675 library"
|
||||
],
|
||||
"esp8266_4mb": [
|
||||
"adafruit/MAX6675 library"
|
||||
]
|
||||
}
|
||||
}
|
||||
546
src/modules/sensors/Mhz19/Mhz19.cpp
Normal file
546
src/modules/sensors/Mhz19/Mhz19.cpp
Normal file
@@ -0,0 +1,546 @@
|
||||
/******************************************************************
|
||||
Support for MHZ19
|
||||
|
||||
adapted for version 4 @cmche
|
||||
******************************************************************/
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
|
||||
//встроена в ядро для 8266, для 32 по этому же имени обращаемся к другой библиотеке plerup/EspSoftwareSerial
|
||||
#include <SoftwareSerial.h>
|
||||
|
||||
extern IoTGpio IoTgpio;
|
||||
|
||||
int rxPinCO2 = 14; // D5 // зеленый провод сенсора к D2 / 4
|
||||
int txPinCO2 = 16; // D0 // синий провод сенсора к D1/5
|
||||
SoftwareSerial swSerialCO2(rxPinCO2, txPinCO2); // RX, TX// ESP8266 D7 / D6 Blue/Green
|
||||
|
||||
int MHZ19_request(int request);
|
||||
|
||||
void MHZ19uart_init();
|
||||
|
||||
bool MHZ19uart_flag = true;
|
||||
// int MHZ19C_PREHEATING_TIME = 2 * 60 * 1000;// покажет реальные данные после прогрева, через 2 мин.
|
||||
int MHZ19C_PREHEATING_TIME = 2 * 30 * 1000; // покажет реальные данные после прогрева, через 2 мин.
|
||||
|
||||
// int prevTemperature = 0;
|
||||
int temperature = 0;
|
||||
bool temperatureUpdated = false;
|
||||
int prevRange = 5000;
|
||||
int range = 5000; // по умолнчанию стоит шкала 5000 (не 2000 как в мануале)
|
||||
bool rangeChaged = false;
|
||||
int prevABC = 1;
|
||||
int ABC = 1;
|
||||
bool ABCchanged = false;
|
||||
|
||||
//Это файл сенсора, в нем осуществляется чтение сенсора.
|
||||
|
||||
class Mhz19uart : public IoTItem {
|
||||
private:
|
||||
//=======================================================================================================
|
||||
// Секция переменных.
|
||||
|
||||
public:
|
||||
//=======================================================================================================
|
||||
|
||||
Mhz19uart(String parameters) : IoTItem(parameters) {
|
||||
rxPinCO2 = jsonReadInt(parameters, "rxPin");
|
||||
txPinCO2 = jsonReadInt(parameters, "txPin");
|
||||
range = jsonReadInt(parameters, "range");
|
||||
ABC = jsonReadInt(parameters, "ABC");
|
||||
}
|
||||
//=======================================================================================================
|
||||
// doByInterval()
|
||||
|
||||
void doByInterval() {
|
||||
MHZ19uart_init();
|
||||
if (millis() > MHZ19C_PREHEATING_TIME) {
|
||||
Serial.println("Start checkUARTCO2");
|
||||
value.valD = MHZ19_request(1);
|
||||
}
|
||||
regEvent(value.valD, "Mhz19uart"); //обязательный вызов хотяб один
|
||||
}
|
||||
//=======================================================================================================
|
||||
|
||||
~Mhz19uart(){};
|
||||
};
|
||||
|
||||
//после замены названия сенсора, на функцию можно не обращать внимания
|
||||
//если сенсор предполагает использование общего объекта библиотеки для нескольких экземпляров сенсора, то в данной функции необходимо предусмотреть
|
||||
//создание и контроль соответствующих глобальных переменных
|
||||
|
||||
class Mhz19pwm : public IoTItem {
|
||||
private:
|
||||
//=======================================================================================================
|
||||
// Секция переменных.
|
||||
int pwmPin; ///// желтый провод сенсора к D8 (14-D5 ok)
|
||||
|
||||
public:
|
||||
//=======================================================================================================
|
||||
|
||||
Mhz19pwm(String parameters) : IoTItem(parameters) {
|
||||
pwmPin = jsonReadInt(parameters, "pin");
|
||||
}
|
||||
//=======================================================================================================
|
||||
|
||||
void doByInterval() {
|
||||
MHZ19pwm_init();
|
||||
if (millis() > MHZ19C_PREHEATING_TIME) //
|
||||
{
|
||||
Serial.println("Start checkPWM_CO2");
|
||||
value.valD = MHZ19pwm_request();
|
||||
}
|
||||
regEvent(value.valD, "Mhz19pwm"); //обязательный вызов хотяб один
|
||||
}
|
||||
//=======================================================================================================
|
||||
|
||||
void MHZ19pwm_init() {
|
||||
static bool MHZ19pwm_flag = true;
|
||||
if (MHZ19pwm_flag) {
|
||||
pinMode(pwmPin, INPUT);
|
||||
MHZ19pwm_flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
int MHZ19pwm_request() {
|
||||
int reply;
|
||||
Serial.println("Запрос замера по PWM запущен");
|
||||
unsigned long th, tl, ppm = 0, ppm2 = 0, ppm3 = 0;
|
||||
do {
|
||||
th = pulseIn(pwmPin, HIGH, 1004000) / 1000;
|
||||
tl = 1004 - th;
|
||||
ppm2 = 2000 * (th - 2) / (th + tl - 4); // расчёт для диапазона от 0 до 2000ppm
|
||||
ppm3 = 5000 * (th - 2) / (th + tl - 4); // расчёт для диапазона от 0 до 5000ppm
|
||||
} while (th == 0);
|
||||
|
||||
// Serial.print(th);
|
||||
// Serial.println(" <- Milliseconds PWM is HIGH");
|
||||
|
||||
if (range == 2000) {
|
||||
reply = ppm2;
|
||||
Serial.print(ppm2);
|
||||
Serial.println(" <- ppm2 (PWM) with 2000ppm as limit");
|
||||
} else {
|
||||
reply = ppm3;
|
||||
Serial.print(ppm3);
|
||||
Serial.println(" <- ppm3 (PWM) with 5000ppm as limit");
|
||||
}
|
||||
Serial.println("Completed checkPwmCO2");
|
||||
return reply;
|
||||
}
|
||||
|
||||
~Mhz19pwm(){};
|
||||
};
|
||||
|
||||
//====================TEMP===================================================================================
|
||||
|
||||
class Mhz19temp : public IoTItem {
|
||||
private:
|
||||
//=======================================================================================================
|
||||
// Секция переменных.
|
||||
public:
|
||||
//====================TEMP===================================================================================
|
||||
|
||||
Mhz19temp(String parameters) : IoTItem(parameters) {
|
||||
rxPinCO2 = jsonReadInt(parameters, "rxPin");
|
||||
txPinCO2 = jsonReadInt(parameters, "txPin");
|
||||
range = jsonReadInt(parameters, "range");
|
||||
ABC = jsonReadInt(parameters, "ABC");
|
||||
}
|
||||
//=======================================================================================================
|
||||
|
||||
void doByInterval() {
|
||||
// Serial.println("Start Mhz19temp doByInterval");
|
||||
if (temperatureUpdated) {
|
||||
value.valD = temperature;
|
||||
temperatureUpdated = false;
|
||||
} else {
|
||||
MHZ19uart_init();
|
||||
Serial.println("Start temperature request");
|
||||
if (MHZ19_request(13)) {
|
||||
value.valD = temperature;
|
||||
}; // change
|
||||
}
|
||||
regEvent(value.valD, "Mhz19temp"); //обязательный вызов хотяб один
|
||||
}
|
||||
//=======================================================================================================
|
||||
|
||||
//=======================================================================================================
|
||||
|
||||
~Mhz19temp(){};
|
||||
};
|
||||
|
||||
//=======================Range================
|
||||
class Mhz19range : public IoTItem {
|
||||
private:
|
||||
public:
|
||||
Mhz19range(String parameters) : IoTItem(parameters) {
|
||||
rxPinCO2 = jsonReadInt(parameters, "rxPin");
|
||||
txPinCO2 = jsonReadInt(parameters, "txPin");
|
||||
range = jsonReadInt(parameters, "range");
|
||||
ABC = jsonReadInt(parameters, "ABC");
|
||||
}
|
||||
|
||||
void doByInterval() {
|
||||
if (range != prevRange) {
|
||||
MHZ19uart_init();
|
||||
Serial.println("Start change range");
|
||||
|
||||
if (range == 2000) {
|
||||
if (MHZ19_request(9)) {
|
||||
prevRange = 2000;
|
||||
value.valD = 2000;
|
||||
} // change range to 2000
|
||||
} else {
|
||||
if (MHZ19_request(10)) {
|
||||
prevRange = 5000;
|
||||
value.valD = 5000;
|
||||
} // change range to 5000
|
||||
}
|
||||
} else {
|
||||
value.valD = prevRange;
|
||||
}
|
||||
regEvent(value.valD, "Mhz19range"); //обязательный вызов хотяб один
|
||||
}
|
||||
|
||||
~Mhz19range(){};
|
||||
};
|
||||
|
||||
//===================ABC=================
|
||||
|
||||
class Mhz19ABC : public IoTItem {
|
||||
private:
|
||||
public:
|
||||
Mhz19ABC(String parameters) : IoTItem(parameters) {
|
||||
rxPinCO2 = jsonReadInt(parameters, "rxPin");
|
||||
txPinCO2 = jsonReadInt(parameters, "txPin");
|
||||
range = jsonReadInt(parameters, "range");
|
||||
ABC = jsonReadInt(parameters, "ABC");
|
||||
}
|
||||
|
||||
void doByInterval() {
|
||||
if (ABC != prevABC) {
|
||||
if (ABC == 1) {
|
||||
if (MHZ19_request(7)) {
|
||||
prevABC = 1;
|
||||
value.valD = 1;
|
||||
} // change ABC to 1
|
||||
} else {
|
||||
if (MHZ19_request(8)) {
|
||||
prevABC = 0;
|
||||
value.valD = 0;
|
||||
} // change ABC to 0
|
||||
}
|
||||
} else {
|
||||
value.valD = prevABC;
|
||||
}
|
||||
regEvent(value.valD, "Mhz19ABC"); //обязательный вызов хотяб один
|
||||
}
|
||||
|
||||
~Mhz19ABC(){};
|
||||
};
|
||||
|
||||
///============== end of classes==========================
|
||||
|
||||
void *getAPI_Mhz19(String subtype, String param) {
|
||||
if (subtype == F("Mhz19uart")) {
|
||||
return new Mhz19uart(param);
|
||||
} else if (subtype == F("Mhz19pwm")) {
|
||||
return new Mhz19pwm(param);
|
||||
} else if (subtype == F("Mhz19temp")) {
|
||||
return new Mhz19temp(param);
|
||||
} else if (subtype == F("Mhz19range")) {
|
||||
return new Mhz19range(param);
|
||||
} else if (subtype == F("Mhz19ABC")) {
|
||||
return new Mhz19ABC(param);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void MHZ19uart_init() {
|
||||
if (MHZ19uart_flag) {
|
||||
int reply;
|
||||
swSerialCO2.begin(9600);
|
||||
|
||||
delay(50);
|
||||
|
||||
reply = MHZ19_request(2); // show range, for test of uart only
|
||||
Serial.print("show range reply = ");
|
||||
Serial.println(reply);
|
||||
|
||||
if (reply) {
|
||||
MHZ19uart_flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!MHZ19uart_flag) {
|
||||
static int prevABC;
|
||||
int reply;
|
||||
|
||||
if (ABC != prevABC) {
|
||||
if (ABC) {
|
||||
reply = MHZ19_request(7); // ABC on
|
||||
} else {
|
||||
reply = MHZ19_request(8); // ABC off
|
||||
}
|
||||
Serial.print("ABC change reply = ");
|
||||
Serial.println(reply);
|
||||
}
|
||||
if (reply) {
|
||||
prevABC = ABC;
|
||||
}
|
||||
}
|
||||
|
||||
static bool MHZ19_range_flag = true;
|
||||
if (MHZ19_range_flag && !MHZ19uart_flag && (millis() > 30 * 1000)) {
|
||||
int reply;
|
||||
if (range == 2000) {
|
||||
reply = MHZ19_request(9); // Установка шкалы 0-2000
|
||||
// 255 155 0 0 7 208 0 3 139
|
||||
} else {
|
||||
reply = MHZ19_request(10); // Установка шкалы 0-5000
|
||||
// 255 155 0 0 19 136 0 3 199
|
||||
}
|
||||
Serial.print("Scale change reply = ");
|
||||
Serial.println(reply);
|
||||
if (reply) {
|
||||
reply = MHZ19_request(2); // show range
|
||||
Serial.print("show range reply = ");
|
||||
Serial.println(reply);
|
||||
|
||||
MHZ19_range_flag = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int MHZ19_request(int request) {
|
||||
int reply;
|
||||
Serial.print("prevRange = ");
|
||||
Serial.println(prevRange);
|
||||
|
||||
byte uartReqSamplePpm[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79}; // PPM
|
||||
// 255 1 134 0 0 0 0 0 121
|
||||
// Response 255 134 1 148 67 0 0 0 162
|
||||
|
||||
byte uartReqSampleABCon[9] = {0xFF, 0x01, 0x79, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xE6}; // ABC logic on
|
||||
// 255 1 121 160 0 0 0 0 230
|
||||
// Response 255 121 1 0 0 0 0 0 134
|
||||
byte uartReqSampleABCoff[9] = {0xFF, 0x01, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86}; // ABC logic off
|
||||
byte uartReqSampleABCstatus[9] = {0xFF, 0x01, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82}; // ABC logic status
|
||||
|
||||
byte uartReqSample1000Range[9] = {0xFF, 0x01, 0x99, 0x00, 0x00, 0x00, 0x03, 0xE8, 0x7B};
|
||||
byte uartReqSample2000Range[9] = {0xFF, 0x01, 0x99, 0x00, 0x00, 0x00, 0x07, 0xD0, 0x8F}; // задаёт диапазон 0 - 2000ppm
|
||||
byte uartReqSample3000Range[9] = {0xFF, 0x01, 0x99, 0x00, 0x00, 0x00, 0x0B, 0xB8, 0xA3}; // задаёт диапазон 0 - 2000ppm
|
||||
|
||||
byte uartReqSample5000Range[9] = {0xFF, 0x01, 0x99, 0x00, 0x00, 0x00, 0x13, 0x88, 0xCB}; // задаёт диапазон 0 - 5000ppm
|
||||
// 255 1 153 0 0 0 19 136 203
|
||||
// Response 255 153 1 0 0 0 0 0 102
|
||||
byte uartReqSampleRequestRange[9] = {0xFF, 0x01, 0x9B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64}; // запрос диапазона
|
||||
// request // 255 1 155 0 0 0 0 0 100
|
||||
// reply // 255 1 155 0 0 0 0 0 100
|
||||
byte uartReqSampleZeroPnt[9] = {0xFF, 0x01, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78}; // !!ZERO POINT CALIBRATION
|
||||
byte uartReqSampleReset[9] = {0xFF, 0x01, 0x8D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72}; // reset
|
||||
|
||||
byte uartReqSampleReset1[9] = {0xFF, 0x01, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87}; // reset - did not work out
|
||||
|
||||
byte request_cmd[9];
|
||||
// byte c;
|
||||
switch (request) {
|
||||
// случаи 3-7 для перезапуска сенсора
|
||||
case 1: {
|
||||
Serial.println("Запрос No.1 - отправлен. Запрос замера по UART");
|
||||
for (int i = 0; i < 9; i++) {
|
||||
request_cmd[i] = uartReqSamplePpm[i];
|
||||
}
|
||||
} break;
|
||||
|
||||
case 2: {
|
||||
for (int i = 0; i < 9; i++) {
|
||||
request_cmd[i] = uartReqSampleRequestRange[i];
|
||||
}
|
||||
Serial.println("Запрос No.2 - отправлен. Запрос шкалы");
|
||||
} break;
|
||||
|
||||
case 3: {
|
||||
// код для запуска сенсора с работой по UART (запуск таймера)
|
||||
Serial.println("Запрос No.3 - отправлен. Сенсор по UART запущен");
|
||||
} break;
|
||||
case 4: {
|
||||
// код для остановке сенсора с работой по UART (остановка таймера)
|
||||
Serial.println("Запрос No.4 - отправлен. Сенсор по UART остановлен");
|
||||
} break;
|
||||
case 5: {
|
||||
// код для запуска сенсора с работой по PWM (запуск таймера)
|
||||
Serial.println("Запрос No.5 - отправлен. Сенсор по PWM запущен");
|
||||
} break;
|
||||
case 6: {
|
||||
// код для остановки сенсора с работой по PWM (остановка таймера)
|
||||
Serial.println("Запрос No.6 - отправлен. Сенсор по PWM остановлен");
|
||||
} break;
|
||||
case 7: {
|
||||
for (int i = 0; i < 9; i++) {
|
||||
request_cmd[i] = uartReqSampleABCon[i];
|
||||
}
|
||||
Serial.println("Запрос No.7 - отправлен. Включаем функцию атокалибровки");
|
||||
} break;
|
||||
case 8: {
|
||||
for (int i = 0; i < 9; i++) {
|
||||
request_cmd[i] = uartReqSampleABCoff[i];
|
||||
}
|
||||
Serial.println("Запрос No.8 - отправлен. Выключаем функцию атокалибровки");
|
||||
} break;
|
||||
case 9: {
|
||||
for (int i = 0; i < 9; i++) {
|
||||
request_cmd[i] = uartReqSample2000Range[i];
|
||||
}
|
||||
Serial.println("Запрос No.9 - отправлен. Установливаем шкалу 0-2000");
|
||||
} break;
|
||||
case 10: {
|
||||
for (int i = 0; i < 9; i++) {
|
||||
request_cmd[i] = uartReqSample5000Range[i];
|
||||
}
|
||||
Serial.println("Запрос No.10 - отправлен. Установливаем шкалу 0-5000");
|
||||
} break;
|
||||
case 11: {
|
||||
for (int i = 0; i < 9; i++) {
|
||||
request_cmd[i] = uartReqSampleZeroPnt[i];
|
||||
}
|
||||
Serial.println("Запрос No.11 - отправлен. Калибровка. Установливаем нулевой уровень");
|
||||
} break;
|
||||
case 12: {
|
||||
for (int i = 0; i < 9; i++) {
|
||||
request_cmd[i] = uartReqSampleReset1[i];
|
||||
}
|
||||
Serial.println("Запрос No.11 - отправлен. Запрос на Сброс");
|
||||
} break;
|
||||
case 13: {
|
||||
for (int i = 0; i < 9; i++) {
|
||||
request_cmd[i] = uartReqSamplePpm[i];
|
||||
}
|
||||
Serial.println("Запрос No.13 - отправлен. Запрос по Температуре");
|
||||
} break;
|
||||
default:
|
||||
// byte c = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
|
||||
// if nothing else matches, do the default
|
||||
// default is optional
|
||||
break;
|
||||
}
|
||||
|
||||
swSerialCO2.write(request_cmd, 9);
|
||||
|
||||
Serial.print("Request : ");
|
||||
for (int i = 0; i < 9; i++) {
|
||||
Serial.print(" ");
|
||||
Serial.print(request_cmd[i]);
|
||||
}
|
||||
Serial.println(" ");
|
||||
|
||||
delay(50);
|
||||
|
||||
unsigned char response[9];
|
||||
|
||||
Serial.print("Response :");
|
||||
swSerialCO2.readBytes(response, 9);
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
Serial.print(" ");
|
||||
Serial.print(response[i]);
|
||||
}
|
||||
Serial.println(" ");
|
||||
|
||||
byte crc = 0;
|
||||
for (int i = 1; i < 8; i++) crc += response[i];
|
||||
crc = 255 - crc;
|
||||
crc += 1;
|
||||
|
||||
if (!(response[0] == 0xFF && response[8] == crc)) {
|
||||
Serial.println("Range CRC error: " + String(crc) + " / " + String(response[8]));
|
||||
reply = 0;
|
||||
} else {
|
||||
// Serial.println("No CRC errors");
|
||||
switch (request) {
|
||||
case 1: {
|
||||
unsigned int responseHigh = (unsigned int)response[2];
|
||||
unsigned int responseLow = (unsigned int)response[3];
|
||||
unsigned int ppm = (256 * responseHigh) + responseLow;
|
||||
|
||||
Serial.print("CO2 UART = ");
|
||||
Serial.println(ppm);
|
||||
|
||||
temperature = response[4] - 44; // - 40;
|
||||
Serial.print("Temperature = ");
|
||||
Serial.println(temperature);
|
||||
temperatureUpdated = true;
|
||||
|
||||
reply = ppm;
|
||||
} break;
|
||||
|
||||
case 2: {
|
||||
reply = 1;
|
||||
Serial.println("Case 2 - OK. На запрос шкалы пришел ответ");
|
||||
} break;
|
||||
case 3: {
|
||||
// Serial.println("Case 3 - OK");
|
||||
reply = 1;
|
||||
} break;
|
||||
case 4: {
|
||||
// Serial.println("Case 4 - OK");
|
||||
reply = 1;
|
||||
} break;
|
||||
case 5: {
|
||||
// Serial.println("Case 5 - OK");
|
||||
reply = 1;
|
||||
} break;
|
||||
case 6: {
|
||||
Serial.println("Case 6 - OK");
|
||||
reply = 1;
|
||||
} break;
|
||||
case 7: {
|
||||
Serial.println("Case 7 - OK. ABC включен");
|
||||
reply = 1;
|
||||
} break;
|
||||
case 8: {
|
||||
Serial.println("Case 8 - OK. ABC выключен");
|
||||
reply = 1;
|
||||
} break;
|
||||
case 9: {
|
||||
Serial.println("Case 9 - OK. Установлена шкала 0-2000");
|
||||
reply = 1;
|
||||
prevRange = 2000;
|
||||
} break;
|
||||
case 10: {
|
||||
Serial.println("Case 9 - OK. Установлена шкала 0-5000");
|
||||
reply = 1;
|
||||
prevRange = 5000;
|
||||
} break;
|
||||
case 11: {
|
||||
reply = 1;
|
||||
Serial.println("Запрос No.11 - сработал. Калибровка. Установлен нулевой уровень");
|
||||
} break;
|
||||
|
||||
case 12: {
|
||||
reply = 1;
|
||||
Serial.println("Запрос No.12 - сработал. Сброс произошел");
|
||||
} break;
|
||||
|
||||
case 13: {
|
||||
reply = 1;
|
||||
temperature = response[4] - 44; // - 40;
|
||||
|
||||
Serial.println("Запрос No.12 - сработал. Температура получена");
|
||||
Serial.println(temperature);
|
||||
} break;
|
||||
|
||||
default:
|
||||
// byte c = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
|
||||
// if nothing else matches, do the default
|
||||
// default is optional
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Serial.print("reply = ");
|
||||
// Serial.println(reply);
|
||||
return reply;
|
||||
}
|
||||
107
src/modules/sensors/Mhz19/modinfo.json
Normal file
107
src/modules/sensors/Mhz19/modinfo.json
Normal file
@@ -0,0 +1,107 @@
|
||||
{
|
||||
"menuSection": "Сенсоры",
|
||||
|
||||
"configItem": [{
|
||||
"name": "Датчик CO2 MHZ-19 UART",
|
||||
"type": "Reading",
|
||||
"subtype": "Mhz19uart",
|
||||
"id": "co2uart",
|
||||
"widget": "anydataPpm",
|
||||
"page": "Сенсоры",
|
||||
"descr": "CO2uart",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 1,
|
||||
"pin": 0,
|
||||
"rxPin": 14,
|
||||
"txPin": 16,
|
||||
"int": 15,
|
||||
"range": 5000,
|
||||
"ABC": 1
|
||||
},
|
||||
{
|
||||
"name": "Датчик CO2 MHZ-19 PWM",
|
||||
"type": "Reading",
|
||||
"subtype": "Mhz19pwm",
|
||||
"id": "co2pwm",
|
||||
"widget": "anydataPpm",
|
||||
"page": "Сенсоры",
|
||||
"descr": "CO2pwm",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 1,
|
||||
"pin": 16,
|
||||
"int": 300
|
||||
},
|
||||
{
|
||||
"name": "Cенсор температуры от MHZ-19 UART",
|
||||
"type": "Reading",
|
||||
"subtype": "Mhz19temp",
|
||||
"id": "Mhz19temp",
|
||||
"widget": "anydataTmp",
|
||||
"page": "Сенсоры",
|
||||
"descr": "Температура",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 1,
|
||||
"rxPin": 14,
|
||||
"txPin": 16,
|
||||
"ABC": 1,
|
||||
"int": 30
|
||||
},
|
||||
{
|
||||
"name": "Рабочий диапазон от MHZ-19 UART",
|
||||
"type": "Reading",
|
||||
"subtype": "Mhz19range",
|
||||
"id": "Mhz19range",
|
||||
"widget": "anydataPpm",
|
||||
"page": "Сенсоры",
|
||||
"descr": "Диапазон",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 1,
|
||||
"rxPin": 14,
|
||||
"txPin": 16,
|
||||
"range": 5000,
|
||||
"ABC": 1,
|
||||
"int": 30
|
||||
},
|
||||
{
|
||||
"name": "Автокалибровка от MHZ-19 UART",
|
||||
"type": "Reading",
|
||||
"subtype": "Mhz19ABC",
|
||||
"id": "Mhz19ABC",
|
||||
"widget": "anydataDef",
|
||||
"page": "Сенсоры",
|
||||
"descr": "ABC",
|
||||
"rxPin": 14,
|
||||
"txPin": 16,
|
||||
"range": 5000,
|
||||
"ABC": 1,
|
||||
"int": 30
|
||||
}],
|
||||
|
||||
"about": {
|
||||
"authorName": "Alex K",
|
||||
"authorContact": "https://t.me/cmche",
|
||||
"authorGit": "",
|
||||
"specialThanks": "",
|
||||
"moduleName": "Mhz19",
|
||||
"moduleVersion": "1.0",
|
||||
"moduleDesc": "Позволяет получить значения температуры и CO2 с Mhz19.",
|
||||
"propInfo": {
|
||||
"int": "Количество секунд между опросами датчика.",
|
||||
"rxPin": "",
|
||||
"txPin": "",
|
||||
"range": "",
|
||||
"ABC": ""
|
||||
}
|
||||
},
|
||||
|
||||
"defActive": false,
|
||||
|
||||
"devices": {
|
||||
"esp32_4mb": [],
|
||||
"esp8266_4mb": []
|
||||
}
|
||||
}
|
||||
73
src/modules/sensors/RCswitch/RCswitch.cpp
Normal file
73
src/modules/sensors/RCswitch/RCswitch.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
|
||||
#include <RCSwitch.h>
|
||||
|
||||
RCSwitch mySwitch = RCSwitch();
|
||||
|
||||
class RCswitch : public IoTItem {
|
||||
private:
|
||||
int _pinRx; // Выход радио модуля
|
||||
int _pinTx; // Выход модуля передатчика
|
||||
|
||||
public:
|
||||
RCswitch(String parameters): IoTItem(parameters) {
|
||||
jsonRead(parameters, "pinRx", _pinRx);
|
||||
jsonRead(parameters, "pinTx", _pinTx);
|
||||
_interval = _interval / 1000; // корректируем величину интервала int, теперь он в миллисекундах
|
||||
if (_pinRx >= 0) {
|
||||
Serial.printf("Protocol: %d", _pinRx);
|
||||
mySwitch.enableReceive(digitalPinToInterrupt(_pinRx));
|
||||
}
|
||||
if (_pinTx >= 0)
|
||||
mySwitch.enableTransmit(_pinTx);
|
||||
}
|
||||
|
||||
void doByInterval() {
|
||||
if (_pinRx >= 0 && mySwitch.available()) {
|
||||
// Serial.print("Received ");
|
||||
//Serial.print( mySwitch.getReceivedValue() );
|
||||
// Serial.print(" / ");
|
||||
// Serial.print( mySwitch.getReceivedBitlength() );
|
||||
// Serial.print("bit ");
|
||||
// Serial.print("Protocol: ");
|
||||
// Serial.println( mySwitch.getReceivedProtocol() );
|
||||
value.valD = mySwitch.getReceivedValue();
|
||||
regEvent(value.valD, "RCswitch");
|
||||
|
||||
mySwitch.resetAvailable();
|
||||
}
|
||||
}
|
||||
|
||||
IoTValue execute(String command, std::vector<IoTValue> ¶m) {
|
||||
if (_pinTx >= 0)
|
||||
if (command == "sendBitStr") { // отправляем строку вида "000000000001010100010001"
|
||||
if (param.size()) {
|
||||
mySwitch.send(param[0].valS.c_str());
|
||||
return {};
|
||||
}
|
||||
} else if (command == "sendTriState") { // отправляем строку вида "00000FFF0F0F"
|
||||
if (param.size()) {
|
||||
mySwitch.sendTriState(param[0].valS.c_str());
|
||||
return {};
|
||||
}
|
||||
} else if (command == "sendDecimal") { // отправляем строку вида 5393 первым параметром и количество бит чтоб заполнить нулями
|
||||
if (param.size()) {
|
||||
mySwitch.send(param[0].valD, param[1].valD);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
~RCswitch() {};
|
||||
};
|
||||
|
||||
void* getAPI_RCswitch(String subtype, String param) {
|
||||
if (subtype == F("RCswitch")) {
|
||||
return new RCswitch(param);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
43
src/modules/sensors/RCswitch/modinfo.json
Normal file
43
src/modules/sensors/RCswitch/modinfo.json
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"menuSection": "Сенсоры",
|
||||
|
||||
"configItem": [{
|
||||
"name": "Сканер кнопок 433 MHz",
|
||||
"num": 31,
|
||||
"type": "Reading",
|
||||
"subtype": "RCswitch",
|
||||
"id": "rsw",
|
||||
"int": 500,
|
||||
"pinRx": 12,
|
||||
"pinTx": 12
|
||||
}],
|
||||
|
||||
"about": {
|
||||
"authorName": "Serghei Crasnicov",
|
||||
"authorContact": "https://t.me/Serghei63",
|
||||
"authorGit": "https://github.com/Serghei63",
|
||||
"specialThanks": "Valentin Khandriga @Valiuhaaa",
|
||||
"moduleName": "RCswitch",
|
||||
"moduleVersion": "1.0",
|
||||
"moduleDesc": "Позволяет принимать и передавать байт-коды на частоте 433 MHz от и для простых пультов, кнопок, радиореле",
|
||||
"propInfo": {
|
||||
"pinRx": "GPIO номер, к которому подключен радио приемник 433 MHz. Если < 0, то приемник выключен",
|
||||
"pinTx": "GPIO номер, к которому подключен радио передатчик 433 MHz. Если < 0, то передатчик выключен",
|
||||
"int": "Количество миллисекунд между опросами датчика. 0 - выключено. (устранение повторений при нажатой кнопке)"
|
||||
}
|
||||
},
|
||||
|
||||
"defActive": true,
|
||||
|
||||
"devices": {
|
||||
"esp32_4mb": [
|
||||
"rc-switch @ ^2.6.4"
|
||||
],
|
||||
"esp8266_1mb": [
|
||||
"rc-switch @ ^2.6.4"
|
||||
],
|
||||
"esp8266_4mb": [
|
||||
"rc-switch @ ^2.6.4"
|
||||
]
|
||||
}
|
||||
}
|
||||
200
src/modules/sensors/Sds011/Sds011.cpp
Normal file
200
src/modules/sensors/Sds011/Sds011.cpp
Normal file
@@ -0,0 +1,200 @@
|
||||
/******************************************************************
|
||||
Supports Sds011, implements whole Laser Dust Sensor Control Protocol V1.3,
|
||||
should also work with other Sds sensors.
|
||||
|
||||
https://github.com/lewapek/sds-dust-sensors-arduino-library
|
||||
|
||||
adapted for version 4 @cmche
|
||||
******************************************************************/
|
||||
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
|
||||
extern IoTGpio IoTgpio;
|
||||
|
||||
#include "SdsDustSensor.h"
|
||||
|
||||
//встроена в ядро для 8266, для 32 по этому же имени обращаемся к другой библиотеке plerup/EspSoftwareSerial
|
||||
#include <SoftwareSerial.h>
|
||||
|
||||
// to do убрать глобальный экземпляр
|
||||
#ifdef ESP8266
|
||||
int rxPinSDS = 13; // D7 – подключаем к Tx сенсора
|
||||
int txPinSDS = 12; // D6 – подключаем к Rx сенсора
|
||||
SdsDustSensor sds(rxPinSDS, txPinSDS);
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
#include <HardwareSerial.h>
|
||||
HardwareSerial sdsSerial(2);
|
||||
SdsDustSensor sds(sdsSerial);
|
||||
#endif
|
||||
|
||||
unsigned int warmUp;
|
||||
unsigned int period;
|
||||
|
||||
bool SDS011_init_flag = true;
|
||||
void SDS011_init();
|
||||
float Sds011request(int sensorID);
|
||||
|
||||
//Это файл сенсора, в нем осуществляется чтение сенсора.
|
||||
//для добавления сенсора вам нужно скопировать этот файл и заменить в нем текст AnalogAdc на название вашего сенсора
|
||||
//Название должно быть уникальным, коротким и отражать суть сенсора.
|
||||
|
||||
class Sds011_25 : public IoTItem {
|
||||
private:
|
||||
//=======================================================================================================
|
||||
// Секция переменных.
|
||||
//Это секция где Вы можете объявлять переменные и объекты arduino библиотек, что бы
|
||||
//впоследствии использовать их в loop и setup
|
||||
// unsigned int _pin;
|
||||
|
||||
public:
|
||||
//=======================================================================================================
|
||||
// setup()
|
||||
//это аналог setup из arduino. Здесь вы можете выполнять методы инициализации сенсора.
|
||||
//Такие как ...begin и подставлять в них параметры полученные из web интерфейса.
|
||||
//Все параметры хранятся в перемененной parameters, вы можете прочитать любой параметр используя jsonRead функции:
|
||||
// jsonReadStr, jsonReadBool, jsonReadInt
|
||||
Sds011_25(String parameters) : IoTItem(parameters) {
|
||||
// _pin = jsonReadInt(parameters, "pin");
|
||||
#ifdef ESP8266
|
||||
rxPinSDS = jsonReadInt(parameters, "rxPin");
|
||||
txPinSDS = jsonReadInt(parameters, "txPin");
|
||||
#endif
|
||||
warmUp = jsonReadInt(parameters, "warmUp"); // сек. пробужнение должен быть больше
|
||||
period = jsonReadInt(parameters, "period"); // сек. время зарогрева/продувки, затем идут замеры
|
||||
}
|
||||
//=======================================================================================================
|
||||
// doByInterval()
|
||||
//это аналог loop из arduino, но вызываемый каждые int секунд, заданные в настройках. Здесь вы должны выполнить чтение вашего сенсора
|
||||
//а затем выполнить regEvent - это регистрация произошедшего события чтения
|
||||
//здесь так же доступны все переменные из секции переменных, и полученные в setup
|
||||
//если у сенсора несколько величин то делайте несколько regEvent
|
||||
//не используйте delay - помните, что данный loop общий для всех модулей. Если у вас планируется длительная операция, постарайтесь разбить ее на порции
|
||||
//и выполнить за несколько тактов
|
||||
void doByInterval() {
|
||||
SDS011_init();
|
||||
Serial.println("request from 25");
|
||||
value.valD = Sds011request(25);
|
||||
|
||||
regEvent(value.valD, "Sds011_25"); //обязательный вызов хотяб один
|
||||
}
|
||||
|
||||
~Sds011_25(){};
|
||||
};
|
||||
|
||||
//////////////////////////////////// for PM 10//=
|
||||
|
||||
class Sds011_10 : public IoTItem {
|
||||
private:
|
||||
//=======================================================================================================
|
||||
// Секция переменных.
|
||||
//Это секция где Вы можете объявлять переменные и объекты arduino библиотек, что бы
|
||||
//впоследствии использовать их в loop и setup
|
||||
|
||||
public:
|
||||
//=======================================================================================================
|
||||
// setup()
|
||||
//это аналог setup из arduino. Здесь вы можете выполнять методы инициализации сенсора.
|
||||
//Такие как ...begin и подставлять в них параметры полученные из web интерфейса.
|
||||
//Все параметры хранятся в перемененной parameters, вы можете прочитать любой параметр используя jsonRead функции:
|
||||
// jsonReadStr, jsonReadBool, jsonReadInt
|
||||
Sds011_10(String parameters) : IoTItem(parameters) {
|
||||
// _pin = jsonReadInt(parameters, "pin");
|
||||
#ifdef ESP8266
|
||||
rxPinSDS = jsonReadInt(parameters, "rxPin");
|
||||
txPinSDS = jsonReadInt(parameters, "txPin");
|
||||
#endif
|
||||
warmUp = jsonReadInt(parameters, "warmUp"); // сек. пробужнение должен быть больше
|
||||
period = jsonReadInt(parameters, "period"); // сек. время зарогрева/продувки, затем идут замеры
|
||||
}
|
||||
//=======================================================================================================
|
||||
// doByInterval()
|
||||
//это аналог loop из arduino, но вызываемый каждые int секунд, заданные в настройках. Здесь вы должны выполнить чтение вашего сенсора
|
||||
//а затем выполнить regEvent - это регистрация произошедшего события чтения
|
||||
//здесь так же доступны все переменные из секции переменных, и полученные в setup
|
||||
//если у сенсора несколько величин то делайте несколько regEvent
|
||||
//не используйте delay - помните, что данный loop общий для всех модулей. Если у вас планируется длительная операция, постарайтесь разбить ее на порции
|
||||
//и выполнить за несколько тактов
|
||||
|
||||
void doByInterval() {
|
||||
SDS011_init();
|
||||
Serial.println("request from 10");
|
||||
value.valD = Sds011request(10);
|
||||
|
||||
regEvent(value.valD, "Sds011_10"); //обязательный вызов хотяб один
|
||||
}
|
||||
~Sds011_10(){};
|
||||
};
|
||||
|
||||
//после замены названия сенсора, на функцию можно не обращать внимания
|
||||
//если сенсор предполагает использование общего объекта библиотеки для нескольких экземпляров сенсора, то в данной функции необходимо предусмотреть
|
||||
//создание и контроль соответствующих глобальных переменных
|
||||
void* getAPI_Sds011(String subtype, String param) {
|
||||
if (subtype == F("Sds011_25")) {
|
||||
return new Sds011_25(param);
|
||||
} else if (subtype == F("Sds011_10")) {
|
||||
return new Sds011_10(param);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
float Sds011request(int sensorID) {
|
||||
float reply = 0;
|
||||
static int a = 0;
|
||||
static float pm25 = 0;
|
||||
static float pm10 = 0;
|
||||
static int startMillis = millis();
|
||||
|
||||
if (a == 0) {
|
||||
Serial.print("SDS011 ... warmUp = ");
|
||||
Serial.print(warmUp);
|
||||
Serial.print(" period = ");
|
||||
Serial.println(period);
|
||||
sds.wakeup();
|
||||
startMillis = millis();
|
||||
a = a + 1;
|
||||
}
|
||||
if (a == 1 && millis() >= (startMillis + warmUp * 1000)) {
|
||||
PmResult pm = sds.readPm();
|
||||
if (pm.isOk()) {
|
||||
pm25 = pm.pm25;
|
||||
pm10 = pm.pm10;
|
||||
Serial.print("PM2.5 = ");
|
||||
Serial.print(pm25);
|
||||
Serial.print(" PM10 = ");
|
||||
Serial.println(pm10);
|
||||
a = a + 1;
|
||||
sds.sleep();
|
||||
} else {
|
||||
Serial.print("Could not read values from sensor 25, reason: ");
|
||||
Serial.println(pm.statusToString());
|
||||
a = a + 1;
|
||||
}
|
||||
}
|
||||
if (a > 1 && millis() >= (startMillis + period * 1000)) {
|
||||
Serial.println("end of period for pm25");
|
||||
a = 0;
|
||||
}
|
||||
if (sensorID == 25) {
|
||||
reply = pm25;
|
||||
}
|
||||
if (sensorID == 10) {
|
||||
reply = pm10;
|
||||
}
|
||||
return reply;
|
||||
}
|
||||
|
||||
void SDS011_init() {
|
||||
if (SDS011_init_flag) {
|
||||
sds.begin();
|
||||
Serial.println(sds.queryFirmwareVersion().toString()); // prints firmware version
|
||||
// Serial.println(sds.setActiveReportingMode().toString()); //
|
||||
String ReportingMode = sds.setActiveReportingMode().toString();
|
||||
Serial.println(ReportingMode);
|
||||
if (ReportingMode == "Mode: active") {
|
||||
SDS011_init_flag = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
66
src/modules/sensors/Sds011/modinfo.json
Normal file
66
src/modules/sensors/Sds011/modinfo.json
Normal file
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"menuSection": "Сенсоры",
|
||||
|
||||
"configItem": [{
|
||||
"name": "Датчик пыли SDS011 PM25",
|
||||
"type": "Reading",
|
||||
"subtype": "Sds011_25",
|
||||
"id": "pmuart25",
|
||||
"widget": "anydataPpm",
|
||||
"page": "Сенсоры",
|
||||
"descr": "PM-2.5",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 10,
|
||||
"rxPin": 13,
|
||||
"txPin": 12,
|
||||
"int": 15,
|
||||
"warmUp": 30,
|
||||
"period": 300
|
||||
},
|
||||
{
|
||||
"name": "Датчик пыли SDS011 PM10",
|
||||
"type": "Reading",
|
||||
"subtype": "Sds011_10",
|
||||
"id": "pmuart10",
|
||||
"widget": "anydataPpm",
|
||||
"page": "Сенсоры",
|
||||
"descr": "PM-10",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 10,
|
||||
"rxPin": 13,
|
||||
"txPin": 12,
|
||||
"int": 15,
|
||||
"warmUp": 30,
|
||||
"period": 300
|
||||
}],
|
||||
|
||||
"about": {
|
||||
"authorName": "Alex K",
|
||||
"authorContact": "https://t.me/cmche",
|
||||
"authorGit": "",
|
||||
"specialThanks": "",
|
||||
"moduleName": "Sds011",
|
||||
"moduleVersion": "1.0",
|
||||
"moduleDesc": "Позволяет получить значения концентрации пыли в воздухе с Sds011.",
|
||||
"propInfo": {
|
||||
"int": "Количество секунд между опросами датчика.",
|
||||
"rxPin": "",
|
||||
"txPin": "",
|
||||
"warmUp": "",
|
||||
"period": ""
|
||||
}
|
||||
},
|
||||
|
||||
"defActive": false,
|
||||
|
||||
"devices": {
|
||||
"esp32_4mb": [
|
||||
"Nova Fitness Sds dust sensors library@1.5.1"
|
||||
],
|
||||
"esp8266_4mb": [
|
||||
"Nova Fitness Sds dust sensors library@1.5.1"
|
||||
]
|
||||
}
|
||||
}
|
||||
54
src/modules/sensors/Sht20/Sht20.cpp
Normal file
54
src/modules/sensors/Sht20/Sht20.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
|
||||
#include "Wire.h"
|
||||
#include "SHT2x.h"
|
||||
|
||||
|
||||
SHT2x* sht = nullptr;
|
||||
|
||||
class Sht20t : public IoTItem {
|
||||
public:
|
||||
Sht20t(String parameters): IoTItem(parameters) { }
|
||||
|
||||
void doByInterval() {
|
||||
sht->read();
|
||||
value.valD = sht->getTemperature();
|
||||
if (value.valD > -46.85F) regEvent(value.valD, "Sht20t");
|
||||
else SerialPrint("E", "Sensor Sht20t", "Error");
|
||||
}
|
||||
|
||||
~Sht20t() {};
|
||||
};
|
||||
|
||||
class Sht20h : public IoTItem {
|
||||
public:
|
||||
Sht20h(String parameters): IoTItem(parameters) { }
|
||||
|
||||
void doByInterval() {
|
||||
sht->read();
|
||||
value.valD = sht->getHumidity();
|
||||
if (value.valD != -6) regEvent(value.valD, "Sht20h");
|
||||
else SerialPrint("E", "Sensor Sht20h", "Error");
|
||||
}
|
||||
|
||||
~Sht20h() {};
|
||||
};
|
||||
|
||||
|
||||
void* getAPI_Sht20(String subtype, String param) {
|
||||
if (subtype == F("Sht20t") || subtype == F("Sht20h")) {
|
||||
if (!sht) {
|
||||
sht = new SHT2x;
|
||||
if (sht) sht->begin();
|
||||
}
|
||||
|
||||
if (subtype == F("Sht20t")) {
|
||||
return new Sht20t(param);
|
||||
} else if (subtype == F("Sht20h")) {
|
||||
return new Sht20h(param);
|
||||
}
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
50
src/modules/sensors/Sht20/modinfo.json
Normal file
50
src/modules/sensors/Sht20/modinfo.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"menuSection": "Сенсоры",
|
||||
|
||||
"configItem": [{
|
||||
"name": "Cенсор температуры Sht20",
|
||||
"type": "Reading",
|
||||
"subtype": "Sht20t",
|
||||
"id": "tmp2",
|
||||
"widget": "anydataTmp",
|
||||
"page": "Сенсоры",
|
||||
"descr": "Температура",
|
||||
"int": 15,
|
||||
"round": 1
|
||||
},
|
||||
{
|
||||
"name": "Cенсор влажности Sht20",
|
||||
"type": "Reading",
|
||||
"subtype": "Sht20h",
|
||||
"id": "Hum2",
|
||||
"widget": "anydataHum",
|
||||
"page": "Сенсоры",
|
||||
"descr": "Влажность",
|
||||
"int": 15,
|
||||
"round": 1
|
||||
}],
|
||||
|
||||
"about": {
|
||||
"authorName": "Ilya Belyakov",
|
||||
"authorContact": "https://t.me/Biveraxe",
|
||||
"authorGit": "https://github.com/biveraxe",
|
||||
"specialThanks": "",
|
||||
"moduleName": "Sht20",
|
||||
"moduleVersion": "1.0",
|
||||
"moduleDesc": "Позволяет получить значения температуры и влажности с Sht20.",
|
||||
"propInfo": {
|
||||
"int": "Количество секунд между опросами датчика."
|
||||
}
|
||||
},
|
||||
|
||||
"defActive": true,
|
||||
|
||||
"devices": {
|
||||
"esp32_4mb": [
|
||||
"robtillaart/SHT2x@^0.1.1"
|
||||
],
|
||||
"esp8266_4mb": [
|
||||
"robtillaart/SHT2x@^0.1.1"
|
||||
]
|
||||
}
|
||||
}
|
||||
61
src/modules/sensors/Sht30/Sht30.cpp
Normal file
61
src/modules/sensors/Sht30/Sht30.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
/******************************************************************
|
||||
Simple library for the WEMOS SHT30 Shield.
|
||||
|
||||
https://github.com/wemos/WEMOS_SHT3x_Arduino_Library
|
||||
|
||||
adapted for version 4 @Serghei63
|
||||
******************************************************************/
|
||||
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
|
||||
|
||||
#include "Wire.h"
|
||||
#include <WEMOS_SHT3X.h>
|
||||
|
||||
SHT3X sht30(0x45);
|
||||
|
||||
class Sht30t : public IoTItem {
|
||||
public:
|
||||
Sht30t(String parameters): IoTItem(parameters) { }
|
||||
|
||||
void doByInterval() {
|
||||
if(sht30.get()==0){
|
||||
value.valD = sht30.cTemp;
|
||||
|
||||
SerialPrint("E", "Sensor Sht30t", "OK");
|
||||
|
||||
if (value.valD < -46.85F) regEvent(value.valD, "Sht30t"); // TODO: найти способ понимания ошибки получения данных
|
||||
else SerialPrint("E", "Sensor Sht30t", "Error");
|
||||
}
|
||||
}
|
||||
~Sht30t() {};
|
||||
};
|
||||
|
||||
class Sht30h : public IoTItem {
|
||||
public:
|
||||
Sht30h(String parameters): IoTItem(parameters) { }
|
||||
|
||||
void doByInterval() {
|
||||
if(sht30.get()==0){
|
||||
value.valD = sht30.humidity;
|
||||
|
||||
SerialPrint("E", "Sensor Sht30h", "OK");
|
||||
if (value.valD != -6) regEvent(value.valD, "Sht30h"); // TODO: найти способ понимания ошибки получения данных
|
||||
else SerialPrint("E", "Sensor Sht30h", "Error");
|
||||
}
|
||||
}
|
||||
~Sht30h() {};
|
||||
};
|
||||
|
||||
|
||||
void* getAPI_Sht30(String subtype, String param) {
|
||||
if (subtype == F("Sht30t")){
|
||||
return new Sht30t(param);
|
||||
}
|
||||
if (subtype == F("Sht30h")) {
|
||||
return new Sht30h(param);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
50
src/modules/sensors/Sht30/modinfo.json
Normal file
50
src/modules/sensors/Sht30/modinfo.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"menuSection": "Сенсоры",
|
||||
|
||||
"configItem": [{
|
||||
"name": "Cенсор температуры Sht30",
|
||||
"type": "Reading",
|
||||
"subtype": "Sht30t",
|
||||
"id": "tmp30",
|
||||
"widget": "anydataTmp",
|
||||
"page": "Сенсоры",
|
||||
"descr": "SHT30 Температура",
|
||||
"int": 15,
|
||||
"round": 1
|
||||
},
|
||||
{
|
||||
"name": "Cенсор влажности Sht30",
|
||||
"type": "Reading",
|
||||
"subtype": "Sht30h",
|
||||
"id": "Hum30",
|
||||
"widget": "anydataHum",
|
||||
"page": "Сенсоры",
|
||||
"descr": "SHT30 Влажность",
|
||||
"int": 15,
|
||||
"round": 1
|
||||
}],
|
||||
|
||||
"about": {
|
||||
"authorName": "Serghei Crasnicov",
|
||||
"authorContact": "https://t.me/Serghei63",
|
||||
"authorGit": "https://github.com/Serghei63",
|
||||
"specialThanks": "",
|
||||
"moduleName": "Sht30",
|
||||
"moduleVersion": "1.0",
|
||||
"moduleDesc": "Позволяет получить температуру и влажность с датчика Sht30.",
|
||||
"propInfo": {
|
||||
"int": "Количество секунд между опросами датчика."
|
||||
}
|
||||
},
|
||||
|
||||
"defActive": true,
|
||||
|
||||
"devices": {
|
||||
"esp32_4mb": [
|
||||
"WEMOS SHT3x@1.0.0"
|
||||
],
|
||||
"esp8266_4mb": [
|
||||
"WEMOS SHT3x@1.0.0"
|
||||
]
|
||||
}
|
||||
}
|
||||
49
src/modules/sensors/Sonar/Sonar.cpp
Normal file
49
src/modules/sensors/Sonar/Sonar.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
|
||||
extern IoTGpio IoTgpio;
|
||||
|
||||
|
||||
class Sonar : public IoTItem {
|
||||
private:
|
||||
unsigned int _pinTrig, _pinEcho;
|
||||
|
||||
public:
|
||||
Sonar(String parameters): IoTItem(parameters) {
|
||||
_pinTrig = jsonReadInt(parameters, "pinTrig");
|
||||
_pinEcho = jsonReadInt(parameters, "pinEcho");
|
||||
|
||||
pinMode(_pinTrig, OUTPUT);
|
||||
pinMode(_pinEcho, INPUT);
|
||||
}
|
||||
|
||||
void doByInterval() {
|
||||
// value.valD = IoTgpio.analogRead(_pin);
|
||||
// для большей точности установим значение LOW на пине Trig
|
||||
digitalWrite(_pinTrig, LOW);
|
||||
delayMicroseconds(2);
|
||||
// Теперь установим высокий уровень на пине Trig
|
||||
digitalWrite(_pinTrig, HIGH);
|
||||
// Подождем 10 μs
|
||||
delayMicroseconds(10);
|
||||
digitalWrite(_pinTrig, LOW);
|
||||
// Рассчитаем расстояние
|
||||
value.valD = pulseIn(_pinEcho, HIGH) / 58;
|
||||
// Выведем значение в Serial Monitor
|
||||
Serial.print(value.valD);
|
||||
Serial.println(" cm");
|
||||
|
||||
regEvent(value.valD, "Sonar");
|
||||
}
|
||||
|
||||
~Sonar() {};
|
||||
};
|
||||
|
||||
|
||||
void* getAPI_Sonar(String subtype, String param) {
|
||||
if (subtype == F("Sonar")) {
|
||||
return new Sonar(param);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
40
src/modules/sensors/Sonar/modinfo.json
Normal file
40
src/modules/sensors/Sonar/modinfo.json
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"menuSection": "Сенсоры",
|
||||
|
||||
"configItem": [{
|
||||
"name": "Сонар HC-SR04",
|
||||
"num": 1,
|
||||
"type": "Reading",
|
||||
"subtype": "Sonar",
|
||||
"id": "sonar",
|
||||
"widget": "anydataTmp",
|
||||
"page": "Сенсоры",
|
||||
"descr": "Расстояние (см)",
|
||||
|
||||
"pinTrig": 5,
|
||||
"pinEcho": 4,
|
||||
"int": 5
|
||||
}],
|
||||
|
||||
"about": {
|
||||
"authorName": "Ilya Belyakov",
|
||||
"authorContact": "https://t.me/Biveraxe",
|
||||
"authorGit": "https://github.com/biveraxe",
|
||||
"specialThanks": "",
|
||||
"moduleName": "Sonar",
|
||||
"moduleVersion": "1.0",
|
||||
"moduleDesc": "Позволяет получить значение расстояния до препятствия с использованием ультразвукового датчика (в сантиметрах).",
|
||||
"propInfo": {
|
||||
"pinTrig": "GPIO контакта Trig",
|
||||
"pinEcho": "GPIO контакта Echo",
|
||||
"int": "Количество секунд между опросами датчика."
|
||||
}
|
||||
},
|
||||
|
||||
"defActive": true,
|
||||
|
||||
"devices": {
|
||||
"esp32_4mb": [],
|
||||
"esp8266_4mb": []
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user